summaryrefslogtreecommitdiff
path: root/ext/session/mod_mm.c
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>1999-09-03 17:46:39 +0000
committerSascha Schumann <sas@php.net>1999-09-03 17:46:39 +0000
commit5b293ecd4dcd22a391784a88cead34d810e7eac7 (patch)
tree368e68e3f30932d16012778b301c2c78fbf5e46a /ext/session/mod_mm.c
parent690575e51f1866e00074411aae18f98d76cfdf26 (diff)
downloadphp-git-5b293ecd4dcd22a391784a88cead34d810e7eac7.tar.gz
- add global startup/shutdown handlers
- improve genif.sh to also consider all header files for inclusion (checks for phpext_) - use vsnprintf in main.c to avoid buffer overflows - improve sessions's mm module to cope better with OOM situations within the shared memory segment - fix typo wrt session.auto_start
Diffstat (limited to 'ext/session/mod_mm.c')
-rw-r--r--ext/session/mod_mm.c85
1 files changed, 73 insertions, 12 deletions
diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c
index 5361dc38ff..41b82ecf62 100644
--- a/ext/session/mod_mm.c
+++ b/ext/session/mod_mm.c
@@ -30,12 +30,18 @@
#include "php_session.h"
#include "mod_mm.h"
+#define PS_MM_PATH "/tmp/session_mm"
+
+/*
+ * this list holds all data associated with one session
+ */
+
typedef struct ps_sd {
+ struct ps_sd *next, *prev;
time_t ctime;
char *key;
void *data;
size_t datalen;
- struct ps_sd *next, *prev;
} ps_sd;
typedef struct {
@@ -46,7 +52,7 @@ typedef struct {
static ps_mm *ps_mm_instance = NULL;
/* should be a prime */
-#define HASH_SIZE 11
+#define HASH_SIZE 577
#if 0
#define ps_mm_debug(a...) fprintf(stderr, a)
@@ -59,6 +65,11 @@ static ps_mm *ps_mm_instance = NULL;
#define ONE_EIGTH ((int) (BITS_IN_int / 8))
#define HIGH_BITS (~((unsigned int)(~0) >> ONE_EIGTH))
+/*
+ * Weinberger's generic hash algorithm, adapted by Holub
+ * (published in [Holub 1990])
+ */
+
static unsigned int ps_sd_hash(const char *data)
{
unsigned int val, i;
@@ -82,13 +93,27 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key, const void *sdata, size_t
h = ps_sd_hash(key) % HASH_SIZE;
sd = mm_malloc(data->mm, sizeof(*sd));
+ if(!sd) {
+ return NULL;
+ }
sd->ctime = 0;
sd->data = mm_malloc(data->mm, sdatalen);
- memcpy(sd->data, sdata, sdatalen);
+ if(!sd->data) {
+ mm_free(data->mm, sd);
+ return NULL;
+ }
+
sd->datalen = sdatalen;
sd->key = mm_strdup(data->mm, key);
+ if(!sd->key) {
+ mm_free(data->mm, sd->data);
+ mm_free(data->mm, sd);
+ return NULL;
+ }
+
+ memcpy(sd->data, sdata, sdatalen);
if((sd->next = data->hash[h]))
sd->next->prev = sd;
@@ -116,7 +141,7 @@ static void ps_sd_destroy(ps_mm *data, ps_sd *sd)
data->hash[h] = sd->next;
mm_free(data->mm, sd->key);
- mm_free(data->mm, sd->data);
+ if(sd->data) mm_free(data->mm, sd->data);
mm_free(data->mm, sd);
}
@@ -159,17 +184,38 @@ static int ps_mm_initialize(ps_mm *data, const char *path)
static void ps_mm_destroy(ps_mm *data)
{
+ int h;
+ ps_sd *sd, *next;
+
+ for(h = 0; h < HASH_SIZE; 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);
}
-PS_OPEN_FUNC(mm)
+PHP_GINIT_FUNCTION(ps_mm)
{
- if(!ps_mm_instance) {
- ps_mm_instance = calloc(sizeof(*data), 1);
- ps_mm_initialize(ps_mm_instance, save_path);
- }
+ ps_mm_instance = calloc(sizeof(*ps_mm_instance), 1);
+ ps_mm_initialize(ps_mm_instance, PS_MM_PATH);
+ return SUCCESS;
+}
+
+PHP_GSHUTDOWN_FUNCTION(ps_mm)
+{
+ ps_mm_destroy(ps_mm_instance);
+ free(ps_mm_instance);
+ return SUCCESS;
+}
+PS_OPEN_FUNC(mm)
+{
+ ps_mm_debug("open: ps_mm_instance=%x\n", ps_mm_instance);
+
PS_SET_MOD_DATA(ps_mm_instance);
return SUCCESS;
@@ -219,14 +265,19 @@ PS_WRITE_FUNC(mm)
mm_free(data->mm, sd->data);
sd->datalen = vallen;
sd->data = mm_malloc(data->mm, vallen);
- memcpy(sd->data, val, vallen);
+ if(!sd->data) {
+ ps_sd_destroy(data, sd);
+ sd = NULL;
+ } else {
+ memcpy(sd->data, val, vallen);
+ }
}
- time(&sd->ctime);
+ if(sd) time(&sd->ctime);
mm_unlock(data->mm);
- return SUCCESS;
+ return sd ? SUCCESS : FAILURE;
}
PS_DESTROY_FUNC(mm)
@@ -274,4 +325,14 @@ PS_GC_FUNC(mm)
return SUCCESS;
}
+zend_module_entry php_session_mm_module = {
+ "Session MM",
+ NULL,
+ NULL, NULL,
+ NULL, NULL,
+ NULL,
+ PHP_GINIT(ps_mm), PHP_GSHUTDOWN(ps_mm),
+ STANDARD_MODULE_PROPERTIES_EX
+};
+
#endif