]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Add ap_slotmem_attach() to the slotmem_storage_method.
authorJean-Frederic Clere <jfclere@apache.org>
Wed, 26 Jul 2006 13:42:43 +0000 (13:42 +0000)
committerJean-Frederic Clere <jfclere@apache.org>
Wed, 26 Jul 2006 13:42:43 +0000 (13:42 +0000)
Cut mod_sharemem.c in 2 so that its features could be
used outside httpd.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/httpd-proxy-scoreboard@425734 13f79535-47bb-0310-9956-ffa450edef68

modules/mem/config5.m4
modules/mem/mod_plainmem.c
modules/mem/mod_scoreboard.c
modules/mem/mod_sharedmem.c
modules/mem/sharedmem_util.c [new file with mode: 0644]
modules/mem/slotmem.h

index 32eedbf1e564ab685371e69e22a893cd764e4d36..94f11c4137f1ba227ed2b96dde3a59d299317247 100644 (file)
@@ -5,7 +5,8 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
 APACHE_MODPATH_INIT(mem)
 
 APACHE_MODULE(scoreboard, memslot provider that uses scoreboard, , , no)
-APACHE_MODULE(sharedmem, memslot provider that shared memory, , , no)
+sharedmem_objs="mod_sharedmem.lo sharedmem_util.lo"
+APACHE_MODULE(sharedmem, memslot provider that shared memory, $sharedmem_objs, , no)
 APACHE_MODULE(plainmem, memslot provider that plain memory, , , no)
 
 # Ensure that other modules can pick up slotmem.h
index 77110c50a81cd5df38816a7971d3f8159f9321f0..612879b3fa1e55e4ba04eb8113448d6ab8bbb523 100644 (file)
@@ -98,6 +98,36 @@ static apr_status_t ap_slotmem_create(ap_slotmem_t **new, const char *name, apr_
     *new = res;
     return APR_SUCCESS;
 }
