flush
[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,
45 void *init_arg TSRMLS_DC);
46
47 /**
48 * The copy constructor of a resource.
49 *
50 * @param opaque the factory's data
51 * @param handle the (persistent) handle to copy
52 */
53 typedef void *(*php_resource_factory_handle_copy_t)(void *opaque,
54 void *handle TSRMLS_DC);
55
56 /**
57 * The destructor of a resource.
58 *
59 * @param opaque the factory's data
60 * @param handle the handle to destroy
61 */
62 typedef void (*php_resource_factory_handle_dtor_t)(void *opaque,
63 void *handle TSRMLS_DC);
64
65 /**
66 * The resource ops consisting of a ctor, a copy ctor and a dtor.
67 *
68 * Define this ops and register them with php_persistent_handle_provide()
69 * in MINIT.
70 */
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;
79
80 /**
81 * The resource factory.
82 */
83 typedef struct php_resource_factory {
84 /** The resource ops */
85 php_resource_factory_ops_t fops;
86 /** Opaque user data */
87 void *data;
88 /** User data destructor */
89 void (*dtor)(void *data);
90 /** How often this factory is referenced */
91 unsigned refcount;
92 } php_resource_factory_t;
93
94 /**
95 * Initialize a resource factory.
96 *
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.
101 *
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
107 */
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));
111
112 /**
113 * Increase the refcount of the resource factory.
114 *
115 * @param rf the resource factory
116 * @return the new refcount
117 */
118 PHP_RAPHF_API unsigned php_resource_factory_addref(php_resource_factory_t *rf);
119
120 /**
121 * Destroy the resource factory.
122 *
123 * If the factory's refcount reaches 0, the \a dtor for \a data is called.
124 *
125 * @param f the resource factory
126 */
127 PHP_RAPHF_API void php_resource_factory_dtor(php_resource_factory_t *f);
128
129 /**
130 * Destroy and free the resource factory.
131 *
132 * Calls php_resource_factory_dtor() and frees \æ f if the factory's refcount
133 * reached 0.
134 *
135 * @param f the resource factory
136 */
137 PHP_RAPHF_API void php_resource_factory_free(php_resource_factory_t **f);
138
139 /**
140 * Construct a resource by the resource factory \a f
141 *
142 * @param f the resource factory
143 * @param init_arg for the resource constructor
144 * @return the new resource
145 */
146 PHP_RAPHF_API void *php_resource_factory_handle_ctor(php_resource_factory_t *f,
147 void *init_arg TSRMLS_DC);
148
149 /**
150 * Create a copy of the resource \a handle
151 *
152 * @param f the resource factory
153 * @param handle the resource to copy
154 * @return the copy
155 */
156 PHP_RAPHF_API void *php_resource_factory_handle_copy(php_resource_factory_t *f,
157 void *handle TSRMLS_DC);
158
159 /**
160 * Destroy (and free) the resource
161 *
162 * @param f the resource factory
163 * @param handle the resource to destroy
164 */
165 PHP_RAPHF_API void php_resource_factory_handle_dtor(php_resource_factory_t *f,
166 void *handle TSRMLS_DC);
167
168 /**
169 * Persistent handles storage
170 */
171 typedef struct php_persistent_handle_list {
172 /** Storage of free resources */
173 HashTable free;
174 /** Count of acquired resources */
175 ulong used;
176 } php_persistent_handle_list_t;
177
178 /**
179 * Definition of a persistent handle provider.
180 * Holds a resource factory an a persistent handle list.
181 */
182 typedef struct php_persistent_handle_provider {
183 /**
184 * The list of free handles.
185 * Hash of "ident" => array(handles) entries. Persistent handles are
186 * acquired out of this list.
187 */
188 php_persistent_handle_list_t list;
189
190 /**
191 * The resource factory.
192 * New handles are created by this factory.
193 */
194 php_resource_factory_t rf;
195 } php_persistent_handle_provider_t;
196
197 typedef struct php_persistent_handle_factory php_persistent_handle_factory_t;
198
199 /**
200 * Wakeup the persistent handle on re-acquisition.
201 */
202 typedef void (*php_persistent_handle_wakeup_t)(
203 php_persistent_handle_factory_t *f, void **handle TSRMLS_DC);
204 /**
205 * Retire the persistent handle on release.
206 */
207 typedef void (*php_persistent_handle_retire_t)(
208 php_persistent_handle_factory_t *f, void **handle TSRMLS_DC);
209
210 /**
211 * Definition of a persistent handle factory.
212 *
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().
216 */
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;
224
225 /** The ident for which this factory manages resources */
226 struct {
227 /** ident string */
228 char *str;
229 /** ident length */
230 size_t len;
231 } ident;
232
233 /** Whether it has to be free'd on php_persistent_handle_abandon() */
234 unsigned free_on_abandon:1;
235 };
236
237 /**
238 * Register a persistent handle provider in MINIT.
239 *
240 * Registers a factory provider for \a name_str with \a fops resource factory
241 * ops. Call this in your MINIT.
242 *
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
245 * raphf hash.
246 *
247 * A php_persistent_handle_factory can then be retrieved by
248 * php_persistent_handle_concede() at runtime.
249 *
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
256 */
257 PHP_RAPHF_API ZEND_RESULT_CODE 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);
260
261 /**
262 * Retrieve a persistent handle factory at runtime.
263 *
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.
267 *
268 * The wakeup routine \a wakeup and the retire routine \a retire will be
269 * assigned to the new php_persistent_handle_factory.
270 *
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
279 */
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);
285
286 /**
287 * Abandon the persistent handle factory.
288 *
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.
292 *
293 * @param a the persistent handle factory to destroy
294 */
295 PHP_RAPHF_API void php_persistent_handle_abandon(
296 php_persistent_handle_factory_t *a);
297
298 /**
299 * Acquire a persistent handle.
300 *
301 * That is, either re-use a resource from the free list or create a new handle.
302 *
303 * If a handle is acquired from the free list, the
304 * php_persistent_handle_factory::wakeup callback will be executed for that
305 * handle.
306 *
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
310 */
311 PHP_RAPHF_API void *php_persistent_handle_acquire(
312 php_persistent_handle_factory_t *a, void *init_arg TSRMLS_DC);
313
314 /**
315 * Release a persistent handle.
316 *
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().
319 *
320 * If a handle is put back into the free list, the
321 * php_persistent_handle_factory::retire callback will be executed for that
322 * handle.
323 *
324 * @param a the persistent handle factory
325 * @param handle the handle to release
326 */
327 PHP_RAPHF_API void php_persistent_handle_release(
328 php_persistent_handle_factory_t *a, void *handle TSRMLS_DC);
329
330 /**
331 * Copy a persistent handle.
332 *
333 * Let the underlying resource factory copy the \a handle.
334 *
335 * @param a the persistent handle factory
336 * @param handle the resource to accrete
337 */
338 PHP_RAPHF_API void *php_persistent_handle_accrete(
339 php_persistent_handle_factory_t *a, void *handle TSRMLS_DC);
340
341 /**
342 * Retrieve persistent handle resource factory ops.
343 *
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
347 * ressources.
348 *
349 * Example:
350 * ~~~~~~~~~~~~~~~{.c}
351 * php_resource_factory_t *create_my_rf(const char *persistent_id_str,
352 * size_t persistent_id_len TSRMLS_DC)
353 * {
354 * php_resource_factory_t *rf;
355 *
356 * if (persistent_id_str) {
357 * php_persistent_handle_factory_t *pf;
358 * php_resource_factory_ops_t *ops;
359 *
360 * ops = php_persistent_handle_get_resource_factory_ops();
361 *
362 * pf = php_persistent_handle_concede(NULL, "my", 2,
363 * persistent_id_str, persistent_id_len, NULL, NULL TSRMLS_CC);
364 *
365 * rf = php_resource_factory_init(NULL, ops, pf, php_persistent_handle_abandon);
366 * } else {
367 * rf = php_resource_factory_init(NULL, &myops, NULL, NULL);
368 * }
369 * return rf;
370 * }
371 * ~~~~~~~~~~~~~~~
372 */
373 PHP_RAPHF_API php_resource_factory_ops_t *
374 php_persistent_handle_get_resource_factory_ops(void);
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_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 */