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