+
+static apr_status_t ap_slotmem_attach(ap_slotmem_t **new, const char *name, apr_size_t item_size, int item_num, apr_pool_t *pool)
+{
+    void *slotmem = NULL;
+    ap_slotmem_t *res;
+    ap_slotmem_t *next = globallistmem;
+    char *fname;
+    apr_status_t rv;
+
+    fname = ap_server_root_relative(pool, name);
+
+    /* first try to attach to existing slotmem */
+    if (next) {
+        for (;;) {
+            if (strcmp(next->name, fname) == 0) {
+                /* we already have it */
+                *new = next;
+                *item_size = next->size;
+                *item_num = next->num;
+                return APR_SUCCESS;
+            }
+            if (!next->next)
+                break;
+            next = next->next;
+        }
+    }
+
+    return APR_ENOSHMAVAIL;
+}
+
 static apr_status_t ap_slotmem_mem(ap_slotmem_t *score, int id, void**mem)
 {
 
@@ -118,6 +148,7 @@ static apr_status_t ap_slotmem_mem(ap_slotmem_t *score, int id, void**mem)
 static const slotmem_storage_method storage = {
     &ap_slotmem_do,
     &ap_slotmem_create,
+    &ap_slotmem_attach,
     &ap_slotmem_mem
 };
 
index 231504ee34991f803a8e8fe603335da1d5e4ccab..03038b11e131acfc1ff47aa13d74e40e5a698dbd 100644 (file)
@@ -84,6 +84,12 @@ static apr_status_t ap_slotmem_create(ap_slotmem_t **new, const char *name, apr_
     *new = res;
     return APR_SUCCESS;
 }
+
+static apr_status_t ap_slotmem_attach(ap_slotmem_t **new, const char *name, apr_size_t *item_size, int *item_num, apr_pool_t *pool)
+{
+    return(ap_slotmem_create(new, name, item_size, item_num, pool));
+}
+
 static apr_status_t ap_slotmem_mem(ap_slotmem_t *score, int id, void**mem)
 {
     void *ptr;
index 98b2add9c535b5ec609dda8d53477afc1d760ac4..2b55118f02c2e5846509b0728cc5fc850bcd5020 100644 (file)
 
 #include  "slotmem.h"
 
-struct ap_slotmem {
-    char *name;
-    apr_shm_t *shm;
-    void *base;
-    apr_size_t size;
-    int num;
-    struct ap_slotmem *next;
-};
-
-/* global pool and list of slotmem we are handling */
-static struct ap_slotmem *globallistmem = NULL;
-static apr_pool_t *globalpool = NULL;
-
-apr_status_t cleanup_slotmem(void *param)
-{
-    ap_slotmem_t **mem = param;
-    apr_status_t rv;
-
-    if (*mem) {
-        ap_slotmem_t *next = *mem;
-        while (next) {
-            rv = apr_shm_destroy(next->shm);
-            next = next->next;
-        }
-    }
-    return APR_SUCCESS;
-}
-
-static apr_status_t ap_slotmem_do(ap_slotmem_t *mem, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)
-{
-    int i;
-    void *ptr;
-
-    if (!mem)
-        return APR_ENOSHMAVAIL;
-
-    ptr = mem->base;
-    for (i = 0; i < mem->num; i++) {
-        ptr = ptr + mem->size;
-        func((void *)ptr, data, pool);
-    }
-    return 0;
-}
-static apr_status_t ap_slotmem_create(ap_slotmem_t **new, const char *name, apr_size_t item_size, int item_num, apr_pool_t *pool)
-{
-    void *slotmem = NULL;
-    ap_slotmem_t *res;
-    ap_slotmem_t *next = globallistmem;
-    char *fname;
-    apr_status_t rv;
-
-    fname = ap_server_root_relative(pool, name);
-
-    /* first try to attach to existing slotmem */
-    if (next) {
-        for (;;) {
-            if (strcmp(next->name, fname) == 0) {
-                /* we already have it */
-                *new = next;
-                return APR_SUCCESS;
-            }
-            if (!next->next)
-                break;
-            next = next->next;
-        }
-    }
-
-    /* first try to attach to existing shared memory */
-    res = (ap_slotmem_t *) apr_pcalloc(globalpool, sizeof(ap_slotmem_t));
-    rv = apr_shm_attach(&res->shm, fname, globalpool);
-    if (rv == APR_SUCCESS) {
-        /* check size */
-        if (apr_shm_size_get(res->shm) != item_size * item_num) {
-            apr_shm_detach(res->shm);
-            res->shm = NULL;
-            return APR_EINVAL;
-        }
-    } else  {
-        rv = apr_shm_create(&res->shm, item_size * item_num, fname, globalpool);
-        if (rv != APR_SUCCESS)
-            return rv;
-        memset(apr_shm_baseaddr_get(res->shm), 0, item_size * item_num);
-    }
-
-    /* For the chained slotmem stuff */
-    res->name = apr_pstrdup(globalpool, fname);
-    res->base = apr_shm_baseaddr_get(res->shm);
-    res->size = item_size;
-    res->num = item_num;
-    res->next = NULL;
-    if (globallistmem==NULL)
-        globallistmem = res;
-    else
-        next->next = res;
-
-    *new = res;
-    return APR_SUCCESS;
-}
-static apr_status_t ap_slotmem_mem(ap_slotmem_t *score, int id, void**mem)
-{
-
-    void *ptr;
-
-    if (!score)
-        return APR_ENOSHMAVAIL;
-    if (id<0 || id>score->num)
-        return APR_ENOSHMAVAIL;
-
-    ptr = score->base + score->size * id;
-    if (!ptr)
-        return APR_ENOSHMAVAIL;
-    *mem = ptr;
-    return APR_SUCCESS;
-}
-
-static const slotmem_storage_method storage = {
-    &ap_slotmem_do,
-    &ap_slotmem_create,
-    &ap_slotmem_mem
-};
-
 /* make sure the shared memory is cleaned */
 static int initialize_cleanup(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
 {
-    apr_pool_cleanup_register(p, &globallistmem, cleanup_slotmem, apr_pool_cleanup_null);
+    sharedmem_initialize_cleanup(p);
     return OK;
 }
 
 static int pre_config(apr_pool_t *p, apr_pool_t *plog,
                              apr_pool_t *ptemp)
 {
-    globalpool = p;
+    sharedmem_initglobalpool(p);
     return OK;
 }
 
 static void ap_sharedmem_register_hook(apr_pool_t *p)
 {
-    ap_register_provider(p, SLOTMEM_STORAGE, "shared", "0", &storage);
+    slotmem_storage_method *storage = sharedmem_getstorage();
+    ap_register_provider(p, SLOTMEM_STORAGE, "shared", "0", storage);
     ap_hook_post_config(initialize_cleanup, NULL, NULL, APR_HOOK_LAST);
     ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE);
 }
diff --git a/modules/mem/sharedmem_util.c b/modules/mem/sharedmem_util.c
new file mode 100644 (file)
index 0000000..800115c
--- /dev/null
@@ -0,0 +1,246 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Memory handler for a shared memory divided in slot.
+ * This one uses shared memory.
+ */
+#define CORE_PRIVATE
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_shm.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+
+#include  "slotmem.h"
+
+/* The description of the slots to reuse the slotmem */
+struct sharedslotdesc {
+    apr_size_t item_size;
+    int item_num;
+};
+
+struct ap_slotmem {
+    char *name;
+    apr_shm_t *shm;
+    void *base;
+    apr_size_t size;
+    int num;
+    struct ap_slotmem *next;
+};
+
+/* global pool and list of slotmem we are handling */
+static struct ap_slotmem *globallistmem = NULL;
+static apr_pool_t *globalpool = NULL;
+
+apr_status_t cleanup_slotmem(void *param)
+{
+    ap_slotmem_t **mem = param;
+    apr_status_t rv;
+
+    if (*mem) {
+        ap_slotmem_t *next = *mem;
+        while (next) {
+            rv = apr_shm_destroy(next->shm);
+            next = next->next;
+        }
+    }
+    return APR_SUCCESS;
+}
+
+static apr_status_t ap_slotmem_do(ap_slotmem_t *mem, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)
+{
+    int i;
+    void *ptr;
+
+    if (!mem)
+        return APR_ENOSHMAVAIL;
+
+    ptr = mem->base;
+    for (i = 0; i < mem->num; i++) {
+        ptr = ptr + mem->size;
+        func((void *)ptr, data, pool);
+    }
+    return 0;
+}
+static apr_status_t ap_slotmem_create(ap_slotmem_t **new, const char *name, apr_size_t item_size, int item_num, apr_pool_t *pool)
+{
+    void *slotmem = NULL;
+    void *ptr;
+    struct sharedslotdesc desc;
+    ap_slotmem_t *res;
+    ap_slotmem_t *next = globallistmem;
+    char *fname;
+    apr_status_t rv;
+
+    fname = ap_server_root_relative(pool, name);
+
+    /* first try to attach to existing slotmem */
+    if (next) {
+        for (;;) {
+            if (strcmp(next->name, fname) == 0) {
+                /* we already have it */
+                *new = next;
+                return APR_SUCCESS;
+            }
+            if (!next->next)
+                break;
+            next = next->next;
+        }
+    }
+
+    /* first try to attach to existing shared memory */
+    res = (ap_slotmem_t *) apr_pcalloc(globalpool, sizeof(ap_slotmem_t));
+    rv = apr_shm_attach(&res->shm, fname, globalpool);
+    if (rv == APR_SUCCESS) {
+        /* check size */
+        if (apr_shm_size_get(res->shm) != item_size * item_num + sizeof(struct sharedslotdesc)) {
+            apr_shm_detach(res->shm);
+            res->shm = NULL;
+            return APR_EINVAL;
+        }
+        ptr = apr_shm_baseaddr_get(res->shm);
+        memcpy(&desc, ptr, sizeof(desc));
+        if ( desc.item_size != item_size || desc.item_num != item_num) {
+            apr_shm_detach(res->shm);
+            res->shm = NULL;
+            return APR_EINVAL;
+        }
+        ptr = ptr +  sizeof(desc);
+    } else  {
+        rv = apr_shm_create(&res->shm, item_size * item_num + sizeof(struct sharedslotdesc), fname, globalpool);
+        if (rv != APR_SUCCESS)
+            return rv;
+        ptr = apr_shm_baseaddr_get(res->shm);
+        desc.item_size = item_size;
+        desc.item_num = item_num;
+        memcpy(ptr, &desc, sizeof(desc));
+        ptr = ptr +  sizeof(desc);
+        memset(ptr, 0, item_size * item_num);
+        
+    }
+
+    /* For the chained slotmem stuff */
+    res->name = apr_pstrdup(globalpool, fname);
+    res->base = ptr;
+    res->size = item_size;
+    res->num = item_num;
+    res->next = NULL;
+    if (globallistmem==NULL)
+        globallistmem = res;
+    else
+        next->next = res;
+
+    *new = res;
+    return APR_SUCCESS;
+}
+static apr_status_t ap_slotmem_attach(ap_slotmem_t **new, const char *name, apr_size_t *item_size, int *item_num, apr_pool_t *pool)
+{
+    void *slotmem = NULL;
+    void *ptr;
+    ap_slotmem_t *res;
+    ap_slotmem_t *next = globallistmem;
+    struct sharedslotdesc desc;
+    char *fname;
+    apr_status_t rv;
+
+    fname = ap_server_root_relative(pool, name);
+
+    /* first try to attach to existing slotmem */
+    if (next) {
+        for (;;) {
+            if (strcmp(next->name, fname) == 0) {
+                /* we already have it */
+                *new = next;
+                *item_size = next->size;
+                *item_num = next->num;
+                return APR_SUCCESS;
+            }
+            if (next->next)
+                break;
+            next = next->next;
+        }
+    }
+
+    /* first try to attach to existing shared memory */
+    res = (ap_slotmem_t *) apr_pcalloc(globalpool, sizeof(ap_slotmem_t));
+    rv = apr_shm_attach(&res->shm, fname, globalpool);
+    if (rv != APR_SUCCESS)
+        return rv;
+
+    /* Read the description of the slotmem */
+    ptr = apr_shm_baseaddr_get(res->shm);
+    memcpy(&desc, ptr, sizeof(desc));
+    ptr = ptr + sizeof(desc);
+
+    /* For the chained slotmem stuff */
+    res->name = apr_pstrdup(globalpool, fname);
+    res->base = ptr;
+    res->size = desc.item_size;
+    res->num = desc.item_num;
+    res->next = NULL;
+    if (globallistmem==NULL)
+        globallistmem = res;
+    else
+        next->next = res;
+
+    *new = res;
+    *item_size = desc.item_size;
+    *item_num = desc.item_num;
+    return APR_SUCCESS;
+}
+static apr_status_t ap_slotmem_mem(ap_slotmem_t *score, int id, void**mem)
+{
+
+    void *ptr;
+
+    if (!score)
+        return APR_ENOSHMAVAIL;
+    if (id<0 || id>score->num)
+        return APR_ENOSHMAVAIL;
+
+    ptr = score->base + score->size * id;
+    if (!ptr)
+        return APR_ENOSHMAVAIL;
+    ptr = score->base + score->size * id;
+    *mem = ptr;
+    return APR_SUCCESS;
+}
+
+static const slotmem_storage_method storage = {
+    &ap_slotmem_do,
+    &ap_slotmem_create,
+    &ap_slotmem_attach,
+    &ap_slotmem_mem
+};
+
+/* make the storage usuable from outside */
+slotmem_storage_method *sharedmem_getstorage()
+{
+    return(&storage);
+}
+/* initialise the global pool */
+void sharedmem_initglobalpool(apr_pool_t *p)
+{
+    globalpool = p;
+}
+/* Add the pool_clean routine */
+void sharedmem_initialize_cleanup(apr_pool_t *p)
+{
+    apr_pool_cleanup_register(p, &globallistmem, cleanup_slotmem, apr_pool_cleanup_null);
+}
index d24b2d04a2e57913065b188059a700e18be9ba85..372d955184b2c9b925e99f93c5508ea6a2d020be 100644 (file)
@@ -64,6 +64,17 @@ AP_DECLARE(apr_status_t) (* slotmem)(ap_slotmem_t *s, ap_slotmem_callback_fn_t *
  */
 AP_DECLARE(apr_status_t) (* ap_slotmem_create)(ap_slotmem_t **new, const char *name, apr_size_t item_size, int item_num, apr_pool_t *pool);
 
+/**
+ * attach to an existing slotmem.
+ * This would attach to  shared memory, basically.
+ * @param pointer to store the address of the scoreboard.
+ * @param name is a key used for debugging and in mod_status output or allow another process to share this space.
+ * @param item_size size of each idem
+ * @param item_num max number of idem.
+ * @param pool is pool to memory allocate.
+ * @return APR_SUCCESS if all went well
+ */
+AP_DECLARE(apr_status_t) (* ap_slotmem_attach)(ap_slotmem_t **new, const char *name, apr_size_t *item_size, int *item_num, apr_pool_t *pool);
 /**
  * get the memory associated with this worker slot.
  * @param s ap_slotmem_t to use.