One solution (attached is the patch, if nobody has someone against it I will apply it):
I switch off the recursion protection for the browscap hash in zend_hash_init_ex because this hash has no recursive things in it and is not modified after it is created.


Uwe

At 18:06 03.12.2003, Uwe Schindler wrote:
Today I got the error from bug #25916 several times on our webserver. Looking through the code I found out the following:
* It depends NOT on the fact if there is a parameter to get_browser() or not
* It happens sometimes when server is very heavy loaded, the homepage of the domain uses the get_browser() function and is the most visited page.


So it must be a multithreading issue (NSAPI is a multithreading webserver). And I have an idea:
Line 257 uses:
zend_hash_apply_with_arguments(&browser_hash, (apply_func_args_t) browser_reg_compare, 2, lookup_browser_name, &found_browser_entry);


This is the only function in this context in zend_hash.c which uses the Recursion protection with
#define HASH_PROTECT_RECURSION(ht) \
if ((ht)->bApplyProtection) { \
if ((ht)->nApplyCount++ >= 3) { \
zend_error(E_ERROR, "Nesting level too deep - recursive dependency?"); \
} \
}


The browser hashtable is a global variable in browscap.c and can be used by more than one call to get_browser() even at the same time. So if one zend_hash_apply_with_arguments() locks the hashtable and a second and third thread tries to do that you will get the error, because (ht)->nApplyCount++ raises and raises...

This evening I will try to put a mutex at the beginning of get_browser to prevent more threads running at the same time there. But as I see this, this zend_hash_apply function is used very often could there be other effects if a global variable is a hashtable?

Only one question: Is there a special PHP way to use mutexes? I am not familar in Zend programming (I do only SAPI...)

----- Uwe Schindler [EMAIL PROTECTED] - http://www.php.net NSAPI SAPI developer Erlangen, Germany
Index: ext/standard/browscap.c
===================================================================
RCS file: /repository/php-src/ext/standard/browscap.c,v
retrieving revision 1.60.2.15
diff -u -r1.60.2.15 browscap.c
--- ext/standard/browscap.c     13 Aug 2003 23:39:03 -0000      1.60.2.15
+++ ext/standard/browscap.c     3 Dec 2003 17:15:01 -0000
@@ -149,7 +149,7 @@
                zend_file_handle fh;
                memset(&fh, 0, sizeof(fh));
 
-               if (zend_hash_init(&browser_hash, 0, NULL, (dtor_func_t) 
browscap_entry_dtor, 1)==FAILURE) {
+               if (zend_hash_init_ex(&browser_hash, 0, NULL, (dtor_func_t) 
browscap_entry_dtor, 1, 0)==FAILURE) {
                        return FAILURE;
                }
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to