rbb 00/01/27 15:49:40
Modified: src/lib/apr configure.in src/lib/apr/include apr.h.in apr_errno.h apr_shmem.h src/lib/apr/shmem/unix Makefile.in shmem.c src/lib/apr/test Makefile.in Added: src/lib/apr/test testshmem.c Removed: src/lib/apr/shmem shmem.c Log: A first pass at shared memory for Unix. This is still pretty ugly, but I will clean it up over the next few days. At least this gives everybody some idea of where I want the shared memory stuff to go in APR. Revision Changes Path 1.49 +15 -1 apache-2.0/src/lib/apr/configure.in Index: configure.in =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/configure.in,v retrieving revision 1.48 retrieving revision 1.49 diff -u -r1.48 -r1.49 --- configure.in 2000/01/26 18:06:30 1.48 +++ configure.in 2000/01/27 23:49:23 1.49 @@ -5,7 +5,7 @@ # These added to allow default directories to be used... DEFAULT_OSDIR="unix" -MODULES="file_io network_io threadproc misc locks time mmap" +MODULES="file_io network_io threadproc misc locks time mmap shmem" echo "Configuring APR library" echo "Platform: ${OS}" @@ -357,6 +357,15 @@ procpthreadser="0" fi +# Shared memory support. Until I figure out how to do this well, we are hard +# coding this. I am hoping to do this more generally ASAP. +anonymous_shm="1" +filebased_shm="0" +keybased_shm="0" +AC_SUBST(anonymous_shm) +AC_SUBST(filebased_shm) +AC_SUBST(keybased_shm) + dnl Start building stuff from our information AC_SUBST(LDLIBS) AC_SUBST(OPTIM) @@ -399,6 +408,11 @@ if test "$ac_cv_struct_tm_gmtoff" = "yes"; then AC_DEFINE(HAVE_GMTOFF) fi + +# run the MM config script regardless of whether we are going to use +# it or not. When we have a much better idea of who is using MM, we can +# run this on a more conditional basis. +AC_CONFIG_SUBDIRS(shmem/unix/mm) MAKEFILE1="Makefile lib/Makefile " SUBDIRS="lib " 1.12 +5 -0 apache-2.0/src/lib/apr/include/apr.h.in Index: apr.h.in =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr.h.in,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- apr.h.in 2000/01/26 18:06:31 1.11 +++ apr.h.in 2000/01/27 23:49:26 1.12 @@ -40,6 +40,11 @@ #define APR_USE_PROC_PTHREAD_SERIALIZE @procpthreadser@ #define APR_USE_PTHREAD_SERIALIZE @pthreadser@ +#define APR_USES_ANONYMOUS_SHM @anonymous_shm@ +#define APR_USES_FILEBASED_SHM @filebased_shm@ +#define APR_USES_KEYBASED_SHM @keybased_shm@ + + #define APR_HAVE_IN_ADDR @have_in_addr@ #define APR_HAVE_INET_ADDR @inet_addr@ #define APR_HAVE_INET_NETWORK @inet_network@ 1.13 +4 -0 apache-2.0/src/lib/apr/include/apr_errno.h Index: apr_errno.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_errno.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- apr_errno.h 1999/12/20 16:10:11 1.12 +++ apr_errno.h 2000/01/27 23:49:27 1.13 @@ -107,6 +107,7 @@ #define APR_ENOTHREAD (APR_OS_START_ERROR + 12) #define APR_ENOTHDKEY (APR_OS_START_ERROR + 13) #define APR_ENOTTHREADSAFE (APR_OS_START_ERROR + 14) +#define APR_ESHMLOCK (APR_OS_START_ERROR + 15) /* APR STATUS VALUES */ #define APR_INCHILD (APR_OS_START_STATUS + 1) @@ -127,6 +128,9 @@ #define APR_LESS (APR_OS_START_STATUS + 16) #define APR_EQUAL (APR_OS_START_STATUS + 17) #define APR_MORE (APR_OS_START_STATUS + 18) +#define APR_ANONYMOUS (APR_OS_START_STATUS + 19) +#define APR_FILEBASED (APR_OS_START_STATUS + 20) +#define APR_KEYBASED (APR_OS_START_STATUS + 21) /* A simple value to be used to initialze a status variable. */ #define APR_EINIT (APR_OS_START_STATUS + 16) 1.3 +19 -12 apache-2.0/src/lib/apr/include/apr_shmem.h Index: apr_shmem.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_shmem.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- apr_shmem.h 1999/10/04 16:36:55 1.2 +++ apr_shmem.h 2000/01/27 23:49:27 1.3 @@ -56,6 +56,7 @@ #ifndef APR_SHMEM_H #define APR_SHMEM_H +#include "apr.h" #include "apr_general.h" #include "apr_errno.h" @@ -63,19 +64,25 @@ extern "C" { #endif /* __cplusplus */ -typedef struct shmem_t ap_shmem_t +#if APR_USES_ANONYMOUS_SHM +typedef void ap_shm_name_t; +#elif APR_USES_FILEBASED_SHM +typedef char * ap_shm_name_t; +#elif APR_USES_KEYBASED_SHM +typedef key_t ap_shm_name_t; +#endif -ap_status_t ap_shm_create(ap_shmem_t **, ap_context_t *, ap_size_t, const char *); -ap_status_t ap_shm_destroy(ap_shmem_t *); -ap_status_t ap_shm_malloc(void **, ap_shmem_t *, ap_size_t); -ap_status_t ap_shm_calloc(void **, ap_shmem_t *, ap_size_t, ap_size_t); -ap_status_t ap_shm_realloc(void **, ap_shmem_t *, ap_size_t); -ap_status_t ap_shm_free(ap_shmem_t *, void *); -ap_status_t ap_shm_strdup(char **, ap_shmem_t *, const char *); -ap_status_t ap_shm_sizeof(ap_shmem_t *, void *, ap_size_t *); -ap_status_t ap_shm_maxsize(ap_size_t *); -ap_status_t ap_shm_available(ap_shmem_t *, ap_size_t *); -ap_status_t ap_shm_child_create(ap_shmem_t**, ap_context_t *, const char *); +typedef struct shmem_t ap_shmem_t; + +ap_status_t ap_shm_init(ap_shmem_t **m, ap_size_t reqsize, const char *file); +ap_status_t ap_shm_destroy(ap_shmem_t *m); +void *ap_shm_malloc(ap_shmem_t *c, ap_size_t reqsize); +void *ap_shm_calloc(ap_shmem_t *shared, ap_size_t size); +ap_status_t ap_shm_free(ap_shmem_t *shared, void *free); +ap_status_t ap_get_shm_name(ap_shmem_t *c, ap_shm_name_t **name); +ap_status_t ap_set_shm_name(ap_shmem_t *c, ap_shm_name_t *name); +ap_status_t ap_open_shmem(ap_shmem_t *c); +ap_status_t ap_shm_avail(ap_shmem_t *c, ap_size_t *avail); #ifdef __cplusplus } 1.3 +4 -1 apache-2.0/src/lib/apr/shmem/unix/Makefile.in Index: Makefile.in =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/shmem/unix/Makefile.in,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Makefile.in 1999/08/27 16:26:06 1.2 +++ Makefile.in 2000/01/27 23:49:31 1.3 @@ -11,7 +11,8 @@ [EMAIL PROTECTED]@ $(LIBS) INCDIR=../../inc INCDIR1=../../include -INCLUDES=-I$(INCDIR) -I$(INCDIR1) -Imm -I. +INCDIR2=../../misc/@OSDIR@ +INCLUDES=-I$(INCDIR) -I$(INCDIR1) -I$(INCDIR2) -Imm -I. LIB=libshmem.a @@ -32,6 +33,8 @@ $(LIB): $(OBJS) $(RM) -f $@ + cd mm; make; cd .. + cp mm/*.o . $(AR) cr $@ $(OBJS) $(RANLIB) $@ 1.4 +139 -81 apache-2.0/src/lib/apr/shmem/unix/shmem.c Index: shmem.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/shmem/unix/shmem.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- shmem.c 1999/10/04 16:37:20 1.3 +++ shmem.c 2000/01/27 23:49:31 1.4 @@ -55,116 +55,174 @@ #include "mm.h" #include "apr_general.h" +#include "apr_shmem.h" #include "apr_errno.h" struct shmem_t { MM *mm; - ap_context_t *cntxt; }; -ap_status_t ap_shm_create(ap_context_t *cont, ap_size_t size, const char *file, - struct shmem_t **new) +/* ***APRDOC******************************************************** + * ap_status_t ap_shm_init(ap_shmem_t *, ap_size_t, char *) + * Create a pool of shared memory for use later. + * arg 1) The shared memory block. + * arg 2) The size of the shared memory pool. + * arg 3) The file to use for the shared memory on platforms that + * require it. + */ +ap_status_t ap_shm_init(struct shmem_t **m, ap_size_t reqsize, const char *file) { - MM *mm = mm_create(size, file); - - if (mm == NULL) { - return APR_ENOMEM; - } - (*new) = (struct shmem_t *)mm_malloc(mm, sizeof(struct shmem_t)); - if ((*new) == NULL) { - return APR_ENOMEM; + MM *newmm = mm_create(reqsize, file); + if (newmm == NULL) { + return errno; } - (*new)->mm = mm; - (*new)->cntxt = cont; + (*m) = mm_malloc(newmm, sizeof(struct shmem_t)); + (*m)->mm = newmm; return APR_SUCCESS; } -ap_status_t ap_shm_destroy(struct shmem_t *shared) +/* ***APRDOC******************************************************** + * ap_status_t ap_shm_destroy(ap_shmem_t *) + * Destroy the shared memory block. + * arg 1) The shared memory block to destroy. + */ +ap_status_t ap_shm_destroy(struct shmem_t *m) { - mm_destroy(shared->mm); - shared->mm = NULL; + mm_destroy(m->mm); + m->mm = NULL; return APR_SUCCESS; } -ap_status_t ap_shm_malloc(void **entity, struct shmem_t *shared, ap_size_t size) +/* ***APRDOC******************************************************** + * ap_status_t ap_shm_malloc(ap_shmem_t *, ap_size_t) + * allocate memory from the block of shared memory. + * arg 1) The shared memory block to destroy. + * arg 2) How much memory to allocate + */ +void *ap_shm_malloc(struct shmem_t *c, ap_size_t reqsize) { - entity = mm_malloc(shared->mm, size); - if (entity == NULL) { - return APR_ENOMEM; + if (c->mm == NULL) { + return NULL; } - return APR_SUCCESS; + return mm_malloc(c->mm, reqsize); } -ap_status_t ap_shm_calloc(struct shmem_t *shared, ap_size_t num, - ap_size_t size, void **entity) +/* ***APRDOC******************************************************** + * ap_status_t ap_shm_calloc(ap_shmem_t *, ap_size_t) + * allocate memory from the block of shared memory and initialize it + * to zero. + * arg 1) The shared memory block to destroy. + * arg 2) How much memory to allocate + */ +void *ap_shm_calloc(struct shmem_t *shared, ap_size_t size) { - entity = mm_calloc(shared->mm, num, size); - if (entity == NULL) { - return APR_ENOMEM; + if (shared == NULL) { + return NULL; } - return APR_SUCCESS; + return mm_calloc(shared->mm, 1, size); } -ap_status_t ap_shm_realloc(void **entity, struct shmem_t *shared, ap_size_t size) -{ - void *new; - - new = mm_realloc(shared->mm, *entity, size); - if (new == NULL) { - return APR_ENOMEM; - } - - (*entity) = new; - return APR_SUCCESS; -} - +/* ***APRDOC******************************************************** + * ap_status_t ap_shm_free(ap_shmem_t *, void *) + * free shared memory previously allocated. + * arg 1) The shared memory block to destroy. + */ ap_status_t ap_shm_free(struct shmem_t *shared, void *entity) { mm_free(shared->mm, entity); return APR_SUCCESS; } - -ap_status_t ap_shm_strdup(char **new, struct shmem_t *shared, const char *old) -{ - (*new) = mm_strdup(shared->mm, old); - if ((*new) == NULL) { - return APR_ENOMEM; - } - return APR_SUCCESS; -} -ap_status_t ap_shm_sizeof(struct shmem_t *shared, const void *ent, - ap_size_t *size) -{ - *size = mm_sizeof(shared->mm, ent); - if ((*size) == -1) { - return APR_EINVAL; +/* ***APRDOC******************************************************** + * ap_status_t ap_get_shm_name(ap_shmem_t *, ap_shm_name_t **) + * Get the name of the shared memory segment if not using + * anonymous shared memory. + * arg 1) The shared memory block to destroy. + * arg 2) The name of the shared memory block, NULL if anonymous + * shared memory. + * return) APR_USES_ANONYMOUS_SHM if we are using anonymous shared + * memory. APR_USES_FILEBASED_SHM if our shared memory is + * based on file access. APR_USES_KEYBASED_SHM if shared + * memory is based on a key value such as shmctl. If the + * shared memory is anonymous, the name is NULL. + */ +ap_status_t ap_get_shm_name(ap_shmem_t *c, ap_shm_name_t **name) +{ +#if APR_USES_ANONYMOUS_SHM + name = NULL; + return APR_ANONYMOUS; +/* Currently, we are not supporting name based shared memory on Unix + * systems. This may change in the future however, so I will leave + * this in here for now. Plus, this gives other platforms a good idea + * of how to proceed. + */ +#elif APR_USES_FILEBASED_SHM +#elif APR_USES_KEYBASED_SHM +#endif +} + +/* ***APRDOC******************************************************** + * ap_status_t ap_set_shm_name(ap_shmem_t *, ap_shm_name_t *) + * Set the name of the shared memory segment if not using + * anonymous shared memory. This is to allow processes to open + * shared memory created by another process. + * arg 1) The shared memory block to destroy. + * arg 2) The name of the shared memory block, NULL if anonymous + * shared memory. + * return) APR_USES_ANONYMOUS_SHM if we are using anonymous shared + * memory. APR_SUCCESS if we are using named shared memory + * and we were able to assign the name correctly. + */ +ap_status_t ap_set_shm_name(ap_shmem_t *c, ap_shm_name_t *name) +{ +#if APR_USES_ANONYMOUS_SHM + return APR_ANONYMOUS; +/* Currently, we are not supporting name based shared memory on Unix + * systems. This may change in the future however, so I will leave + * this in here for now. Plus, this gives other platforms a good idea + * of how to proceed. + */ +#elif APR_USES_FILEBASED_SHM +#elif APR_USES_KEYBASED_SHM +#endif +} + +/* ***APRDOC******************************************************** + * ap_status_t ap_open_shmem(ap_shmem_t *) + * Open the shared memory block in a child process. + * arg 1) The shared memory block to open in the child. + * return) This should be called after ap_set_shm_name. The ap_shmem_t + * variable must refer to the memory segment to open. + */ +ap_status_t ap_open_shmem(struct shmem_t *c) +{ +#if APR_USES_ANONYMOUS_SHM +/* When using MM, we don't need to open shared memory segments in child + * segments, so just return immediately. + */ + return APR_SUCCESS; +/* Currently, we are not supporting name based shared memory on Unix + * systems. This may change in the future however, so I will leave + * this in here for now. Plus, this gives other platforms a good idea + * of how to proceed. + */ +#elif APR_USES_FILEBASED_SHM +#elif APR_USES_KEYBASED_SHM +#endif +} + +/* ***APRDOC******************************************************** + * ap_status_t ap_shm_avail(ap_shmem_t *, ap_size_t *) + * Determine how much memory is available in the specified shared + * memory block + * arg 1) The shared memory block to open in the child. + * arg 2) The amount of space available in the shared memory block. + */ +ap_status_t ap_shm_avail(struct shmem_t *c, ap_size_t *size) +{ + *size = mm_available(c); + if (*size == 0) { + return APR_ESHMLOCK; } return APR_SUCCESS; } - -ap_status_t ap_shm_maxsize(ap_size_t *size) -{ - (*size) = mm_maxsize(); - if ((*size) <= 0) { - return APR_ENOMEM; - } - return APR_SUCCESS; -} - -ap_status_t ap_shm_available(struct shmem_t *shared, ap_size_t *size) -{ - (*size) = mm_available(shared->mm); - if ((*size) <= 0) { - return APR_ENOMEM; - } - return APR_SUCCESS; -} - -ap_status_t ap_shm_child_create(ap_context_t *cont, const char *fname, - struct shmem_t **shared) -{ - return APR_SUCCESS; -} - - 1.11 +5 -1 apache-2.0/src/lib/apr/test/Makefile.in Index: Makefile.in =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/test/Makefile.in,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- Makefile.in 1999/12/19 18:10:04 1.10 +++ Makefile.in 2000/01/27 23:49:34 1.11 @@ -22,7 +22,8 @@ [EMAIL PROTECTED]@ \ [EMAIL PROTECTED]@ \ [EMAIL PROTECTED]@ \ - [EMAIL PROTECTED]@ + [EMAIL PROTECTED]@ \ + [EMAIL PROTECTED]@ OBJS= testfile.o \ testproc.o \ @@ -71,6 +72,9 @@ [EMAIL PROTECTED]@: testmmap.o $(CC) $(CFLAGS) testmmap.o -o [EMAIL PROTECTED]@ $(LDFLAGS) + [EMAIL PROTECTED]@: testshmem.o + $(CC) $(CFLAGS) testshmem.o -o [EMAIL PROTECTED]@ $(LDFLAGS) clean: $(RM) -f *.o *.a *.so $(TARGETS) 1.1 apache-2.0/src/lib/apr/test/testshmem.c Index: testshmem.c =================================================================== /* ==================================================================== * Copyright (c) 1999 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ #include "apr_shmem.h" #include "apr_lock.h" #include "apr_errno.h" #include "apr_general.h" #include "apr_lib.h" #include "errno.h" #include <stdio.h> #ifdef BEOS #include <unistd.h> #endif typedef struct mbox { char msg[1024]; int msgavail; } mbox; ap_context_t *context; mbox *boxes; void msgwait(int boxnum) { volatile int test = 0; while (test == 0) { test = boxes[boxnum].msgavail; } fprintf(stdout, "\nreceived a message in box %d, message was: %s\n", boxnum, boxes[boxnum].msg); } void msgput(int boxnum, char *msg) { fprintf(stdout, "Sending message to box %d\n", boxnum); ap_cpystrn(boxes[boxnum].msg, msg, strlen(msg)); boxes[boxnum].msgavail = 1; } int main() { ap_status_t s4; ap_shmem_t *shm; pid_t pid; ap_status_t s1; int size; ap_initialize(); fprintf(stdout, "Initializing the context......."); if (ap_create_context(&context, NULL) != APR_SUCCESS) { fprintf(stderr, "could not initialize\n"); exit(-1); } fprintf(stdout, "OK\n"); fprintf(stdout, "Creating shared memory block......."); if (ap_shm_init(&shm, 1048576, NULL) != APR_SUCCESS) { fprintf(stderr, "Error allocating shared memory block\n"); exit(-1); } fprintf(stdout, "OK\n"); fprintf(stdout, "Allocating shared memory......."); size = sizeof(mbox) * 2; boxes = ap_shm_calloc(shm, size); if (boxes == NULL) { fprintf(stderr, "Error creating message boxes.\n"); exit(-1); } fprintf(stdout, "OK\n"); fprintf(stdout, "Creating a child process\n"); pid = fork(); if (pid == 0) { sleep(1); msgwait(1); msgput(0, "Msg received\n"); exit(1); } else if (pid > 0) { msgput(1, "Sending a message\n"); sleep(1); msgwait(0); exit(1); } else { fprintf(stderr, "Error creating a child process\n"); exit(1); } }