Annotation of embedaddon/php/Zend/zend_list.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | Zend Engine |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1998-2012 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 321634 2012-01-01 13:15:04Z felipe $ */
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: {
37: int index;
38: zend_rsrc_list_entry le;
39: TSRMLS_FETCH();
40:
41: le.ptr=ptr;
42: le.type=type;
43: le.refcount=1;
44:
45: index = zend_hash_next_free_element(&EG(regular_list));
46:
47: zend_hash_index_update(&EG(regular_list), index, (void *) &le, sizeof(zend_rsrc_list_entry), NULL);
48: return index;
49: }
50:
51: ZEND_API int _zend_list_delete(ulong id TSRMLS_DC)
52: {
53: zend_rsrc_list_entry *le;
54:
55: 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: if (--le->refcount<=0) {
58: return zend_hash_index_del(&EG(regular_list), id);
59: } else {
60: return SUCCESS;
61: }
62: } else {
63: return FAILURE;
64: }
65: }
66:
67:
68: ZEND_API void *_zend_list_find(ulong id, int *type TSRMLS_DC)
69: {
70: zend_rsrc_list_entry *le;
71:
72: if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
73: *type = le->type;
74: return le->ptr;
75: } else {
76: *type = -1;
77: return NULL;
78: }
79: }
80:
81: ZEND_API int _zend_list_addref(ulong id TSRMLS_DC)
82: {
83: zend_rsrc_list_entry *le;
84:
85: 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: le->refcount++;
88: return SUCCESS;
89: } else {
90: return FAILURE;
91: }
92: }
93:
94:
95: ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type)
96: {
97: int rsrc_id;
98:
99: rsrc_id = zend_list_insert(rsrc_pointer, rsrc_type);
100:
101: if (rsrc_result) {
102: rsrc_result->value.lval = rsrc_id;
103: rsrc_result->type = IS_RESOURCE;
104: }
105:
106: 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: {
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: if (default_id==-1) { /* use id */
121: if (!passed_id) {
122: if (resource_type_name) {
123: class_name = get_active_class_name(&space TSRMLS_CC);
124: 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: return NULL;
127: } else if ((*passed_id)->type != IS_RESOURCE) {
128: if (resource_type_name) {
129: class_name = get_active_class_name(&space TSRMLS_CC);
130: 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: return NULL;
133: }
134: id = (*passed_id)->value.lval;
135: } else {
136: id = default_id;
137: }
138:
139: resource = zend_list_find(id, &actual_resource_type);
140: if (!resource) {
141: if (resource_type_name) {
142: class_name = get_active_class_name(&space TSRMLS_CC);
143: 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: return NULL;
146: }
147:
148: va_start(resource_types, num_resource_types);
149: for (i=0; i<num_resource_types; i++) {
150: if (actual_resource_type == va_arg(resource_types, int)) {
151: va_end(resource_types);
152: if (found_resource_type) {
153: *found_resource_type = actual_resource_type;
154: }
155: return resource;
156: }
157: }
158: va_end(resource_types);
159:
160: if (resource_type_name) {
161: class_name = get_active_class_name(&space TSRMLS_CC);
162: 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: return NULL;
166: }
167:
168:
169: void list_entry_destructor(void *ptr)
170: {
171: zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
172: zend_rsrc_list_dtors_entry *ld;
173: TSRMLS_FETCH();
174:
175: if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
176: switch (ld->type) {
177: case ZEND_RESOURCE_LIST_TYPE_STD:
178: if (ld->list_dtor) {
179: (ld->list_dtor)(le->ptr);
180: }
181: break;
182: case ZEND_RESOURCE_LIST_TYPE_EX:
183: if (ld->list_dtor_ex) {
184: ld->list_dtor_ex(le TSRMLS_CC);
185: }
186: break;
187: EMPTY_SWITCH_DEFAULT_CASE()
188: }
189: } else {
190: zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", le->type);
191: }
192: }
193:
194:
195: void plist_entry_destructor(void *ptr)
196: {
197: zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
198: zend_rsrc_list_dtors_entry *ld;
199: TSRMLS_FETCH();
200:
201: if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
202: switch (ld->type) {
203: case ZEND_RESOURCE_LIST_TYPE_STD:
204: if (ld->plist_dtor) {
205: (ld->plist_dtor)(le->ptr);
206: }
207: break;
208: case ZEND_RESOURCE_LIST_TYPE_EX:
209: if (ld->plist_dtor_ex) {
210: ld->plist_dtor_ex(le TSRMLS_CC);
211: }
212: break;
213: EMPTY_SWITCH_DEFAULT_CASE()
214: }
215: } else {
216: zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)", le->type);
217: }
218: }
219:
220:
221: int zend_init_rsrc_list(TSRMLS_D)
222: {
223: if (zend_hash_init(&EG(regular_list), 0, NULL, list_entry_destructor, 0)==SUCCESS) {
224: EG(regular_list).nNextFreeElement=1; /* we don't want resource id 0 */
225: return SUCCESS;
226: } else {
227: return FAILURE;
228: }
229: }
230:
231:
232: int zend_init_rsrc_plist(TSRMLS_D)
233: {
234: 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: {
240: zend_hash_graceful_reverse_destroy(ht);
241: }
242:
243: static int clean_module_resource(zend_rsrc_list_entry *le, int *resource_id TSRMLS_DC)
244: {
245: if (le->type == *resource_id) {
246: return 1;
247: } else {
248: 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: {
255: if (ld->module_number == *module_number) {
256: zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) clean_module_resource, (void *) &(ld->resource_id) TSRMLS_CC);
257: return 1;
258: } else {
259: return 0;
260: }
261: }
262:
263:
264: void zend_clean_module_rsrc_dtors(int module_number TSRMLS_DC)
265: {
266: zend_hash_apply_with_argument(&list_destructors, (apply_func_arg_t) zend_clean_module_rsrc_dtors_cb, (void *) &module_number TSRMLS_CC);
267: }
268:
269:
270: ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number)
271: {
272: zend_rsrc_list_dtors_entry lde;
273:
274: #if 0
275: printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
276: #endif
277:
278: lde.list_dtor=(void (*)(void *)) ld;
279: lde.plist_dtor=(void (*)(void *)) pld;
280: lde.list_dtor_ex = lde.plist_dtor_ex = NULL;
281: lde.module_number = module_number;
282: lde.resource_id = list_destructors.nNextFreeElement;
283: lde.type = ZEND_RESOURCE_LIST_TYPE_STD;
284: lde.type_name = NULL;
285:
286: if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
287: return FAILURE;
288: }
289: return list_destructors.nNextFreeElement-1;
290: }
291:
292:
293: ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char *type_name, int module_number)
294: {
295: zend_rsrc_list_dtors_entry lde;
296:
297: #if 0
298: printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
299: #endif
300:
301: lde.list_dtor = NULL;
302: lde.plist_dtor = NULL;
303: lde.list_dtor_ex = ld;
304: lde.plist_dtor_ex = pld;
305: lde.module_number = module_number;
306: lde.resource_id = list_destructors.nNextFreeElement;
307: lde.type = ZEND_RESOURCE_LIST_TYPE_EX;
308: lde.type_name = type_name;
309:
310: if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
311: return FAILURE;
312: }
313: return list_destructors.nNextFreeElement-1;
314: }
315:
316: ZEND_API int zend_fetch_list_dtor_id(char *type_name)
317: {
318: zend_rsrc_list_dtors_entry *lde;
319: HashPosition pos;
320:
321: zend_hash_internal_pointer_reset_ex(&list_destructors, &pos);
322: while (zend_hash_get_current_data_ex(&list_destructors, (void **)&lde, &pos) == SUCCESS) {
323: if (lde->type_name && (strcmp(type_name, lde->type_name) == 0)) {
324: #if 0
325: printf("Found resource id %d for resource type %s\n", (*lde).resource_id, type_name);
326: #endif
327: return lde->resource_id;
328: }
329: zend_hash_move_forward_ex(&list_destructors, &pos);
330: }
331:
332: return 0;
333: }
334:
335: int zend_init_rsrc_list_dtors(void)
336: {
337: int retval;
338:
339: retval = zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
340: list_destructors.nNextFreeElement=1; /* we don't want resource type 0 */
341:
342: return retval;
343: }
344:
345:
346: void zend_destroy_rsrc_list_dtors(void)
347: {
348: zend_hash_destroy(&list_destructors);
349: }
350:
351:
352: char *zend_rsrc_list_get_rsrc_type(ulong resource TSRMLS_DC)
353: {
354: zend_rsrc_list_dtors_entry *lde;
355: int rsrc_type;
356:
357: if (!zend_list_find(resource, &rsrc_type))
358: return NULL;
359:
360: if (zend_hash_index_find(&list_destructors, rsrc_type, (void **) &lde)==SUCCESS) {
361: return lde->type_name;
362: } else {
363: return NULL;
364: }
365: }
366:
367: /*
368: * Local variables:
369: * tab-width: 4
370: * c-basic-offset: 4
371: * indent-tabs-mode: t
372: * End:
373: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>