]> granicus.if.org Git - apache/blobdiff - server/mpm/winnt/mpm_winnt.c
That's not a -D'ef - its an envar - you can't pass foo=bar in apache!
[apache] / server / mpm / winnt / mpm_winnt.c
index 1b764f38fe26fdb124b6dd22f874d7265b1619c6..96585a7c5c7b12e68c41d6816b64aa596a9e6cf2 100644 (file)
 #include "ap_config.h"
 #include "ap_listen.h"
 #include "mpm_default.h"
-#include "ap_iol.h"
 #include "mpm_winnt.h"
 #include "mpm_common.h"
 
+typedef HANDLE thread;
+
 /*
  * Definitions of WINNT MPM specific config globals
  */
@@ -112,8 +113,8 @@ OSVERSIONINFO osver; /* VER_PLATFORM_WIN32_NT */
 int ap_max_requests_per_child=0;
 int ap_daemons_to_start=0;
 
-static event *exit_event;
-HANDLE maintenance_event;
+static HANDLE exit_event;
+static HANDLE maintenance_event;
 apr_lock_t *start_mutex;
 DWORD my_pid;
 DWORD parent_pid;
@@ -156,16 +157,12 @@ static apr_status_t socket_cleanup(void *sock)
  * or thrown out entirely...
  */
 
-typedef void semaphore;
-typedef void event;
-
-static semaphore *
-create_semaphore(int initial)
+static HANDLE create_semaphore(int initial)
 {
     return(CreateSemaphore(NULL, initial, 1000000, NULL));
 }
 
-static void acquire_semaphore(semaphore *semaphore_id)
+static void acquire_semaphore(HANDLE semaphore_id)
 {
     int rv;
     
@@ -174,12 +171,12 @@ static void acquire_semaphore(semaphore *semaphore_id)
     return;
 }
 
-static int release_semaphore(semaphore *semaphore_id)
+static int release_semaphore(HANDLE semaphore_id)
 {
     return(ReleaseSemaphore(semaphore_id, 1, NULL));
 }
 
-static void destroy_semaphore(semaphore *semaphore_id)
+static void destroy_semaphore(HANDLE semaphore_id)
 {
     CloseHandle(semaphore_id);
 }
@@ -199,14 +196,15 @@ static PSECURITY_ATTRIBUTES GetNullACL()
     if (pSD == NULL || sa == NULL) {
         return NULL;
     }
+    apr_set_os_error(0);
     if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)
-       || GetLastError()) {
+       || apr_get_os_error()) {
         LocalFree( pSD );
         LocalFree( sa );
         return NULL;
     }
     if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE)
-       || GetLastError()) {
+       || apr_get_os_error()) {
         LocalFree( pSD );
         LocalFree( sa );
         return NULL;
@@ -315,13 +313,13 @@ void signal_parent(int type)
        /* Um, problem, can't signal the parent, which means we can't
         * signal ourselves to die. Ignore for now...
         */
-       ap_log_error(APLOG_MARK, APLOG_EMERG, GetLastError(), server_conf,
+       ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), server_conf,
                      "OpenEvent on %s event", signal_name);
        return;
     }
     if (SetEvent(e) == 0) {
        /* Same problem as above */
-       ap_log_error(APLOG_MARK, APLOG_EMERG, GetLastError(), server_conf,
+       ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), server_conf,
                      "SetEvent on %s event", signal_name);
        CloseHandle(e);
        return;
@@ -331,17 +329,17 @@ void signal_parent(int type)
 
 static int volatile is_graceful = 0;
 
-API_EXPORT(int) ap_graceful_stop_signalled(void)
+AP_DECLARE(int) ap_graceful_stop_signalled(void)
 {
     return is_graceful;
 }
 
-API_EXPORT(void) ap_start_shutdown(void)
+AP_DECLARE(void) ap_start_shutdown(void)
 {
     signal_parent(0);
 }
 
-API_EXPORT(void) ap_start_restart(int gracefully)
+AP_DECLARE(void) ap_start_restart(int gracefully)
 {
     is_graceful = gracefully;
     signal_parent(1);
@@ -468,7 +466,7 @@ static int setup_inherited_listeners(server_rec *s)
     for (lr = ap_listeners; lr; lr = lr->next) {
         if (!ReadFile(pipe, &WSAProtocolInfo, sizeof(WSAPROTOCOL_INFO), 
                       &BytesRead, (LPOVERLAPPED) NULL)) {
-            ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                          "setup_inherited_listeners: Unable to read socket data from parent");
             signal_parent(0);  /* tell parent to die */
             exit(1);
@@ -478,7 +476,7 @@ static int setup_inherited_listeners(server_rec *s)
         nsd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
                         &WSAProtocolInfo, 0, 0);
         if (nsd == INVALID_SOCKET) {
-            ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), server_conf,
+            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), server_conf,
                          "Child %d: setup_inherited_listeners(), WSASocket failed to open the inherited socket.", my_pid);
             signal_parent(0);  /* tell parent to die */
             exit(1);
