]> granicus.if.org Git - apache/commitdiff
Port the scoreboard from the mpmt_pthread MPM to use APR's shared memory.
authorRyan Bloom <rbb@apache.org>
Mon, 14 Feb 2000 22:20:34 +0000 (22:20 +0000)
committerRyan Bloom <rbb@apache.org>
Mon, 14 Feb 2000 22:20:34 +0000 (22:20 +0000)
Tested on Linux, but it could use testing on other platforms.

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

server/mpm/mpmt_pthread/mpmt_pthread.c
server/mpm/mpmt_pthread/scoreboard.c

index 6b29134d4086a7d872e6583dc85bdae66e665ba6..e7a0ea21b315fc57b00a7292c5d5452e20a90c88 100644 (file)
@@ -84,7 +84,7 @@
 int ap_threads_per_child=0;         /* Worker threads per child */
 int ap_max_requests_per_child=0;
 static char *ap_pid_fname=NULL;
-static char *ap_scoreboard_fname=NULL;
+API_VAR_EXPORT char *ap_scoreboard_fname=NULL;
 static int ap_daemons_to_start=0;
 static int min_spare_threads=0;
 static int max_spare_threads=0;
index bfa31a8fb739b934b6f32a22b5b32f2b7de4c486..baaa34bac5d93c0bfb3dcf4b2a2a34dd6639cc01 100644 (file)
 #include "mpmt_pthread.h"
 #include "scoreboard.h"
 #include <sys/types.h>
-#ifdef USE_SHMGET_SCOREBOARD
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-
-#ifdef USE_OS2_SCOREBOARD
-    /* Add MMAP style functionality to OS/2 */
-#define INCL_DOSMEMMGR
-#define INCL_DOSEXCEPTIONS
-#define INCL_DOSSEMAPHORES
-#include <os2.h>
-#include <umalloc.h>
-#include <stdio.h>
-caddr_t create_shared_heap(const char *, size_t);
-caddr_t get_shared_heap(const char *);
-#endif
 
 scoreboard *ap_scoreboard_image = NULL;
-
+API_VAR_IMPORT char *ap_scoreboard_fname;
 /*****************************************************************
  *
  * Dealing with the scoreboard... a lot of these variables are global
@@ -70,405 +54,46 @@ API_EXPORT(void) ap_sync_scoreboard_image(void)
 
 
 #else /* MULTITHREAD */
-#if defined(USE_OS2_SCOREBOARD)
-
-/* The next two routines are used to access shared memory under OS/2.  */
-/* This requires EMX v09c to be installed.                           */
-
-caddr_t create_shared_heap(const char *name, size_t size)
-{
-    ULONG rc;
-    void *mem;
-    Heap_t h;
-
-    rc = DosAllocSharedMem(&mem, name, size,
-                          PAG_COMMIT | PAG_READ | PAG_WRITE);
-    if (rc != 0)
-       return NULL;
-    h = _ucreate(mem, size, !_BLOCK_CLEAN, _HEAP_REGULAR | _HEAP_SHARED,
-                NULL, NULL);
-    if (h == NULL)
-       DosFreeMem(mem);
-    return (caddr_t) h;
-}
-
-caddr_t get_shared_heap(const char *Name)
-{
-
-    PVOID BaseAddress;         /* Pointer to the base address of
-                                  the shared memory object */
-    ULONG AttributeFlags;      /* Flags describing characteristics
-                                  of the shared memory object */
-    APIRET rc;                 /* Return code */
-
-    /* Request read and write access to */
-    /*   the shared memory object       */
-    AttributeFlags = PAG_WRITE | PAG_READ;
-
-    rc = DosGetNamedSharedMem(&BaseAddress, Name, AttributeFlags);
-
-    if (rc != 0) {
-       printf("DosGetNamedSharedMem error: return code = %ld", rc);
-       return 0;
-    }
-
-    return BaseAddress;
-}
-
-static void setup_shared_mem(ap_context_t *p)
-{
-    caddr_t m;
-
-    int rc;
-
-    m = (caddr_t) create_shared_heap("\\SHAREMEM\\SCOREBOARD", SCOREBOARD_SIZE);
-    if (m == 0) {
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                     "%s: Could not create OS/2 Shared memory pool.",
-                    ap_server_argv0);
-       exit(APEXIT_INIT);
-    }
+#if APR_HAS_SHARED_MEMORY
+#include "apr_shmem.h"
 
