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 "2.0.0dev"
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
, void *init_arg
);
47 * The copy constructor of a resource.
49 * @param opaque the factory's data
50 * @param handle the (persistent) handle to copy
52 typedef void *(*php_resource_factory_handle_copy_t
)(void *opaque
, void *handle
);
55 * The destructor of a resource.
57 * @param opaque the factory's data
58 * @param handle the handle to destroy
60 typedef void (*php_resource_factory_handle_dtor_t
)(void *opaque
, void *handle
);
63 * The resource ops consisting of a ctor, a copy ctor and a dtor.
65 * Define this ops and register them with php_persistent_handle_provide()
68 typedef struct php_resource_factory_ops
{
69 /** The resource constructor */
70 php_resource_factory_handle_ctor_t ctor
;
71 /** The resource's copy constructor */
72 php_resource_factory_handle_copy_t copy
;
73 /** The resource's destructor */
74 php_resource_factory_handle_dtor_t dtor
;
75 } php_resource_factory_ops_t
;
78 * The resource factory.
80 typedef struct php_resource_factory
{
81 /** The resource ops */
82 php_resource_factory_ops_t fops
;
83 /** Opaque user data */
85 /** User data destructor */
86 void (*dtor
)(void *data
);
87 /** How often this factory is referenced */
89 } php_resource_factory_t
;
92 * Initialize a resource factory.
94 * If you register a \a dtor for a resource factory used with a persistent
95 * handle provider, be sure to call php_persistent_handle_cleanup() for your
96 * registered provider in MSHUTDOWN, else the dtor will point to no longer
97 * available memory if the extension has already been unloaded.
99 * @param f the factory to initialize; if NULL allocated on the heap
100 * @param fops the resource ops to assign to the factory
101 * @param data opaque user data; may be NULL
102 * @param dtor a destructor for the data; may be NULL
103 * @return \a f or an allocated resource factory
105 PHP_RAPHF_API php_resource_factory_t
*php_resource_factory_init(
106 php_resource_factory_t
*f
, php_resource_factory_ops_t
*fops
, void *data
,
107 void (*dtor
)(void *data
));
110 * Increase the refcount of the resource factory.
112 * @param rf the resource factory
113 * @return the new refcount
115 PHP_RAPHF_API
unsigned php_resource_factory_addref(php_resource_factory_t
*rf
);
118 * Destroy the resource factory.
120 * If the factory's refcount reaches 0, the \a dtor for \a data is called.
122 * @param f the resource factory
124 PHP_RAPHF_API
void php_resource_factory_dtor(php_resource_factory_t
*f
);
127 * Destroy and free the resource factory.
129 * Calls php_resource_factory_dtor() and frees \a f if the factory's refcount
132 * @param f the resource factory
134 PHP_RAPHF_API
void php_resource_factory_free(php_resource_factory_t
**f
);
137 * Construct a resource by the resource factory \a f
139 * @param f the resource factory
140 * @param init_arg for the resource constructor
141 * @return the new resource
143 PHP_RAPHF_API
void *php_resource_factory_handle_ctor(php_resource_factory_t
*f
,
147 * Create a copy of the resource \a handle
149 * @param f the resource factory
150 * @param handle the resource to copy
153 PHP_RAPHF_API
void *php_resource_factory_handle_copy(php_resource_factory_t
*f
,
157 * Destroy (and free) the resource
159 * @param f the resource factory
160 * @param handle the resource to destroy
162 PHP_RAPHF_API
void php_resource_factory_handle_dtor(php_resource_factory_t
*f
,
166 * Persistent handles storage
168 typedef struct php_persistent_handle_list
{
169 /** Storage of free resources */
171 /** Count of acquired resources */
173 } php_persistent_handle_list_t
;
176 * Definition of a persistent handle provider.
177 * Holds a resource factory an a persistent handle list.
179 typedef struct php_persistent_handle_provider
{
181 * The list of free handles.
182 * Hash of "ident" => array(handles) entries. Persistent handles are
183 * acquired out of this list.
185 php_persistent_handle_list_t list
;
188 * The resource factory.
189 * New handles are created by this factory.
191 php_resource_factory_t rf
;
192 } php_persistent_handle_provider_t
;
194 typedef struct php_persistent_handle_factory php_persistent_handle_factory_t
;
197 * Wakeup the persistent handle on re-acquisition.
199 typedef void (*php_persistent_handle_wakeup_t
)(
200 php_persistent_handle_factory_t
*f
, void **handle
);
202 * Retire the persistent handle on release.
204 typedef void (*php_persistent_handle_retire_t
)(
205 php_persistent_handle_factory_t
*f
, void **handle
);
208 * Definition of a persistent handle factory.
210 * php_persistent_handle_concede() will return a pointer to a
211 * php_persistent_handle_factory if a provider for the \a name_str has
212 * been registered with php_persistent_handle_provide().
214 struct php_persistent_handle_factory
{
215 /** The persistent handle provider */
216 php_persistent_handle_provider_t
*provider
;
217 /** The persistent handle wakeup routine; may be NULL */
218 php_persistent_handle_wakeup_t wakeup
;
219 /** The persistent handle retire routine; may be NULL */
220 php_persistent_handle_retire_t retire
;
222 /** The ident for which this factory manages resources */
230 /** Whether it has to be free'd on php_persistent_handle_abandon() */
231 unsigned free_on_abandon
:1;
235 * Register a persistent handle provider in MINIT.
237 * Registers a factory provider for \a name_str with \a fops resource factory
238 * ops. Call this in your MINIT.
240 * A php_resource_factory will be created with \a fops, \a data and \a dtor
241 * and will be stored together with a php_persistent_handle_list in the global
244 * A php_persistent_handle_factory can then be retrieved by
245 * php_persistent_handle_concede() at runtime.
247 * @param name_str the provider name, e.g. "http\Client\Curl"
248 * @param name_len the provider name length, e.g. strlen("http\Client\Curl")
249 * @param fops the resource factory ops
250 * @param data opaque user data
251 * @param dtor \a data destructor
252 * @return SUCCESS/FAILURE
254 PHP_RAPHF_API ZEND_RESULT_CODE
php_persistent_handle_provide(
255 const char *name_str
, size_t name_len
, php_resource_factory_ops_t
*fops
,
256 void *data
, void (*dtor
)(void *));
259 * Retrieve a persistent handle factory at runtime.
261 * If a persistent handle provider has been registered for \a name_str, a new
262 * php_persistent_handle_factory creating resources in the \a ident_str
263 * namespace will be constructed.
265 * The wakeup routine \a wakeup and the retire routine \a retire will be
266 * assigned to the new php_persistent_handle_factory.
268 * @param a pointer to a factory; allocated on the heap if NULL
269 * @param name_str the provider name, e.g. "http\Client\Curl"
270 * @param name_len the provider name length, e.g. strlen("http\Client\Curl")
271 * @param ident_str the subsidiary namespace, e.g. "php.net:80"
272 * @param ident_len the subsidiary namespace lenght, e.g. strlen("php.net:80")
273 * @param wakeup any persistent handle wakeup routine
274 * @param retire any persistent handle retire routine
275 * @return \a a or an allocated persistent handle factory
277 PHP_RAPHF_API php_persistent_handle_factory_t
*php_persistent_handle_concede(
278 php_persistent_handle_factory_t
*a
, const char *name_str
,
279 size_t name_len
, const char *ident_str
, size_t ident_len
,
280 php_persistent_handle_wakeup_t wakeup
,
281 php_persistent_handle_retire_t retire
);
284 * Abandon the persistent handle factory.
286 * Destroy a php_persistent_handle_factory created by
287 * php_persistent_handle_concede(). If the memory for the factory was allocated,
288 * it will automatically be free'd.
290 * @param a the persistent handle factory to destroy
292 PHP_RAPHF_API
void php_persistent_handle_abandon(
293 php_persistent_handle_factory_t
*a
);
296 * Acquire a persistent handle.
298 * That is, either re-use a resource from the free list or create a new handle.
300 * If a handle is acquired from the free list, the
301 * php_persistent_handle_factory::wakeup callback will be executed for that
304 * @param a the persistent handle factory
305 * @param init_arg the \a init_arg for php_resource_factory_handle_ctor()
306 * @return the acquired resource
308 PHP_RAPHF_API
void *php_persistent_handle_acquire(
309 php_persistent_handle_factory_t
*a
, void *init_arg
);
312 * Release a persistent handle.
314 * That is, either put it back into the free list for later re-use or clean it
315 * up with php_resource_factory_handle_dtor().
317 * If a handle is put back into the free list, the
318 * php_persistent_handle_factory::retire callback will be executed for that
321 * @param a the persistent handle factory
322 * @param handle the handle to release
324 PHP_RAPHF_API
void php_persistent_handle_release(
325 php_persistent_handle_factory_t
*a
, void *handle
);
328 * Copy a persistent handle.
330 * Let the underlying resource factory copy the \a handle.
332 * @param a the persistent handle factory
333 * @param handle the resource to accrete
335 PHP_RAPHF_API
void *php_persistent_handle_accrete(
336 php_persistent_handle_factory_t
*a
, void *handle
);
339 * Retrieve persistent handle resource factory ops.
341 * These ops can be used to mask a persistent handle factory as
342 * resource factory itself, so you can transparently use the
343 * resource factory API, both for persistent and non-persistent
347 * ~~~~~~~~~~~~~~~{.c}
348 * php_resource_factory_t *create_my_rf(const char *persistent_id_str,
349 * size_t persistent_id_len TSRMLS_DC)
351 * php_resource_factory_t *rf;
353 * if (persistent_id_str) {
354 * php_persistent_handle_factory_t *pf;
355 * php_resource_factory_ops_t *ops;
357 * ops = php_persistent_handle_get_resource_factory_ops();
359 * pf = php_persistent_handle_concede(NULL, "my", 2,
360 * persistent_id_str, persistent_id_len, NULL, NULL TSRMLS_CC);
362 * rf = php_resource_factory_init(NULL, ops, pf, php_persistent_handle_abandon);
364 * rf = php_resource_factory_init(NULL, &myops, NULL, NULL);
370 PHP_RAPHF_API php_resource_factory_ops_t
*
371 php_persistent_handle_get_resource_factory_ops(void);
374 * Clean persistent handles up.
376 * Destroy persistent handles of provider \a name_str and in subsidiary
377 * namespace \a ident_str.
379 * If \a name_str is NULL, all persistent handles of all providers with a
380 * matching \a ident_str will be cleaned up.
382 * If \a ident_str is NULL all persistent handles of the provider will be
385 * Ergo, if both, \a name_str and \a ident_str are NULL, then all
386 * persistent handles will be cleaned up.
388 * You must call this in MSHUTDOWN, if your resource factory ops hold a
389 * registered php_resource_factory::dtor, else the dtor will point to
390 * memory not any more available if the extension has already been unloaded.
392 * @param name_str the provider name; may be NULL
393 * @param name_len the provider name length
394 * @param ident_str the subsidiary namespace name; may be NULL
395 * @param ident_len the subsidiary namespace name length
397 PHP_RAPHF_API
void php_persistent_handle_cleanup(const char *name_str
,
398 size_t name_len
, const char *ident_str
, size_t ident_len
);
401 * Retrieve statistics about the current process/thread's persistent handles.
403 * @return a HashTable like:
415 PHP_RAPHF_API HashTable
*php_persistent_handle_statall(HashTable
*ht
);
417 #endif /* PHP_RAPHF_H */
425 * vim600: noet sw=4 ts=4 fdm=marker
426 * vim<600: noet sw=4 ts=4