LTP GCOV extension - code coverage report
Current view: directory - Zend - zend_list.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 150
Code covered: 53.3 % Executed lines: 80
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2007 Zend Technologies Ltd. (http://www.zend.com) |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 2.00 of the Zend license,     |
       8                 :    | that is bundled with this package in the file LICENSE, and is        | 
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.zend.com/license/2_00.txt.                                |
      11                 :    | If you did not receive a copy of the Zend license and are unable to  |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@zend.com so we can mail you a copy immediately.              |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16                 :    |          Zeev Suraski <zeev@zend.com>                                |
      17                 :    +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: zend_list.c,v 1.66.2.1.2.1 2007/01/01 09:35:46 sebastian Exp $ */
      21                 : 
      22                 : /* resource lists */
      23                 : 
      24                 : #include "zend.h"
      25                 : #include "zend_list.h"
      26                 : #include "zend_API.h"
      27                 : #include "zend_globals.h"
      28                 : 
      29                 : ZEND_API int le_index_ptr;
      30                 : 
      31                 : /* true global */
      32                 : static HashTable list_destructors;
      33                 : 
      34                 : 
      35                 : ZEND_API int zend_list_insert(void *ptr, int type)
      36            1781 : {
      37                 :         int index;
      38                 :         zend_rsrc_list_entry le;
      39                 :         TSRMLS_FETCH();
      40                 : 
      41            1781 :         le.ptr=ptr;
      42            1781 :         le.type=type;
      43            1781 :         le.refcount=1;
      44                 : 
      45            1781 :         index = zend_hash_next_free_element(&EG(regular_list));
      46                 : 
      47            1781 :         zend_hash_index_update(&EG(regular_list), index, (void *) &le, sizeof(zend_rsrc_list_entry), NULL);
      48            1781 :         return index;
      49                 : }
      50                 : 
      51                 : ZEND_API int _zend_list_delete(int id TSRMLS_DC)
      52            3064 : {
      53                 :         zend_rsrc_list_entry *le;
      54                 :         
      55            3064 :         if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
      56                 : /*              printf("del(%d): %d->%d\n", id, le->refcount, le->refcount-1); */
      57            1842 :                 if (--le->refcount<=0) {
      58            1663 :                         return zend_hash_index_del(&EG(regular_list), id);
      59                 :                 } else {
      60             179 :                         return SUCCESS;
      61                 :                 }
      62                 :         } else {
      63            1222 :                 return FAILURE;
      64                 :         }
      65                 : }
      66                 : 
      67                 : 
      68                 : ZEND_API void *_zend_list_find(int id, int *type TSRMLS_DC)
      69           28891 : {
      70                 :         zend_rsrc_list_entry *le;
      71                 : 
      72           28891 :         if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
      73           23497 :                 *type = le->type;
      74           23497 :                 return le->ptr;
      75                 :         } else {
      76            5394 :                 *type = -1;
      77            5394 :                 return NULL;
      78                 :         }
      79                 : }
      80                 : 
      81                 : ZEND_API int _zend_list_addref(int id TSRMLS_DC)
      82             179 : {
      83                 :         zend_rsrc_list_entry *le;
      84                 :         
      85             179 :         if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
      86                 : /*              printf("add(%d): %d->%d\n", id, le->refcount, le->refcount+1); */
      87             179 :                 le->refcount++;
      88             179 :                 return SUCCESS;
      89                 :         } else {
      90               0 :                 return FAILURE;
      91                 :         }
      92                 : }
      93                 : 
      94                 : 
      95                 : ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type)
      96            1781 : {
      97                 :         int rsrc_id;
      98                 : 
      99            1781 :         rsrc_id = zend_list_insert(rsrc_pointer, rsrc_type);
     100                 :         
     101            1781 :         if (rsrc_result) {
     102             216 :                 rsrc_result->value.lval = rsrc_id;
     103             216 :                 rsrc_result->type = IS_RESOURCE;
     104                 :         }
     105                 : 
     106            1781 :         return rsrc_id;
     107                 : }
     108                 : 
     109                 : 
     110                 : ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, char *resource_type_name, int *found_resource_type, int num_resource_types, ...)
     111           28891 : {
     112                 :         int id;
     113                 :         int actual_resource_type;
     114                 :         void *resource;
     115                 :         va_list resource_types;
     116                 :         int i;
     117                 :         char *space;
     118                 :         char *class_name;
     119                 : 
     120           28891 :         if (default_id==-1) { /* use id */
     121           28891 :                 if (!passed_id) {
     122               0 :                         if (resource_type_name) {
     123               0 :                                 class_name = get_active_class_name(&space TSRMLS_CC);
     124               0 :                                 zend_error(E_WARNING, "%s%s%s(): no %s resource supplied", class_name, space, get_active_function_name(TSRMLS_C), resource_type_name);
     125                 :                         }
     126               0 :                         return NULL;
     127           28891 :                 } else if ((*passed_id)->type != IS_RESOURCE) {
     128               0 :                         if (resource_type_name) {
     129               0 :                                 class_name = get_active_class_name(&space TSRMLS_CC);
     130               0 :                                 zend_error(E_WARNING, "%s%s%s(): supplied argument is not a valid %s resource", class_name, space, get_active_function_name(TSRMLS_C), resource_type_name);
     131                 :                         }
     132               0 :                         return NULL;
     133                 :                 }
     134           28891 :                 id = (*passed_id)->value.lval;
     135                 :         } else {
     136               0 :                 id = default_id;
     137                 :         }
     138                 : 
     139           28891 :         resource = zend_list_find(id, &actual_resource_type);
     140           28891 :         if (!resource) {
     141            5394 :                 if (resource_type_name) {
     142            5394 :                         class_name = get_active_class_name(&space TSRMLS_CC);
     143            5394 :                         zend_error(E_WARNING, "%s%s%s(): %d is not a valid %s resource", class_name, space, get_active_function_name(TSRMLS_C), id, resource_type_name);
     144                 :                 }
     145            5394 :                 return NULL;
     146                 :         }
     147                 : 
     148           23497 :         va_start(resource_types, num_resource_types);
     149           23497 :         for (i=0; i<num_resource_types; i++) {
     150           23497 :                 if (actual_resource_type == va_arg(resource_types, int)) {
     151           23497 :                         va_end(resource_types);
     152           23497 :                         if (found_resource_type) {
     153               0 :                                 *found_resource_type = actual_resource_type;
     154                 :                         }
     155           23497 :                         return resource;
     156                 :                 }
     157                 :         }
     158               0 :         va_end(resource_types);
     159                 : 
     160               0 :         if (resource_type_name) {
     161               0 :                 class_name = get_active_class_name(&space TSRMLS_CC);
     162               0 :                 zend_error(E_WARNING, "%s%s%s(): supplied resource is not a valid %s resource", class_name, space, get_active_function_name(TSRMLS_C), resource_type_name);
     163                 :         }
     164                 : 
     165               0 :         return NULL;
     166                 : }
     167                 : 
     168                 : 
     169                 : void list_entry_destructor(void *ptr)
     170            1781 : {
     171            1781 :         zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
     172                 :         zend_rsrc_list_dtors_entry *ld;
     173                 :         TSRMLS_FETCH();
     174                 :         
     175            1781 :         if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
     176            1781 :                 switch (ld->type) {
     177                 :                         case ZEND_RESOURCE_LIST_TYPE_STD:
     178               0 :                                 if (ld->list_dtor) {
     179               0 :                                         (ld->list_dtor)(le->ptr);
     180                 :                                 }
     181               0 :                                 break;
     182                 :                         case ZEND_RESOURCE_LIST_TYPE_EX:
     183            1781 :                                 if (ld->list_dtor_ex) {
     184            1768 :                                         ld->list_dtor_ex(le TSRMLS_CC);
     185                 :                                 }
     186                 :                                 break;
     187                 :                         EMPTY_SWITCH_DEFAULT_CASE()
     188                 :                 }
     189                 :         } else {
     190               0 :                 zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", le->type);
     191                 :         }
     192            1781 : }
     193                 : 
     194                 : 
     195                 : void plist_entry_destructor(void *ptr)
     196               0 : {
     197               0 :         zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
     198                 :         zend_rsrc_list_dtors_entry *ld;
     199                 :         TSRMLS_FETCH();
     200                 : 
     201               0 :         if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
     202               0 :                 switch (ld->type) {
     203                 :                         case ZEND_RESOURCE_LIST_TYPE_STD:
     204               0 :                                 if (ld->plist_dtor) {
     205               0 :                                         (ld->plist_dtor)(le->ptr);
     206                 :                                 }
     207               0 :                                 break;
     208                 :                         case ZEND_RESOURCE_LIST_TYPE_EX:
     209               0 :                                 if (ld->plist_dtor_ex) {
     210               0 :                                         ld->plist_dtor_ex(le TSRMLS_CC);
     211                 :                                 }
     212                 :                                 break;
     213                 :                                 EMPTY_SWITCH_DEFAULT_CASE()
     214                 :                 }
     215                 :         } else {
     216               0 :                 zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)", le->type);
     217                 :         }
     218               0 : }
     219                 : 
     220                 : 
     221                 : int zend_init_rsrc_list(TSRMLS_D)
     222             219 : {
     223             219 :         if (zend_hash_init(&EG(regular_list), 0, NULL, list_entry_destructor, 0)==SUCCESS) {
     224             219 :                 EG(regular_list).nNextFreeElement=1;    /* we don't want resource id 0 */
     225             219 :                 return SUCCESS;
     226                 :         } else {
     227               0 :                 return FAILURE;
     228                 :         }
     229                 : }
     230                 : 
     231                 : 
     232                 : int zend_init_rsrc_plist(TSRMLS_D)
     233             220 : {
     234             220 :         return zend_hash_init_ex(&EG(persistent_list), 0, NULL, plist_entry_destructor, 1, 0);
     235                 : }
     236                 : 
     237                 : 
     238                 : void zend_destroy_rsrc_list(HashTable *ht TSRMLS_DC)
     239             438 : {
     240             438 :         zend_hash_graceful_reverse_destroy(ht);
     241             438 : }
     242                 : 
     243                 : static int clean_module_resource(zend_rsrc_list_entry *le, int *resource_id TSRMLS_DC)
     244               0 : {
     245               0 :         if (le->type == *resource_id) {
     246               0 :                 return 1;
     247                 :         } else {
     248               0 :                 return 0;
     249                 :         }
     250                 : }
     251                 : 
     252                 : 
     253                 : static int zend_clean_module_rsrc_dtors_cb(zend_rsrc_list_dtors_entry *ld, int *module_number TSRMLS_DC)
     254               0 : {
     255               0 :         if (ld->module_number == *module_number) {
     256               0 :                 zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) clean_module_resource, (void *) &(ld->resource_id) TSRMLS_CC);
     257               0 :                 zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) clean_module_resource, (void *) &(ld->resource_id) TSRMLS_CC);
     258               0 :                 return 1;
     259                 :         } else {
     260               0 :                 return 0;
     261                 :         }
     262                 : }
     263                 : 
     264                 : 
     265                 : void zend_clean_module_rsrc_dtors(int module_number TSRMLS_DC)
     266               0 : {
     267               0 :         zend_hash_apply_with_argument(&list_destructors, (apply_func_arg_t) zend_clean_module_rsrc_dtors_cb, (void *) &module_number TSRMLS_CC);
     268               0 : }
     269                 : 
     270                 : 
     271                 : ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number)
     272               0 : {
     273                 :         zend_rsrc_list_dtors_entry lde;
     274                 :         
     275                 : #if 0
     276                 :         printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
     277                 : #endif
     278                 :         
     279               0 :         lde.list_dtor=(void (*)(void *)) ld;
     280               0 :         lde.plist_dtor=(void (*)(void *)) pld;
     281               0 :         lde.list_dtor_ex = lde.plist_dtor_ex = NULL;
     282               0 :         lde.module_number = module_number;
     283               0 :         lde.resource_id = list_destructors.nNextFreeElement;
     284               0 :         lde.type = ZEND_RESOURCE_LIST_TYPE_STD;
     285               0 :         lde.type_name = NULL;
     286                 :         
     287               0 :         if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
     288               0 :                 return FAILURE;
     289                 :         }
     290               0 :         return list_destructors.nNextFreeElement-1;
     291                 : }
     292                 : 
     293                 : 
     294                 : ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char *type_name, int module_number)
     295            2420 : {
     296                 :         zend_rsrc_list_dtors_entry lde;
     297                 :         
     298                 : #if 0
     299                 :         printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
     300                 : #endif
     301                 : 
     302            2420 :         lde.list_dtor = NULL;
     303            2420 :         lde.plist_dtor = NULL;
     304            2420 :         lde.list_dtor_ex = ld;
     305            2420 :         lde.plist_dtor_ex = pld;
     306            2420 :         lde.module_number = module_number;
     307            2420 :         lde.resource_id = list_destructors.nNextFreeElement;
     308            2420 :         lde.type = ZEND_RESOURCE_LIST_TYPE_EX;
     309            2420 :         lde.type_name = type_name;
     310                 :         
     311            2420 :         if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
     312               0 :                 return FAILURE;
     313                 :         }
     314            2420 :         return list_destructors.nNextFreeElement-1;
     315                 : }
     316                 : 
     317                 : ZEND_API int zend_fetch_list_dtor_id(char *type_name)
     318               0 : {
     319                 :         zend_rsrc_list_dtors_entry *lde;
     320                 :         HashPosition pos;
     321                 : 
     322               0 :         zend_hash_internal_pointer_reset_ex(&list_destructors, &pos);
     323               0 :         while (zend_hash_get_current_data_ex(&list_destructors, (void **)&lde, &pos) == SUCCESS) {
     324               0 :                 if (lde->type_name && (strcmp(type_name, lde->type_name) == 0)) {
     325                 : #if 0
     326                 :                         printf("Found resource id %d for resource type %s\n", (*lde).resource_id, type_name);
     327                 : #endif
     328               0 :                         return lde->resource_id;
     329                 :                 }
     330               0 :                 zend_hash_move_forward_ex(&list_destructors, &pos);
     331                 :         }
     332                 : 
     333               0 :         return 0;
     334                 : }
     335                 : 
     336                 : int zend_init_rsrc_list_dtors(void)
     337             220 : {
     338                 :         int retval;
     339                 : 
     340             220 :         retval = zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
     341             220 :         list_destructors.nNextFreeElement=1;    /* we don't want resource type 0 */
     342                 : 
     343             220 :         return retval;
     344                 : }
     345                 : 
     346                 : 
     347                 : void zend_destroy_rsrc_list_dtors(void)
     348             219 : {
     349             219 :         zend_hash_destroy(&list_destructors);
     350             219 : }
     351                 : 
     352                 : 
     353                 : char *zend_rsrc_list_get_rsrc_type(int resource TSRMLS_DC)
     354               0 : {
     355                 :         zend_rsrc_list_dtors_entry *lde;
     356                 :         int rsrc_type;
     357                 : 
     358               0 :         if (!zend_list_find(resource, &rsrc_type))
     359               0 :                 return NULL;
     360                 : 
     361               0 :         if (zend_hash_index_find(&list_destructors, rsrc_type, (void **) &lde)==SUCCESS) {
     362               0 :                 return lde->type_name;
     363                 :         } else {
     364               0 :                 return NULL;
     365                 :         }
     366                 : }
     367                 : 
     368                 : /*
     369                 :  * Local variables:
     370                 :  * tab-width: 4
     371                 :  * c-basic-offset: 4
     372                 :  * indent-tabs-mode: t
     373                 :  * End:
     374                 :  */

Generated by: LTP GCOV extension version 1.5