apr_pool_t *gpool; /* per segment global pool */
apr_global_mutex_t *smutex; /* mutex */
struct ap_slotmem_t *next; /* location of next allocated segment */
+ char *inuse; /* is-use flag table*/
};
unsigned int item_num;
};
+/*
+ * Memory layout:
+ * sharedslotdesc | slots | isuse array
+ */
+
/* global pool and list of slotmem we are handling */
static struct ap_slotmem_t *globallistmem = NULL;
static apr_pool_t *gpool = NULL;
if (rv != APR_SUCCESS) {
return;
}
- nbytes = slotmem->size * slotmem->num;
+ nbytes = (slotmem->size * slotmem->num) + (slotmem->num + sizeof(char));
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, unsigned int item_num, apr_pool_t *pool)
+static void restore_slotmem(void *ptr, const char *name, apr_size_t size, apr_pool_t *pool)
{
const char *storename;
apr_file_t *fp;
- apr_size_t nbytes = item_size * item_num;
+ apr_size_t nbytes = size;
apr_status_t rv;
storename = store_filename(pool, name);
{
unsigned int i;
void *ptr;
+ char *inuse;
if (!mem) {
return APR_ENOSHMAVAIL;
}
ptr = mem->base;
+ inuse = ptr + (mem->size * mem->num);
SLOTMEM_LOCK(mem->smutex);
- for (i = 0; i < mem->num; i++) {
- ptr = ptr + mem->size;
- func((void *) ptr, data, pool);
+ for (i = 0; i < mem->num; i++, inuse++) {
+ if (*inuse) {
+ func((void *) ptr, data, pool);
+ }
+ ptr += mem->size;
}
SLOTMEM_UNLOCK(mem->smutex);
return APR_SUCCESS;
ap_slotmem_t *next = globallistmem;
const char *fname;
apr_shm_t *shm;
+ apr_size_t basesize = (item_size * item_num);
+ apr_size_t size = sizeof(struct sharedslotdesc) + (item_num * sizeof(char)) + basesize;
apr_status_t rv;
if (gpool == NULL)
}
if (rv == APR_SUCCESS) {
/* check size */
- if (apr_shm_size_get(shm) != item_size * item_num + sizeof(struct sharedslotdesc)) {
+ if (apr_shm_size_get(shm) != size) {
apr_shm_detach(shm);
return APR_EINVAL;
}
ptr = ptr + sizeof(desc);
}
else {
+ apr_size_t dsize = size - sizeof(struct sharedslotdesc);
SLOTMEM_LOCK(smutex);
if (name && name[0] != ':') {
apr_shm_remove(fname, gpool);
- rv = apr_shm_create(&shm, item_size * item_num + sizeof(struct sharedslotdesc), fname, gpool);
+ rv = apr_shm_create(&shm, size, fname, gpool);
}
else {
- rv = apr_shm_create(&shm, item_size * item_num + sizeof(struct sharedslotdesc), NULL, gpool);
+ rv = apr_shm_create(&shm, size, NULL, gpool);
}
SLOTMEM_UNLOCK(smutex);
if (rv != APR_SUCCESS) {
desc.item_num = item_num;
memcpy(ptr, &desc, sizeof(desc));
ptr = ptr + sizeof(desc);
- memset(ptr, 0, item_size * item_num);
+ memset(ptr, 0, dsize);
if (type == SLOTMEM_PERSIST)
- restore_slotmem(ptr, fname, item_size, item_num, pool);
+ restore_slotmem(ptr, fname, dsize, pool);
}
/* For the chained slotmem stuff */
res->gpool = gpool;
res->smutex = smutex;
res->next = NULL;
+ res->inuse = ptr + basesize;
if (globallistmem == NULL) {
globallistmem = res;
}
res->num = desc.item_num;
res->gpool = gpool;
res->smutex = smutex;
+ res->inuse = ptr + (desc.item_size * desc.item_num);
res->next = NULL;
if (globallistmem == NULL) {
globallistmem = res;
{
void *ptr;
+ char *inuse;
apr_status_t ret;
ret = slotmem_mem(slot, id, &ptr);
return ret;
}
memcpy(ptr, src, src_len); /* bounds check? */
+ /* We know the id fit it */
+ inuse = (slot->base + (slot->size * slot->num);
+ inuse[id] = 1;
return APR_SUCCESS;
}