]> granicus.if.org Git - apache/commitdiff
Catch exceptions in worker threads so a segfault doesn't kill all active
authorBrian Havard <bjh@apache.org>
Mon, 20 Aug 2001 16:10:57 +0000 (16:10 +0000)
committerBrian Havard <bjh@apache.org>
Mon, 20 Aug 2001 16:10:57 +0000 (16:10 +0000)
connections in the process. When this occurs, a graceful shutdown of the
child is initiated so any leaked resources & hosed memory is disposed of ASAP.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90400 13f79535-47bb-0310-9956-ffa450edef68

server/mpm/mpmt_os2/mpmt_os2.c
server/mpm/mpmt_os2/mpmt_os2_child.c

index 1c078badfa8fb96c8cd209b9fffea99d1b77c451..10802514377e88c8c005e2a2f09b5040eb1ece1a 100644 (file)
@@ -77,7 +77,6 @@
 /*
  Todo list
  - Enforce MaxClients somehow
- - Catch thread exceptions & initiate graceful shutdown of child process
 */
 #define CORE_PRIVATE
 #define INCL_NOPMAPI
index 36a96ca939c616a4ec58d064ba6fd719881c9faf..e9cfcecbe8f3860d8a9fad203120f97ebcac36d2 100644 (file)
@@ -340,6 +340,39 @@ void add_worker()
 
 
 
+ULONG APIENTRY thread_exception_handler(EXCEPTIONREPORTRECORD *pReportRec,
+                                        EXCEPTIONREGISTRATIONRECORD *pRegRec,
+                                        CONTEXTRECORD *pContext,
+                                        PVOID p)
+{
+    int c;
+
+    if (pReportRec->fHandlerFlags & EH_NESTED_CALL) {
+        return XCPT_CONTINUE_SEARCH;
+    }
+
+    if (pReportRec->ExceptionNum == XCPT_ACCESS_VIOLATION ||
+        pReportRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO) {
+        ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, ap_server_conf,
+                     "caught exception in worker thread, initiating child shutdown pid=%d", getpid());
+        for (c=0; c<HARD_THREAD_LIMIT; c++) {
+            if (ap_scoreboard_image->servers[child_slot][c].tid == _gettid()) {
+                ap_scoreboard_image->servers[child_slot][c].status = SERVER_DEAD;
+                break;
+            }
+        }
+
+        /* Shut down process ASAP, it could be quite unhealthy & leaking resources */
+        shutdown_pending = 1;
+        ap_scoreboard_image->parent[child_slot].quiescing = 1;
+        DosUnwindException(UNWIND_ALL, 0, 0);
+    }
+  
+    return XCPT_CONTINUE_SEARCH;
+}
+
+
+
 static void worker_main(void *vpArg)
 {
     long conn_id;
@@ -353,6 +386,10 @@ static void worker_main(void *vpArg)
     ULONG len;
     BYTE priority;
     int thread_slot = (int)vpArg;
+    EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler };
+  
+    /* Trap exceptions in this thread so we don't take down the whole process */
+    DosSetExceptionHandler( &reg_rec );
 
     rc = DosOpenQueue(&owner, &workq,
                       apr_psprintf(pchild, "/queues/httpd/work.%d", getpid()));