Brian, We're on the job. I generally think you're right, we have to do some more thinking but chances are we will change the shutdown order to be reversed. Sorry for not ack'ing earlier.
Zeev At 09:44 PM 6/7/2002, Brian France wrote: >Zend Engine unloading extension in the wrong order! (Re-post due to no >response) > >I have been tracking down a core dump with my php extension when it is >unloading some of its shared libraries. I have shared extension that is >link against libexpat and will load fine if it is the only on in the >php.ini. If I then load xml.so extension then my extension it works fine, >but if it is my extension then xml.so it crashes while xml.so is unloading >libexapt. > >What I have found is the Zend Engine is unloading extension in the same >order it loaded them. > >load: foo_bar.so >load: xml.so > >unload: foo_bar.so >unload: xml.so > >I believe this is wrong and think it should be in reverse order. > >load: foo_bar.so >load: xml.so > >unload: xml.so >unload: foo_bar.so > > >There are two ways to fix this problem. One is to push the modules to the >head of the hash, but looking at the zend_hash_add function I decided to >go with the second. Second way is to destroy them in reverse order. I >created a zend_hash_reverse_destroy and call that instead of >zend_hash_destroy. There may be a better way to do this, but this is the >quick fix for me. > >I have included a patch below, should I submit a bug report as well? > >Thanks, > >Brian > > >diff -rc php-4.2.1/Zend/zend.c >*** php-4.2.1/Zend/zend.c Tue Feb 26 10:59:25 2002 >--- php-4.2.1/Zend/zend.c Thu Jun 6 11:32:57 2002 >*************** >*** 487,493 **** > zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC); > #endif > zend_destroy_rsrc_list_dtors(); >! zend_hash_destroy(&module_registry); > zend_hash_destroy(GLOBAL_FUNCTION_TABLE); > free(GLOBAL_FUNCTION_TABLE); > zend_hash_destroy(GLOBAL_CLASS_TABLE); >--- 487,493 ---- > zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC); > #endif > zend_destroy_rsrc_list_dtors(); >! zend_hash_reverse_destroy(&module_registry); > zend_hash_destroy(GLOBAL_FUNCTION_TABLE); > free(GLOBAL_FUNCTION_TABLE); > zend_hash_destroy(GLOBAL_CLASS_TABLE); >diff -rc php-4.2.1/Zend/zend_hash.c >*** php-4.2.1/Zend/zend_hash.c Mon Apr 22 23:53:26 2002 >--- php-4.2.1/Zend/zend_hash.c Thu Jun 6 11:32:57 2002 >*************** >*** 550,555 **** >--- 550,579 ---- > SET_INCONSISTENT(HT_DESTROYED); > } > >+ ZEND_API void zend_hash_reverse_destroy(HashTable *ht) >+ { >+ Bucket *p, *q; >+ >+ IS_CONSISTENT(ht); >+ >+ SET_INCONSISTENT(HT_IS_DESTROYING); >+ >+ p = ht->pListTail; >+ while (p != NULL) { >+ q = p; >+ p = p->pLast; >+ if (ht->pDestructor) { >+ ht->pDestructor(q->pData); >+ } >+ if (!q->pDataPtr && q->pData) { >+ pefree(q->pData, ht->persistent); >+ } >+ pefree(q, ht->persistent); >+ } >+ pefree(ht->arBuckets, ht->persistent); >+ >+ SET_INCONSISTENT(HT_DESTROYED); >+ } > > ZEND_API void zend_hash_clean(HashTable *ht) > { > >-- >PHP Development Mailing List <http://www.php.net/> >To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php