@@ -599,7 +597,7 @@ typedef struct joblist_s {
  */
 
 typedef struct globals_s {
-    semaphore *jobsemaphore;
+    HANDLE jobsemaphore;
     joblist *jobhead;
     joblist *jobtail;
     apr_lock_t *jobmutex;
@@ -702,7 +700,7 @@ static void accept_and_queue_connections(void * dummy)
 
        rc = select(listenmaxfd + 1, &main_fds, NULL, NULL, &tv);
 
-        if (rc == 0 || (rc == SOCKET_ERROR && h_errno == WSAEINTR)) {
+        if (rc == 0 || (rc == SOCKET_ERROR && APR_STATUS_IS_EINTR(apr_get_netos_error()))) {
             count_select_errors = 0;    /* reset count of errors */            
             continue;
         }
@@ -711,12 +709,12 @@ static void accept_and_queue_connections(void * dummy)
              * select errors. This count is used to ensure we don't go into
              * a busy loop of continuous errors.
              */
-            ap_log_error(APLOG_MARK, APLOG_INFO, h_errno, server_conf, 
-                         "select failed with errno %d", h_errno);
+            ap_log_error(APLOG_MARK, APLOG_INFO, apr_get_netos_error(), server_conf, 
+                         "select failed with error %d", apr_get_netos_error());
             count_select_errors++;
             if (count_select_errors > MAX_SELECT_ERRORS) {
                 shutdown_in_progress = 1;
-                ap_log_error(APLOG_MARK, APLOG_ERR, h_errno, server_conf,
+                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), server_conf,
                              "Too many errors in select loop. Child process exiting.");
                 break;
             }
@@ -736,11 +734,11 @@ static void accept_and_queue_connections(void * dummy)
             if (csd == INVALID_SOCKET) {
                 csd = -1;
             }
-        } while (csd < 0 && h_errno == WSAEINTR);
+        } while (csd < 0 && APR_STATUS_IS_EINTR(apr_get_netos_error()));
 
        if (csd < 0) {
-            if (h_errno != WSAECONNABORTED) {
-               ap_log_error(APLOG_MARK, APLOG_ERR, h_errno, server_conf,
+            if (APR_STATUS_IS_ECONNABORTED(apr_get_netos_error())) {
+               ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), server_conf,
                            "accept: (client socket)");
             }
        }
@@ -759,7 +757,7 @@ static PCOMP_CONTEXT win9x_get_connection(PCOMP_CONTEXT context)
         /* allocate the completion context and the transaction pool */
         context = apr_pcalloc(pconf, sizeof(COMP_CONTEXT));
         if (!context) {
-            ap_log_error(APLOG_MARK,APLOG_ERR, GetLastError(), server_conf,
+            ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), server_conf,
                          "win9x_get_connection: apr_pcalloc() failed. Process will exit.");
             return NULL;
         }
@@ -777,7 +775,7 @@ static PCOMP_CONTEXT win9x_get_connection(PCOMP_CONTEXT context)
         context->sa_server = apr_palloc(context->ptrans, len);
         if (getsockname(context->accept_socket, 
                         context->sa_server, &len)== SOCKET_ERROR) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, WSAGetLastError(), server_conf, 
+            ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), server_conf, 
                          "getsockname failed");
             continue;
         }
@@ -785,13 +783,11 @@ static PCOMP_CONTEXT win9x_get_connection(PCOMP_CONTEXT context)
         context->sa_client = apr_palloc(context->ptrans, len);
         if ((getpeername(context->accept_socket,
                          context->sa_client, &len)) == SOCKET_ERROR) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, WSAGetLastError(), server_conf, 
+            ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), server_conf, 
                          "getpeername failed");
             memset(&context->sa_client, '\0', sizeof(context->sa_client));
         }
 
-        context->conn_io = ap_bcreate(context->ptrans, B_RDWR);
-
         /* do we NEED_DUPPED_CSD ?? */
         
         return context;
@@ -820,17 +816,17 @@ static void drain_acceptex_complport(HANDLE hComplPort, BOOLEAN bCleanUp)
         rc = GetQueuedCompletionStatus(hComplPort, &BytesRead, &CompKey,
                                        &pol, 1000);
         if (!rc) {
-            rc = GetLastError();
-            if (rc == ERROR_OPERATION_ABORTED) {
-                ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, server_conf,
-                             "Child %d: Draining an ABORTED packet off "
+            rc = apr_get_os_error();
+            if (rc == APR_FROM_OS_ERROR(ERROR_OPERATION_ABORTED)) {
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, server_conf,
+                             "Child %d: Draining an ABORTED packet off "
                              "the AcceptEx completion port.", my_pid);
                 continue;
             }
             break;
         }
         ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, server_conf,
-                     "Child %d: Draining and discarding an active connection "
+                     "Child %d: Draining and discarding an active connection "
                      "off the AcceptEx completion port.", my_pid);
         context = (PCOMP_CONTEXT) pol;
         if (context && bCleanUp) {
@@ -850,7 +846,7 @@ static int create_acceptex_context(apr_pool_t *_pconf, ap_listen_rec *lr)
     /* allocate the completion context */
     context = apr_pcalloc(_pconf, sizeof(COMP_CONTEXT));
     if (!context) {
-        ap_log_error(APLOG_MARK,APLOG_ERR, GetLastError(), server_conf,
+        ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), server_conf,
                      "create_acceptex_context: apr_pcalloc() failed. Process will exit.");
         return -1;
     }
