Merge branch 'master' into phpng
[m6w6/ext-raphf] / php_raphf.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_H
14 #define PHP_RAPHF_H
15
16 #ifndef DOXYGEN
17
18 extern zend_module_entry raphf_module_entry;
19 #define phpext_raphf_ptr &raphf_module_entry
20
21 #define PHP_RAPHF_VERSION "2.0.0dev"
22
23 #ifdef PHP_WIN32
24 # define PHP_RAPHF_API __declspec(dllexport)
25 #elif defined(__GNUC__) && __GNUC__ >= 4
26 # define PHP_RAPHF_API extern __attribute__ ((visibility("default")))
27 #else
28 # define PHP_RAPHF_API extern
29 #endif
30
31 #ifdef ZTS
32 # include "TSRM.h"
33 #endif
34
35 #endif
36
37 /**
38 * A resource constructor.
39 *
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
43 */
44 typedef void *(*php_resource_factory_handle_ctor_t)(void *opaque, void *init_arg);
45
46 /**
47 * The copy constructor of a resource.
48 *
49 * @param opaque the factory's data
50 * @param handle the (persistent) handle to copy
51 */
52 typedef void *(*php_resource_factory_handle_copy_t)(void *opaque, void *handle);
53
54 /**
55 * The destructor of a resource.
56 *
57 * @param opaque the factory's data
58 * @param handle the handle to destroy
59 */
60 typedef void (*php_resource_factory_handle_dtor_t)(void *opaque, void *handle);
61
62 /**
63 * The resource ops consisting of a ctor, a copy ctor and a dtor.
64 *
65 * Define this ops and register them with php_persistent_handle_provide()
66 * in MINIT.
67 */
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;
76
77 /**
78 * The resource factory.
79 */
80 typedef struct php_resource_factory {
81 /** The resource ops */
82 php_resource_factory_ops_t fops;
83 /** Opaque user data */
84 void *data;
85 /** User data destructor */
86 void (*dtor)(void *data);
87 /** How often this factory is referenced */
88 unsigned refcount;
89 } php_resource_factory_t;
90
91 /**
92 * Initialize a resource factory.
93 *
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.
98 *
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
104 */
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));
108
109 /**
110 * Increase the refcount of the resource factory.
111 *
112 * @param rf the resource factory
113 * @return the new refcount
114 */
115 PHP_RAPHF_API unsigned php_resource_factory_addref(php_resource_factory_t *rf);
116
117 /**
118 * Destroy the resource factory.
119 *
120 * If the factory's refcount reaches 0, the \a dtor for \a data is called.
121 *
122 * @param f the resource factory
123 */
124 PHP_RAPHF_API void php_resource_factory_dtor(php_resource_factory_t *f);
125
126 /**
127 * Destroy and free the resource factory.
128 *
129 * Calls php_resource_factory_dtor() and frees \a f if the factory's refcount
130 * reached 0.
131 *
132 * @param f the resource factory
133 */
134 PHP_RAPHF_API void php_resource_factory_free(php_resource_factory_t **f);
135
136 /**
137 * Construct a resource by the resource factory \a f
138 *
139 * @param f the resource factory
140 * @param init_arg for the resource constructor
141 * @return the new resource
142 */
143 PHP_RAPHF_API void *php_resource_factory_handle_ctor(php_resource_factory_t *f,
144 void *init_arg);
145
146 /**
147 * Create a copy of the resource \a handle
148 *
149 * @param f the resource factory
150 * @param handle the resource to copy
151 * @return the copy
152 */
153 PHP_RAPHF_API void *php_resource_factory_handle_copy(php_resource_factory_t *f,
154 void *handle);
155
156 /**
157 * Destroy (and free) the resource
158 *
159 * @param f the resource factory
160 * @param handle the resource to destroy
161 */
162 PHP_RAPHF_API void php_resource_factory_handle_dtor(php_resource_factory_t *f,
163 void *handle);
164
165 /**
166 * Persistent handles storage
167 */
168 typedef struct php_persistent_handle_list {
169 /** Storage of free resources */
170 HashTable free;
171 /** Count of acquired resources */
172 ulong used;
173 } php_persistent_handle_list_t;
174
175 /**
176 * Definition of a persistent handle provider.
177 * Holds a resource factory an a persistent handle list.
178 */
179 typedef struct php_persistent_handle_provider {
180 /**
181 * The list of free handles.
182 * Hash of "ident" => array(handles) entries. Persistent handles are
183 * acquired out of this list.
184 */
185 php_persistent_handle_list_t list;
186
187 /**
188 * The resource factory.
189 * New handles are created by this factory.
190 */
191 php_resource_factory_t rf;
192 } php_persistent_handle_provider_t;
193
194 typedef struct php_persistent_handle_factory php_persistent_handle_factory_t;
195
196 /**
197 * Wakeup the persistent handle on re-acquisition.
198 */
199 typedef void (*php_persistent_handle_wakeup_t)(
200 php_persistent_handle_factory_t *f, void **handle);
201 /**
202 * Retire the persistent handle on release.
203 */
204 typedef void (*php_persistent_handle_retire_t)(
205 php_persistent_handle_factory_t *f, void **handle);
206
207 /**
208 * Definition of a persistent handle factory.
209 *
210 * php_persistent_handle_concede() will return a pointer to a
211 * php_persistent_handle_factory if a provider for the \a name has
212 * been registered with php_persistent_handle_provide().
213 */
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;
221
222 /** The ident for which this factory manages resources */
223 zend_string *ident;
224
225 /** Whether it has to be free'd on php_persistent_handle_abandon() */
226 unsigned free_on_abandon:1;
227 };
228
229 /**
230 * Register a persistent handle provider in MINIT.
231 *
232 * Registers a factory provider for \a name_str with \a fops resource factory
233 * ops. Call this in your MINIT.
234 *
235 * A php_resource_factory will be created with \a fops, \a data and \a dtor
236 * and will be stored together with a php_persistent_handle_list in the global
237 * raphf hash.
238 *
239 * A php_persistent_handle_factory can then be retrieved by
240 * php_persistent_handle_concede() at runtime.
241 *
242 * @param name the provider name, e.g. "http\Client\Curl"
243 * @param fops the resource factory ops
244 * @param data opaque user data
245 * @param dtor \a data destructor
246 * @return SUCCESS/FAILURE
247 */
248 PHP_RAPHF_API ZEND_RESULT_CODE php_persistent_handle_provide(
249 zend_string *name, php_resource_factory_ops_t *fops,
250 void *data, void (*dtor)(void *));
251
252 /**
253 * Retrieve a persistent handle factory at runtime.
254 *
255 * If a persistent handle provider has been registered for \a name, a new
256 * php_persistent_handle_factory creating resources in the \a ident
257 * namespace will be constructed.
258 *
259 * The wakeup routine \a wakeup and the retire routine \a retire will be
260 * assigned to the new php_persistent_handle_factory.
261 *
262 * @param a pointer to a factory; allocated on the heap if NULL
263 * @param name the provider name, e.g. "http\Client\Curl"
264 * @param ident the subsidiary namespace, e.g. "php.net:80"
265 * @param wakeup any persistent handle wakeup routine
266 * @param retire any persistent handle retire routine
267 * @return \a a or an allocated persistent handle factory
268 */
269 PHP_RAPHF_API php_persistent_handle_factory_t *php_persistent_handle_concede(
270 php_persistent_handle_factory_t *a,
271 zend_string *name, zend_string *ident,
272 php_persistent_handle_wakeup_t wakeup,
273 php_persistent_handle_retire_t retire);
274
275 /**
276 * Abandon the persistent handle factory.
277 *
278 * Destroy a php_persistent_handle_factory created by
279 * php_persistent_handle_concede(). If the memory for the factory was allocated,
280 * it will automatically be free'd.
281 *
282 * @param a the persistent handle factory to destroy
283 */
284 PHP_RAPHF_API void php_persistent_handle_abandon(
285 php_persistent_handle_factory_t *a);
286
287 /**
288 * Acquire a persistent handle.
289 *
290 * That is, either re-use a resource from the free list or create a new handle.
291 *
292 * If a handle is acquired from the free list, the
293 * php_persistent_handle_factory::wakeup callback will be executed for that
294 * handle.
295 *
296 * @param a the persistent handle factory
297 * @param init_arg the \a init_arg for php_resource_factory_handle_ctor()
298 * @return the acquired resource
299 */
300 PHP_RAPHF_API void *php_persistent_handle_acquire(
301 php_persistent_handle_factory_t *a, void *init_arg);
302
303 /**
304 * Release a persistent handle.
305 *
306 * That is, either put it back into the free list for later re-use or clean it
307 * up with php_resource_factory_handle_dtor().
308 *
309 * If a handle is put back into the free list, the
310 * php_persistent_handle_factory::retire callback will be executed for that
311 * handle.
312 *
313 * @param a the persistent handle factory
314 * @param handle the handle to release
315 */
316 PHP_RAPHF_API void php_persistent_handle_release(
317 php_persistent_handle_factory_t *a, void *handle);
318
319 /**
320 * Copy a persistent handle.
321 *
322 * Let the underlying resource factory copy the \a handle.
323 *
324 * @param a the persistent handle factory
325 * @param handle the resource to accrete
326 */
327 PHP_RAPHF_API void *php_persistent_handle_accrete(
328 php_persistent_handle_factory_t *a, void *handle);
329
330 /**
331 * Retrieve persistent handle resource factory ops.
332 *
333 * These ops can be used to mask a persistent handle factory as
334 * resource factory itself, so you can transparently use the
335 * resource factory API, both for persistent and non-persistent
336 * ressources.
337 *
338 * Example:
339 * ~~~~~~~~~~~~~~~{.c}
340 * php_resource_factory_t *create_my_rf(zend_string *persistent_id)
341 * {
342 * php_resource_factory_t *rf;
343 *
344 * if (persistent_id) {
345 * php_persistent_handle_factory_t *pf;
346 * php_resource_factory_ops_t *ops;
347 * zend_string *ns = zend_string_init("my", 2, 1);
348 *
349 * ops = php_persistent_handle_get_resource_factory_ops();
350 * pf = php_persistent_handle_concede(NULL, ns, persistent_id, NULL, NULL);
351 * rf = php_persistent_handle_resource_factory_init(NULL, pf);
352 * zend_string_release(ns);
353 * } else {
354 * rf = php_resource_factory_init(NULL, &myops, NULL, NULL);
355 * }
356 * return rf;
357 * }
358 * ~~~~~~~~~~~~~~~
359 */
360 PHP_RAPHF_API php_resource_factory_ops_t *
361 php_persistent_handle_get_resource_factory_ops(void);
362
363 /**
364 * Create a resource factory for persistent handles.
365 *
366 * This will create a resource factory with persistent handle ops, which wraps
367 * the provided reource factory \a pf.
368 *
369 * @param a the persistent handle resource factory to initialize
370 * @param pf the resource factory to wrap
371 */
372 PHP_RAPHF_API php_resource_factory_t *
373 php_persistent_handle_resource_factory_init(php_resource_factory_t *a,
374 php_persistent_handle_factory_t *pf);
375
376 /**
377 * Check whether a resource factory is a persistent handle resource factory.
378 *
379 * @param a the resource factory to check
380 */
381 PHP_RAPHF_API zend_bool php_resource_factory_is_persistent(
382 php_resource_factory_t *a);
383
384 /**
385 * Clean persistent handles up.
386 *
387 * Destroy persistent handles of provider \a name and in subsidiary
388 * namespace \a ident.
389 *
390 * If \a name is NULL, all persistent handles of all providers with a
391 * matching \a ident will be cleaned up.
392 *
393 * If \a identr is NULL all persistent handles of the provider will be
394 * cleaned up.
395 *
396 * Ergo, if both, \a name and \a ident are NULL, then all
397 * persistent handles will be cleaned up.
398 *
399 * You must call this in MSHUTDOWN, if your resource factory ops hold a
400 * registered php_resource_factory::dtor, else the dtor will point to
401 * memory not any more available if the extension has already been unloaded.
402 *
403 * @param name the provider name; may be NULL
404 * @param ident the subsidiary namespace name; may be NULL
405 */
406 PHP_RAPHF_API void php_persistent_handle_cleanup(zend_string *name,
407 zend_string *ident);
408
409 /**
410 * Retrieve statistics about the current process/thread's persistent handles.
411 *
412 * @return a HashTable like:
413 * ~~~~~~~~~~~~~~~
414 * [
415 * "name" => [
416 * "ident" => [
417 * "used" => 1,
418 * "free" => 0,
419 * ]
420 * ]
421 * ]
422 * ~~~~~~~~~~~~~~~
423 */
424 PHP_RAPHF_API HashTable *php_persistent_handle_statall(HashTable *ht);
425
426 #endif /* PHP_RAPHF_H */
427
428
429 /*
430 * Local variables:
431 * tab-width: 4
432 * c-basic-offset: 4
433 * End:
434 * vim600: noet sw=4 ts=4 fdm=marker
435 * vim<600: noet sw=4 ts=4
436 */