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 +--------------------------------------------------------------------+
13 #ifndef PHP_RAPHF_API_H
14 #define PHP_RAPHF_API_H
17 * A resource constructor.
19 * @param opaque is the \a data from php_persistent_handle_provide()
20 * @param init_arg is the \a init_arg from php_resource_factory_init()
21 * @return the created (persistent) handle
23 typedef void *(*php_resource_factory_handle_ctor_t
)(void *opaque
,
24 void *init_arg TSRMLS_DC
);
27 * The copy constructor of a resource.
29 * @param opaque the factory's data
30 * @param handle the (persistent) handle to copy
32 typedef void *(*php_resource_factory_handle_copy_t
)(void *opaque
,
33 void *handle TSRMLS_DC
);
36 * The destructor of a resource.
38 * @param opaque the factory's data
39 * @param handle the handle to destroy
41 typedef void (*php_resource_factory_handle_dtor_t
)(void *opaque
,
42 void *handle TSRMLS_DC
);
45 * The resource ops consisting of a ctor, a copy ctor and a dtor.
47 * Define this ops and register them with php_persistent_handle_provide()
50 typedef struct php_resource_factory_ops
{
51 /** The resource constructor */
52 php_resource_factory_handle_ctor_t ctor
;
53 /** The resource's copy constructor */
54 php_resource_factory_handle_copy_t copy
;
55 /** The resource's destructor */
56 php_resource_factory_handle_dtor_t dtor
;
57 } php_resource_factory_ops_t
;
60 * The resource factory.
62 typedef struct php_resource_factory
{
63 /** The resource ops */
64 php_resource_factory_ops_t fops
;
65 /** Opaque user data */
67 /** User data destructor */
68 void (*dtor
)(void *data
);
69 /** How often this factory is referenced */
71 } php_resource_factory_t
;
74 * Initialize a resource factory.
76 * If you register a \a dtor for a resource factory used with a persistent
77 * handle provider, be sure to call php_persistent_handle_cleanup() for your
78 * registered provider in MSHUTDOWN, else the dtor will point to no longer
79 * available memory if the extension has already been unloaded.
81 * @param f the factory to initialize; if NULL allocated on the heap
82 * @param fops the resource ops to assign to the factory
83 * @param data opaque user data; may be NULL
84 * @param dtor a destructor for the data; may be NULL
85 * @return \a f or an allocated resource factory
87 PHP_RAPHF_API php_resource_factory_t
*php_resource_factory_init(
88 php_resource_factory_t
*f
, php_resource_factory_ops_t
*fops
, void *data
,
89 void (*dtor
)(void *data
));
92 * Increase the refcount of the resource factory.
94 * @param rf the resource factory
95 * @return the new refcount
97 PHP_RAPHF_API
unsigned php_resource_factory_addref(php_resource_factory_t
*rf
);
100 * Destroy the resource factory.
102 * If the factory's refcount reaches 0, the \a dtor for \a data is called.
104 * @param f the resource factory
106 PHP_RAPHF_API
void php_resource_factory_dtor(php_resource_factory_t
*f
);
109 * Destroy and free the resource factory.
111 * Calls php_resource_factory_dtor() and frees \æ f if the factory's refcount
114 * @param f the resource factory
116 PHP_RAPHF_API
void php_resource_factory_free(php_resource_factory_t
**f
);
119 * Construct a resource by the resource factory \a f
121 * @param f the resource factory
122 * @param init_arg for the resource constructor
123 * @return the new resource
125 PHP_RAPHF_API
void *php_resource_factory_handle_ctor(php_resource_factory_t
*f
,
126 void *init_arg TSRMLS_DC
);
129 * Create a copy of the resource \a handle
131 * @param f the resource factory
132 * @param handle the resource to copy
135 PHP_RAPHF_API
void *php_resource_factory_handle_copy(php_resource_factory_t
*f
,
136 void *handle TSRMLS_DC
);
139 * Destroy (and free) the resource
141 * @param f the resource factory
142 * @param handle the resource to destroy
144 PHP_RAPHF_API
void php_resource_factory_handle_dtor(php_resource_factory_t
*f
,
145 void *handle TSRMLS_DC
);
148 * Persistent handles storage
150 typedef struct php_persistent_handle_list
{
151 /** Storage of free resources */
153 /** Count of acquired resources */
155 } php_persistent_handle_list_t
;
158 * Definition of a persistent handle provider.
159 * Holds a resource factory an a persistent handle list.
161 typedef struct php_persistent_handle_provider
{
163 * The list of free handles.
164 * Hash of "ident" => array(handles) entries. Persistent handles are
165 * acquired out of this list.
167 php_persistent_handle_list_t list
;
170 * The resource factory.
171 * New handles are created by this factory.
173 php_resource_factory_t rf
;
174 } php_persistent_handle_provider_t
;
176 typedef struct php_persistent_handle_factory php_persistent_handle_factory_t
;
179 * Wakeup the persistent handle on re-acquisition.
181 typedef void (*php_persistent_handle_wakeup_t
)(
182 php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
);
184 * Retire the persistent handle on release.
186 typedef void (*php_persistent_handle_retire_t
)(
187 php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
);
190 * Definition of a persistent handle factory.
192 * php_persistent_handle_concede() will return a pointer to a
193 * php_persistent_handle_factory if a provider for the \a name_str has
194 * been registered with php_persistent_handle_provide().
196 struct php_persistent_handle_factory
{
197 /** The persistent handle provider */
198 php_persistent_handle_provider_t
*provider
;
199 /** The persistent handle wakeup routine; may be NULL */
200 php_persistent_handle_wakeup_t wakeup
;
201 /** The persistent handle retire routine; may be NULL */
202 php_persistent_handle_retire_t retire
;
204 /** The ident for which this factory manages resources */
212 /** Whether it has to be free'd on php_persistent_handle_abandon() */
213 unsigned free_on_abandon
:1;
217 * Register a persistent handle provider in MINIT.
219 * Registers a factory provider for \a name_str with \a fops resource factory
220 * ops. Call this in your MINIT.
222 * A php_resource_factory will be created with \a fops, \a data and \a dtor
223 * and will be stored together with a php_persistent_handle_list in the global
226 * A php_persistent_handle_factory can then be retrieved by
227 * php_persistent_handle_concede() at runtime.
229 * @param name_str the provider name, e.g. "http\Client\Curl"
230 * @param name_len the provider name length, e.g. strlen("http\Client\Curl")
231 * @param fops the resource factory ops
232 * @param data opaque user data
233 * @param dtor \a data destructor
234 * @return SUCCESS/FAILURE
236 PHP_RAPHF_API
int /* SUCCESS|FAILURE */ php_persistent_handle_provide(
237 const char *name_str
, size_t name_len
, php_resource_factory_ops_t
*fops
,
238 void *data
, void (*dtor
)(void *) TSRMLS_DC
);
241 * Retrieve a persistent handle factory at runtime.
243 * If a persistent handle provider has been registered for \a name_str, a new
244 * php_persistent_handle_factory creating resources in the \a ident_str
245 * namespace will be constructed.
247 * The wakeup routine \a wakeup and the retire routine \a retire will be
248 * assigned to the new php_persistent_handle_factory.
250 * @param a pointer to a factory; allocated on the heap if NULL
251 * @param name_str the provider name, e.g. "http\Client\Curl"
252 * @param name_len the provider name length, e.g. strlen("http\Client\Curl")
253 * @param ident_str the subsidiary namespace, e.g. "php.net:80"
254 * @param ident_len the subsidiary namespace lenght, e.g. strlen("php.net:80")
255 * @param wakeup any persistent handle wakeup routine
256 * @param retire any persistent handle retire routine
257 * @return \a a or an allocated persistent handle factory
259 PHP_RAPHF_API php_persistent_handle_factory_t
*php_persistent_handle_concede(
260 php_persistent_handle_factory_t
*a
, const char *name_str
,
261 size_t name_len
, const char *ident_str
, size_t ident_len
,
262 php_persistent_handle_wakeup_t wakeup
,
263 php_persistent_handle_retire_t retire TSRMLS_DC
);
266 * Abandon the persistent handle factory.
268 * Destroy a php_persistent_handle_factory created by
269 * php_persistent_handle_concede(). If the memory for the factory was allocated,
270 * it will automatically be free'd.
272 * @param a the persistent handle factory to destroy
274 PHP_RAPHF_API
void php_persistent_handle_abandon(
275 php_persistent_handle_factory_t
*a
);
278 * Acquire a persistent handle.
280 * That is, either re-use a resource from the free list or create a new handle.
282 * If a handle is acquired from the free list, the
283 * php_persistent_handle_factory::wakeup callback will be executed for that
286 * @param a the persistent handle factory
287 * @param init_arg the \a init_arg for php_resource_factory_handle_ctor()
288 * @return the acquired resource
290 PHP_RAPHF_API
void *php_persistent_handle_acquire(
291 php_persistent_handle_factory_t
*a
, void *init_arg TSRMLS_DC
);
294 * Release a persistent handle.
296 * That is, either put it back into the free list for later re-use or clean it
297 * up with php_resource_factory_handle_dtor().
299 * If a handle is put back into the free list, the
300 * php_persistent_handle_factory::retire callback will be executed for that
303 * @param a the persistent handle factory
304 * @param handle the handle to release
306 PHP_RAPHF_API
void php_persistent_handle_release(
307 php_persistent_handle_factory_t
*a
, void *handle TSRMLS_DC
);
310 * Copy a persistent handle.
312 * Let the underlying resource factory copy the \a handle.
314 * @param a the persistent handle factory
315 * @param handle the resource to accrete
317 PHP_RAPHF_API
void *php_persistent_handle_accrete(
318 php_persistent_handle_factory_t
*a
, void *handle TSRMLS_DC
);
321 * Retrieve persistent handle resource factory ops.
323 * These ops can be used to mask a persistent handle factory as
324 * resource factory itself, so you can transparently use the
325 * resource factory API, both for persistent and non-persistent
330 * php_resource_factory_t *create_my_rf(const char *persistent_id_str,
331 * size_t persistent_id_len TSRMLS_DC)
333 * php_resource_factory_t *rf;
335 * if (persistent_id_str) {
336 * php_persistent_handle_factory_t *pf;
337 * php_resource_factory_ops_t *ops;
339 * ops = php_persistent_handle_get_resource_factory_ops();
341 * pf = php_persistent_handle_concede(NULL, "my", 2,
342 * persistent_id_str, persistent_id_len, NULL, NULL TSRMLS_CC);
344 * rf = php_persistent_handle_resource_factory_init(NULL, pf);
346 * rf = php_resource_factory_init(NULL, &myops, NULL, NULL);
352 PHP_RAPHF_API php_resource_factory_ops_t
*
353 php_persistent_handle_get_resource_factory_ops(void);
356 * Create a resource factory for persistent handles.
358 * This will create a resource factory with persistent handle ops, which wraps
359 * the provided reource factory \a pf.
361 * @param a the persistent handle resource factory to initialize
362 * @param pf the resource factory to wrap
364 PHP_RAPHF_API php_resource_factory_t
*
365 php_persistent_handle_resource_factory_init(php_resource_factory_t
*a
,
366 php_persistent_handle_factory_t
*pf
);
369 * Check whether a resource factory is a persistent handle resource factory.
371 * @param a the resource factory to check
373 PHP_RAPHF_API zend_bool
php_resource_factory_is_persistent(
374 php_resource_factory_t
*a
);
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_API_H */
428 * vim600: noet sw=4 ts=4 fdm=marker
429 * vim<600: noet sw=4 ts=4