@@ -859,7 +855,7 @@ static int create_acceptex_context(apr_pool_t *_pconf, ap_listen_rec *lr)
     context->lr = lr;
     context->Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 
     if (context->Overlapped.hEvent == NULL) {
-        ap_log_error(APLOG_MARK,APLOG_ERR, GetLastError(), server_conf,
+        ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), server_conf,
                      "create_acceptex_context: CreateEvent() failed. Process will exit.");
         return -1;
     }
@@ -868,7 +864,7 @@ static int create_acceptex_context(apr_pool_t *_pconf, ap_listen_rec *lr)
     apr_get_os_sock(&nsd, context->lr->sd);
     context->accept_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (context->accept_socket == INVALID_SOCKET) {
-        ap_log_error(APLOG_MARK,APLOG_ERR, WSAGetLastError(), server_conf,
+        ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_netos_error(), server_conf,
                      "create_acceptex_context: socket() failed. Process will exit.");
         return -1;
     }
@@ -877,28 +873,32 @@ static int create_acceptex_context(apr_pool_t *_pconf, ap_listen_rec *lr)
     if (setsockopt(context->accept_socket, SOL_SOCKET,
                    SO_UPDATE_ACCEPT_CONTEXT, (char *)&nsd,
                    sizeof(nsd))) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, WSAGetLastError(), server_conf,
+        ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), server_conf,
                      "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed.");
         /* Not a failure condition. Keep running. */
     }
 
     apr_create_pool(&context->ptrans, _pconf);
-    context->conn_io = ap_bcreate(context->ptrans, B_RDWR);
-    context->recv_buf = context->conn_io->inbase;
-    context->recv_buf_size = context->conn_io->bufsiz - 2*PADDED_ADDR_SIZE;
 