-    rc = _uopen((Heap_t) m);
-    if (rc != 0) {
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-               "%s: Could not uopen() newly created OS/2 Shared memory pool.",
-               ap_server_argv0);
-    }
-    ap_scoreboard_image = (scoreboard *) m;
-    ap_scoreboard_image->global.running_generation = 0;
-}
+static ap_shmem_t *scoreboard_shm = NULL;
 
-API_EXPORT(void) reopen_scoreboard(ap_context_t *p)
+ap_status_t cleanup_shared_mem(void *d)
 {
-    caddr_t m;
-    int rc;
-
-    m = (caddr_t) get_shared_heap("\\SHAREMEM\\SCOREBOARD");
-    if (m == 0) {
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                     "%s: Could not find existing OS/2 Shared memory pool.",
-                    ap_server_argv0);
-       exit(APEXIT_INIT);
-    }
-
-    rc = _uopen((Heap_t) m);
-    ap_scoreboard_image = (scoreboard *) m;
-}
-
-#elif defined(USE_POSIX_SCOREBOARD)
-#include <sys/mman.h>
-/* 
- * POSIX 1003.4 style
- *
- * Note 1: 
- * As of version 4.23A, shared memory in QNX must reside under /dev/shmem,
- * where no subdirectories allowed.
- *
- * POSIX shm_open() and shm_unlink() will take care about this issue,
- * but to avoid confusion, I suggest to redefine scoreboard file name
- * in httpd.conf to cut "logs/" from it. With default setup actual name
- * will be "/dev/shmem/logs.apache_status". 
- * 
- * If something went wrong and Apache did not unlinked this object upon
- * exit, you can remove it manually, using "rm -f" command.
- * 
- * Note 2:
- * <sys/mman.h> in QNX defines MAP_ANON, but current implementation 
- * does NOT support BSD style anonymous mapping. So, the order of 
- * conditional compilation is important: 
- * this #ifdef section must be ABOVE the next one (BSD style).
- *
- * I tested this stuff and it works fine for me, but if it provides 
- * trouble for you, just comment out USE_MMAP_SCOREBOARD in QNX section
- * of ap_config.h
- *
- * June 5, 1997, 
- * Igor N. Kovalenko -- infoh@mail.wplus.net
- */
-
-static void cleanup_shared_mem(void *d)
-{
-    shm_unlink(ap_scoreboard_fname);
+    mm_free(scoreboard_shm, ap_scoreboard_image);
+    ap_scoreboard_image = NULL;
+    ap_shm_destroy(scoreboard_shm);
 }
 
-static void setup_shared_mem(ap_context_t *p)
+void setup_shared_mem(ap_context_t *p)
 {
     char buf[512];
-    caddr_t m;
-    int fd;
-
-    fd = shm_open(ap_scoreboard_fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
-    if (fd == -1) {
-       ap_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard",
-                   ap_server_argv0);
-       perror(buf);
-       exit(APEXIT_INIT);
+    const char *fname;
+
+    fname = ap_server_root_relative(p, ap_scoreboard_fname);
+    if (ap_shm_init(&scoreboard_shm, SCOREBOARD_SIZE + 40, fname) != APR_SUCCESS) {
+        ap_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard",
+                    ap_server_argv0);
+        perror(buf);
+        exit(APEXIT_INIT);
     }
-    if (ltrunc(fd, (off_t) SCOREBOARD_SIZE, SEEK_SET) == -1) {
-       ap_snprintf(buf, sizeof(buf), "%s: could not ltrunc scoreboard",
-                   ap_server_argv0);
-       perror(buf);
-       shm_unlink(ap_scoreboard_fname);
-       exit(APEXIT_INIT);
-    }
-    if ((m = (caddr_t) mmap((caddr_t) 0,
-                           (size_t) SCOREBOARD_SIZE, PROT_READ | PROT_WRITE,
-                           MAP_SHARED, fd, (off_t) 0)) == (caddr_t) - 1) {
-       ap_snprintf(buf, sizeof(buf), "%s: cannot mmap scoreboard",
-                   ap_server_argv0);
-       perror(buf);
-       shm_unlink(ap_scoreboard_fname);
-       exit(APEXIT_INIT);
+    ap_scoreboard_image = ap_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE);
+    if (ap_scoreboard_image == NULL) {
+        ap_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard",
+                    ap_server_argv0);
+        perror(buf);
+        ap_shm_destroy(scoreboard_shm);
+        exit(APEXIT_INIT);
     }
