--- /dev/null
+
+include $(top_srcdir)/build/special.mk
--- /dev/null
+dnl modules enabled in this directory by default
+
+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)
+APACHE_MODULE(plainmem, memslot provider that plain memory, , , no)
+
+# Ensure that other modules can pick up slotmem.h
+APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
+
+APACHE_MODPATH_FINISH
--- /dev/null
+/* Copyright 1999-2006 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed 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;
+ 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;
+ }
+ }
+
+ /* 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;
+ memset(res->base, 0, item_size * item_num);
+
+ /* 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_mem(ap_slotmem_t *score, int id, void**mem)
+{
+
+ void *ptr = score->base + score->size * id;
+
+ if (!score)
+ return APR_ENOSHMAVAIL;
+ if (id<0 || id>score->num)
+ return APR_ENOSHMAVAIL;
+
+ 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
+};
+
+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 */
+};
--- /dev/null
+/* Copyright 1999-2006 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed 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 the scoreboard and is only the proxy_worker loadbalancer
+ */
+#define CORE_PRIVATE
+
+#include "apr.h"
+#include "apr_pools.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+
+#include "scoreboard.h"
+
+#include "slotmem.h"
+
+#if MODULE_MAGIC_NUMBER_MAJOR > 20020903
+#define PROXY_HAS_SCOREBOARD 1
+#else
+#define PROXY_HAS_SCOREBOARD 0
+#endif
+
+struct ap_slotmem {
+ void *ptr;
+ apr_size_t size;
+ int num;
+};
+
+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;
+
+#if PROXY_HAS_SCOREBOARD
+ for (i = 0; i < mem->num; i++) {
+ ptr = (void *)ap_get_scoreboard_lb(i);
+ func((void *)ptr, data, pool);
+ }
+ return 0;
+#else
+ return APR_ENOSHMAVAIL;
+#endif
+}
+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 *score = NULL;
+ ap_slotmem_t *res;
+
+#if PROXY_HAS_SCOREBOARD
+ if (ap_scoreboard_image) {
+ score = (void *)ap_get_scoreboard_lb(0);
+ if (!score)
+ return APR_ENOSHMAVAIL;
+ }
+#else
+ return APR_ENOSHMAVAIL;
+#endif
+ if (!score)
+ return APR_ENOSHMAVAIL;
+
+ res = (ap_slotmem_t *) apr_pcalloc(pool, sizeof(ap_slotmem_t));
+ res->ptr = score;
+ res->size = item_size;
+ res->num = item_num;
+ *new = res;
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "ap_slotmem_create: score %d", score);
+
+ 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 PROXY_HAS_SCOREBOARD
+ if (ap_scoreboard_image)
+ ptr = (void *)ap_get_scoreboard_lb(id);
+#else
+ return APR_ENOSHMAVAIL;
+#endif
+
+ if (!ptr)
+ return APR_ENOSHMAVAIL;
+ *mem = ptr;
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "ap_slotmem_mem: score %d", score);
+ return APR_SUCCESS;
+}
+
+static const slotmem_storage_method storage = {
+ &ap_slotmem_do,
+ &ap_slotmem_create,
+ &ap_slotmem_mem
+};
+
+static int pre_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+#if PROXY_HAS_SCOREBOARD
+ return OK;
+#else
+ return DECLINED;
+#endif
+}
+
+static void ap_scoreboard_register_hook(apr_pool_t *p)
+{
+ ap_register_provider(p, SLOTMEM_STORAGE, "score", "0", &storage);
+ ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+module AP_MODULE_DECLARE_DATA scoreboard_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_scoreboard_register_hook /* register hooks */
+};
--- /dev/null
+/* Copyright 1999-2006 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed 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"
+
+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 = score->base + score->size * id;
+
+ if (!score)
+ return APR_ENOSHMAVAIL;
+ if (id<0 || id>score->num)
+ return APR_ENOSHMAVAIL;
+ if (apr_shm_size_get(score->shm) != score->size * score->num)
+ return APR_ENOSHMAVAIL;
+
+ 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)
+{
+ ap_slotmem_t *next = globallistmem;
+ while (next) { next = globallistmem;
+ next = next->next;
+ }
+ apr_pool_cleanup_register(p, &globallistmem, cleanup_slotmem, apr_pool_cleanup_null);
+ return OK;
+}
+
+static int pre_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+ globalpool = p;
+ return OK;
+}
+
+static void ap_sharedmem_register_hook(apr_pool_t *p)
+{
+ 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 */
+};
--- /dev/null
+/* Copyright 1999-2006 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed 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.
+ */
+#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
+ * @{
+ */
+
+
+#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 idem
+ * @param item_num number of idem 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);
+
+/**
+ * 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;