diff options
author | Jean-Frederic Clere <jfclere@apache.org> | 2006-07-26 13:42:43 +0000 |
---|---|---|
committer | Jean-Frederic Clere <jfclere@apache.org> | 2006-07-26 13:42:43 +0000 |
commit | 3e5ef3ea80c46c4bd97222c22e9f67fbf5296ade (patch) | |
tree | 6faf1e86efae1744a05fe8299033dba6df80c9b2 | |
parent | cd80ecf805e4856cdb6c0ad199bd97bf3f91f7ba (diff) | |
download | httpd-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.m4 | 3 | ||||
-rw-r--r-- | modules/mem/mod_plainmem.c | 31 | ||||
-rw-r--r-- | modules/mem/mod_scoreboard.c | 6 | ||||
-rw-r--r-- | modules/mem/mod_sharedmem.c | 128 | ||||
-rw-r--r-- | modules/mem/sharedmem_util.c | 246 | ||||
-rw-r--r-- | modules/mem/slotmem.h | 11 |
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 |