DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11913>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11913 Timing issues with ISAPIFakeAsync completion notification causes Apache lockups Summary: Timing issues with ISAPIFakeAsync completion notification causes Apache lockups Product: Apache httpd-2.0 Version: 2.0.39 Platform: PC OS/Version: Windows NT/2K Status: NEW Severity: Critical Priority: Other Component: mod_isapi AssignedTo: [email protected] ReportedBy: [EMAIL PROTECTED] When trying to use the MS SOAP ISAPI DLL with Apache I encountered an issue where if the ISAPIFakeAsync flag was used the ISAPI handler could miss the signal that the DLL was done and cause each of the worker threads in Apache to block indefinately, which would eventually end up the winnt_accept() function in mpm_winnt.c in 2.0.39 or child.c in 2.0.40 spinning with a Sleep(0) when all the worked threads ended up blocking. After looking into the issue on the 2.0.39 code base and double checking the 2.0.40 code base but not the current code base to see if it was already fixed, it appears that the problem is that the ISAPI module was receiving the asynchronous completion notification through the ServerSupportFunction() before the code that was handling the HSE_STATUS_PENDING return from the ISAPI dll in the isapi_handler() function in mod_isapi.c was set up to handle receiving the completion. To resolve this issue I added a new int didcomplete member variable to the isapi_cid structure and set that to 1 in the ServerSupportFunction() when it received HSE_REQ_DONE_WITH_SESSION. cid->didcomplete = 1; if (cid->completed) { apr_thread_mutex_unlock(cid->completed); } Then in the isapi_handler() function in the switch statement handling HSE_STATUS_PENDING after reserving the mutex I added a check to see if didcomplete was 1, and if it was I continued out of the switch statement, otherwise I waited on locking the mutex as was being done before to catch ServerSupportFunction(HSE_REQ_DONE_WITH_SESSION). rv = apr_thread_mutex_create(&cid->completed, APR_THREAD_MUTEX_UNNESTED, r->pool); comp = cid->completed; if (cid->completed && (rv == APR_SUCCESS)) { rv = apr_thread_mutex_lock(comp); } if (cid->didcomplete == 1) { /* The request must have completed in another thread before we * got to this point so we don't need to wait */ } else { /* The completion port is now locked. When we regain the * lock, we may destroy the request. */ if (cid->completed && (rv == APR_SUCCESS)) { rv = apr_thread_mutex_lock(comp); } } A quick check to cid->didcomplete could probably be done first to see if it was already set and if mutex even needed to be created, but the above code sample works and demonstrates a possible solution. Additionally it is probably worth while to change the Sleep(0) in the winnt_accept() function in server\mpm\winnt\child.c in 2.0.40 when mpm_get_completion_context() returns NULL to a Sleep(100) as is done if the socket can not be initialized below the call to mpm_get_completion_context(). This should give any lower priority threads that may be involved in a request through an ISAPI filter or otherwise more processor time to complete their task and free up the worker threads that winnt_accept() is waiting on. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