+    /* recv_buf must be large enough to hold the remote and local
+     * addresses. Note that recv_buf_size is the amount of recv_buf
+     * available for AcceptEx to receive bytes into. Since we 
+     * don't want AcceptEx to do a recv, set the size to 0.
+     */
+    context->recv_buf = apr_pcalloc(_pconf, 2*PADDED_ADDR_SIZE);
+    context->recv_buf_size = 0;
 
     /* AcceptEx on the completion context. The completion context will be signaled
      * when a connection is accepted. */
     if (!AcceptEx(nsd, context->accept_socket,
                   context->recv_buf, 
-                  0, //context->recv_buf_size,
+                  context->recv_buf_size,
                   PADDED_ADDR_SIZE, PADDED_ADDR_SIZE,
                   &BytesRead,
                   (LPOVERLAPPED) context)) {
-        lasterror = WSAGetLastError();
-        if (lasterror != ERROR_IO_PENDING) {
-            ap_log_error(APLOG_MARK,APLOG_ERR, WSAGetLastError(), server_conf,
+        lasterror = apr_get_netos_error();
+        if (lasterror != APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
+            ap_log_error(APLOG_MARK,APLOG_ERR, lasterror, server_conf,
                          "create_acceptex_context: AcceptEx failed. Process will exit.");
             return -1;
         }
@@ -917,9 +917,6 @@ static apr_inline apr_status_t reset_acceptex_context(PCOMP_CONTEXT context)
     /* reset the buffer pools */
     apr_clear_pool(context->ptrans);
     context->sock = NULL;
-    context->conn_io = ap_bcreate(context->ptrans, B_RDWR);
-    context->recv_buf = context->conn_io->inbase;
-    context->recv_buf_size = context->conn_io->bufsiz - 2*PADDED_ADDR_SIZE;
 
     /* recreate and initialize the accept socket if it is not being reused */
     apr_get_os_sock(&nsd, context->lr->sd);
@@ -936,7 +933,7 @@ static apr_inline apr_status_t reset_acceptex_context(PCOMP_CONTEXT context)
         if (context->accept_socket == INVALID_SOCKET) {
             context->accept_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
             if (context->accept_socket == INVALID_SOCKET) {
-                rc = WSAGetLastError();
+                rc = apr_get_netos_error();
                 ap_log_error(APLOG_MARK,APLOG_ERR, rc, server_conf,
                              "reset_acceptex_context: socket() failed. Process will exit.");
                 return rc;
@@ -945,20 +942,25 @@ static apr_inline apr_status_t reset_acceptex_context(PCOMP_CONTEXT context)
             /* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */
             if (setsockopt(context->accept_socket, SOL_SOCKET,
                            SO_UPDATE_ACCEPT_CONTEXT, (char *)&nsd, sizeof(nsd))) {
-                ap_log_error(APLOG_MARK, APLOG_WARNING, WSAGetLastError(),
+                ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(),
                              server_conf,
                              "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed.");
             }
         }
 
-        if (!AcceptEx(nsd, context->accept_socket, context->recv_buf, 0,
-                      PADDED_ADDR_SIZE, PADDED_ADDR_SIZE, &BytesRead, 
+        if (!AcceptEx(nsd, context->accept_socket, 
+                      context->recv_buf,                   
+                      context->recv_buf_size,
+                      PADDED_ADDR_SIZE, 
+                      PADDED_ADDR_SIZE, 
+                      &BytesRead, 
                       (LPOVERLAPPED) context)) {
-            rc = WSAGetLastError();
-            if (rc != ERROR_IO_PENDING) {
-                ap_log_error(APLOG_MARK, APLOG_INFO, rc, server_conf,
+
+            rc = apr_get_netos_error();
+            if (rc != APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, rc, server_conf,
                              "reset_acceptex_context: AcceptEx failed for "
-                             "listening socket: %d and accept socket: %d", 
+                             "listening socket: %d and accept socket: %d. Getting a new accept socket.", 
                              nsd, context->accept_socket);
                 closesocket(context->accept_socket);
                 context->accept_socket = INVALID_SOCKET;
@@ -1013,15 +1015,15 @@ static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT context)
         rc = GetQueuedCompletionStatus(AcceptExCompPort, &BytesRead, &CompKey,
                                        &pol, INFINITE);
         if (!rc) {
-            rc = GetLastError();
-            if (rc != ERROR_OPERATION_ABORTED) {
+            rc = apr_get_os_error();
+            if (rc != APR_FROM_OS_ERROR(ERROR_OPERATION_ABORTED)) {
                 /* Is this a deadly condition? 
                  * We sometimes get ERROR_NETNAME_DELETED when a client
                  * disconnects when attempting to reuse sockets. Not sure why 
                  * we see this now and not during AcceptEx(). Reset the
                  * AcceptEx context and continue...
                  */
-                ap_log_error(APLOG_MARK,APLOG_INFO, rc, server_conf,
+                ap_log_error(APLOG_MARK,APLOG_DEBUG, rc, server_conf,
                              "Child %d: - GetQueuedCompletionStatus() failed", 
                              my_pid);
                 /* Reset the completion context */
@@ -1044,7 +1046,7 @@ static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT context)
                 /* Sometimes we catch ERROR_OPERATION_ABORTED completion packets
                  * from the old child process (during a restart). Ignore them.
                  */
-                ap_log_error(APLOG_MARK,APLOG_INFO, rc, server_conf,
+                ap_log_error(APLOG_MARK,APLOG_DEBUG, rc, server_conf,
                              "Child %d: - Draining ERROR_OPERATION_ABORTED packet off "
                              "the completion port.", my_pid);
             }
@@ -1084,9 +1086,8 @@ static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT context)
     }
 
     /* Received a connection */
-    context->conn_io->incnt = BytesRead;
     GetAcceptExSockaddrs(context->recv_buf, 
-                         0, //context->recv_buf_size,
+                         context->recv_buf_size,
                          PADDED_ADDR_SIZE,
                          PADDED_ADDR_SIZE,
                          &context->sa_server,
@@ -1120,10 +1121,10 @@ static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT context)
 static void worker_main(int child_num)
 {
     PCOMP_CONTEXT context = NULL;
+    apr_os_sock_info_t sockinfo;
 
     while (1) {
         conn_rec *c;
-        ap_iol *iol;
         apr_int32_t disconnected;
 
         /* Grab a connection off the network */
@@ -1137,39 +1138,28 @@ static void worker_main(int child_num)
         if (!context)
             break;
         sock_disable_nagle(context->accept_socket);
-        apr_put_os_sock(&context->sock, &context->accept_socket, context->ptrans);
 
-        iol = ap_iol_attach_socket(context->ptrans, context->sock);
-        if (iol == NULL) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, APR_ENOMEM, server_conf,
-                         "worker_main: attach_socket() failed. Continuing...");
-            closesocket(context->accept_socket);
-            continue;
-        }
-        ap_bpush_iol(context->conn_io, iol);
-        c = ap_new_connection(context->ptrans, server_conf, context->conn_io,
-                              (struct sockaddr_in *) context->sa_client,
-                              (struct sockaddr_in *) context->sa_server,
+        sockinfo.os_sock = &context->accept_socket;
+        sockinfo.local   = context->sa_server;
+        sockinfo.remote  = context->sa_client;
+        sockinfo.family  = APR_INET;
+        sockinfo.type    = SOCK_STREAM;
+        apr_make_os_sock(&context->sock, &sockinfo, context->ptrans);
+
+        c = ap_new_connection(context->ptrans, server_conf, context->sock,
                               child_num);
 
         ap_process_connection(c);
 
 
         apr_getsocketopt(context->sock, APR_SO_DISCONNECTED, &disconnected);
-        if (disconnected) {
-            /* Kill the clean-up registered by the iol. We want to leave 
-             * the accept socket open because we are about to try to 
-             * reuse it
-             */
-            ap_bpop_iol(&iol, context->conn_io);
-        }
-        else {
+        if (!disconnected) {
             context->accept_socket = INVALID_SOCKET;
             ap_lingering_close(c);
         }
     }
 
-    ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, server_conf,
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, server_conf,
                  "Child %d: Thread exiting.", my_pid);
 #if 0
 
@@ -1178,7 +1168,7 @@ static void worker_main(int child_num)
     /* TODO: Add code to clean-up completion contexts here */
 }
 
-static void cleanup_thread(thread **handles, int *thread_cnt, int thread_to_clean)
+static void cleanup_thread(thread *handles, int *thread_cnt, int thread_to_clean)
 {
     int i;
 
@@ -1195,7 +1185,7 @@ static void create_listeners()
     for (lr = ap_listeners; lr != NULL; lr = lr->next) {
         while (lr->count < NUM_LISTENERS) {
             if (create_acceptex_context(pconf, lr) == -1) {
-                ap_log_error(APLOG_MARK,APLOG_ERR, GetLastError(), server_conf,
+                ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), server_conf,
                              "Unable to create an AcceptEx completion context -- process will exit");
                 signal_parent(0);      /* tell parent to die */
             }
@@ -1219,7 +1209,7 @@ static void child_main()
     char* exit_event_name;
     int nthreads = ap_threads_per_child;
     int tid;
-    thread **child_handles;
+    thread *child_handles;
     int rv;
     time_t end_time;
     int i;
@@ -1282,10 +1272,10 @@ static void child_main()
     /* Create the worker thread pool */
     ap_log_error(APLOG_MARK,APLOG_INFO, APR_SUCCESS, server_conf, 
                  "Child %d: Starting %d worker threads.", my_pid, nthreads);
-    child_handles = (thread *) alloca(nthreads * sizeof(int));
+    child_handles = (thread) alloca(nthreads * sizeof(int));
     for (i = 0; i < nthreads; i++) {
-        child_handles[i] = (thread *) _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) worker_main,
-                                                     NULL, 0, &tid);
+        child_handles[i] = (thread) _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) worker_main,
+                                                   NULL, 0, &tid);
     }
 
     /* Begin accepting connections */
@@ -1316,7 +1306,7 @@ static void child_main()
         cld = rv - WAIT_OBJECT_0;
         if (rv == WAIT_FAILED) {
             /* Something serious is wrong */
-            ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                          "Child %d: WAIT_FAILED -- shutting down server");
             break;
         }
@@ -1513,7 +1503,7 @@ static int create_process(apr_pool_t *p, HANDLE *handles, HANDLE *events, int *p
                      "Parent: Path to Apache process too long");
         return -1;
     } else if (rv == 0) {
-        ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                      "Parent: GetModuleFileName() returned NULL for current process.");
         return -1;
     }
@@ -1551,7 +1541,7 @@ static int create_process(apr_pool_t *p, HANDLE *handles, HANDLE *events, int *p
     pEnvVar = '\0';
     /* Create a pipe to send socket info to the child */
     if (!CreatePipe(&hPipeRead, &hPipeWrite, &sa, 0)) {
-        ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                      "Parent: Unable to create pipe to child process.");
         return -1;
     }
@@ -1572,7 +1562,7 @@ static int create_process(apr_pool_t *p, HANDLE *handles, HANDLE *events, int *p
                        pEnvBlock,          /* Environment block */
                        NULL,
                        &si, &pi)) {
-        ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                      "Parent: Not able to create the child process.");
         /*
          * We must close the handles to the new process and its main thread
@@ -1594,7 +1584,7 @@ static int create_process(apr_pool_t *p, HANDLE *handles, HANDLE *events, int *p
     sa.lpSecurityDescriptor = NULL;        
     kill_event = CreateEvent(&sa, TRUE, FALSE, apr_psprintf(pconf,"apC%d", pi.dwProcessId));
     if (!kill_event) {
-        ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                      "Parent: Could not create exit event for child process");
         CloseHandle(pi.hProcess);
         CloseHandle(pi.hThread);
@@ -1621,7 +1611,7 @@ static int create_process(apr_pool_t *p, HANDLE *handles, HANDLE *events, int *p
                      "Parent: Duplicating socket %d and sending it to child process %d", nsd, pi.dwProcessId);
         if (WSADuplicateSocket(nsd, pi.dwProcessId,
                                lpWSAProtocolInfo) == SOCKET_ERROR) {
-            ap_log_error(APLOG_MARK, APLOG_CRIT, h_errno, server_conf,
+            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), server_conf,
                          "Parent: WSADuplicateSocket failed for socket %d.", lr->sd );
             return -1;
         }
@@ -1629,11 +1619,11 @@ static int create_process(apr_pool_t *p, HANDLE *handles, HANDLE *events, int *p
         if (!WriteFile(hPipeWrite, lpWSAProtocolInfo, (DWORD) sizeof(WSAPROTOCOL_INFO),
                        &BytesWritten,
                        (LPOVERLAPPED) NULL)) {
-            ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                          "Parent: Unable to write duplicated socket %d to the child.", lr->sd );
             return -1;
         }
-        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, APR_SUCCESS, server_conf,
+        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, APR_SUCCESS, server_conf,
                      "Parent: BytesWritten = %d WSAProtocolInfo = %x20", BytesWritten, *lpWSAProtocolInfo);
     }
     if (osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
@@ -1641,7 +1631,7 @@ static int create_process(apr_pool_t *p, HANDLE *handles, HANDLE *events, int *p
         if (!DuplicateHandle(GetCurrentProcess(), AcceptExCompPort, 
                              pi.hProcess, &hDupedCompPort,  0,
                              TRUE, DUPLICATE_SAME_ACCESS)) {
-            ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                          "Parent: Unable to duplicate AcceptEx completion port. Shutting down.");
             return -1;
         }
@@ -1677,7 +1667,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
     while (remaining_children_to_start--) {
         if (create_process(pconf, process_handles, process_kill_events, 
                            &current_live_processes) < 0) {
-            ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
+            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), server_conf,
                          "master_main: create child process failed. Exiting.");
             shutdown_pending = 1;
             goto die_now;
@@ -1698,13 +1688,13 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
     cld = rv - WAIT_OBJECT_0;
     if (rv == WAIT_FAILED) {
         /* Something serious is wrong */
-        ap_log_error(APLOG_MARK,APLOG_CRIT, GetLastError(), server_conf,
+        ap_log_error(APLOG_MARK,APLOG_CRIT, apr_get_os_error(), server_conf,
                      "master_main: WaitForMultipeObjects WAIT_FAILED -- doing server shutdown");
         shutdown_pending = 1;
     }
     else if (rv == WAIT_TIMEOUT) {
         /* Hey, this cannot happen */
-        ap_log_error(APLOG_MARK, APLOG_ERR, GetLastError(), s,
+        ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,
                      "master_main: WaitForMultipeObjects with INFINITE wait exited with WAIT_TIMEOUT");
         shutdown_pending = 1;
     }
@@ -1713,9 +1703,9 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
         shutdown_pending = 1;
         printf("shutdown event signaled\n");
         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, APR_SUCCESS, s, 
-                     "master_main: Shutdown event signaled -- doing server shutdown.");
+                     "Parent: SHUTDOWN EVENT SIGNALED -- Shutting down the server.");
         if (ResetEvent(shutdown_event) == 0) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, GetLastError(), s,
