From 9ece649f7c64061fc874865ee9a1ab4a0161afce Mon Sep 17 00:00:00 2001 From: Jani Taskinen Date: Mon, 18 May 2009 16:10:09 +0000 Subject: MFH: ws + sync --- ext/session/mod_mm.c | 125 ++++++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 57 deletions(-) (limited to 'ext/session/mod_mm.c') diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c index b2f51d5ef9..78f1b8fcc5 100644 --- a/ext/session/mod_mm.c +++ b/ext/session/mod_mm.c @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ @@ -42,9 +42,7 @@ /* For php_uint32 */ #include "ext/standard/basic_functions.h" -/* - * this list holds all data associated with one session - */ +/* This list holds all data associated with one session. */ typedef struct ps_sd { struct ps_sd *next; @@ -67,21 +65,21 @@ typedef struct { static ps_mm *ps_mm_instance = NULL; #if 0 -#define ps_mm_debug(a) printf a +# define ps_mm_debug(a) printf a #else -#define ps_mm_debug(a) +# 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; } @@ -91,10 +89,10 @@ static void hash_split(ps_mm *data) 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; @@ -119,9 +117,9 @@ 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) { TSRMLS_FETCH(); @@ -132,24 +130,25 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key) 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) + 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; @@ -161,19 +160,22 @@ static void ps_sd_destroy(ps_mm *data, ps_sd *sd) slot = ps_sd_hash(sd->key, strlen(sd->key)) & data->hash_max; - if (data->hash[slot] == sd) + if (data->hash[slot] == sd) { data->hash[slot] = sd->next; - else { + } 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) + + if (sd->data) { mm_free(data->mm, sd->data); + } + mm_free(data->mm, sd); } @@ -184,22 +186,25 @@ static ps_sd *ps_sd_lookup(ps_mm *data, const char *key, int rw) 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)) + + 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) + 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; } @@ -236,14 +241,17 @@ static void ps_mm_destroy(ps_mm *data) /* 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; + if (data->owner != getpid()) { + return; + } - for (h = 0; h < data->hash_max + 1; h++) + 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); @@ -258,17 +266,17 @@ PHP_MINIT_FUNCTION(ps_mm) int ret; ps_mm_instance = calloc(sizeof(*ps_mm_instance), 1); - if (!ps_mm_instance) { + if (!ps_mm_instance) { return FAILURE; } if (!(euid_len = slprintf(euid, sizeof(euid), "%d", geteuid()))) { return FAILURE; } - - /* Directory + '/' + File + Module Name + Effective UID + \0 */ + + /* Directory + '/' + File + Module Name + Effective UID + \0 */ ps_mm_path = emalloc(save_path_len + 1 + (sizeof(PS_MM_FILE) - 1) + mod_name_len + euid_len + 1); - + memcpy(ps_mm_path, PS(save_path), save_path_len); if (PS(save_path)[save_path_len - 1] != DEFAULT_SLASH) { ps_mm_path[save_path_len] = DEFAULT_SLASH; @@ -282,15 +290,15 @@ PHP_MINIT_FUNCTION(ps_mm) ps_mm_path[save_path_len + euid_len] = '\0'; ret = ps_mm_initialize(ps_mm_instance, ps_mm_path); - + efree(ps_mm_path); - + if (ret != SUCCESS) { free(ps_mm_instance); ps_mm_instance = NULL; return FAILURE; } - + php_session_register_module(&ps_mod_mm); return SUCCESS; } @@ -307,12 +315,12 @@ PHP_MSHUTDOWN_FUNCTION(ps_mm) PS_OPEN_FUNC(mm) { ps_mm_debug(("open: ps_mm_instance=%p\n", ps_mm_instance)); - - if (!ps_mm_instance) + + if (!ps_mm_instance) { return FAILURE; - + } PS_SET_MOD_DATA(ps_mm_instance); - + return SUCCESS; } @@ -330,7 +338,7 @@ PS_READ_FUNC(mm) int ret = FAILURE; mm_lock(data->mm, MM_LOCK_RD); - + sd = ps_sd_lookup(data, key, 0); if (sd) { *vallen = sd->datalen; @@ -341,7 +349,7 @@ PS_READ_FUNC(mm) } mm_unlock(data->mm); - + return ret; } @@ -360,8 +368,9 @@ PS_WRITE_FUNC(mm) if (sd) { if (vallen >= sd->alloclen) { - if (data->mm) + if (data->mm) { mm_free(data->mm, sd->data); + } sd->alloclen = vallen + 1; sd->data = mm_malloc(data->mm, sd->alloclen); @@ -379,7 +388,7 @@ PS_WRITE_FUNC(mm) } mm_unlock(data->mm); - + return sd ? SUCCESS : FAILURE; } @@ -387,28 +396,29 @@ 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) + if (sd) { ps_sd_destroy(data, sd); - + } + mm_unlock(data->mm); - + return SUCCESS; } -PS_GC_FUNC(mm) +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; @@ -416,7 +426,7 @@ PS_GC_FUNC(mm) mm_lock(data->mm, MM_LOCK_RW); ehash = data->hash + data->hash_max + 1; - for (ohash = data->hash; ohash < ehash; ohash++) + for (ohash = data->hash; ohash < ehash; ohash++) { for (sd = *ohash; sd; sd = next) { next = sd->next; if (sd->ctime < limit) { @@ -425,9 +435,10 @@ PS_GC_FUNC(mm) (*nrdels)++; } } + } mm_unlock(data->mm); - + return SUCCESS; } -- cgit v1.2.1