disable PHP_RAPHF_DEBUG_PHANDLES
[m6w6/ext-raphf] / php_raphf.c
1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2012 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "php_raphf.h"
29
30 ZEND_DECLARE_MODULE_GLOBALS(raphf)
31
32 typedef int STATUS;
33
34 #ifndef PHP_RAPHF_DEBUG_PHANDLES
35 # define PHP_RAPHF_DEBUG_PHANDLES 0
36 #endif
37 #if PHP_RAPHF_DEBUG_PHANDLES
38 # undef inline
39 # define inline
40 #endif
41
42 static HashTable php_persistent_handle_hash;
43
44 #ifdef ZTS
45 # define LOCK() tsrm_mutex_lock(php_persistent_handle_lock)
46 # define UNLOCK() tsrm_mutex_unlock(php_persistent_handle_lock)
47 static MUTEX_T php_persistent_handle_lock;
48 #else
49 # define LOCK()
50 # define UNLOCK()
51 #endif
52
53 typedef struct php_persistent_handle_list {
54 HashTable free;
55 ulong used;
56 } php_persistent_handle_list_t;
57
58 typedef struct php_persistent_handle_provider {
59 php_persistent_handle_list_t list; /* "ident" => array(handles) entries */
60 php_resource_factory_t rf;
61 } php_persistent_handle_provider_t;
62
63
64 PHP_RAPHF_API php_resource_factory_t *php_resource_factory_init(php_resource_factory_t *f, php_resource_factory_ops_t *fops, void *data, void (*dtor)(void *data))
65 {
66 if (!f) {
67 f = emalloc(sizeof(*f));
68 }
69 memset(f, 0, sizeof(*f));
70
71 memcpy(&f->fops, fops, sizeof(*fops));
72
73 f->data = data;
74 f->dtor = dtor;
75
76 f->refcount = 1;
77
78 return f;
79 }
80
81 PHP_RAPHF_API unsigned php_resource_factory_addref(php_resource_factory_t *rf)
82 {
83 return ++rf->refcount;
84 }
85
86 PHP_RAPHF_API void php_resource_factory_dtor(php_resource_factory_t *f)
87 {
88 --f->refcount;
89
90 if (!f->refcount) {
91 if (f->dtor) {
92 f->dtor(f->data);
93 }
94 }
95 }
96
97 PHP_RAPHF_API void php_resource_factory_free(php_resource_factory_t **f)
98 {
99 if (*f) {
100 php_resource_factory_dtor(*f);
101 if (!(*f)->refcount) {
102 efree(*f);
103 *f = NULL;
104 }
105 }
106 }
107
108 PHP_RAPHF_API void *php_resource_factory_handle_ctor(php_resource_factory_t *f, void *init_arg TSRMLS_DC)
109 {
110 if (f->fops.ctor) {
111 return f->fops.ctor(f->data, init_arg TSRMLS_CC);
112 }
113 return NULL;
114 }
115
116 PHP_RAPHF_API void *php_resource_factory_handle_copy(php_resource_factory_t *f, void *handle TSRMLS_DC)
117 {
118 if (f->fops.copy) {
119 return f->fops.copy(f->data, handle TSRMLS_CC);
120 }
121 return NULL;
122 }
123
124 PHP_RAPHF_API void php_resource_factory_handle_dtor(php_resource_factory_t *f, void *handle TSRMLS_DC)
125 {
126 if (f->fops.dtor) {
127 f->fops.dtor(f->data, handle TSRMLS_CC);
128 }
129 }
130
131 static inline php_persistent_handle_list_t *php_persistent_handle_list_init(php_persistent_handle_list_t *list)
132 {
133 int free_list;
134
135 if ((free_list = !list)) {
136 list = pemalloc(sizeof(php_persistent_handle_list_t), 1);
137 }
138
139 list->used = 0;
140
141 if (SUCCESS != zend_hash_init(&list->free, 0, NULL, NULL, 1)) {
142 if (free_list) {
143 pefree(list, 1);
144 }
145 list = NULL;
146 }
147
148 return list;
149 }
150
151 static int php_persistent_handle_apply_stat(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
152 {
153 php_persistent_handle_list_t **list = p;
154 zval *zsubentry, *zentry = va_arg(argv, zval *);
155
156 MAKE_STD_ZVAL(zsubentry);
157 array_init(zsubentry);
158 add_assoc_long_ex(zsubentry, ZEND_STRS("used"), (*list)->used);
159 add_assoc_long_ex(zsubentry, ZEND_STRS("free"), zend_hash_num_elements(&(*list)->free));
160 add_assoc_zval_ex(zentry, key->arKey, key->nKeyLength, zsubentry);
161
162 return ZEND_HASH_APPLY_KEEP;
163 }
164
165 static int php_persistent_handle_apply_statall(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
166 {
167 php_persistent_handle_provider_t *provider = p;
168 HashTable *ht = va_arg(argv, HashTable *);
169 zval *zentry;
170
171 MAKE_STD_ZVAL(zentry);
172 array_init(zentry);
173
174 zend_hash_apply_with_arguments(&provider->list.free TSRMLS_CC, php_persistent_handle_apply_stat, 1, zentry);
175 zend_symtable_update(ht, key->arKey, key->nKeyLength, &zentry, sizeof(zval *), NULL);
176
177 return ZEND_HASH_APPLY_KEEP;
178 }
179
180 static int php_persistent_handle_apply_cleanup_ex(void *pp, void *arg TSRMLS_DC)
181 {
182 php_resource_factory_t *rf = arg;
183 void **handle = pp;
184
185 #if PHP_RAPHF_DEBUG_PHANDLES
186 fprintf(stderr, "DESTROY: %p\n", *handle);
187 #endif
188 php_resource_factory_handle_dtor(rf, *handle TSRMLS_CC);
189 return ZEND_HASH_APPLY_REMOVE;
190 }
191
192 static int php_persistent_handle_apply_cleanup(void *pp, void *arg TSRMLS_DC)
193 {
194 php_resource_factory_t *rf = arg;
195 php_persistent_handle_list_t **listp = pp;
196
197 zend_hash_apply_with_argument(&(*listp)->free, php_persistent_handle_apply_cleanup_ex, rf TSRMLS_CC);
198 if ((*listp)->used) {
199 return ZEND_HASH_APPLY_KEEP;
200 }
201 zend_hash_destroy(&(*listp)->free);
202 #if PHP_RAPHF_DEBUG_PHANDLES
203 fprintf(stderr, "LSTFREE: %p\n", *listp);
204 #endif
205 pefree(*listp, 1);
206 *listp = NULL;
207 return ZEND_HASH_APPLY_REMOVE;
208 }
209
210 static inline void php_persistent_handle_list_dtor(php_persistent_handle_list_t *list, php_persistent_handle_provider_t *provider TSRMLS_DC)
211 {
212 #if PHP_RAPHF_DEBUG_PHANDLES
213 fprintf(stderr, "LSTDTOR: %p\n", list);
214 #endif
215 zend_hash_apply_with_argument(&list->free, php_persistent_handle_apply_cleanup_ex, &provider->rf TSRMLS_CC);
216 zend_hash_destroy(&list->free);
217 }
218
219 static inline void php_persistent_handle_list_free(php_persistent_handle_list_t **list, php_persistent_handle_provider_t *provider TSRMLS_DC)
220 {
221 php_persistent_handle_list_dtor(*list, provider TSRMLS_CC);
222 #if PHP_RAPHF_DEBUG_PHANDLES
223 fprintf(stderr, "LSTFREE: %p\n", *list);
224 #endif
225 pefree(*list, 1);
226 *list = NULL;
227 }
228
229 static int php_persistent_handle_list_apply_dtor(void *listp, void *provider TSRMLS_DC)
230 {
231 php_persistent_handle_list_free(listp, provider TSRMLS_CC);
232 return ZEND_HASH_APPLY_REMOVE;
233 }
234
235 static inline php_persistent_handle_list_t *php_persistent_handle_list_find(php_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len TSRMLS_DC)
236 {
237 php_persistent_handle_list_t **list, *new_list;
238
239 if (SUCCESS == zend_symtable_find(&provider->list.free, ident_str, ident_len + 1, (void *) &list)) {
240 #if PHP_RAPHF_DEBUG_PHANDLES
241 fprintf(stderr, "LSTFIND: %p\n", *list);
242 #endif
243 return *list;
244 }
245
246 if ((new_list = php_persistent_handle_list_init(NULL))) {
247 if (SUCCESS == zend_symtable_update(&provider->list.free, ident_str, ident_len + 1, (void *) &new_list, sizeof(php_persistent_handle_list_t *), (void *) &list)) {
248 #if PHP_RAPHF_DEBUG_PHANDLES
249 fprintf(stderr, "LSTFIND: %p (new)\n", *list);
250 #endif
251 return *list;
252 }
253 php_persistent_handle_list_free(&new_list, provider TSRMLS_CC);
254 }
255
256 return NULL;
257 }
258
259 static int php_persistent_handle_apply_cleanup_all(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
260 {
261 php_persistent_handle_provider_t *provider = p;
262 const char *ident_str = va_arg(argv, const char *);
263 size_t ident_len = va_arg(argv, size_t);
264 php_persistent_handle_list_t *list;
265
266 if (ident_str && ident_len) {
267 if ((list = php_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
268 zend_hash_apply_with_argument(&list->free, php_persistent_handle_apply_cleanup_ex, &provider->rf TSRMLS_CC);
269 }
270 } else {
271 zend_hash_apply_with_argument(&provider->list.free, php_persistent_handle_apply_cleanup, &provider->rf TSRMLS_CC);
272 }
273
274 return ZEND_HASH_APPLY_KEEP;
275 }
276
277 static inline STATUS php_persistent_handle_do_acquire(php_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len, void *init_arg, void **handle TSRMLS_DC)
278 {
279 ulong index;
280 void **handle_ptr;
281 php_persistent_handle_list_t *list;
282
283 if ((list = php_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
284 zend_hash_internal_pointer_end(&list->free);
285 if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(&list->free, NULL, &index, 0) && SUCCESS == zend_hash_get_current_data(&list->free, (void *) &handle_ptr)) {
286 *handle = *handle_ptr;
287 zend_hash_index_del(&list->free, index);
288 } else {
289 *handle = php_resource_factory_handle_ctor(&provider->rf, init_arg TSRMLS_CC);
290 }
291 #if PHP_RAPHF_DEBUG_PHANDLES
292 fprintf(stderr, "CREATED: %p\n", *handle);
293 #endif
294 if (*handle) {
295 ++provider->list.used;
296 ++list->used;
297 return SUCCESS;
298 }
299 } else {
300 *handle = NULL;
301 }
302
303 return FAILURE;
304 }
305
306 static inline STATUS php_persistent_handle_do_release(php_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len, void **handle TSRMLS_DC)
307 {
308 php_persistent_handle_list_t *list;
309
310 if ((list = php_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
311 if (provider->list.used >= PHP_RAPHF_G->persistent_handle.limit) {
312 #if PHP_RAPHF_DEBUG_PHANDLES
313 fprintf(stderr, "DESTROY: %p\n", *handle);
314 #endif
315 php_resource_factory_handle_dtor(&provider->rf, *handle TSRMLS_CC);
316 } else {
317 if (SUCCESS != zend_hash_next_index_insert(&list->free, (void *) handle, sizeof(void *), NULL)) {
318 return FAILURE;
319 }
320 }
321
322 *handle = NULL;
323 --provider->list.used;
324 --list->used;
325 return SUCCESS;
326 }
327
328 return FAILURE;
329 }
330
331 static inline STATUS php_persistent_handle_do_accrete(php_persistent_handle_provider_t *provider, const char *ident_str, size_t ident_len, void *old_handle, void **new_handle TSRMLS_DC)
332 {
333 php_persistent_handle_list_t *list;
334
335 if ((*new_handle = php_resource_factory_handle_copy(&provider->rf, old_handle TSRMLS_CC))) {
336 if ((list = php_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
337 ++list->used;
338 }
339 ++provider->list.used;
340 return SUCCESS;
341 }
342 return FAILURE;
343 }
344
345 static void php_persistent_handle_hash_dtor(void *p)
346 {
347 php_persistent_handle_provider_t *provider = (php_persistent_handle_provider_t *) p;
348 TSRMLS_FETCH();
349
350 zend_hash_apply_with_argument(&provider->list.free, php_persistent_handle_list_apply_dtor, provider TSRMLS_CC);
351 zend_hash_destroy(&provider->list.free);
352 php_resource_factory_dtor(&provider->rf);
353 }
354
355 PHP_RAPHF_API STATUS php_persistent_handle_provide(const char *name_str, size_t name_len, php_resource_factory_ops_t *fops, void *data, void (*dtor)(void *))
356 {
357 STATUS status = FAILURE;
358 php_persistent_handle_provider_t provider;
359
360 LOCK();
361 if (php_persistent_handle_list_init(&provider.list)) {
362 if (php_resource_factory_init(&provider.rf, fops, data, dtor)) {
363 #if PHP_RAPHF_DEBUG_PHANDLES
364 fprintf(stderr, "PROVIDE: %s\n", name_str);
365 #endif
366
367 if (SUCCESS == zend_symtable_update(&php_persistent_handle_hash, name_str, name_len+1, (void *) &provider, sizeof(php_persistent_handle_provider_t), NULL)) {
368 status = SUCCESS;
369 } else {
370 php_resource_factory_dtor(&provider.rf);
371 }
372 }
373 }
374 UNLOCK();
375
376 return status;
377 }
378
379 PHP_RAPHF_API php_persistent_handle_factory_t *php_persistent_handle_concede(php_persistent_handle_factory_t *a, const char *name_str, size_t name_len, const char *ident_str, size_t ident_len TSRMLS_DC)
380 {
381 STATUS status = FAILURE;
382 php_persistent_handle_factory_t *free_a = NULL;
383
384 if (!a) {
385 free_a = a = emalloc(sizeof(*a));
386 }
387 memset(a, 0, sizeof(*a));
388
389 LOCK();
390 status = zend_symtable_find(&php_persistent_handle_hash, name_str, name_len+1, (void *) &a->provider);
391 UNLOCK();
392
393 if (SUCCESS == status) {
394 a->ident.str = estrndup(ident_str, a->ident.len = ident_len);
395 if (free_a) {
396 a->free_on_abandon = 1;
397 }
398 } else {
399 if (free_a) {
400 efree(free_a);
401 }
402 a = NULL;
403 }
404
405 #if PHP_RAPHF_DEBUG_PHANDLES
406 fprintf(stderr, "CONCEDE: %p (%s) (%s)\n", a ? a->provider : NULL, name_str, ident_str);
407 #endif
408
409 return a;
410 }
411
412 PHP_RAPHF_API void php_persistent_handle_abandon(php_persistent_handle_factory_t *a)
413 {
414 zend_bool f = a->free_on_abandon;
415
416 #if PHP_RAPHF_DEBUG_PHANDLES
417 fprintf(stderr, "ABANDON: %p\n", a->provider);
418 #endif
419
420 STR_FREE(a->ident.str);
421 memset(a, 0, sizeof(*a));
422 if (f) {
423 efree(a);
424 }
425 }
426
427 PHP_RAPHF_API void *php_persistent_handle_acquire(php_persistent_handle_factory_t *a, void *init_arg TSRMLS_DC)
428 {
429 void *handle = NULL;
430
431 LOCK();
432 php_persistent_handle_do_acquire(a->provider, a->ident.str, a->ident.len, init_arg, &handle TSRMLS_CC);
433 UNLOCK();
434
435 return handle;
436 }
437
438 PHP_RAPHF_API void *php_persistent_handle_accrete(php_persistent_handle_factory_t *a, void *handle TSRMLS_DC)
439 {
440 void *new_handle = NULL;
441
442 LOCK();
443 php_persistent_handle_do_accrete(a->provider, a->ident.str, a->ident.len, handle, &new_handle TSRMLS_CC);
444 UNLOCK();
445
446 return new_handle;
447 }
448
449 PHP_RAPHF_API void php_persistent_handle_release(php_persistent_handle_factory_t *a, void *handle TSRMLS_DC)
450 {
451 LOCK();
452 php_persistent_handle_do_release(a->provider, a->ident.str, a->ident.len, &handle TSRMLS_CC);
453 UNLOCK();
454 }
455
456 PHP_RAPHF_API void php_persistent_handle_cleanup(const char *name_str, size_t name_len, const char *ident_str, size_t ident_len TSRMLS_DC)
457 {
458 php_persistent_handle_provider_t *provider;
459 php_persistent_handle_list_t *list;
460
461 LOCK();
462 if (name_str && name_len) {
463 if (SUCCESS == zend_symtable_find(&php_persistent_handle_hash, name_str, name_len+1, (void *) &provider)) {
464 if (ident_str && ident_len) {
465 if ((list = php_persistent_handle_list_find(provider, ident_str, ident_len TSRMLS_CC))) {
466 zend_hash_apply_with_argument(&list->free, php_persistent_handle_apply_cleanup_ex, &provider->rf TSRMLS_CC);
467 }
468 } else {
469 zend_hash_apply_with_argument(&provider->list.free, php_persistent_handle_apply_cleanup, &provider->rf TSRMLS_CC);
470 }
471 }
472 } else {
473 zend_hash_apply_with_arguments(&php_persistent_handle_hash TSRMLS_CC, php_persistent_handle_apply_cleanup_all, 2, ident_str, ident_len);
474 }
475 UNLOCK();
476 }
477
478 PHP_RAPHF_API HashTable *php_persistent_handle_statall(HashTable *ht TSRMLS_DC)
479 {
480 LOCK();
481 if (zend_hash_num_elements(&php_persistent_handle_hash)) {
482 if (!ht) {
483 ALLOC_HASHTABLE(ht);
484 zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
485 }
486 zend_hash_apply_with_arguments(&php_persistent_handle_hash TSRMLS_CC, php_persistent_handle_apply_statall, 1, ht);
487 } else if (ht) {
488 ht = NULL;
489 }
490 UNLOCK();
491
492 return ht;
493 }
494
495 static php_resource_factory_ops_t php_persistent_handle_resource_factory_ops = {
496 (php_resource_factory_handle_ctor_t) php_persistent_handle_acquire,
497 (php_resource_factory_handle_copy_t) php_persistent_handle_accrete,
498 (php_resource_factory_handle_dtor_t) php_persistent_handle_release
499 };
500
501 PHP_RAPHF_API php_resource_factory_ops_t *php_persistent_handle_get_resource_factory_ops(void)
502 {
503 return &php_persistent_handle_resource_factory_ops;
504 }
505
506 ZEND_BEGIN_ARG_INFO_EX(ai_raphf_stat_persistent_handles, 0, 0, 0)
507 ZEND_END_ARG_INFO();
508 static PHP_FUNCTION(raphf_stat_persistent_handles)
509 {
510 if (SUCCESS == zend_parse_parameters_none()) {
511 object_init(return_value);
512 if (php_persistent_handle_statall(HASH_OF(return_value) TSRMLS_CC)) {
513 return;
514 }
515 zval_dtor(return_value);
516 }
517 RETURN_FALSE;
518 }
519
520 ZEND_BEGIN_ARG_INFO_EX(ai_raphf_clean_persistent_handles, 0, 0, 0)
521 ZEND_ARG_INFO(0, name)
522 ZEND_ARG_INFO(0, ident)
523 ZEND_END_ARG_INFO();
524 static PHP_FUNCTION(raphf_clean_persistent_handles)
525 {
526 char *name_str = NULL, *ident_str = NULL;
527 int name_len = 0, ident_len = 0;
528
529 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!", &name_str, &name_len, &ident_str, &ident_len)) {
530 php_persistent_handle_cleanup(name_str, name_len, ident_str, ident_len TSRMLS_CC);
531 }
532 }
533
534 static const zend_function_entry raphf_functions[] = {
535 ZEND_NS_FENTRY("raphf", stat_persistent_handles, ZEND_FN(raphf_stat_persistent_handles), ai_raphf_stat_persistent_handles, 0)
536 ZEND_NS_FENTRY("raphf", clean_persistent_handles, ZEND_FN(raphf_clean_persistent_handles), ai_raphf_clean_persistent_handles, 0)
537 {0}
538 };
539
540 PHP_INI_BEGIN()
541 STD_PHP_INI_ENTRY("raphf.persistent_handle.limit", "-1", PHP_INI_SYSTEM, OnUpdateLong, persistent_handle.limit, zend_raphf_globals, raphf_globals)
542 PHP_INI_END()
543
544 static void php_raphf_init_globals(zend_raphf_globals *raphf_globals)
545 {
546 raphf_globals->persistent_handle.limit = -1;
547 }
548
549 PHP_MINIT_FUNCTION(raphf)
550 {
551 ZEND_INIT_MODULE_GLOBALS(raphf, php_raphf_init_globals, NULL);
552 zend_hash_init(&php_persistent_handle_hash, 0, NULL, php_persistent_handle_hash_dtor, 1);
553 #ifdef ZTS
554 php_persistent_handle_lock = tsrm_mutex_alloc();
555 #endif
556 REGISTER_INI_ENTRIES();
557 return SUCCESS;
558 }
559
560 PHP_MSHUTDOWN_FUNCTION(raphf)
561 {
562 zend_hash_destroy(&php_persistent_handle_hash);
563 #ifdef ZTS
564 tsrm_mutex_free(php_persistent_handle_lock);
565 #endif
566 UNREGISTER_INI_ENTRIES();
567 return SUCCESS;
568 }
569
570 static int php_persistent_handle_apply_info_ex(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
571 {
572 php_persistent_handle_list_t **list = p;
573 zend_hash_key *super_key = va_arg(argv, zend_hash_key *);
574 char used[21], free[21];
575
576 slprintf(used, sizeof(used), "%u", (*list)->used);
577 slprintf(free, sizeof(free), "%d", zend_hash_num_elements(&(*list)->free));
578
579 php_info_print_table_row(4, super_key->arKey, key->arKey, used, free);
580
581 return ZEND_HASH_APPLY_KEEP;
582 }
583
584 static int php_persistent_handle_apply_info(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
585 {
586 php_persistent_handle_provider_t *provider = p;
587
588 zend_hash_apply_with_arguments(&provider->list.free TSRMLS_CC, php_persistent_handle_apply_info_ex, 1, key);
589
590 return ZEND_HASH_APPLY_KEEP;
591 }
592
593 PHP_MINFO_FUNCTION(raphf)
594 {
595 php_info_print_table_start();
596 php_info_print_table_header(2, "Resource and persistent handle factory support", "enabled");
597 php_info_print_table_row(2, "Extension version", PHP_RAPHF_VERSION);
598 php_info_print_table_end();
599
600 php_info_print_table_start();
601 php_info_print_table_colspan_header(4, "Persistent handles");
602 php_info_print_table_header(4, "Provider", "Ident", "Used", "Free");
603 LOCK();
604 zend_hash_apply_with_arguments(&php_persistent_handle_hash TSRMLS_CC, php_persistent_handle_apply_info, 0);
605 UNLOCK();
606 php_info_print_table_end();
607
608 DISPLAY_INI_ENTRIES();
609 }
610
611 zend_module_entry raphf_module_entry = {
612 STANDARD_MODULE_HEADER,
613 "raphf",
614 raphf_functions,
615 PHP_MINIT(raphf),
616 PHP_MSHUTDOWN(raphf),
617 NULL,
618 NULL,
619 PHP_MINFO(raphf),
620 PHP_RAPHF_VERSION,
621 STANDARD_MODULE_PROPERTIES
622 };
623 /* }}} */
624
625 #ifdef COMPILE_DL_RAPHF
626 ZEND_GET_MODULE(raphf)
627 #endif
628
629
630 /*
631 * Local variables:
632 * tab-width: 4
633 * c-basic-offset: 4
634 * End:
635 * vim600: noet sw=4 ts=4 fdm=marker
636 * vim<600: noet sw=4 ts=4
637 */