+            ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,
                          "ResetEvent(shutdown_event)");
         }
 
@@ -1725,9 +1715,9 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
         int children_to_kill = current_live_processes;
         restart_pending = 1;
         ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, s, 
-                     "master_main: Restart event signaled. Doing a graceful restart.");
+                     "Parent: RESTART EVENT SIGNALED -- Restarting the server.");
         if (ResetEvent(restart_event) == 0) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, GetLastError(), s,
+            ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,
                          "master_main: ResetEvent(restart_event) failed.");
         }
         /* Signal each child process to die 
@@ -1738,7 +1728,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
          */
         for (i = 0; i < children_to_kill; i++) {
             if (SetEvent(process_kill_events[i]) == 0)
-                ap_log_error(APLOG_MARK, APLOG_ERR, GetLastError(), s,
+                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s,
                              "master_main: SetEvent for child process in slot #%d failed", i);
             cleanup_process(process_handles, process_kill_events, i, &current_live_processes);
         }
@@ -1756,7 +1746,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
          */
         restart_pending = 1;
         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, APR_SUCCESS, server_conf, 
-                     "master_main: Child process failed. Restarting the child process.");
+                     "Parent: CHILD PROCESS FAILED -- Restarting the child process.");
         ap_assert(cld < current_live_processes);
         cleanup_process(process_handles, process_kill_events, cld, &current_live_processes);
         /* APD2("main_process: child in slot %d died", rv); */
