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