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