Re: browscap and nesting level too deep (bug #25916)
| From: | Uwe Schindler | Date: | Wed, 03 Dec 2003 17:17:47 +0000 |
| Subject: | Re: browscap and nesting level too deep (bug #25916) | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-6126@lists.php.net to get a copy of this message | ||
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
thetaphi@php.net - 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; }
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; }