@@ -1779,7 +1769,7 @@ die_now:
         for (i = 0; i < current_live_processes; i++) {
             printf("SetEvent handle = %d\n", process_kill_events[i]);
             if (SetEvent(process_kill_events[i]) == 0)
-                ap_log_error(APLOG_MARK,APLOG_ERR, GetLastError(), server_conf,
+                ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), server_conf,
                              "master_main: SetEvent for child process in slot #%d failed", i);
         }
 
@@ -1794,7 +1784,7 @@ die_now:
         }
         for (i = 0; i < current_live_processes; i++) {
             ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO, APR_SUCCESS, server_conf,
-                         "forcing termination of child #%d (handle %d)", i, process_handles[i]);
+                         "Parent: Forcing termination of child #%d (handle %d)", i, process_handles[i]);
             TerminateProcess((HANDLE) process_handles[i], 1);
         }
         return 0;  /* Tell the caller we do not want to restart */
@@ -1804,7 +1794,7 @@ die_now:
 }
 
 
-#define SERVICE_UNNAMED -1
+#define SERVICE_UNNAMED (-1)
 
 /* service_nt_main_fn needs to append the StartService() args 
  * outside of our call stack and thread as the service starts...
@@ -1818,7 +1808,7 @@ apr_array_header_t *mpm_new_argv;
 
 static apr_status_t service_to_start_success;
 static int inst_argc;
-static char **inst_argv;
+static const char * const *inst_argv;
     
 void winnt_rewrite_args(process_rec *process) 
 {
@@ -1836,12 +1826,10 @@ void winnt_rewrite_args(process_rec *process)
     char fnbuf[MAX_PATH];
     char optbuf[3];
     const char *optarg;
-    const char **new_arg;
     int fixed_args;
     char *pid;
     apr_getopt_t *opt;
-
-    one_process = !!getenv("ONE_PROCESS");
+    int running_as_service = 1;
 
     osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
     GetVersionEx(&osver);
@@ -1851,8 +1839,8 @@ void winnt_rewrite_args(process_rec *process)
     if (pid) 
     {
         /* This is the child */
-        parent_pid = (DWORD) atol(pid);
         my_pid = GetCurrentProcessId();
+        parent_pid = (DWORD) atol(pid);
 
         /* The parent is responsible for providing the
          * COMPLETE ARGUMENTS REQUIRED to the child.
@@ -1881,40 +1869,39 @@ void winnt_rewrite_args(process_rec *process)
      *         The requested service's (-n) registry ConfigArgs
      *             The WinNT SCM's StartService() args
      */
