typo
[m6w6/ext-raphf] / php_raphf_api.h
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: raphf |
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 +--------------------------------------------------------------------+
11 */
12
13 #ifndef PHP_RAPHF_API_H
14 #define PHP_RAPHF_API_H
15
16 /**
17 * A resource constructor.
18 *
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
22 */
23 typedef void *(*php_resource_factory_handle_ctor_t)(void *opaque,
24 void *init_arg TSRMLS_DC);
25
26 /**
27 * The copy constructor of a resource.
28 *
29 * @param opaque the factory's data
30 * @param handle the (persistent) handle to copy
31 */
32 typedef void *(*php_resource_factory_handle_copy_t)(void *opaque,
33 void *handle TSRMLS_DC);
34
35 /**
36 * The destructor of a resource.
37 *
38 * @param opaque the factory's data
39 * @param handle the handle to destroy
40 */
41 typedef void (*php_resource_factory_handle_dtor_t)(void *opaque,
42 void *handle TSRMLS_DC);
43
44 /**
45 * The resource ops consisting of a ctor, a copy ctor and a dtor.
46 *
47 * Define this ops and register them with php_persistent_handle_provide()
48 * in MINIT.
49 */
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;
58
59 /**
60 * The resource factory.
61 */
62 typedef struct php_resource_factory {
63 /** The resource ops */
64 php_resource_factory_ops_t fops;
65 /** Opaque user data */
66 void *data;
67 /** User data destructor */
68 void (*dtor)(void *data);
69 /** How often this factory is referenced */
70 unsigned refcount;
71 } php_resource_factory_t;
72
73 /**
74 * Initialize a resource factory.
75 *
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.
80 *
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
86 */
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));
90
91 /**
92 * Increase the refcount of the resource factory.
93 *
94 * @param rf the resource factory
95 * @return the new refcount
96 */
97 PHP_RAPHF_API unsigned php_resource_factory_addref(php_resource_factory_t *rf);
98
99 /**
100 * Destroy the resource factory.
101 *
102 * If the factory's refcount reaches 0, the \a dtor for \a data is called.
103 *
104 * @param f the resource factory
105 */
106 PHP_RAPHF_API void php_resource_factory_dtor(php_resource_factory_t *f);
107
108 /**
109 * Destroy and free the resource factory.
110 *
111 * Calls php_resource_factory_dtor() and frees \æ f if the factory's refcount
112 * reached 0.
113 *
114 * @param f the resource factory
115 */
116 PHP_RAPHF_API void php_resource_factory_free(php_resource_factory_t **f);
117
118 /**
119 * Construct a resource by the resource factory \a f
120 *
121 * @param f the resource factory
122 * @param init_arg for the resource constructor
123 * @return the new resource
124 */
125 PHP_RAPHF_API void *php_resource_factory_handle_ctor(php_resource_factory_t *f,
126 void *init_arg TSRMLS_DC);
127
128 /**
129 * Create a copy of the resource \a handle
130 *
131 * @param f the resource factory
132 * @param handle the resource to copy
133 * @return the copy
134 */
135 PHP_RAPHF_API void *php_resource_factory_handle_copy(php_resource_factory_t *f,
136 void *handle TSRMLS_DC);
137
138 /**
139 * Destroy (and free) the resource
140 *
141 * @param f the resource factory
142 * @param handle the resource to destroy
143 */
144 PHP_RAPHF_API void php_resource_factory_handle_dtor(php_resource_factory_t *f,
145 void *handle TSRMLS_DC);
146
147 /**
148 * Persistent handles storage
149 */
150 typedef struct php_persistent_handle_list {
151 /** Storage of free resources */
152 HashTable free;
153 /** Count of acquired resources */
154 ulong used;
155 } php_persistent_handle_list_t;
156
157 /**
158 * Definition of a persistent handle provider.
159 * Holds a resource factory an a persistent handle list.
160 */
161 typedef struct php_persistent_handle_provider {
162 /**
163 * The list of free handles.
164 * Hash of "ident" => array(handles) entries. Persistent handles are
165 * acquired out of this list.
166 */
167 php_persistent_handle_list_t list;
168
169 /**
170 * The resource factory.
171 * New handles are created by this factory.
172 */
173 php_resource_factory_t rf;
174 } php_persistent_handle_provider_t;
175
176 typedef struct php_persistent_handle_factory php_persistent_handle_factory_t;
177
178 /**
179 * Wakeup the persistent handle on re-acquisition.
180 */
181 typedef void (*php_persistent_handle_wakeup_t)(
182 php_persistent_handle_factory_t *f, void **handle TSRMLS_DC);
183 /**
184 * Retire the persistent handle on release.
185 */
186 typedef void (*php_persistent_handle_retire_t)(
187 php_persistent_handle_factory_t *f, void **handle TSRMLS_DC);
188
189 /**
190 * Definition of a persistent handle factory.
191 *
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().
195 */
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;
203
204 /** The ident for which this factory manages resources */
205 struct {
206 /** ident string */
207 char *str;
208 /** ident length */
209 size_t len;
210 } ident;
211
212 /** Whether it has to be free'd on php_persistent_handle_abandon() */
213 unsigned free_on_abandon:1;
214 };
215
216 /**
217 * Register a persistent handle provider in MINIT.
218 *
219 * Registers a factory provider for \a name_str with \a fops resource factory
220 * ops. Call this in your MINIT.
221 *
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
224 * raphf hash.
225 *
226 * A php_persistent_handle_factory can then be retrieved by
227 * php_persistent_handle_concede() at runtime.
228 *
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
235 */
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);
239
240 /**
241 * Retrieve a persistent handle factory at runtime.
242 *
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.
246 *
247 * The wakeup routine \a wakeup and the retire routine \a retire will be
248 * assigned to the new php_persistent_handle_factory.
249 *
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
258 */
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);
264
265 /**
266 * Abandon the persistent handle factory.
267 *
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.
271 *
272 * @param a the persistent handle factory to destroy
273 */
274 PHP_RAPHF_API void php_persistent_handle_abandon(
275 php_persistent_handle_factory_t *a);
276
277 /**
278 * Acquire a persistent handle.
279 *
280 * That is, either re-use a resource from the free list or create a new handle.
281 *
282 * If a handle is acquired from the free list, the
283 * php_persistent_handle_factory::wakeup callback will be executed for that
284 * handle.
285 *
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
289 */
290 PHP_RAPHF_API void *php_persistent_handle_acquire(
291 php_persistent_handle_factory_t *a, void *init_arg TSRMLS_DC);
292
293 /**
294 * Release a persistent handle.
295 *
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().
298 *
299 * If a handle is put back into the free list, the
300 * php_persistent_handle_factory::retire callback will be executed for that
301 * handle.
302 *
303 * @param a the persistent handle factory
304 * @param handle the handle to release
305 */
306 PHP_RAPHF_API void php_persistent_handle_release(
307 php_persistent_handle_factory_t *a, void *handle TSRMLS_DC);
308
309 /**
310 * Copy a persistent handle.
311 *
312 * Let the underlying resource factory copy the \a handle.
313 *
314 * @param a the persistent handle factory
315 * @param handle the resource to accrete
316 */
317 PHP_RAPHF_API void *php_persistent_handle_accrete(
318 php_persistent_handle_factory_t *a, void *handle TSRMLS_DC);
319
320 /**
321 * Retrieve persistent handle resource factory ops.
322 *
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
326 * ressources.
327 *
328 * Example:
329 * ~~~~~~~~~~~~~~~{.c}
330 * php_resource_factory_t *create_my_rf(const char *persistent_id_str,
331 * size_t persistent_id_len TSRMLS_DC)
332 * {
333 * php_resource_factory_t *rf;
334 *
335 * if (persistent_id_str) {
336 * php_persistent_handle_factory_t *pf;
337 * php_resource_factory_ops_t *ops;
338 *
339 * ops = php_persistent_handle_get_resource_factory_ops();
340 *
341 * pf = php_persistent_handle_concede(NULL, "my", 2,
342 * persistent_id_str, persistent_id_len, NULL, NULL TSRMLS_CC);
343 *
344 * rf = php_persistent_handle_resource_factory_init(NULL, pf);
345 * } else {
346 * rf = php_resource_factory_init(NULL, &myops, NULL, NULL);
347 * }
348 * return rf;
349 * }
350 * ~~~~~~~~~~~~~~~
351 */
352 PHP_RAPHF_API php_resource_factory_ops_t *
353 php_persistent_handle_get_resource_factory_ops(void);
354
355 /**
356 * Create a resource factory for persistent handles.
357 *
358 * This will create a resource factory with persistent handle ops, which wraps
359 * the provided reource factory \a pf.
360 *
361 * @param a the persistent handle resource factory to initialize
362 * @param pf the resource factory to wrap
363 */
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);
367
368 /**
369 * Check whether a resource factory is a persistent handle resource factory.
370 *
371 * @param a the resource factory to check
372 */
373 PHP_RAPHF_API zend_bool php_resource_factory_is_persistent(
374 php_resource_factory_t *a);
375
376 /**
377 * Clean persistent handles up.
378 *
379 * Destroy persistent handles of provider \a name_str and in subsidiary
380 * namespace \a ident_str.
381 *
382 * If \a name_str is NULL, all persistent handles of all providers with a
383 * matching \a ident_str will be cleaned up.
384 *
385 * If \a ident_str is NULL all persistent handles of the provider will be
386 * cleaned up.
387 *
388 * Ergo, if both, \a name_str and \a ident_str are NULL, then all
389 * persistent handles will be cleaned up.
390 *
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.
394 *
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
399 */
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);
402
403 /**
404 * Retrieve statistics about the current process/thread's persistent handles.
405 *
406 * @return a HashTable like:
407 * ~~~~~~~~~~~~~~~
408 * [
409 * "name" => [
410 * "ident" => [
411 * "used" => 1,
412 * "free" => 0,
413 * ]
414 * ]
415 * ]
416 * ~~~~~~~~~~~~~~~
417 */
418 PHP_RAPHF_API HashTable *php_persistent_handle_statall(HashTable *ht TSRMLS_DC);
419
420 #endif /* PHP_RAPHF_API_H */
421
422
423 /*
424 * Local variables:
425 * tab-width: 4
426 * c-basic-offset: 4
427 * End:
428 * vim600: noet sw=4 ts=4 fdm=marker
429 * vim<600: noet sw=4 ts=4
430 */