bye bye TSRM*
[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_str 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 struct {
224 /** ident string */
225 char *str;
226 /** ident length */
227 size_t len;
228 } ident;
229
230 /** Whether it has to be free'd on php_persistent_handle_abandon() */
231 unsigned free_on_abandon:1;
232 };
233
234 /**
235 * Register a persistent handle provider in MINIT.
236 *
237 * Registers a factory provider for \a name_str with \a fops resource factory
238 * ops. Call this in your MINIT.
239 *
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
242 * raphf hash.
243 *
244 * A php_persistent_handle_factory can then be retrieved by
245 * php_persistent_handle_concede() at runtime.
246 *
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
253 */
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 *));
257
258 /**
259 * Retrieve a persistent handle factory at runtime.
260 *
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.
264 *
265 * The wakeup routine \a wakeup and the retire routine \a retire will be
266 * assigned to the new php_persistent_handle_factory.
267 *
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
276 */
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);
282
283 /**
284 * Abandon the persistent handle factory.
285 *
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.
289 *
290 * @param a the persistent handle factory to destroy
291 */
292 PHP_RAPHF_API void php_persistent_handle_abandon(
293 php_persistent_handle_factory_t *a);
294
295 /**
296 * Acquire a persistent handle.
297 *
298 * That is, either re-use a resource from the free list or create a new handle.
299 *
300 * If a handle is acquired from the free list, the
301 * php_persistent_handle_factory::wakeup callback will be executed for that
302 * handle.
303 *
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
307 */
308 PHP_RAPHF_API void *php_persistent_handle_acquire(
309 php_persistent_handle_factory_t *a, void *init_arg);
310
311 /**
312 * Release a persistent handle.
313 *
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().
316 *
317 * If a handle is put back into the free list, the
318 * php_persistent_handle_factory::retire callback will be executed for that
319 * handle.
320 *
321 * @param a the persistent handle factory
322 * @param handle the handle to release
323 */
324 PHP_RAPHF_API void php_persistent_handle_release(
325 php_persistent_handle_factory_t *a, void *handle);
326
327 /**
328 * Copy a persistent handle.
329 *
330 * Let the underlying resource factory copy the \a handle.
331 *
332 * @param a the persistent handle factory
333 * @param handle the resource to accrete
334 */
335 PHP_RAPHF_API void *php_persistent_handle_accrete(
336 php_persistent_handle_factory_t *a, void *handle);
337
338 /**
339 * Retrieve persistent handle resource factory ops.
340 *
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
344 * ressources.
345 *
346 * Example:
347 * ~~~~~~~~~~~~~~~{.c}
348 * php_resource_factory_t *create_my_rf(const char *persistent_id_str,
349 * size_t persistent_id_len TSRMLS_DC)
350 * {
351 * php_resource_factory_t *rf;
352 *
353 * if (persistent_id_str) {
354 * php_persistent_handle_factory_t *pf;
355 * php_resource_factory_ops_t *ops;
356 *
357 * ops = php_persistent_handle_get_resource_factory_ops();
358 *
359 * pf = php_persistent_handle_concede(NULL, "my", 2,
360 * persistent_id_str, persistent_id_len, NULL, NULL TSRMLS_CC);
361 *
362 * rf = php_resource_factory_init(NULL, ops, pf, php_persistent_handle_abandon);
363 * } else {
364 * rf = php_resource_factory_init(NULL, &myops, NULL, NULL);
365 * }
366 * return rf;
367 * }
368 * ~~~~~~~~~~~~~~~
369 */
370 PHP_RAPHF_API php_resource_factory_ops_t *
371 php_persistent_handle_get_resource_factory_ops(void);
372
373 /**
374 * Clean persistent handles up.
375 *
376 * Destroy persistent handles of provider \a name_str and in subsidiary
377 * namespace \a ident_str.
378 *
379 * If \a name_str is NULL, all persistent handles of all providers with a
380 * matching \a ident_str will be cleaned up.
381 *
382 * If \a ident_str is NULL all persistent handles of the provider will be
383 * cleaned up.
384 *
385 * Ergo, if both, \a name_str and \a ident_str are NULL, then all
386 * persistent handles will be cleaned up.
387 *
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.
391 *
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
396 */
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);
399
400 /**
401 * Retrieve statistics about the current process/thread's persistent handles.
402 *
403 * @return a HashTable like:
404 * ~~~~~~~~~~~~~~~
405 * [
406 * "name" => [
407 * "ident" => [
408 * "used" => 1,
409 * "free" => 0,
410 * ]
411 * ]
412 * ]
413 * ~~~~~~~~~~~~~~~
414 */
415 PHP_RAPHF_API HashTable *php_persistent_handle_statall(HashTable *ht);
416
417 #endif /* PHP_RAPHF_H */
418
419
420 /*
421 * Local variables:
422 * tab-width: 4
423 * c-basic-offset: 4
424 * End:
425 * vim600: noet sw=4 ts=4 fdm=marker
426 * vim<600: noet sw=4 ts=4
427 */