-    close(fd);
     ap_register_cleanup(p, NULL, cleanup_shared_mem, ap_null_cleanup);
-    ap_scoreboard_image = (scoreboard *) m;
-    ap_scoreboard_image->global.running_generation = 0;
-}
-
-API_EXPORT(void) reopen_scoreboard(ap_context_t *p)
-{
-}
-
-#elif defined(USE_MMAP_SCOREBOARD)
-
-static void setup_shared_mem(ap_context_t *p)
-{
-    caddr_t m;
-
-#if defined(MAP_ANON)
-/* BSD style */
-#ifdef CONVEXOS11
-    /*
-     * 9-Aug-97 - Jeff Venters (venters@convex.hp.com)
-     * ConvexOS maps address space as follows:
-     *   0x00000000 - 0x7fffffff : Kernel
-     *   0x80000000 - 0xffffffff : User
-     * Start mmapped area 1GB above start of text.
-     *
-     * Also, the length requires a pointer as the actual length is
-     * returned (rounded up to a page boundary).
-     */
-    {
-       unsigned len = SCOREBOARD_SIZE;
-
-       m = mmap((caddr_t) 0xC0000000, &len,
-                PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, NOFD, 0);
-    }
-#elif defined(MAP_TMPFILE)
-    {
-       char mfile[] = "/tmp/apache_shmem_XXXX";
-       int fd = mkstemp(mfile);
-       if (fd == -1) {
-           perror("open");
-           ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                         "%s: Could not open %s", ap_server_argv0, mfile);
-           exit(APEXIT_INIT);
-       }
-       m = mmap((caddr_t) 0, SCOREBOARD_SIZE,
-               PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-       if (m == (caddr_t) - 1) {
-           perror("mmap");
-           ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                         "%s: Could not mmap %s", ap_server_argv0, mfile);
-           exit(APEXIT_INIT);
-       }
-       close(fd);
-       unlink(mfile);
-    }
-#else
-    m = mmap((caddr_t) 0, SCOREBOARD_SIZE,
-            PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
-#endif
-    if (m == (caddr_t) - 1) {
-       perror("mmap");
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                     "%s: Could not mmap memory", ap_server_argv0);
-       exit(APEXIT_INIT);
-    }
-#else
-/* Sun style */
-    int fd;
-
-    fd = open("/dev/zero", O_RDWR);
-    if (fd == -1) {
-       perror("open");
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                     "%s: Could not open /dev/zero", ap_server_argv0);
-       exit(APEXIT_INIT);
-    }
-    m = mmap((caddr_t) 0, SCOREBOARD_SIZE,
-            PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-    if (m == (caddr_t) - 1) {
-       perror("mmap");
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                     "%s: Could not mmap /dev/zero", ap_server_argv0);
-       exit(APEXIT_INIT);
-    }
-    close(fd);
-#endif
-    ap_scoreboard_image = (scoreboard *) m;
-    ap_scoreboard_image->global.running_generation = 0;
-}
-
-API_EXPORT(void) reopen_scoreboard(ap_context_t *p)
-{
-}
-
-#elif defined(USE_SHMGET_SCOREBOARD)
-static key_t shmkey = IPC_PRIVATE;
-static int shmid = -1;
-
-static void setup_shared_mem(ap_context_t *p)
-{
-    struct shmid_ds shmbuf;
-    const server_rec * server_conf = ap_get_server_conf();
-#ifdef MOVEBREAK
-    char *obrk;
-#endif
-
-    if ((shmid = shmget(shmkey, SCOREBOARD_SIZE, IPC_CREAT | SHM_R | SHM_W)) == -1) {
-#ifdef LINUX
-       if (errno == ENOSYS) {
-           ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, 0, server_conf,
-                        "Your kernel was built without CONFIG_SYSVIPC\n"
-                        "%s: Please consult the Apache FAQ for details",
-                        ap_server_argv0);
-       }
-#endif
-       ap_log_error(APLOG_MARK, APLOG_EMERG, errno, server_conf,
-                   "could not call shmget");
-       exit(APEXIT_INIT);
-    }
-
-    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, server_conf,
-               "created shared memory segment #%d", shmid);
-
-#ifdef MOVEBREAK
-    /*
-     * Some SysV systems place the shared segment WAY too close
-     * to the dynamic memory break point (sbrk(0)). This severely
-     * limits the use of malloc/sbrk in the program since sbrk will
-     * refuse to move past that point.
-     *
-     * To get around this, we move the break point "way up there",
-     * attach the segment and then move break back down. Ugly
-     */
-    if ((obrk = sbrk(MOVEBREAK)) == (char *) -1) {
-       ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
-           "sbrk() could not move break");
-    }
-#endif
-
-#define BADSHMAT       ((scoreboard *)(-1))
-    if ((ap_scoreboard_image = (scoreboard *) shmat(shmid, 0, 0)) == BADSHMAT) {
-       ap_log_error(APLOG_MARK, APLOG_EMERG, errno, server_conf, "shmat error");
-       /*
-        * We exit below, after we try to remove the segment
-        */
-    }
-    else {                     /* only worry about permissions if we attached the segment */
-       if (shmctl(shmid, IPC_STAT, &shmbuf) != 0) {
-           ap_log_error(APLOG_MARK, APLOG_ERR, errno, server_conf,
-               "shmctl() could not stat segment #%d", shmid);
-       }
-       else {
-           shmbuf.shm_perm.uid = unixd_config.user_id;
-           shmbuf.shm_perm.gid = unixd_config.group_id;
-           if (shmctl(shmid, IPC_SET, &shmbuf) != 0) {
-               ap_log_error(APLOG_MARK, APLOG_ERR, errno, server_conf,
-                   "shmctl() could not set segment #%d", shmid);
-           }
-       }
-    }
-    /*
-     * We must avoid leaving segments in the kernel's
-     * (small) tables.
-     */
-    if (shmctl(shmid, IPC_RMID, NULL) != 0) {
-       ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf,
-               "shmctl: IPC_RMID: could not remove shared memory segment #%d",
-               shmid);
-    }
-    if (ap_scoreboard_image == BADSHMAT)       /* now bailout */
-       exit(APEXIT_INIT);
-
-#ifdef MOVEBREAK
-    if (obrk == (char *) -1)
-       return;                 /* nothing else to do */
-    if (sbrk(-(MOVEBREAK)) == (char *) -1) {
-       ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
-           "sbrk() could not move break back");
-    }
-#endif
     ap_scoreboard_image->global.running_generation = 0;
 }
 
