From: William A. Rowe Jr Date: Fri, 25 Jan 2002 07:21:40 +0000 (+0000) Subject: No. I don't like this patch. I like what it does [shared scoreboard X-Git-Tag: 2.0.31~91 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2b87916666dff71af6092251cce1cf6579c5f182;p=apache No. I don't like this patch. I like what it does [shared scoreboard for Windows, finally] but not how it's implemented. However it works, and is equally crufty to what already exists for win32 listeners and other exposed data within scoreboard.c. To do this right, we need to drop all the external references to data within the scoreboard, and add an accessor for remaining bits (such as Win32's need for direct access to the apr_shm_t.) And within Win32, we need to stack all this _within_ the pre-mpm hook. But those are missions in and of themselves. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93027 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 8af700ac36..22389bc15d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ Changes with Apache 2.0.31-dev + *) The Win32 mpm_winnt now has a shared scoreboard. [William Rowe] + *) Change ap_get_brigade prototype to use apr_off_t instead of apr_off_t*. [Justin Erenkrantz] diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 807d9daf9b..e6cd50767b 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -99,6 +99,7 @@ */ #define HARD_SERVER_LIMIT 1 +extern apr_shm_t *ap_scoreboard_shm; server_rec *ap_server_conf; typedef HANDLE thread; @@ -469,6 +470,7 @@ static int get_listeners_from_parent(server_rec *s) * data. The sockets have been set to listening in the parent process. */ pipe = GetStdHandle(STD_INPUT_HANDLE); + for (lr = ap_listeners; lr; lr = lr->next) { if (!ReadFile(pipe, &WSAProtocolInfo, sizeof(WSAPROTOCOL_INFO), &BytesRead, (LPOVERLAPPED) NULL)) { @@ -1224,6 +1226,8 @@ static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_ HANDLE hShareError; HANDLE hShareErrorDup; HANDLE hCurrentProcess = GetCurrentProcess(); + HANDLE sb_os_shm; + HANDLE dup_os_shm; SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; LPWSAPROTOCOL_INFO lpWSAProtocolInfo; @@ -1399,6 +1403,25 @@ static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_ */ Sleep(1000); + if ((rv = apr_os_shm_get(&sb_os_shm, ap_scoreboard_shm)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to retrieve the scoreboard handle"); + return -1; + } + if (!DuplicateHandle(hCurrentProcess, sb_os_shm, pi.hProcess, &dup_os_shm, + 0, FALSE, DUPLICATE_SAME_ACCESS)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Unable to duplicate the scoreboard handle to the child"); + return -1; + } + if (!WriteFile(hPipeWrite, &dup_os_shm, sizeof(dup_os_shm), + &BytesWritten, (LPOVERLAPPED) NULL) + || (BytesWritten != sizeof(dup_os_shm))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Unable to send the scoreboard handle to the child"); + return -1; + } + /* Run the chain of open sockets. For each socket, duplicate it * for the target process then send the WSAPROTOCOL_INFO * (returned by dup socket) to the child. @@ -2078,13 +2101,35 @@ AP_DECLARE(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) if (one_process) { /* Set up the scoreboard. */ - ap_run_pre_mpm(pconf, SB_NOT_SHARED); + ap_run_pre_mpm(pconf, SB_SHARED); if (ap_setup_listeners(ap_server_conf) < 1) { return 1; } } else { /* Set up the scoreboard. */ + HANDLE pipe; + HANDLE sb_os_shm; + DWORD BytesRead; + apr_status_t rv; + + pipe = GetStdHandle(STD_INPUT_HANDLE); + if (!ReadFile(pipe, &sb_os_shm, sizeof(sb_os_shm), + &BytesRead, (LPOVERLAPPED) NULL) + || (BytesRead != sizeof(sb_os_shm))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "child: Unable to access scoreboard handle from parent"); + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + exit(1); + } + if ((rv = apr_os_shm_put(&ap_scoreboard_shm, &sb_os_shm, s->process->pool)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "child: Unable to access scoreboard handle from parent"); + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + exit(1); + } + ap_run_pre_mpm(pconf, SB_SHARED_CHILD); ap_my_generation = atoi(getenv("AP_MY_GENERATION")); get_listeners_from_parent(ap_server_conf); @@ -2101,7 +2146,7 @@ AP_DECLARE(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) "Child %d: Child process is exiting", my_pid); return 1; } - else { + else /* Child */ { /* Set up the scoreboard. */ ap_run_pre_mpm(pconf, SB_SHARED); diff --git a/server/scoreboard.c b/server/scoreboard.c index 927a636423..7726379862 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -85,8 +85,14 @@ AP_DECLARE_DATA int ap_extended_status = 0; AP_DECLARE_DATA apr_time_t ap_restart_time = 0; #if APR_HAS_SHARED_MEMORY + #include "apr_shm.h" -static apr_shm_t *scoreboard_shm = NULL; + +#ifndef WIN32 +static /* but must be exported to mpm_winnt */ +#endif + apr_shm_t *ap_scoreboard_shm = NULL; + #endif APR_HOOK_STRUCT( @@ -118,7 +124,7 @@ static apr_status_t ap_cleanup_shared_mem(void *d) #if APR_HAS_SHARED_MEMORY free(ap_scoreboard_image); ap_scoreboard_image = NULL; - apr_shm_destroy(scoreboard_shm); + apr_shm_destroy(ap_scoreboard_shm); #endif return APR_SUCCESS; } @@ -165,7 +171,7 @@ static apr_status_t open_scoreboard(apr_pool_t *p) char *fname = NULL; #ifndef WIN32 - rv = apr_shm_create(&scoreboard_shm, scoreboard_size, fname, p); + rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, p); if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "Fatal error: could not create scoreboard " @@ -179,7 +185,7 @@ static apr_status_t open_scoreboard(apr_pool_t *p) if (ap_scoreboard_fname) { fname = ap_server_root_relative(p, ap_scoreboard_fname); } - rv = apr_shm_create(&scoreboard_shm, scoreboard_size, fname, p); + rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, p); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "Fatal error: could not open(create) scoreboard"); @@ -203,20 +209,12 @@ apr_status_t reopen_scoreboard(apr_pool_t *p, int detached) if (!detached) { return APR_SUCCESS; } - if (ap_scoreboard_fname) { - fname = ap_server_root_relative(p, ap_scoreboard_fname); - } - rv = apr_shm_attach(&scoreboard_shm, fname, p); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "Fatal error: could not open(create) scoreboard"); - return rv; - } - if (apr_shm_size_get(scoreboard_shm) < scoreboard_size) { + if (apr_shm_size_get(ap_scoreboard_shm) < scoreboard_size) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "Fatal error: shared scoreboard too small for child!"); - apr_shm_detach(scoreboard_shm); - scoreboard_shm = NULL; + apr_shm_detach(ap_scoreboard_shm); + ap_scoreboard_shm = NULL; + return APR_EINVAL; } /* everything will be cleared shortly */ #endif @@ -259,7 +257,7 @@ void ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) if (sb_type == SB_SHARED) { void *sb_shared; rv = open_scoreboard(p); - if (rv || !(sb_shared = apr_shm_baseaddr_get(scoreboard_shm))) { + if (rv || !(sb_shared = apr_shm_baseaddr_get(ap_scoreboard_shm))) { exit(APEXIT_INIT); /* XXX need to return an error from this function */ } memset(sb_shared, 0, scoreboard_size); @@ -268,7 +266,7 @@ void ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) else if (sb_type == SB_SHARED_CHILD) { void *sb_shared; rv = reopen_scoreboard(p, 1); - if (rv || !(sb_shared = apr_shm_baseaddr_get(scoreboard_shm))) { + if (rv || !(sb_shared = apr_shm_baseaddr_get(ap_scoreboard_shm))) { exit(APEXIT_INIT); /* XXX need to return an error from this function */ } ap_init_scoreboard(sb_shared); @@ -291,10 +289,10 @@ void ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) if (sb_type != SB_SHARED_CHILD) { ap_scoreboard_image->global->sb_type = sb_type; ap_scoreboard_image->global->running_generation = running_gen; - ap_restart_time = apr_time_now(); apr_pool_cleanup_register(p, NULL, ap_cleanup_scoreboard, apr_pool_cleanup_null); } + ap_restart_time = apr_time_now(); } /* Routines called to deal with the scoreboard image