LCOV - code coverage report
Current view: top level - ext/raphf - php_raphf.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 208 266 78.2 %
Date: 2015-02-17 20:30:22 Functions: 29 36 80.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11