Changes with Apache 2.0b1
+ *) Begin restructuring scoreboard code to enable adding back in
+ the ability to use IPC other than shared memory.
+ Get mod_status working on Windows again. [Bill Stoddard]
*) Make mod_status work with 2.0. This will work for prefork,
mpmt_pthread, and dexter. [Ryan Bloom]
*/
typedef int ap_generation_t;
+/* Is the scoreboard shared between processes or not?
+ * Set by the MPM when the scoreboard is created.
+ */
+typedef enum {
+ SB_SHARED = 1,
+ SB_NOT_SHARED = 2
+} ap_scoreboard_e;
+
/* stuff which is thread/process specific */
typedef struct {
#ifdef OPTIMIZE_TIMEOUTS
} short_score;
typedef struct {
+ ap_scoreboard_e sb_type;
ap_generation_t running_generation; /* the generation of children which
* should still be serving requests. */
} global_score;
#endif
AP_DECLARE(int) ap_exists_scoreboard_image(void);
+AP_DECLARE(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e t);
void reinit_scoreboard(apr_pool_t *p);
apr_status_t ap_cleanup_shared_mem(void *d);
AP_DECLARE(void) reopen_scoreboard(apr_pool_t *p);
-apr_inline void ap_sync_scoreboard_image(void);
+void ap_sync_scoreboard_image(void);
void increment_counts(int child_num, int thread_num, request_rec *r);
void update_scoreboard_global(void);
AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid);
# End Source File
# Begin Source File
+SOURCE=.\server\scoreboard.c
+# End Source File
+# Begin Source File
+
SOURCE=.\server\vhost.c
# End Source File
# End Group
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 /nologo /subsystem:windows /dll /incremental:no /map /out:"Release/mod_file_cache.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
-# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /map /out:"Release/mod_file_cache.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
+# ADD BASE LINK32 /nologo /subsystem:windows /dll /map /machine:I386 /out:"Release/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
+# ADD LINK32 /nologo /subsystem:windows /dll /map /machine:I386 /out:"Release/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
!ELSEIF "$(CFG)" == "mod_file_cache - Win32 Debug"
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 /nologo /subsystem:windows /dll /incremental:no /map /debug /out:"Debug/mod_file_cache.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
-# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /map /debug /out:"Debug/mod_file_cache.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
+# ADD BASE LINK32 /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /out:"Debug/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
+# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /out:"Debug/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache
!ENDIF
if (r->header_only)
return 0;
- ap_sync_scoreboard_image();
+/* ap_sync_scoreboard_image(); */
for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
int indx = (i * HARD_THREAD_LIMIT) + j;
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MD /W3 /O2 /I "..\..\include" /I "..\..\os\win32" /I "..\..\srclib\apr\include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_status" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /I "..\..\include" /I "..\..\os\win32" /I "..\..\srclib\apr\include" /I "../../srclib/apr-util/include" /I "../../server/mpm/winnt" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_status" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /map /out:"Release/mod_status.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_status
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /map /out:"Release/mod_status.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_status
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /map /machine:I386 /out:"Release/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /map /machine:I386 /out:"Release/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status
!ELSEIF "$(CFG)" == "mod_status - Win32 Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\..\include" /I "..\..\os\win32" /I "..\..\srclib\apr\include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_status" /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\..\include" /I "..\..\os\win32" /I "..\..\srclib\apr\include" /I "../../srclib/apr-util/include" /I "../../server/mpm/winnt" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_status" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /out:"Debug/mod_status.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_status
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /out:"Debug/mod_status.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_status
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /out:"Debug/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /out:"Debug/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status
!ENDIF
#ifndef APACHE_MPM_H
#define APACHE_MPM_H
+/* mpm.h is the place to make declarations that are MPM specific but that must be
+ * shared with non-mpm specific code in the server. Hummm, perhaps we can
+ * move most of this stuff to mpm_common.h?
+ */
+extern int ap_threads_per_child;
#endif /* APACHE_MPM_H */
#ifndef APACHE_MPM_DEFAULT_H
#define APACHE_MPM_DEFAULT_H
+/* AP_CHILD_THREAD_FROM_ID is used by the scoreboard. */
+#define AP_CHILD_THREAD_FROM_ID(i) i, 0
+
/* Number of threads to spawn off by default --- also, if fewer than
* this free when the caretaker checks, it will spawn more.
*/
+
/* ====================================================================
* The Apache Software License, Version 1.1
*
#include "mpm_default.h"
#include "mpm_winnt.h"
#include "mpm_common.h"
+#include "scoreboard.h"
typedef HANDLE thread;
/*
* Definitions of WINNT MPM specific config globals
*/
+
static int workers_may_exit = 0;
static int shutdown_in_progress = 0;
static unsigned int g_blocked_threads = 0;
static char *ap_pid_fname = NULL;
-static int ap_threads_per_child = 0;
+int ap_threads_per_child = 0;
static int max_requests_per_child = 0;
static HANDLE shutdown_event; /* used to signal shutdown to parent */
DWORD my_pid;
DWORD parent_pid;
+/* ap_get_max_daemons and ap_my_generation are used by the scoreboard
+ * code
+ */
+ap_generation_t volatile ap_my_generation=0; /* Used by the scoreboard */
+AP_DECLARE(int) ap_get_max_daemons(void)
+{
+ return 1;
+}
+
/* This is the helper code to resolve late bound entry points
* missing from one or more releases of the Win32 API...
* but it sure would be nice if we didn't duplicate this code
int cld;
apr_pool_t *pchild;
+ /* Set up the scoreboard. The scoreboard in this MPM only applies to the
+ * child process and is not shared across processes
+ */
+ ap_create_scoreboard(pconf, SB_NOT_SHARED);
/* This is the child process or we are running in single process
* mode.
/* From winnt.c: */
extern OSVERSIONINFO osver;
-extern int ap_threads_per_child;
extern int ap_max_requests_per_child;
-extern int ap_extended_status;
extern void clean_child_exit(int);
AP_DECLARE(void) ap_start_shutdown(void);
#include "http_main.h"
#include "http_core.h"
#include "http_config.h"
+/* ToDo: Fix this right */
+#ifndef WIN32
#include "unixd.h"
+#endif
+
#include "http_conf_globals.h"
#include "mpm.h"
#include "scoreboard.h"
#if APR_HAS_SHARED_MEMORY
#include "apr_shmem.h"
-
static apr_shmem_t *scoreboard_shm = NULL;
-
+#endif
+/*
+ * ToDo:
+ * This function should be renamed to cleanup_shared
+ * and it should handle cleaning up a scoreboard shared
+ * between processes using any form of IPC (file, shared memory
+ * segment, etc.). Leave it as is now because it is being used
+ * by various MPMs.
+ */
apr_status_t ap_cleanup_shared_mem(void *d)
{
+#if APR_HAD_SHARED_MEMORY
apr_shm_free(scoreboard_shm, ap_scoreboard_image);
ap_scoreboard_image = NULL;
apr_shm_destroy(scoreboard_shm);
-
+#endif
return APR_SUCCESS;
}
-static void setup_shared_mem(apr_pool_t *p)
+/* ToDo: This function should be made to handle setting up
+ * a scoreboard shared between processes using any IPC technique,
+ * not just a shared memory segment
+ */
+static void setup_shared(apr_pool_t *p)
{
+#if APR_HAD_SHARED_MEMORY
char buf[512];
char errmsg[120];
const char *fname;
apr_shm_destroy(scoreboard_shm);
exit(APEXIT_INIT);
}
- apr_register_cleanup(p, NULL, ap_cleanup_shared_mem, apr_null_cleanup);
ap_scoreboard_image->global.running_generation = 0;
+#endif
}
-void reopen_scoreboard(apr_pool_t *p)
+AP_DECLARE(void) reopen_scoreboard(apr_pool_t *p)
{
}
-#endif /* APR_SHARED_MEM */
-/* Called by parent process */
-void reinit_scoreboard(apr_pool_t *p)
+/* ap_cleanup_scoreboard
+ *
+ */
+static void ap_cleanup_scoreboard(void *d) {
+ if (ap_scoreboard_image == NULL)
+ return;
+ if (ap_scoreboard_image->global.sb_type == SB_SHARED) {
+ ap_cleanup_shared_mem(NULL);
+ }
+ else {
+ free(ap_scoreboard_image);
+ ap_scoreboard_image = NULL;
+ }
+}
+
+/* ap_create_scoreboard(apr_pool_t*, ap_scoreboard_e t)
+ *
+ * Create or reinit an existing scoreboard. The MPM can control whether
+ * the scoreboard is shared across multiple processes or not
+ */
+AP_DECLARE(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type)
{
int running_gen = 0;
if (ap_scoreboard_image)
running_gen = ap_scoreboard_image->global.running_generation;
if (ap_scoreboard_image == NULL) {
- setup_shared_mem(p);
+ if (sb_type == SB_SHARED) {
+ setup_shared(p);
+ ap_scoreboard_image->global.sb_type = SB_SHARED;
+ }
+ else {
+ /* A simple malloc will suffice */
+ char buf[512];
+ ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE);
+ if (ap_scoreboard_image == NULL) {
+ apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard",
+ ap_server_argv0);
+ perror(buf); /* o.k. since MM sets errno */
+ exit(APEXIT_INIT);
+ }
+ ap_scoreboard_image->global.sb_type = SB_NOT_SHARED;
+ }
}
memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE);
ap_scoreboard_image->global.running_generation = running_gen;
+ apr_register_cleanup(p, NULL, ap_cleanup_scoreboard, apr_null_cleanup);
+}
+
+/* ToDo:
+ * reinit_scoreboard should be eliminated when all MPMs migrate to
+ * ap_create_scoreboard()
+ */
+void reinit_scoreboard(apr_pool_t *p)
+{
+ ap_create_scoreboard(p, SB_SHARED);
}
/* Routines called to deal with the scoreboard image
* anyway.
*/
-apr_inline void ap_sync_scoreboard_image(void)
+void ap_sync_scoreboard_image(void)
{
}