summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Frederic Clere <jfclere@apache.org>2006-07-26 13:42:43 +0000
committerJean-Frederic Clere <jfclere@apache.org>2006-07-26 13:42:43 +0000
commit3e5ef3ea80c46c4bd97222c22e9f67fbf5296ade (patch)
tree6faf1e86efae1744a05fe8299033dba6df80c9b2
parentcd80ecf805e4856cdb6c0ad199bd97bf3f91f7ba (diff)
downloadhttpd-3e5ef3ea80c46c4bd97222c22e9f67fbf5296ade.tar.gz
Add ap_slotmem_attach() to the slotmem_storage_method.
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
-rw-r--r--modules/mem/config5.m43
-rw-r--r--modules/mem/mod_plainmem.c31
-rw-r--r--modules/mem/mod_scoreboard.c6
-rw-r--r--modules/mem/mod_sharedmem.c128
-rw-r--r--modules/mem/sharedmem_util.c246
-rw-r--r--modules/mem/slotmem.h11
6 files changed, 300 insertions, 125 deletions
diff --git a/modules/mem/config5.m4 b/modules/mem/config5.m4
index 32eedbf1e5..94f11c4137 100644
--- a/modules/mem/config5.m4
+++ b/modules/mem/config5.m4
@@ -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
diff --git a/modules/mem/mod_plainmem.c b/modules/mem/mod_plainmem.c
index 77110c50a8..612879b3fa 100644
--- a/modules/mem/mod_plainmem.c
+++ b/modules/mem/mod_plainmem.c
@@ -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
};
diff --git a/modules/mem/mod_scoreboard.c b/modules/mem/mod_scoreboard.c
index 231504ee34..03038b11e1 100644
--- a/modules/mem/mod_scoreboard.c
+++ b/modules/mem/mod_scoreboard.c
@@ -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;
diff --git a/modules/mem/mod_sharedmem.c b/modules/mem/mod_sharedmem.c
index 98b2add9c5..2b55118f02 100644
--- a/modules/mem/mod_sharedmem.c
+++ b/modules/mem/mod_sharedmem.c
@@ -29,144 +29,24 @@
#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
index 0000000000..800115c06b
--- /dev/null
+++ b/modules/mem/sharedmem_util.c
@@ -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);
+}
diff --git a/modules/mem/slotmem.h b/modules/mem/slotmem.h
index d24b2d04a2..372d955184 100644
--- a/modules/mem/slotmem.h
+++ b/modules/mem/slotmem.h
@@ -65,6 +65,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.
* @param item_id item to return for 0 to item_num