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);
}
}