-API_EXPORT(void) reopen_scoreboard(ap_context_t *p)
+void reopen_scoreboard(ap_context_t *p)
 {
 }
-
-#else
-#define SCOREBOARD_FILE
-static scoreboard _scoreboard_image;
-static ap_file_t *scoreboard_file = NULL;
-
-/* XXX: things are seriously screwed if we ever have to do a partial
- * read or write ... we could get a corrupted scoreboard
- */
-static int force_write(int fd, void *buffer, int bufsz)
-{
-    int rv, orig_sz = bufsz;
-
-    do {
-       rv = write(fd, buffer, bufsz);
-       if (rv > 0) {
-           buffer = (char *) buffer + rv;
-           bufsz -= rv;
-       }
-    } while ((rv > 0 && bufsz > 0) || (rv == -1 && errno == EINTR));
-
-    return rv < 0 ? rv : orig_sz - bufsz;
-}
-
-static int force_read(int fd, void *buffer, int bufsz)
-{
-    int rv, orig_sz = bufsz;
-
-    do {
-       rv = read(fd, buffer, bufsz);
-       if (rv > 0) {
-           buffer = (char *) buffer + rv;
-           bufsz -= rv;
-       }
-    } while ((rv > 0 && bufsz > 0) || (rv == -1 && errno == EINTR));
-
-    return rv < 0 ? rv : orig_sz - bufsz;
-}
-
-static void cleanup_scoreboard_file(void *foo)
-{
-    unlink(ap_scoreboard_fname);
-}
-
-API_EXPORT(void) reopen_scoreboard(ap_context_t *p)
-{
-    if (scoreboard_fd != -1)
-       ap_close(scoreboard_file);
-
-    ap_open(p, ap_scoreboard_fname, APR_CREATE | APR_BINARY | APR_READ | APR_WRITE,
-            APR_UREAD | APR_UWRITE | APR_GREAD | APR_GWRITE | APR_WREAD | APR_WWRITE,
-            &scoreboard_file);
-    ap_get_os_file(&scoreboard_fd, scoreboard_file);
-    if (scoreboard_fd == -1) {
-       perror(ap_scoreboard_fname);
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                     "Cannot open scoreboard file:");
-       clean_child_exit(1);
-    }
-}
-#endif
+#endif   /* APR_SHARED_MEM */
 
 /* Called by parent process */
 void reinit_scoreboard(ap_context_t *p)
