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