-
     if (!GetModuleFileName(NULL, fnbuf, sizeof(fnbuf))) {
-        /* WARNING: There is an implict assumption here that the
-         * executable resides in the ServerRoot!
-         */
-        rv = GetLastError();
+        rv = apr_get_os_error();
         ap_log_error(APLOG_MARK,APLOG_ERR, rv, NULL, 
-                     "Failed to get the running module's file name");
+                     "Failed to get the path of Apache.exe");
         exit(1);
     }
+    /* WARNING: There is an implict assumption here that the
+     * executable resides in ServerRoot or ServerRoot\bin
+     */
     def_server_root = (char *) apr_filename_of_pathname(fnbuf);
     if (def_server_root > fnbuf) {
         *(def_server_root - 1) = '\0';
-        def_server_root = ap_os_canonical_filename(process->pool, fnbuf);
+        def_server_root = (char *) apr_filename_of_pathname(fnbuf);
+        if (!strcasecmp(def_server_root, "bin"))
+            *(def_server_root - 1) = '\0';
     }
+    def_server_root = ap_os_canonical_filename(process->pool, fnbuf);
 
     /* Use process->pool so that the rewritten argv
      * lasts for the lifetime of the server process,
      * because pconf will be destroyed after the 
      * initial pre-flight of the config parser.
      */
-
-    mpm_new_argv = apr_make_array(process->pool, process->argc + 2, sizeof(char *));
-    new_arg = (char**) apr_push_array(mpm_new_argv);
-    *new_arg = (char *) process->argv[0];
-    
-    new_arg = (char**) apr_push_array(mpm_new_argv);
-    *new_arg = "-d";
-    new_arg = (char**) apr_push_array(mpm_new_argv);
-    *new_arg = def_server_root;
+    mpm_new_argv = apr_make_array(process->pool, process->argc + 2,
+                                  sizeof(const char *));
+    *(const char **)apr_push_array(mpm_new_argv) = process->argv[0];
+    *(const char **)apr_push_array(mpm_new_argv) = "-d";
+    *(const char **)apr_push_array(mpm_new_argv) = def_server_root;
 
     fixed_args = mpm_new_argv->nelts;
 
-    optbuf[0] = '-'; optbuf[2] = '\0';
+    optbuf[0] = '-';
+    optbuf[2] = '\0';
     apr_initopt(&opt, process->pool, process->argc, (char**) process->argv);
     while (apr_getopt(opt, "n:k:iu" AP_SERVER_BASEARGS, 
                       optbuf + 1, &optarg) == APR_SUCCESS) {
@@ -1926,20 +1913,21 @@ void winnt_rewrite_args(process_rec *process)
             signal_arg = optarg;
             break;
         case 'i':
-            /* TODO: warn of depreciated syntax, "use -k install instead" */
+            ap_log_error(APLOG_MARK,APLOG_WARNING, 0, NULL,
+                "-i is deprecated.  Use -k install.");
             signal_arg = "install";
             break;
         case 'u':
-            /* TODO: warn of depreciated syntax, "use -k uninstall instead" */
+            ap_log_error(APLOG_MARK,APLOG_WARNING, 0, NULL,
+                "-u is deprecated.  Use -k uninstall.");
             signal_arg = "uninstall";
             break;
         default:
-            optbuf[1] = (char) opt;
-            new_arg = (char**) apr_push_array(mpm_new_argv);
-            *new_arg = apr_pstrdup(process->pool, optbuf);
+            *(const char **)apr_push_array(mpm_new_argv) =
+                apr_pstrdup(process->pool, optbuf);
+
             if (optarg) {
-                new_arg = (char**) apr_push_array(mpm_new_argv);
-                *new_arg = optarg;
+                *(const char **)apr_push_array(mpm_new_argv) = optarg;
             }
             break;
         }
@@ -1950,7 +1938,10 @@ void winnt_rewrite_args(process_rec *process)
 
     /* Provide a default 'run' -k arg to simplify signal_arg tests */
     if (!signal_arg)
+    {
         signal_arg = "run";
+        running_as_service = 0;
+    }
 
     if (!strcasecmp(signal_arg, "runservice")) 
     {
@@ -1974,7 +1965,7 @@ void winnt_rewrite_args(process_rec *process)
         }
     }
 
-    if (service_named == SERVICE_UNNAMED) {
+    if (service_named == SERVICE_UNNAMED && running_as_service) {
         service_named = mpm_service_set_name(process->pool, 
                                              DEFAULT_SERVICE_NAME);
     }
@@ -1988,22 +1979,27 @@ void winnt_rewrite_args(process_rec *process)
             exit(1);
         }
     }