@@ -476,32 +101,11 @@ void reinit_scoreboard(ap_context_t *p)
     int running_gen = 0;
     if (ap_scoreboard_image)
        running_gen = ap_scoreboard_image->global.running_generation;
-
-#ifndef SCOREBOARD_FILE
     if (ap_scoreboard_image == NULL) {
-       setup_shared_mem(p);
+        setup_shared_mem(p);
     }
     memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE);
     ap_scoreboard_image->global.running_generation = running_gen;
-#else
-    ap_scoreboard_image = &_scoreboard_image;
-    ap_scoreboard_fname = ap_server_root_relative(p, ap_scoreboard_fname);
-
-    ap_open(p, ap_scoreboard_fname, APR_CREATE | APR_BINARY | APR_READ | APR_WRITE,
-            APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD, &scoreboard_file);
-    ap_get_os_file(&scoreboard_fd, scoreboard_file);
-    if (scoreboard_fd == -1) {
-       perror(ap_scoreboard_fname);
-       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
-                     "Cannot open scoreboard file:");
-       exit(APEXIT_INIT);
-    }
-    ap_register_cleanup(p, NULL, cleanup_scoreboard_file, ap_null_cleanup);
-
-    memset((char *) ap_scoreboard_image, 0, sizeof(*ap_scoreboard_image));
-    ap_scoreboard_image->global.running_generation = running_gen;
-    force_write(scoreboard_fd, ap_scoreboard_image, sizeof(*ap_scoreboard_image));
-#endif
 }
 
 /* Routines called to deal with the scoreboard image
@@ -517,10 +121,6 @@ void reinit_scoreboard(ap_context_t *p)
 
 ap_inline void ap_sync_scoreboard_image(void)
 {
-#ifdef SCOREBOARD_FILE
-    lseek(scoreboard_fd, 0L, 0);
-    force_read(scoreboard_fd, ap_scoreboard_image, sizeof(*ap_scoreboard_image));
-#endif
 }
 
 #endif /* MULTITHREAD */