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