* @return number of slots
*/
unsigned int (* num_slots)(ap_slotmem_instance_t *s);
+ /**
+ * return number of free (not used) slots allocated for this entry.
+ * Valid for slots which are AP_SLOTMEM_TYPE_PREGRAB as well as
+ * any which use get/release.
+ * @param s ap_slotmem_instance_t to use.
+ * @return number of slots
+ */
+ unsigned int (* num_free_slots)(ap_slotmem_instance_t *s);
/**
* return slot size allocated for this entry.
* @param s ap_slotmem_instance_t to use.
if (ret != APR_SUCCESS) {
return ret;
}
+ *inuse=1;
memcpy(dest, ptr, dest_len); /* bounds check? */
return APR_SUCCESS;
}
if (ret != APR_SUCCESS) {
return ret;
}
+ *inuse=1;
memcpy(ptr, src, src_len); /* bounds check? */
return APR_SUCCESS;
}
return slot->num;
}
+static unsigned int slotmem_num_free_slots(ap_slotmem_instance_t *slot)
+{
+ unsigned int i, counter=0;
+ char *inuse = slot->inuse;
+ for (i=0; i<desc.num; i++, inuse++) {
+ if (!*inuse)
+ counter++;
+ }
+ return counter;
+}
+
static apr_size_t slotmem_slot_size(ap_slotmem_instance_t *slot)
{
return slot->size;
&slotmem_get,
&slotmem_put,
&slotmem_num_slots,
+ &slotmem_num_free_slots
&slotmem_slot_size,
&slotmem_grab,
&slotmem_release
typedef struct {
apr_size_t size; /* size of each memory slot */
unsigned int num; /* number of mem slots */
+ unsigned int free; /* number of free mem slots */
ap_slotmem_type_t type; /* type-specific flags */
} sharedslotdesc_t;
apr_status_t rv;
storename = store_filename(pool, name);
-
+
if (storename) {
rv = apr_file_open(&fp, storename, APR_READ | APR_WRITE, APR_OS_DEFAULT,
pool);
}
ptr = (char *)apr_shm_baseaddr_get(shm);
desc.size = item_size;
- desc.num = item_num;
+ desc.free = desc.num = item_num;
desc.type = type;
memcpy(ptr, &desc, sizeof(desc));
ptr = ptr + AP_SLOTMEM_OFFSET;
* TODO: Error check the below... What error makes
* sense if the restore fails? Any?
*/
- if (type & AP_SLOTMEM_TYPE_PERSIST)
+ if (type & AP_SLOTMEM_TYPE_PERSIST) {
+ unsigned int i, counter=0;
+ char *inuse = ptr + basesize;
restore_slotmem(ptr, fname, dsize, pool);
+ for (i=0; i<desc.num; i++, inuse++)
+ if (!*inuse)
+ counter++;
+ desc.free = counter;
+ }
}
/* For the chained slotmem stuff */
if (ret != APR_SUCCESS) {
return ret;
}
+ *inuse = 1;
memcpy(dest, ptr, dest_len); /* bounds check? */
return APR_SUCCESS;
}
if (ret != APR_SUCCESS) {
return ret;
}
+ *inuse=1;
memcpy(ptr, src, src_len); /* bounds check? */
return APR_SUCCESS;
}
return slot->desc.num;
}
+static unsigned int slotmem_num_free_slots(ap_slotmem_instance_t *slot)
+{
+ if (AP_SLOTMEM_IS_PREGRAB(slot))
+ return slot->desc.free;
+ else {
+ unsigned int i, counter=0;
+ char *inuse = slot->inuse;
+ for (i=0; i<slot->desc.num; i++, inuse++) {
+ if (!*inuse)
+ counter++;
+ }
+ return counter;
+ }
+}
+
static apr_size_t slotmem_slot_size(ap_slotmem_instance_t *slot)
{
return slot->desc.size;
}
-/*
- * XXXX: if !AP_SLOTMEM_IS_PREGRAB, then still worry about
- * inuse for grab and return?
- */
static apr_status_t slotmem_grab(ap_slotmem_instance_t *slot, unsigned int *id)
{
unsigned int i;
}
*inuse = 1;
*id = i;
+ slot->desc.free--;
return APR_SUCCESS;
}
return APR_NOTFOUND;
}
inuse[id] = 0;
+ slot->desc.free++;
return APR_SUCCESS;
}
&slotmem_get,
&slotmem_put,
&slotmem_num_slots,
+ &slotmem_num_free_slots,
&slotmem_slot_size,
&slotmem_grab,
&slotmem_release