You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

368 lines
9.5 KiB

27 years ago
23 years ago
27 years ago
24 years ago
27 years ago
24 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
25 years ago
27 years ago
25 years ago
27 years ago
27 years ago
27 years ago
25 years ago
27 years ago
25 years ago
27 years ago
27 years ago
25 years ago
27 years ago
27 years ago
27 years ago
25 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
25 years ago
25 years ago
27 years ago
27 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998-2003 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 at through the world-wide-web at |
  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. /* $Id$ */
  20. /* resource lists */
  21. #include "zend.h"
  22. #include "zend_list.h"
  23. #include "zend_API.h"
  24. #include "zend_globals.h"
  25. ZEND_API int le_index_ptr;
  26. /* true global */
  27. static HashTable list_destructors;
  28. ZEND_API int zend_list_insert(void *ptr, int type)
  29. {
  30. int index;
  31. zend_rsrc_list_entry le;
  32. TSRMLS_FETCH();
  33. le.ptr=ptr;
  34. le.type=type;
  35. le.refcount=1;
  36. index = zend_hash_next_free_element(&EG(regular_list));
  37. zend_hash_index_update(&EG(regular_list), index, (void *) &le, sizeof(zend_rsrc_list_entry), NULL);
  38. return index;
  39. }
  40. ZEND_API int _zend_list_delete(int id TSRMLS_DC)
  41. {
  42. zend_rsrc_list_entry *le;
  43. if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
  44. /* printf("del(%d): %d->%d\n", id, le->refcount, le->refcount-1); */
  45. if (--le->refcount<=0) {
  46. return zend_hash_index_del(&EG(regular_list), id);
  47. } else {
  48. return SUCCESS;
  49. }
  50. } else {
  51. return FAILURE;
  52. }
  53. }
  54. ZEND_API void *_zend_list_find(int id, int *type TSRMLS_DC)
  55. {
  56. zend_rsrc_list_entry *le;
  57. if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
  58. *type = le->type;
  59. return le->ptr;
  60. } else {
  61. *type = -1;
  62. return NULL;
  63. }
  64. }
  65. ZEND_API int _zend_list_addref(int id TSRMLS_DC)
  66. {
  67. zend_rsrc_list_entry *le;
  68. if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
  69. /* printf("add(%d): %d->%d\n", id, le->refcount, le->refcount+1); */
  70. le->refcount++;
  71. return SUCCESS;
  72. } else {
  73. return FAILURE;
  74. }
  75. }
  76. ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type)
  77. {
  78. int rsrc_id;
  79. rsrc_id = zend_list_insert(rsrc_pointer, rsrc_type);
  80. if (rsrc_result) {
  81. rsrc_result->value.lval = rsrc_id;
  82. rsrc_result->type = IS_RESOURCE;
  83. }
  84. return rsrc_id;
  85. }
  86. 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, ...)
  87. {
  88. int id;
  89. int actual_resource_type;
  90. void *resource;
  91. va_list resource_types;
  92. int i;
  93. if (default_id==-1) { /* use id */
  94. if (!passed_id) {
  95. if (resource_type_name) {
  96. zend_error(E_WARNING, "%s(): no %s resource supplied", get_active_function_name(TSRMLS_C), resource_type_name);
  97. }
  98. return NULL;
  99. } else if ((*passed_id)->type != IS_RESOURCE) {
  100. if (resource_type_name) {
  101. zend_error(E_WARNING, "%s(): supplied argument is not a valid %s resource", get_active_function_name(TSRMLS_C), resource_type_name);
  102. }
  103. return NULL;
  104. }
  105. id = (*passed_id)->value.lval;
  106. } else {
  107. id = default_id;
  108. }
  109. resource = zend_list_find(id, &actual_resource_type);
  110. if (!resource) {
  111. if (resource_type_name) {
  112. zend_error(E_WARNING, "%s(): %d is not a valid %s resource", get_active_function_name(TSRMLS_C), id, resource_type_name);
  113. }
  114. return NULL;
  115. }
  116. va_start(resource_types, num_resource_types);
  117. for (i=0; i<num_resource_types; i++) {
  118. if (actual_resource_type == va_arg(resource_types, int)) {
  119. va_end(resource_types);
  120. if (found_resource_type) {
  121. *found_resource_type = actual_resource_type;
  122. }
  123. return resource;
  124. }
  125. }
  126. va_end(resource_types);
  127. if (resource_type_name) {
  128. zend_error(E_WARNING, "%s(): supplied resource is not a valid %s resource", get_active_function_name(TSRMLS_C), resource_type_name);
  129. }
  130. return NULL;
  131. }
  132. void list_entry_destructor(void *ptr)
  133. {
  134. zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
  135. zend_rsrc_list_dtors_entry *ld;
  136. TSRMLS_FETCH();
  137. if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
  138. switch (ld->type) {
  139. case ZEND_RESOURCE_LIST_TYPE_STD:
  140. if (ld->list_dtor) {
  141. (ld->list_dtor)(le->ptr);
  142. }
  143. break;
  144. case ZEND_RESOURCE_LIST_TYPE_EX:
  145. if (ld->list_dtor_ex) {
  146. ld->list_dtor_ex(le TSRMLS_CC);
  147. }
  148. break;
  149. EMPTY_SWITCH_DEFAULT_CASE()
  150. }
  151. } else {
  152. zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", le->type);
  153. }
  154. }
  155. void plist_entry_destructor(void *ptr)
  156. {
  157. zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
  158. zend_rsrc_list_dtors_entry *ld;
  159. TSRMLS_FETCH();
  160. if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
  161. switch (ld->type) {
  162. case ZEND_RESOURCE_LIST_TYPE_STD:
  163. if (ld->plist_dtor) {
  164. (ld->plist_dtor)(le->ptr);
  165. }
  166. break;
  167. case ZEND_RESOURCE_LIST_TYPE_EX:
  168. if (ld->plist_dtor_ex) {
  169. ld->plist_dtor_ex(le TSRMLS_CC);
  170. }
  171. break;
  172. EMPTY_SWITCH_DEFAULT_CASE()
  173. }
  174. } else {
  175. zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)", le->type);
  176. }
  177. }
  178. int zend_init_rsrc_list(TSRMLS_D)
  179. {
  180. if (zend_hash_init(&EG(regular_list), 0, NULL, list_entry_destructor, 0)==SUCCESS) {
  181. EG(regular_list).nNextFreeElement=1; /* we don't want resource id 0 */
  182. return SUCCESS;
  183. } else {
  184. return FAILURE;
  185. }
  186. }
  187. int zend_init_rsrc_plist(TSRMLS_D)
  188. {
  189. return zend_hash_init_ex(&EG(persistent_list), 0, NULL, plist_entry_destructor, 1, 0);
  190. }
  191. void zend_destroy_rsrc_list(HashTable *ht TSRMLS_DC)
  192. {
  193. zend_hash_graceful_reverse_destroy(ht);
  194. }
  195. static int clean_module_resource(zend_rsrc_list_entry *le, int *resource_id TSRMLS_DC)
  196. {
  197. if (le->type == *resource_id) {
  198. return 1;
  199. } else {
  200. return 0;
  201. }
  202. }
  203. static int zend_clean_module_rsrc_dtors_cb(zend_rsrc_list_dtors_entry *ld, int *module_number TSRMLS_DC)
  204. {
  205. if (ld->module_number == *module_number) {
  206. zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) clean_module_resource, (void *) &(ld->resource_id) TSRMLS_CC);
  207. zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) clean_module_resource, (void *) &(ld->resource_id) TSRMLS_CC);
  208. return 1;
  209. } else {
  210. return 0;
  211. }
  212. }
  213. void zend_clean_module_rsrc_dtors(int module_number TSRMLS_DC)
  214. {
  215. zend_hash_apply_with_argument(&list_destructors, (apply_func_arg_t) zend_clean_module_rsrc_dtors_cb, (void *) &module_number TSRMLS_CC);
  216. }
  217. ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number)
  218. {
  219. zend_rsrc_list_dtors_entry lde;
  220. #if 0
  221. printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
  222. #endif
  223. lde.list_dtor=(void (*)(void *)) ld;
  224. lde.plist_dtor=(void (*)(void *)) pld;
  225. lde.list_dtor_ex = lde.plist_dtor_ex = NULL;
  226. lde.module_number = module_number;
  227. lde.resource_id = list_destructors.nNextFreeElement;
  228. lde.type = ZEND_RESOURCE_LIST_TYPE_STD;
  229. lde.type_name = NULL;
  230. if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
  231. return FAILURE;
  232. }
  233. return list_destructors.nNextFreeElement-1;
  234. }
  235. ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char *type_name, int module_number)
  236. {
  237. zend_rsrc_list_dtors_entry lde;
  238. #if 0
  239. printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
  240. #endif
  241. lde.list_dtor = NULL;
  242. lde.plist_dtor = NULL;
  243. lde.list_dtor_ex = ld;
  244. lde.plist_dtor_ex = pld;
  245. lde.module_number = module_number;
  246. lde.resource_id = list_destructors.nNextFreeElement;
  247. lde.type = ZEND_RESOURCE_LIST_TYPE_EX;
  248. lde.type_name = type_name;
  249. if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
  250. return FAILURE;
  251. }
  252. return list_destructors.nNextFreeElement-1;
  253. }
  254. ZEND_API int zend_fetch_list_dtor_id(char *type_name)
  255. {
  256. zend_rsrc_list_dtors_entry *lde;
  257. HashPosition pos;
  258. zend_hash_internal_pointer_reset_ex(&list_destructors, &pos);
  259. while (zend_hash_get_current_data_ex(&list_destructors, (void **)&lde, &pos) == SUCCESS) {
  260. if (strcmp(type_name, lde->type_name) == 0) {
  261. #if 0
  262. printf("Found resource id %d for resource type %s\n", (*lde).resource_id, type_name);
  263. #endif
  264. return lde->resource_id;
  265. }
  266. zend_hash_move_forward_ex(&list_destructors, &pos);
  267. }
  268. return 0;
  269. }
  270. int zend_init_rsrc_list_dtors(void)
  271. {
  272. int retval;
  273. retval = zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
  274. list_destructors.nNextFreeElement=1; /* we don't want resource type 0 */
  275. return retval;
  276. }
  277. void zend_destroy_rsrc_list_dtors(void)
  278. {
  279. zend_hash_destroy(&list_destructors);
  280. }
  281. char *zend_rsrc_list_get_rsrc_type(int resource TSRMLS_DC)
  282. {
  283. zend_rsrc_list_dtors_entry *lde;
  284. int rsrc_type;
  285. if (!zend_list_find(resource, &rsrc_type))
  286. return NULL;
  287. if (zend_hash_index_find(&list_destructors, rsrc_type, (void **) &lde)==SUCCESS) {
  288. return lde->type_name;
  289. } else {
  290. return NULL;
  291. }
  292. }
  293. /*
  294. * Local variables:
  295. * tab-width: 4
  296. * c-basic-offset: 4
  297. * indent-tabs-mode: t
  298. * End:
  299. */