summaryrefslogtreecommitdiff
path: root/ext/session/mod_mm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/session/mod_mm.c')
-rw-r--r--ext/session/mod_mm.c416
1 files changed, 0 insertions, 416 deletions
diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c
deleted file mode 100644
index aeefcd5a3d..0000000000
--- a/ext/session/mod_mm.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP version 4.0 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2001 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 2.02 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available at through the world-wide-web at |
- | http://www.php.net/license/2_02.txt. |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Sascha Schumann <sascha@schumann.cx> |
- +----------------------------------------------------------------------+
- */
-
-/* $Id$ */
-
-#include "php.h"
-
-#ifdef HAVE_LIBMM
-
-#include <mm.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-#include "php_session.h"
-#include "mod_mm.h"
-
-#ifdef ZTS
-# error mm is not thread-safe
-#endif
-
-#define PS_MM_PATH "/tmp/session_mm"
-
-/* For php_uint32 */
-#include "ext/standard/basic_functions.h"
-
-/*
- * this list holds all data associated with one session
- */
-
-typedef struct ps_sd {
- struct ps_sd *next;
- php_uint32 hv; /* hash value of key */
- time_t ctime; /* time of last change */
- void *data;
- size_t datalen; /* amount of valid data */
- size_t alloclen; /* amount of allocated memory for data */
- char key[1]; /* inline key */
-} ps_sd;
-
-typedef struct {
- MM *mm;
- ps_sd **hash;
- php_uint32 hash_max;
- php_uint32 hash_cnt;
- pid_t owner;
-} ps_mm;
-
-static ps_mm *ps_mm_instance = NULL;
-
-#if 0
-#define ps_mm_debug(a) printf a
-#else
-#define ps_mm_debug(a)
-#endif
-
-static inline php_uint32 ps_sd_hash(const char *data, int len)
-{
- php_uint32 h;
- const char *e = data + len;
-
- for (h = 2166136261U; data < e; ) {
- h *= 16777619;
- h ^= *data++;
- }
-
- return h;
-}
-
-static void hash_split(ps_mm *data)
-{
- php_uint32 nmax;
- ps_sd **nhash;
- ps_sd **ohash, **ehash;
- ps_sd *ps, *next;
-
- nmax = ((data->hash_max + 1) << 1) - 1;
- nhash = mm_calloc(data->mm, nmax + 1, sizeof(*data->hash));
-
- if (!nhash) {
- /* no further memory to expand hash table */
- return;
- }
-
- ehash = data->hash + data->hash_max + 1;
- for (ohash = data->hash; ohash < ehash; ohash++) {
- for (ps = *ohash; ps; ps = next) {
- next = ps->next;
- ps->next = nhash[ps->hv & nmax];
- nhash[ps->hv & nmax] = ps;
- }
- }
- mm_free(data->mm, data->hash);
-
- data->hash = nhash;
- data->hash_max = nmax;
-}
-
-static ps_sd *ps_sd_new(ps_mm *data, const char *key)
-{
- php_uint32 hv, slot;
- ps_sd *sd;
- int keylen;
-
- keylen = strlen(key);
-
- sd = mm_malloc(data->mm, sizeof(ps_sd) + keylen);
- if (!sd) {
- php_error(E_WARNING, "mm_malloc failed, avail %d, err %s", mm_available(data->mm), mm_error());
- return NULL;
- }
-
- hv = ps_sd_hash(key, keylen);
- slot = hv & data->hash_max;
-
- sd->ctime = 0;
- sd->hv = hv;
- sd->data = NULL;
- sd->alloclen = sd->datalen = 0;
-
- memcpy(sd->key, key, keylen + 1);
-
- sd->next = data->hash[slot];
- data->hash[slot] = sd;
-
- data->hash_cnt++;
-
- if (!sd->next) {
- if (data->hash_cnt >= data->hash_max)
- hash_split(data);
- }
-
- ps_mm_debug(("inserting %s(%p) into slot %d\n", key, sd, slot));
-
- return sd;
-}
-
-static void ps_sd_destroy(ps_mm *data, ps_sd *sd)
-{
- php_uint32 slot;
-
- slot = ps_sd_hash(sd->key, strlen(sd->key)) & data->hash_max;
-
- if (data->hash[slot] == sd)
- data->hash[slot] = sd->next;
- else {
- ps_sd *prev;
-
- /* There must be some entry before the one we want to delete */
- for (prev = data->hash[slot]; prev->next != sd; prev = prev->next);
- prev->next = sd->next;
- }
-
- data->hash_cnt--;
- if (sd->data)
- mm_free(data->mm, sd->data);
- mm_free(data->mm, sd);
-}
-
-static ps_sd *ps_sd_lookup(ps_mm *data, const char *key, int rw)
-{
- php_uint32 hv, slot;
- ps_sd *ret, *prev;
-
- hv = ps_sd_hash(key, strlen(key));
- slot = hv & data->hash_max;
-
- for (prev = NULL, ret = data->hash[slot]; ret; prev = ret, ret = ret->next)
- if (ret->hv == hv && !strcmp(ret->key, key))
- break;
-
- if (ret && rw && ret != data->hash[slot]) {
- /* Move the entry to the top of the linked list */
-
- if (prev)
- prev->next = ret->next;
- ret->next = data->hash[slot];
- data->hash[slot] = ret;
- }
-
- ps_mm_debug(("lookup(%s): ret=%p,hv=%u,slot=%d\n", key, ret, hv, slot));
-
- return ret;
-}
-
-ps_module ps_mod_mm = {
- PS_MOD(mm)
-};
-
-#define PS_MM_DATA ps_mm *data = PS_GET_MOD_DATA()
-
-static int ps_mm_initialize(ps_mm *data, const char *path)
-{
- data->owner = getpid();
- data->mm = mm_create(0, path);
- if (!data->mm) {
- return FAILURE;
- }
-
- data->hash_cnt = 0;
- data->hash_max = 511;
- data->hash = mm_calloc(data->mm, data->hash_max + 1, sizeof(ps_sd *));
- if (!data->hash) {
- mm_destroy(data->mm);
- return FAILURE;
- }
-
- return SUCCESS;
-}
-
-static void ps_mm_destroy(ps_mm *data)
-{
- int h;
- ps_sd *sd, *next;
-
- /* This function is called during each module shutdown,
- but we must not release the shared memory pool, when
- an Apache child dies! */
- if (data->owner != getpid()) return;
-
- for (h = 0; h < data->hash_max + 1; h++)
- for (sd = data->hash[h]; sd; sd = next) {
- next = sd->next;
- ps_sd_destroy(data, sd);
- }
-
- mm_free(data->mm, data->hash);
- mm_destroy(data->mm);
- free(data);
-}
-
-PHP_MINIT_FUNCTION(ps_mm)
-{
- ps_mm_instance = calloc(sizeof(*ps_mm_instance), 1);
- if (ps_mm_initialize(ps_mm_instance, PS_MM_PATH) != SUCCESS) {
- ps_mm_instance = NULL;
- return FAILURE;
- }
-
- php_session_register_module(&ps_mod_mm);
- return SUCCESS;
-}
-
-PHP_MSHUTDOWN_FUNCTION(ps_mm)
-{
- if (ps_mm_instance) {
- ps_mm_destroy(ps_mm_instance);
- return SUCCESS;
- }
- return FAILURE;
-}
-
-PS_OPEN_FUNC(mm)
-{
- ps_mm_debug(("open: ps_mm_instance=%p\n", ps_mm_instance));
-
- if (!ps_mm_instance)
- return FAILURE;
-
- PS_SET_MOD_DATA(ps_mm_instance);
-
- return SUCCESS;
-}
-
-PS_CLOSE_FUNC(mm)
-{
- PS_SET_MOD_DATA(NULL);
-
- return SUCCESS;
-}
-
-PS_READ_FUNC(mm)
-{
- PS_MM_DATA;
- ps_sd *sd;
- int ret = FAILURE;
-
- mm_lock(data->mm, MM_LOCK_RD);
-
- sd = ps_sd_lookup(data, key, 0);
- if (sd) {
- *vallen = sd->datalen;
- *val = emalloc(sd->datalen + 1);
- memcpy(*val, sd->data, sd->datalen);
- (*val)[sd->datalen] = '\0';
- ret = SUCCESS;
- }
-
- mm_unlock(data->mm);
-
- return ret;
-}
-
-PS_WRITE_FUNC(mm)
-{
- PS_MM_DATA;
- ps_sd *sd;
-
- mm_lock(data->mm, MM_LOCK_RW);
-
- sd = ps_sd_lookup(data, key, 1);
- if (!sd) {
- sd = ps_sd_new(data, key);
- ps_mm_debug(("new entry for %s\n", key));
- }
-
- if (sd) {
- if (vallen >= sd->alloclen) {
- if (data->mm)
- mm_free(data->mm, sd->data);
- sd->alloclen = vallen + 1;
- sd->data = mm_malloc(data->mm, sd->alloclen);
-
- if (!sd->data) {
- ps_sd_destroy(data, sd);
- php_error(E_WARNING, "cannot allocate new data segment");
- sd = NULL;
- }
- }
- if (sd) {
- sd->datalen = vallen;
- memcpy(sd->data, val, vallen);
- time(&sd->ctime);
- }
- }
-
- mm_unlock(data->mm);
-
- return sd ? SUCCESS : FAILURE;
-}
-
-PS_DESTROY_FUNC(mm)
-{
- PS_MM_DATA;
- ps_sd *sd;
-
- mm_lock(data->mm, MM_LOCK_RW);
-
- sd = ps_sd_lookup(data, key, 0);
- if (sd)
- ps_sd_destroy(data, sd);
-
- mm_unlock(data->mm);
-
- return SUCCESS;
-}
-
-PS_GC_FUNC(mm)
-{
- PS_MM_DATA;
- time_t limit;
- ps_sd **ohash, **ehash;
- ps_sd *sd, *next;
-
- *nrdels = 0;
- ps_mm_debug(("gc\n"));
-
- time(&limit);
-
- limit -= maxlifetime;
-
- mm_lock(data->mm, MM_LOCK_RW);
-
- ehash = data->hash + data->hash_max + 1;
- for (ohash = data->hash; ohash < ehash; ohash++)
- for (sd = *ohash; sd; sd = next) {
- next = sd->next;
- if (sd->ctime < limit) {
- ps_mm_debug(("purging %s\n", sd->key));
- ps_sd_destroy(data, sd);
- (*nrdels)++;
- }
- }
-
- mm_unlock(data->mm);
-
- return SUCCESS;
-}
-
-zend_module_entry php_session_mm_module = {
- STANDARD_MODULE_HEADER,
- "session mm",
- NULL,
- PHP_MINIT(ps_mm), PHP_MSHUTDOWN(ps_mm),
- NULL, NULL,
- NULL,
- NO_VERSION_YET,
- STANDARD_MODULE_PROPERTIES
-};
-
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */