zeev, andi
i have to following problem: while the zend_destroy_rsrc_list() is running a _dtor function for one of my resources it (the dtor of the resource) does a zend_list_delete, which does a hash_find on the resource-list again. the problem is that zend_destroy_rsrc_list takes out the bucked it will dtor from the hash's mail linked list but it leaves the bucket in ht->arBuckets. so my zend_list_delete might find an already dealloced entry (cause the resource_list is inconsistent) -> boom! the attached patch fixes this by removing the bucket not only from the hashes global linked list but by also removing all traces of it from the ht->arBuckets. i have stolen some code from zend_hash_del_key_or_index. so - we could either apply this patch as it is as zend_destroy_rsrc_list() already fiddles with hash-internals -or- i create a macro in zend_hash.h called DISCONNECT_BUCKET_FROM_ARLIST(ht, bucket). a patch along these lines is needed to have a consistent resource_list while the _dtors are called. i don't think we'll see a measuarable speed impact once this patch is in. comments? tc
? .zend_hash.c.swp Index: zend_list.c =================================================================== RCS file: /repository/Zend/zend_list.c,v retrieving revision 1.52 diff -u -r1.52 zend_list.c --- zend_list.c 6 Jan 2002 15:21:09 -0000 1.52 +++ zend_list.c 16 Apr 2002 15:17:12 -0000 @@ -231,8 +231,10 @@ void zend_destroy_rsrc_list(HashTable *ht TSRMLS_DC) { Bucket *p, *q; + uint nIndex; while (1) { + /* remove bucket from main linked-list */ p = ht->pListTail; if (!p) { break; @@ -242,6 +244,34 @@ q->pListNext = NULL; } ht->pListTail = q; + + /* stolen from zend_hash_del_key_or_index - should be moved back into +zend_hash */ + nIndex = p->h & ht->nTableMask; + + if (p == ht->arBuckets[nIndex]) { + ht->arBuckets[nIndex] = p->pNext; + } else { + p->pLast->pNext = p->pNext; + } + if (p->pNext) { + p->pNext->pLast = p->pLast; + } + if (p->pListLast != NULL) { + p->pListLast->pListNext = p->pListNext; + } else { + /* Deleting the head of the list */ + ht->pListHead = p->pListNext; + } + if (p->pListNext != NULL) { + p->pListNext->pListLast = p->pListLast; + } else { + ht->pListTail = p->pListLast; + } + if (ht->pInternalPointer == p) { + ht->pInternalPointer = p->pListNext; + } + ht->nNumOfElements--; + /* now the hashtable is consistent again */ if (ht->pDestructor) { zend_try {
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php