From: Jim Jagielski Date: Tue, 23 Dec 2008 18:39:56 +0000 (+0000) Subject: Add in the useful slotmem memory module, from httpd-scoreboard. X-Git-Tag: 2.3.1~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=efc36d996064b0b3f0351d8afbf6de7506e9e406;p=apache Add in the useful slotmem memory module, from httpd-scoreboard. Cleaned up... git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@729059 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/mem/.deps b/modules/mem/.deps new file mode 100644 index 0000000000..e69de29bb2 diff --git a/modules/mem/Makefile b/modules/mem/Makefile new file mode 100644 index 0000000000..57b25cf2cb --- /dev/null +++ b/modules/mem/Makefile @@ -0,0 +1,7 @@ +top_srcdir = /Users/jim/src/asf/code/dev/httpd-trunk +top_builddir = /Users/jim/src/asf/code/dev/httpd-trunk +srcdir = /Users/jim/src/asf/code/dev/httpd-trunk/modules/mem +builddir = /Users/jim/src/asf/code/dev/httpd-trunk/modules/mem +VPATH = /Users/jim/src/asf/code/dev/httpd-trunk/modules/mem + +include $(top_srcdir)/build/special.mk diff --git a/modules/mem/Makefile.in b/modules/mem/Makefile.in new file mode 100644 index 0000000000..e32210f185 --- /dev/null +++ b/modules/mem/Makefile.in @@ -0,0 +1,2 @@ + +include $(top_srcdir)/build/special.mk diff --git a/modules/mem/config5.m4 b/modules/mem/config5.m4 new file mode 100644 index 0000000000..6b996fc2b2 --- /dev/null +++ b/modules/mem/config5.m4 @@ -0,0 +1,14 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(mem) + +sharedmem_objs="mod_sharedmem.lo sharedmem_util.lo" +APACHE_MODULE(sharedmem, memslot provider that uses shared memory, $sharedmem_objs, , most) +APACHE_MODULE(plainmem, memslot provider that uses plain memory, , , no) + +# Ensure that other modules can pick up slotmem.h +APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) + +APACHE_MODPATH_FINISH diff --git a/modules/mem/mod_plainmem.c b/modules/mem/mod_plainmem.c new file mode 100644 index 0000000000..d3a814d9e4 --- /dev/null +++ b/modules/mem/mod_plainmem.c @@ -0,0 +1,188 @@ +/* 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 plain memory divided in slot. + * This one uses plain memory. + */ +#define CORE_PRIVATE + +#include "apr.h" +#include "apr_pools.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" + +#include "slotmem.h" + +struct ap_slotmem { + char *name; + 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; + +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; + const char *fname; + apr_status_t rv; + + if (name) { + if (name[0] == ':') + fname = name; + else + 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; + } + } + } else + fname = "anonymous"; + + /* create the memory using the globalpool */ + res = (ap_slotmem_t *) apr_pcalloc(globalpool, sizeof(ap_slotmem_t)); + res->base = apr_pcalloc(globalpool, item_size * item_num); + if (!res->base) + return APR_ENOSHMAVAIL; + + /* For the chained slotmem stuff */ + res->name = apr_pstrdup(globalpool, fname); + 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; + ap_slotmem_t *res; + ap_slotmem_t *next = globallistmem; + const char *fname; + apr_status_t rv; + + if (name) { + if (name[0] == ':') + fname = name; + else + fname = ap_server_root_relative(pool, name); + } else + return APR_ENOSHMAVAIL; + + /* 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) +{ + + 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_attach, + &ap_slotmem_mem +}; + +static int pre_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + globalpool = p; + return OK; +} + +static void ap_plainmem_register_hook(apr_pool_t *p) +{ + ap_register_provider(p, SLOTMEM_STORAGE, "plain", "0", &storage); + ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA plainmem_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + ap_plainmem_register_hook /* register hooks */ +}; diff --git a/modules/mem/mod_sharedmem.c b/modules/mem/mod_sharedmem.c new file mode 100644 index 0000000000..cb8f0c1fa7 --- /dev/null +++ b/modules/mem/mod_sharedmem.c @@ -0,0 +1,72 @@ +/* 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" +#include "sharedmem_util.h" + +/* 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) +{ + sharedmem_initialize_cleanup(p); + return OK; +} + +static int pre_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + apr_pool_t *global_pool; + apr_status_t rv; + + rv = apr_pool_create(&global_pool, NULL); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "Fatal error: unable to create global pool for shared slotmem"); + return rv; + } + sharedmem_initglobalpool(global_pool); + return OK; +} + +static void ap_sharedmem_register_hook(apr_pool_t *p) +{ + const 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); +} + +module AP_MODULE_DECLARE_DATA sharedmem_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + ap_sharedmem_register_hook /* register hooks */ +}; diff --git a/modules/mem/modules.mk b/modules/mem/modules.mk new file mode 100644 index 0000000000..67c877b192 --- /dev/null +++ b/modules/mem/modules.mk @@ -0,0 +1,5 @@ +libmod_sharedmem.la: mod_sharedmem.lo sharedmem_util.lo + $(MOD_LINK) mod_sharedmem.lo sharedmem_util.lo $(MOD_SHAREDMEM_LDADD) +DISTCLEAN_TARGETS = modules.mk +static = libmod_sharedmem.la +shared = diff --git a/modules/mem/sharedmem_util.c b/modules/mem/sharedmem_util.c new file mode 100644 index 0000000000..b106bd755a --- /dev/null +++ b/modules/mem/sharedmem_util.c @@ -0,0 +1,376 @@ +/* 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_file_io.h" +#include "apr_strings.h" +#include "apr_pools.h" +#include "apr_shm.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" + +#include "slotmem.h" +#include "sharedmem_util.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; + apr_pool_t *globalpool; + 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; + +/* + * Persiste the slotmem in a file + * slotmem name and file name. + * anonymous : $server_root/logs/anonymous.slotmem + * :module.c : $server_root/logs/module.c.slotmem + * abs_name : $abs_name.slotmem + * + */ +static const char *store_filename(apr_pool_t *pool, const char *slotmemname) +{ + const char *storename; + const char *fname; + if (strcmp(slotmemname, "anonymous") == 0) + fname = ap_server_root_relative(pool, "logs/anonymous"); + else if (slotmemname[0] == ':') { + const char *tmpname; + tmpname = apr_pstrcat(pool, "logs/", &slotmemname[1], NULL); + fname = ap_server_root_relative(pool, tmpname); + } + else { + fname = slotmemname; + } + storename = apr_pstrcat(pool, fname , ".slotmem", NULL); + return storename; +} +static void store_slotmem(ap_slotmem_t *slotmem) +{ + apr_file_t *fp; + apr_status_t rv; + apr_size_t nbytes; + const char *storename; + + storename = store_filename(slotmem->globalpool, slotmem->name); + + rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, slotmem->globalpool); + if (APR_STATUS_IS_EEXIST(rv)) { + apr_file_remove(storename, slotmem->globalpool); + rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, slotmem->globalpool); + } + if (rv != APR_SUCCESS) { + return; + } + nbytes = slotmem->size * slotmem->num; + apr_file_write(fp, slotmem->base, &nbytes); + apr_file_close(fp); +} + +static void restore_slotmem(void *ptr, const char *name, apr_size_t item_size, int item_num, apr_pool_t *pool) +{ + const char *storename; + apr_file_t *fp; + apr_size_t nbytes = item_size * item_num; + apr_status_t rv; + + storename = store_filename(pool, name); + rv = apr_file_open(&fp, storename, APR_READ | APR_WRITE, APR_OS_DEFAULT, pool); + if (rv == APR_SUCCESS) { + apr_finfo_t fi; + if (apr_file_info_get(&fi, APR_FINFO_SIZE, fp) == APR_SUCCESS) { + if (fi.size == nbytes) { + apr_file_read(fp, ptr, &nbytes); + } + else { + apr_file_close(fp); + apr_file_remove(storename, pool); + return; + } + } + apr_file_close(fp); + } +} + +static apr_status_t cleanup_slotmem(void *param) +{ + ap_slotmem_t **mem = param; + apr_status_t rv; + apr_pool_t *pool = NULL; + + if (*mem) { + ap_slotmem_t *next = *mem; + pool = next->globalpool; + while (next) { + store_slotmem(next); + rv = apr_shm_destroy(next->shm); + next = next->next; + } + apr_pool_destroy(pool); + } + 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; + const char *fname; + apr_status_t rv; + + if (globalpool == NULL) + return APR_ENOSHMAVAIL; + if (name) { + if (name[0] == ':') { + fname = name; + } + else { + 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; + } + } + } + else { + fname = "anonymous"; + } + + /* first try to attach to existing shared memory */ + res = (ap_slotmem_t *) apr_pcalloc(globalpool, sizeof(ap_slotmem_t)); + if (name && name[0] != ':') { + rv = apr_shm_attach(&res->shm, fname, globalpool); + } + else { + rv = APR_EINVAL; + } + 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 { + if (name && name[0] != ':') { + apr_shm_remove(fname, globalpool); + rv = apr_shm_create(&res->shm, item_size * item_num + sizeof(struct sharedslotdesc), fname, globalpool); + } + else { + rv = apr_shm_create(&res->shm, item_size * item_num + sizeof(struct sharedslotdesc), NULL, 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); + restore_slotmem(ptr, fname, item_size, item_num, pool); + } + + /* For the chained slotmem stuff */ + res->name = apr_pstrdup(globalpool, fname); + res->base = ptr; + res->size = item_size; + res->num = item_num; + res->globalpool = globalpool; + 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; + const char *fname; + apr_status_t rv; + + if (globalpool == NULL) { + return APR_ENOSHMAVAIL; + } + if (name) { + if (name[0] == ':') { + fname = name; + } + else { + fname = ap_server_root_relative(pool, name); + } + } + else { + return APR_ENOSHMAVAIL; + } + + /* 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->globalpool = globalpool; + 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 */ +const slotmem_storage_method *sharedmem_getstorage(void) +{ + 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/sharedmem_util.h b/modules/mem/sharedmem_util.h new file mode 100644 index 0000000000..66afa7b350 --- /dev/null +++ b/modules/mem/sharedmem_util.h @@ -0,0 +1,22 @@ +/* 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. + */ +const slotmem_storage_method *sharedmem_getstorage(void); +void sharedmem_initglobalpool(apr_pool_t *p); +void sharedmem_initialize_cleanup(apr_pool_t *p); diff --git a/modules/mem/slotmem.h b/modules/mem/slotmem.h new file mode 100644 index 0000000000..2e230ef226 --- /dev/null +++ b/modules/mem/slotmem.h @@ -0,0 +1,100 @@ +/* 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. + */ + +#ifndef SLOTMEM_H +#define SLOTMEM_H + +/* Memory handler for a shared memory divided in slot. + */ +/** + * @file slotmem.h + * @brief Memory Slot Extension Storage Module for Apache + * + * @defgroup MEM mem + * @ingroup APACHE_MODS + * @{ + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_pools.h" +#include "apr_shm.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "ap_provider.h" + +#define SLOTMEM_STORAGE "slotmem" + +typedef struct ap_slotmem ap_slotmem_t; + +/** + * callback function used for slotmem. + * @param mem is the memory associated with a worker. + * @param data is what is passed to slotmem. + * @param pool is pool used to create scoreboard + * @return APR_SUCCESS if all went well + */ +typedef apr_status_t ap_slotmem_callback_fn_t(void* mem, void *data, apr_pool_t *pool); + +struct slotmem_storage_method { +/** + * call the callback on all worker slots + * @param s ap_slotmem_t to use. + * @param funct callback function to call for each element. + * @param data parameter for the callback function. + * @param pool is pool used to create scoreboard + * @return APR_SUCCESS if all went well + */ +AP_DECLARE(apr_status_t) (* slotmem)(ap_slotmem_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool); + +/** + * create a new slotmem with each item size is item_size. + * This would create 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 item + * @param item_num number of item to create. + * @param pool is pool used to create scoreboard + * @return APR_SUCCESS if all went well + */ +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 item + * @param item_num max number of item. + * @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 + * @param mem address to store the pointer to the slot + * @return APR_SUCCESS if all went well + */ +AP_DECLARE(apr_status_t) (* ap_slotmem_mem)(ap_slotmem_t *s, int item_id, void**mem); +}; + +typedef struct slotmem_storage_method slotmem_storage_method; + +#endif /*SLOTMEM_H*/