You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bugs@httpd.apache.org by bu...@apache.org on 2002/08/22 01:29:48 UTC

DO NOT REPLY [Bug 11913] New: - Timing issues with ISAPIFakeAsync completion notification causes Apache lockups

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: bugs@httpd.apache.org
        ReportedBy: jdesetto@radiantsystems.com


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: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org