-    else
+    else if (running_as_service)
     {
         if (service_named == APR_SUCCESS) 
         {
             rv = mpm_merge_service_args(process->pool, mpm_new_argv, 
                                         fixed_args);
-            if (rv != APR_SUCCESS) {
-                ap_log_error(APLOG_MARK,APLOG_ERR, rv, NULL,
-                             "%s: ConfigArgs are missing from the registry.",
-                             display_name);
+            if (rv == APR_SUCCESS) {
+                ap_log_error(APLOG_MARK,APLOG_NOERRNO|APLOG_INFO, 0, NULL,
+                             "Using ConfigArgs of the installed service "
+                             "\"%s\".", display_name);
             }
+           else  {
+                ap_log_error(APLOG_MARK,APLOG_INFO, rv, NULL,
+                             "No installed ConfigArgs for the service "
+                             "\"%s\", using Apache defaults.", display_name);
+           }
         }
         else
         {
-            ap_log_error(APLOG_MARK,APLOG_ERR, 0, NULL,
-                 "%s: No installed service by that name.", display_name);
+            ap_log_error(APLOG_MARK,APLOG_INFO|APLOG_NOERRNO, 0, NULL,
+                 "No installed service named \"%s\".", display_name);
             exit(1);
         }
     }
@@ -2012,10 +2008,11 @@ void winnt_rewrite_args(process_rec *process)
      * These will be used for the -k install parameters, as well as
      * for the -k start service override arguments.
      */
-    inst_argv = (char**) mpm_new_argv->elts + mpm_new_argv->nelts - inst_argc;
+    inst_argv = (const char * const *)mpm_new_argv->elts
+        + mpm_new_argv->nelts - inst_argc;
 
     process->argc = mpm_new_argv->nelts; 
-    process->argv = (char**) mpm_new_argv->elts;
+    process->argv = (const char * const *) mpm_new_argv->elts;
 }
 
 
@@ -2031,6 +2028,12 @@ static void winnt_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pt
      */
     apr_status_t rv;
 
+    if (ap_exists_config_define("ONE_PROCESS"))
+        one_process = -1;
+
+    if (ap_exists_config_define("ONE_PROCESS"))
+        one_process = -1;
+
     if (!strcasecmp(signal_arg, "runservice")
             && (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
             && (service_to_start_success != APR_SUCCESS)) {
@@ -2113,7 +2116,7 @@ static void winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *p
                                                           0,
                                                           0); /* CONCURRENT ACTIVE THREADS */
                 if (AcceptExCompPort == NULL) {
-                    ap_log_error(APLOG_MARK,APLOG_ERR, GetLastError(), server_conf,
+                    ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), server_conf,
                                  "Parent: Unable to create the AcceptExCompletionPort -- process will exit");
                     exit(1);
                 }
@@ -2126,7 +2129,7 @@ static void winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *p
              */
             shutdown_event = CreateEvent(sa, FALSE, FALSE, signal_shutdown_name);
             if (!shutdown_event) {
-                ap_log_error(APLOG_MARK, APLOG_EMERG, GetLastError(), server_conf,
+                ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), server_conf,
                              "Parent: Cannot create shutdown event %s", signal_shutdown_name);
                 CleanNullACL((void *)sa);
                 exit(1);
@@ -2138,7 +2141,7 @@ static void winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *p
             restart_event = CreateEvent(sa, FALSE, FALSE, signal_restart_name);
             if (!restart_event) {
                 CloseHandle(shutdown_event);
-                ap_log_error(APLOG_MARK, APLOG_EMERG, GetLastError(), server_conf,
+                ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), server_conf,
                              "Parent: Cannot create restart event %s", signal_restart_name);
                 CleanNullACL((void *)sa);
                 exit(1);
@@ -2182,7 +2185,7 @@ static void winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *p
     }
 }
 
-API_EXPORT(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
+AP_DECLARE(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
 {
     static int restart = 0;            /* Default is "not a restart" */
 
@@ -2225,7 +2228,6 @@ API_EXPORT(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
 
 static void winnt_hooks(void)
 {
-    one_process = 0;
     ap_hook_pre_config(winnt_pre_config, NULL, NULL, AP_HOOK_MIDDLE);
     ap_hook_post_config(winnt_post_config, NULL, NULL, 0);
 }
@@ -2308,18 +2310,18 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, char *arg)
 
 /* Stub functions until this MPM supports the connection status API */
 
-API_EXPORT(void) ap_update_connection_status(long conn_id, const char *key, \
+AP_DECLARE(void) ap_update_connection_status(long conn_id, const char *key, \
                                              const char *value)
 {
     /* NOP */
 }
 
-API_EXPORT(void) ap_reset_connection_status(long conn_id)
+AP_DECLARE(void) ap_reset_connection_status(long conn_id)
 {
     /* NOP */
 }
 
-API_EXPORT(apr_array_header_t *) ap_get_status_table(apr_pool_t *p)
+AP_DECLARE(apr_array_header_t *) ap_get_status_table(apr_pool_t *p)
 {
     /* NOP */
     return NULL;
@@ -2338,7 +2340,7 @@ LISTEN_COMMANDS
 { NULL }
 };
 
-MODULE_VAR_EXPORT module mpm_winnt_module = {
+AP_MODULE_DECLARE_DATA module mpm_winnt_module = {
     MPM20_MODULE_STUFF,
     winnt_rewrite_args,         /* hook to run before apache parses args */
     NULL,                      /* create per-directory config structure */
@@ -2346,6 +2348,5 @@ MODULE_VAR_EXPORT module mpm_winnt_module = {
     NULL,                      /* create per-server config structure */
     NULL,                      /* merge per-server config structures */
     winnt_cmds,                        /* command apr_table_t */
-    NULL,                      /* handlers */
     winnt_hooks                /* register_hooks */
 };