2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
18 extern zend_module_entry raphf_module_entry
;
19 #define phpext_raphf_ptr &raphf_module_entry
21 #define PHP_RAPHF_VERSION "1.0.4"
24 # define PHP_RAPHF_API __declspec(dllexport)
25 #elif defined(__GNUC__) && __GNUC__ >= 4
26 # define PHP_RAPHF_API extern __attribute__ ((visibility("default")))
28 # define PHP_RAPHF_API extern
38 * A resource constructor.
40 * @param opaque is the \a data from php_persistent_handle_provide()
41 * @param init_arg is the \a init_arg from php_resource_factory_init()
42 * @return the created (persistent) handle
44 typedef void *(*php_resource_factory_handle_ctor_t
)(void *opaque
,
45 void *init_arg TSRMLS_DC
);
48 * The copy constructor of a resource.
50 * @param opaque the factory's data
51 * @param handle the (persistent) handle to copy
53 typedef void *(*php_resource_factory_handle_copy_t
)(void *opaque
,
54 void *handle TSRMLS_DC
);
57 * The destructor of a resource.
59 * @param opaque the factory's data
60 * @param handle the handle to destroy
62 typedef void (*php_resource_factory_handle_dtor_t
)(void *opaque
,
63 void *handle TSRMLS_DC
);
66 * The resource ops consisting of a ctor, a copy ctor and a dtor.
68 * Define this ops and register them with php_persistent_handle_provide()
71 typedef struct php_resource_factory_ops
{
72 /** The resource constructor */
73 php_resource_factory_handle_ctor_t ctor
;
74 /** The resource's copy constructor */
75 php_resource_factory_handle_copy_t copy
;
76 /** The resource's destructor */
77 php_resource_factory_handle_dtor_t dtor
;
78 } php_resource_factory_ops_t
;
81 * The resource factory.
83 typedef struct php_resource_factory
{
84 /** The resource ops */
85 php_resource_factory_ops_t fops
;
86 /** Opaque user data */
88 /** User data destructor */
89 void (*dtor
)(void *data
);
90 /** How often this factory is referenced */
92 } php_resource_factory_t
;
95 * Initialize a resource factory.
97 * If you register a \a dtor for a resource factory used with a persistent
98 * handle provider, be sure to call php_persistent_handle_cleanup() for your
99 * registered provider in MSHUTDOWN, else the dtor will point to no longer
100 * available memory if the extension has already been unloaded.
102 * @param f the factory to initialize; if NULL allocated on the heap
103 * @param fops the resource ops to assign to the factory
104 * @param data opaque user data; may be NULL
105 * @param dtor a destructor for the data; may be NULL
106 * @return \a f or an allocated resource factory
108 PHP_RAPHF_API php_resource_factory_t
*php_resource_factory_init(
109 php_resource_factory_t
*f
, php_resource_factory_ops_t
*fops
, void *data
,
110 void (*dtor
)(void *data
));
113 * Increase the refcount of the resource factory.
115 * @param rf the resource factory
116 * @return the new refcount
118 PHP_RAPHF_API
unsigned php_resource_factory_addref(php_resource_factory_t
*rf
);
121 * Destroy the resource factory.
123 * If the factory's refcount reaches 0, the \a dtor for \a data is called.
125 * @param f the resource factory
127 PHP_RAPHF_API
void php_resource_factory_dtor(php_resource_factory_t
*f
);
130 * Destroy and free the resource factory.
132 * Calls php_resource_factory_dtor() and frees \æ f if the factory's refcount
135 * @param f the resource factory
137 PHP_RAPHF_API
void php_resource_factory_free(php_resource_factory_t
**f
);
140 * Construct a resource by the resource factory \a f
142 * @param f the resource factory
143 * @param init_arg for the resource constructor
144 * @return the new resource
146 PHP_RAPHF_API
void *php_resource_factory_handle_ctor(php_resource_factory_t
*f
,
147 void *init_arg TSRMLS_DC
);
150 * Create a copy of the resource \a handle
152 * @param f the resource factory
153 * @param handle the resource to copy
156 PHP_RAPHF_API
void *php_resource_factory_handle_copy(php_resource_factory_t
*f
,
157 void *handle TSRMLS_DC
);
160 * Destroy (and free) the resource
162 * @param f the resource factory
163 * @param handle the resource to destroy
165 PHP_RAPHF_API
void php_resource_factory_handle_dtor(php_resource_factory_t
*f
,
166 void *handle TSRMLS_DC
);
169 * Persistent handles storage
171 typedef struct php_persistent_handle_list
{
172 /** Storage of free resources */
174 /** Count of acquired resources */
176 } php_persistent_handle_list_t
;
179 * Definition of a persistent handle provider.
180 * Holds a resource factory an a persistent handle list.
182 typedef struct php_persistent_handle_provider
{
184 * The list of free handles.
185 * Hash of "ident" => array(handles) entries. Persistent handles are
186 * acquired out of this list.
188 php_persistent_handle_list_t list
;
191 * The resource factory.
192 * New handles are created by this factory.
194 php_resource_factory_t rf
;
195 } php_persistent_handle_provider_t
;
197 typedef struct php_persistent_handle_factory php_persistent_handle_factory_t
;
200 * Wakeup the persistent handle on re-acquisition.
202 typedef void (*php_persistent_handle_wakeup_t
)(
203 php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
);
205 * Retire the persistent handle on release.
207 typedef void (*php_persistent_handle_retire_t
)(
208 php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
);
211 * Definition of a persistent handle factory.
213 * php_persistent_handle_concede() will return a pointer to a
214 * php_persistent_handle_factory if a provider for the \a name_str has
215 * been registered with php_persistent_handle_provide().
217 struct php_persistent_handle_factory
{
218 /** The persistent handle provider */
219 php_persistent_handle_provider_t
*provider
;
220 /** The persistent handle wakeup routine; may be NULL */
221 php_persistent_handle_wakeup_t wakeup
;
222 /** The persistent handle retire routine; may be NULL */
223 php_persistent_handle_retire_t retire
;
225 /** The ident for which this factory manages resources */
233 /** Whether it has to be free'd on php_persistent_handle_abandon() */
234 unsigned free_on_abandon
:1;
238 * Register a persistent handle provider in MINIT.
240 * Registers a factory provider for \a name_str with \a fops resource factory
241 * ops. Call this in your MINIT.
243 * A php_resource_factory will be created with \a fops, \a data and \a dtor
244 * and will be stored together with a php_persistent_handle_list in the global
247 * A php_persistent_handle_factory can then be retrieved by
248 * php_persistent_handle_concede() at runtime.
250 * @param name_str the provider name, e.g. "http\Client\Curl"
251 * @param name_len the provider name length, e.g. strlen("http\Client\Curl")
252 * @param fops the resource factory ops
253 * @param data opaque user data
254 * @param dtor \a data destructor
255 * @return SUCCESS/FAILURE
257 PHP_RAPHF_API
int /* SUCCESS|FAILURE */ php_persistent_handle_provide(
258 const char *name_str
, size_t name_len
, php_resource_factory_ops_t
*fops
,
259 void *data
, void (*dtor
)(void *) TSRMLS_DC
);
262 * Retrieve a persistent handle factory at runtime.
264 * If a persistent handle provider has been registered for \a name_str, a new
265 * php_persistent_handle_factory creating resources in the \a ident_str
266 * namespace will be constructed.
268 * The wakeup routine \a wakeup and the retire routine \a retire will be
269 * assigned to the new php_persistent_handle_factory.
271 * @param a pointer to a factory; allocated on the heap if NULL
272 * @param name_str the provider name, e.g. "http\Client\Curl"
273 * @param name_len the provider name length, e.g. strlen("http\Client\Curl")
274 * @param ident_str the subsidiary namespace, e.g. "php.net:80"
275 * @param ident_len the subsidiary namespace lenght, e.g. strlen("php.net:80")
276 * @param wakeup any persistent handle wakeup routine
277 * @param retire any persistent handle retire routine
278 * @return \a a or an allocated persistent handle factory
280 PHP_RAPHF_API php_persistent_handle_factory_t
*php_persistent_handle_concede(
281 php_persistent_handle_factory_t
*a
, const char *name_str
,
282 size_t name_len
, const char *ident_str
, size_t ident_len
,
283 php_persistent_handle_wakeup_t wakeup
,
284 php_persistent_handle_retire_t retire TSRMLS_DC
);
287 * Abandon the persistent handle factory.
289 * Destroy a php_persistent_handle_factory created by
290 * php_persistent_handle_concede(). If the memory for the factory was allocated,
291 * it will automatically be free'd.
293 * @param a the persistent handle factory to destroy
295 PHP_RAPHF_API
void php_persistent_handle_abandon(
296 php_persistent_handle_factory_t
*a
);
299 * Acquire a persistent handle.
301 * That is, either re-use a resource from the free list or create a new handle.
303 * If a handle is acquired from the free list, the
304 * php_persistent_handle_factory::wakeup callback will be executed for that
307 * @param a the persistent handle factory
308 * @param init_arg the \a init_arg for php_resource_factory_handle_ctor()
309 * @return the acquired resource
311 PHP_RAPHF_API
void *php_persistent_handle_acquire(
312 php_persistent_handle_factory_t
*a
, void *init_arg TSRMLS_DC
);
315 * Release a persistent handle.
317 * That is, either put it back into the free list for later re-use or clean it
318 * up with php_resource_factory_handle_dtor().
320 * If a handle is put back into the free list, the
321 * php_persistent_handle_factory::retire callback will be executed for that
324 * @param a the persistent handle factory
325 * @param handle the handle to release
327 PHP_RAPHF_API
void php_persistent_handle_release(
328 php_persistent_handle_factory_t
*a
, void *handle TSRMLS_DC
);
331 * Copy a persistent handle.
333 * Let the underlying resource factory copy the \a handle.
335 * @param a the persistent handle factory
336 * @param handle the resource to accrete
338 PHP_RAPHF_API
void *php_persistent_handle_accrete(
339 php_persistent_handle_factory_t
*a
, void *handle TSRMLS_DC
);
342 * Retrieve persistent handle resource factory ops.
344 * These ops can be used to mask a persistent handle factory as
345 * resource factory itself, so you can transparently use the
346 * resource factory API, both for persistent and non-persistent
350 * ~~~~~~~~~~~~~~~{.c}
351 * php_resource_factory_t *create_my_rf(const char *persistent_id_str,
352 * size_t persistent_id_len TSRMLS_DC)
354 * php_resource_factory_t *rf;
356 * if (persistent_id_str) {
357 * php_persistent_handle_factory_t *pf;
358 * php_resource_factory_ops_t *ops;
360 * ops = php_persistent_handle_get_resource_factory_ops();
362 * pf = php_persistent_handle_concede(NULL, "my", 2,
363 * persistent_id_str, persistent_id_len, NULL, NULL TSRMLS_CC);
365 * rf = php_resource_factory_init(NULL, ops, pf, php_persistent_handle_abandon);
367 * rf = php_resource_factory_init(NULL, &myops, NULL, NULL);
373 PHP_RAPHF_API php_resource_factory_ops_t
*
374 php_persistent_handle_get_resource_factory_ops(void);
377 * Clean persistent handles up.
379 * Destroy persistent handles of provider \a name_str and in subsidiary
380 * namespace \a ident_str.
382 * If \a name_str is NULL, all persistent handles of all providers with a
383 * matching \a ident_str will be cleaned up.
385 * If \a ident_str is NULL all persistent handles of the provider will be
388 * Ergo, if both, \a name_str and \a ident_str are NULL, then all
389 * persistent handles will be cleaned up.
391 * You must call this in MSHUTDOWN, if your resource factory ops hold a
392 * registered php_resource_factory::dtor, else the dtor will point to
393 * memory not any more available if the extension has already been unloaded.
395 * @param name_str the provider name; may be NULL
396 * @param name_len the provider name length
397 * @param ident_str the subsidiary namespace name; may be NULL
398 * @param ident_len the subsidiary namespace name length
400 PHP_RAPHF_API
void php_persistent_handle_cleanup(const char *name_str
,
401 size_t name_len
, const char *ident_str
, size_t ident_len TSRMLS_DC
);
404 * Retrieve statistics about the current process/thread's persistent handles.
406 * @return a HashTable like:
418 PHP_RAPHF_API HashTable
*php_persistent_handle_statall(HashTable
*ht TSRMLS_DC
);
420 #endif /* PHP_RAPHF_H */
428 * vim600: noet sw=4 ts=4 fdm=marker
429 * vim<600: noet sw=4 ts=4