You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2010/02/09 04:43:18 UTC
svn commit: r907917 - in /httpd/httpd/trunk: include/ap_mmn.h
include/ap_socache.h modules/cache/mod_socache_dbm.c
modules/cache/mod_socache_dc.c modules/cache/mod_socache_memcache.c
modules/cache/mod_socache_shmcb.c
Author: wrowe
Date: Tue Feb 9 03:43:18 2010
New Revision: 907917
URL: http://svn.apache.org/viewvc?rev=907917&view=rev
Log:
distcache already demonstrates sub-second resolutions, but much more
importantly, let us not introduce more Y2k38 bugs?
Changes the ->store method to take expiry as an apr_time_t, and introduce
a placeholder to implement provider-specific iterators of the current
elements of an socache store.
Cleans up confusion where expiry might be confused with a timeout-period.
Finally clean up some hUngarian noteAtion. Someones' hands need to be slapped.
Modified:
httpd/httpd/trunk/include/ap_mmn.h
httpd/httpd/trunk/include/ap_socache.h
httpd/httpd/trunk/modules/cache/mod_socache_dbm.c
httpd/httpd/trunk/modules/cache/mod_socache_dc.c
httpd/httpd/trunk/modules/cache/mod_socache_memcache.c
httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c
Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=907917&r1=907916&r2=907917&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Tue Feb 9 03:43:18 2010
@@ -214,15 +214,16 @@
* 20091230.2 (2.3.5-dev) add ap_get_server_name_for_url()
* 20091230.3 (2.3.6-dev) add ap_parse_log_level()
* 20091230.4 (2.3.6-dev) export ap_process_request_after_handler() for mod_serf
+ * 20100208.0 (2.3.6-dev) ap_socache_provider_t API changes to store and iterate
*
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20091230
+#define MODULE_MAGIC_NUMBER_MAJOR 20100208
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 4 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Modified: httpd/httpd/trunk/include/ap_socache.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_socache.h?rev=907917&r1=907916&r2=907917&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_socache.h (original)
+++ httpd/httpd/trunk/include/ap_socache.h Tue Feb 9 03:43:18 2010
@@ -29,6 +29,7 @@
#include "httpd.h"
#include "ap_provider.h"
#include "apr_pools.h"
+#include "apr_time.h"
#ifdef __cplusplus
extern "C" {
@@ -37,7 +38,10 @@
/** If this flag is set, the store/retrieve/remove/status interfaces
* of the provider are NOT safe to be called concurrently from
* multiple processes or threads, and an external global mutex must be
- * used to serialize access to the provider. */
+ * used to serialize access to the provider.
+ * XXX: Even if store/retrieve/remove is atomic, isn't it useful to note
+ * independently that status and iterate may or may not be?
+ */
#define AP_SOCACHE_FLAG_NOTMPSAFE (0x0001)
/** A cache instance. */
@@ -50,11 +54,31 @@
apr_size_t avg_id_len;
/** Approximate average size of objects: */
apr_size_t avg_obj_size;
- /** Interval (in seconds) after which an expiry run is
+ /** Interval after which an expiry run is
* necessary. */
- time_t expiry_interval;
+ apr_interval_time_t expiry_interval;
};
+/**
+ * Iterator callback prototype for the ap_socache_provider_t->iterate() method
+ * @param instance The cache instance (passed through)
+ * @param s Associated server structure (passed through)
+ * @param id Unique ID for the object; binary blob
+ * @param idlen Length of id blob
+ * @param data Output buffer to place retrievd data (binary blob)
+ * @param datalen Length of data buffer
+ * @param pool Pool for temporary allocations (passed through)
+ * @return APR status value; return APR_SUCCESS or the iteration will halt;
+ * this value is returned to the ap_socache_provider_t->iterate() caller
+ */
+typedef apr_status_t (*ap_socache_iterator_t)(ap_socache_instance_t *instance,
+ server_rec *s,
+ const unsigned char *id,
+ unsigned int idlen,
+ unsigned char *data,
+ unsigned int *datalen,
+ apr_pool_t *pool);
+
/** A socache provider structure. socache providers are registered
* with the ap_provider.h interface using the AP_SOCACHE_PROVIDER_*
* constants. */
@@ -121,7 +145,7 @@
*/
apr_status_t (*store)(ap_socache_instance_t *instance, server_rec *s,
const unsigned char *id, unsigned int idlen,
- time_t expiry,
+ apr_time_t expiry,
unsigned char *data, unsigned int datalen,
apr_pool_t *pool);
@@ -156,12 +180,28 @@
/** Dump the status of a cache instance for mod_status. Will use
* the ap_r* interfaces to produce appropriate status output.
+ * XXX: apr_r* are deprecated, bad dogfood
*
* @param instance The cache instance
* @param r The request structure
* @param flags The AP_STATUS_* constants used (see mod_status.h)
*/
void (*status)(ap_socache_instance_t *instance, request_rec *r, int flags);
+
+ /**
+ * Dump all cached objects through an iterator callback.
+ * @param instance The cache instance
+ * @param s Associated server structure (for logging purposes)
+ * @param iterator The user provided callback which will receive
+ * individual calls for each unexpired id/data pair
+ * @param pool Pool for temporary allocations.
+ * @return APR status value; APR_NOTFOUND if the object was not
+ * found
+ */
+ apr_status_t (*iterate)(ap_socache_instance_t *instance, server_rec *s,
+ ap_socache_iterator_t *iterator,
+ apr_pool_t *pool);
+
} ap_socache_provider_t;
/** The provider group used to register socache providers. */
Modified: httpd/httpd/trunk/modules/cache/mod_socache_dbm.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_socache_dbm.c?rev=907917&r1=907916&r2=907917&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_socache_dbm.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_socache_dbm.c Tue Feb 9 03:43:18 2010
@@ -44,8 +44,8 @@
const char *data_file;
/* Pool must only be used with the mutex held. */
apr_pool_t *pool;
- time_t last_expiry;
- time_t expiry_interval;
+ apr_time_t last_expiry;
+ apr_interval_time_t expiry_interval;
};
/**
@@ -136,7 +136,7 @@
apr_dbm_close(dbm);
ctx->expiry_interval = (hints && hints->expiry_interval
- ? hints->expiry_interval : 30);
+ ? hints->expiry_interval : apr_time_from_sec(30));
#if AP_NEED_SET_MUTEX_PERMS
/*
@@ -183,7 +183,7 @@
static apr_status_t socache_dbm_store(ap_socache_instance_t *ctx,
server_rec *s, const unsigned char *id,
- unsigned int idlen, time_t expiry,
+ unsigned int idlen, apr_time_t expiry,
unsigned char *ucaData,
unsigned int nData, apr_pool_t *pool)
{
@@ -196,14 +196,14 @@
#ifdef PAIRMAX
if ((idlen + nData) >= PAIRMAX) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "data size too large for DBM session cache: %d >= %d",
+ "data size too large for DBM socache: %d >= %d",
(idlen + nData), PAIRMAX);
return APR_ENOSPC;
}
#else
if ((idlen + nData) >= 950 /* at least less than approx. 1KB */) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "data size too large for DBM session cache: %d >= %d",
+ "data size too large for DBM socache: %d >= %d",
(idlen + nData), 950);
return APR_ENOSPC;
}
@@ -214,15 +214,15 @@
dbmkey.dsize = idlen;
/* create DBM value */
- dbmval.dsize = sizeof(time_t) + nData;
+ dbmval.dsize = sizeof(apr_time_t) + nData;
dbmval.dptr = (char *)malloc(dbmval.dsize);
if (dbmval.dptr == NULL) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"malloc error creating DBM value");
return APR_ENOMEM;
}
- memcpy((char *)dbmval.dptr, &expiry, sizeof(time_t));
- memcpy((char *)dbmval.dptr+sizeof(time_t), ucaData, nData);
+ memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t));
+ memcpy((char *)dbmval.dptr+sizeof(apr_time_t), ucaData, nData);
/* and store it to the DBM file */
apr_pool_clear(ctx->pool);
@@ -264,8 +264,8 @@
apr_datum_t dbmkey;
apr_datum_t dbmval;
unsigned int nData;
- time_t expiry;
- time_t now;
+ apr_time_t expiry;
+ apr_time_t now;
apr_status_t rc;
/* allow the regular expiring to occur */
@@ -293,26 +293,26 @@
apr_dbm_close(dbm);
return rc;
}
- if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) {
+ if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) {
apr_dbm_close(dbm);
return APR_EGENERAL;
}
/* parse resulting data */
- nData = dbmval.dsize-sizeof(time_t);
+ nData = dbmval.dsize-sizeof(apr_time_t);
if (nData > *destlen) {
apr_dbm_close(dbm);
return APR_ENOSPC;
}
*destlen = nData;
- memcpy(&expiry, dbmval.dptr, sizeof(time_t));
- memcpy(dest, (char *)dbmval.dptr + sizeof(time_t), nData);
+ memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
+ memcpy(dest, (char *)dbmval.dptr + sizeof(apr_time_t), nData);
apr_dbm_close(dbm);
/* make sure the stuff is still not expired */
- now = time(NULL);
+ now = apr_time_now();
if (expiry <= now) {
socache_dbm_remove(ctx, s, id, idlen, p);
return APR_NOTFOUND;
@@ -355,27 +355,27 @@
apr_dbm_t *dbm;
apr_datum_t dbmkey;
apr_datum_t dbmval;
- time_t tExpiresAt;
- int nElements = 0;
- int nDeleted = 0;
- int bDelete;
+ apr_time_t expiry;
+ int elts = 0;
+ int deleted = 0;
+ int expired;
apr_datum_t *keylist;
int keyidx;
int i;
- time_t tNow;
+ apr_time_t now;
apr_status_t rv;
/*
- * make sure the expiration for still not-accessed session
- * cache entries is done only from time to time
+ * make sure the expiration for still not-accessed
+ * socache entries is done only from time to time
*/
- tNow = time(NULL);
+ now = time(NULL);
- if (tNow < ctx->last_expiry + ctx->expiry_interval) {
+ if (now < ctx->last_expiry + ctx->expiry_interval) {
return;
}
- ctx->last_expiry = tNow;
+ ctx->last_expiry = now;
/*
* Here we have to be very carefully: Not all DBM libraries are
@@ -410,17 +410,17 @@
}
apr_dbm_firstkey(dbm, &dbmkey);
while (dbmkey.dptr != NULL) {
- nElements++;
- bDelete = FALSE;
+ elts++;
+ expired = FALSE;
apr_dbm_fetch(dbm, dbmkey, &dbmval);
- if (dbmval.dsize <= sizeof(time_t) || dbmval.dptr == NULL)
- bDelete = TRUE;
+ if (dbmval.dsize <= sizeof(apr_time_t) || dbmval.dptr == NULL)
+ expired = TRUE;
else {
- memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t));
- if (tExpiresAt <= tNow)
- bDelete = TRUE;
+ memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
+ if (expiry <= now)
+ expired = TRUE;
}
- if (bDelete) {
+ if (expired) {
if ((keylist[keyidx].dptr = apr_pmemdup(ctx->pool, dbmkey.dptr, dbmkey.dsize)) != NULL) {
keylist[keyidx].dsize = dbmkey.dsize;
keyidx++;
@@ -443,7 +443,7 @@
}
for (i = 0; i < keyidx; i++) {
apr_dbm_delete(dbm, keylist[i]);
- nDeleted++;
+ deleted++;
}
apr_dbm_close(dbm);
@@ -454,7 +454,7 @@
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"Inter-Process Session Cache (DBM) Expiry: "
"old: %d, new: %d, removed: %d",
- nElements, nElements-nDeleted, nDeleted);
+ elts, elts-deleted, deleted);
}
static void socache_dbm_status(ap_socache_instance_t *ctx, request_rec *r,
@@ -463,13 +463,13 @@
apr_dbm_t *dbm;
apr_datum_t dbmkey;
apr_datum_t dbmval;
- int nElem;
- int nSize;
- int nAverage;
+ int elts;
+ long size;
+ int avg;
apr_status_t rv;
- nElem = 0;
- nSize = 0;
+ elts = 0;
+ size = 0;
apr_pool_clear(ctx->pool);
if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
@@ -488,20 +488,28 @@
apr_dbm_fetch(dbm, dbmkey, &dbmval);
if (dbmval.dptr == NULL)
continue;
- nElem += 1;
- nSize += dbmval.dsize;
+ elts += 1;
+ size += dbmval.dsize;
}
apr_dbm_close(dbm);
- if (nSize > 0 && nElem > 0)
- nAverage = nSize / nElem;
+ if (size > 0 && elts > 0)
+ avg = (int)(size / (long)elts);
else
- nAverage = 0;
+ avg = 0;
ap_rprintf(r, "cache type: <b>DBM</b>, maximum size: <b>unlimited</b><br>");
- ap_rprintf(r, "current sessions: <b>%d</b>, current size: <b>%d</b> bytes<br>", nElem, nSize);
- ap_rprintf(r, "average session size: <b>%d</b> bytes<br>", nAverage);
+ ap_rprintf(r, "current entries: <b>%d</b>, current size: <b>%ld</b> bytes<br>", elts, size);
+ ap_rprintf(r, "average entry size: <b>%d</b> bytes<br>", avg);
return;
}
+apr_status_t socache_dbm_iterate(ap_socache_instance_t *instance,
+ server_rec *s,
+ ap_socache_iterator_t *iterator,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
static const ap_socache_provider_t socache_dbm = {
"dbm",
AP_SOCACHE_FLAG_NOTMPSAFE,
@@ -511,7 +519,8 @@
socache_dbm_store,
socache_dbm_retrieve,
socache_dbm_remove,
- socache_dbm_status
+ socache_dbm_status,
+ socache_dbm_iterate
};
static void register_hooks(apr_pool_t *p)
Modified: httpd/httpd/trunk/modules/cache/mod_socache_dc.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_socache_dc.c?rev=907917&r1=907916&r2=907917&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_socache_dc.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_socache_dc.c Tue Feb 9 03:43:18 2010
@@ -92,15 +92,18 @@
static apr_status_t socache_dc_store(ap_socache_instance_t *ctx, server_rec *s,
const unsigned char *id, unsigned int idlen,
- time_t timeout,
+ time_t expiry,
unsigned char *der, unsigned int der_len,
apr_pool_t *p)
{
- /* !@#$%^ - why do we deal with *absolute* time anyway??? */
- timeout -= time(NULL);
+ /* !@#$%^ - why do we deal with *absolute* time anyway???
+ * Uhm - because most things expire things at a specific time?
+ * Were the API were thought out expiry - r->request_time is a good approximation
+ */
+ expiry -= apr_time_t(NULL);
/* Send the serialised session to the distributed cache context */
if (!DC_CTX_add_session(ctx->dc, id, idlen, der, der_len,
- (unsigned long)timeout * 1000)) {
+ apr_time_in_msec(expiry)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'add_session' failed");
return APR_EGENERAL;
}
@@ -151,6 +154,14 @@
" target: <b>%s</b><br>", ctx->target);
}
+apr_status_t socache_dc_iterate(ap_socache_instance_t *instance,
+ server_rec *s,
+ ap_socache_iterator_t *iterator,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
static const ap_socache_provider_t socache_dc = {
"distcache",
0,
@@ -160,7 +171,8 @@
socache_dc_store,
socache_dc_retrieve,
socache_dc_remove,
- socache_dc_status
+ socache_dc_status,
+ socache_dc_iterate
};
static void register_hooks(apr_pool_t *p)
Modified: httpd/httpd/trunk/modules/cache/mod_socache_memcache.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_socache_memcache.c?rev=907917&r1=907916&r2=907917&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_socache_memcache.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_socache_memcache.c Tue Feb 9 03:43:18 2010
@@ -200,7 +200,7 @@
static apr_status_t socache_mc_store(ap_socache_instance_t *ctx, server_rec *s,
const unsigned char *id, unsigned int idlen,
- time_t timeout,
+ apr_time_t expiry,
unsigned char *ucaData, unsigned int nData,
apr_pool_t *p)
{
@@ -211,7 +211,8 @@
return APR_EINVAL;
}
- rv = apr_memcache_set(ctx->mc, buf, (char*)ucaData, nData, timeout, 0);
+ /* In APR-util - unclear what 'timeout' is, as it was not implemented */
+ rv = apr_memcache_set(ctx->mc, buf, (char*)ucaData, nData, 0, 0);
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
@@ -286,6 +287,14 @@
/* TODO: Make a mod_status handler. meh. */
}
+apr_status_t socache_mc_iterate(ap_socache_instance_t *instance,
+ server_rec *s,
+ ap_socache_iterator_t *iterator,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
static const ap_socache_provider_t socache_mc = {
"memcache",
0,
@@ -295,7 +304,8 @@
socache_mc_store,
socache_mc_retrieve,
socache_mc_remove,
- socache_mc_status
+ socache_mc_status,
+ socache_mc_iterate
};
#endif /* HAVE_APU_MEMCACHE */
Modified: httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c?rev=907917&r1=907916&r2=907917&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c Tue Feb 9 03:43:18 2010
@@ -80,14 +80,14 @@
*/
typedef struct {
/* absolute time this entry expires */
- time_t expires;
+ apr_time_t expires;
/* location within the subcache's data area */
unsigned int data_pos;
/* size (most logic ignores this, we keep it only to minimise memcpy) */
unsigned int data_used;
/* length of the used data which contains the id */
unsigned int id_len;
- /* Used to mark explicitly-removed sessions */
+ /* Used to mark explicitly-removed socache entries */
unsigned char removed;
} SHMCBIndex;
@@ -147,7 +147,7 @@
sizeof(SHMCBHeader) + \
(num) * ((pHeader)->subcache_size))
-/* This macro takes a pointer to the header and a session id and returns a
+/* This macro takes a pointer to the header and an id and returns a
* pointer to the corresponding subcache. */
#define SHMCB_MASK(pHeader, id) \
SHMCB_SUBCACHE((pHeader), *(id) & ((pHeader)->subcache_num - 1))
@@ -239,13 +239,14 @@
/* Prototypes for low-level subcache operations */
-static void shmcb_subcache_expire(server_rec *, SHMCBHeader *, SHMCBSubcache *);
+static void shmcb_subcache_expire(server_rec *, SHMCBHeader *, SHMCBSubcache *,
+ apr_time_t);
/* Returns zero on success, non-zero on failure. */
static int shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
SHMCBSubcache *subcache,
unsigned char *data, unsigned int data_len,
const unsigned char *id, unsigned int id_len,
- time_t expiry);
+ apr_time_t expiry);
/* Returns zero on success, non-zero on failure. */
static int shmcb_subcache_retrieve(server_rec *, SHMCBHeader *, SHMCBSubcache *,
const unsigned char *id, unsigned int idlen,
@@ -437,7 +438,7 @@
subcache->data_pos = subcache->data_used = 0;
}
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Shared memory session cache initialised");
+ "Shared memory socache initialised");
/* Success ... */
return APR_SUCCESS;
@@ -453,7 +454,7 @@
static apr_status_t socache_shmcb_store(ap_socache_instance_t *ctx,
server_rec *s, const unsigned char *id,
- unsigned int idlen, time_t timeout,
+ unsigned int idlen, apr_time_t expiry,
unsigned char *encoded,
unsigned int len_encoded,
apr_pool_t *p)
@@ -464,15 +465,16 @@
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"socache_shmcb_store (0x%02x -> subcache %d)",
SHMCB_MASK_DBG(header, id));
+ /* XXX: Says who? Why shouldn't this be acceptable, or padded if not? */
if (idlen < 4) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short id provided "
"(%u bytes)", idlen);
return APR_EINVAL;
}
if (shmcb_subcache_store(s, header, subcache, encoded,
- len_encoded, id, idlen, timeout)) {
+ len_encoded, id, idlen, expiry)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "can't store a session!");
+ "can't store an socache entry!");
return APR_ENOSPC;
}
header->stat_stores++;
@@ -495,7 +497,7 @@
"socache_shmcb_retrieve (0x%02x -> subcache %d)",
SHMCB_MASK_DBG(header, id));
- /* Get the session corresponding to the session_id, if it exists. */
+ /* Get the entry corresponding to the id, if it exists. */
rv = shmcb_subcache_retrieve(s, header, subcache, id, idlen,
dest, destlen);
if (rv == 0)
@@ -520,7 +522,7 @@
"socache_shmcb_remove (0x%02x -> subcache %d)",
SHMCB_MASK_DBG(header, id));
if (idlen < 4) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short id provided "
"(%u bytes)", idlen);
return APR_EINVAL;
}
@@ -543,8 +545,8 @@
server_rec *s = r->server;
SHMCBHeader *header = ctx->header;
unsigned int loop, total = 0, cache_total = 0, non_empty_subcaches = 0;
- time_t idx_expiry, min_expiry = 0, max_expiry = 0, average_expiry = 0;
- time_t now = time(NULL);
+ apr_time_t idx_expiry, min_expiry = 0, max_expiry = 0, average_expiry = 0;
+ apr_time_t now = apr_time_now();
double expiry_total = 0;
int index_pct, cache_pct;
@@ -555,7 +557,7 @@
/* Iterate over the subcaches */
for (loop = 0; loop < header->subcache_num; loop++) {
SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
- shmcb_subcache_expire(s, header, subcache);
+ shmcb_subcache_expire(s, header, subcache, now);
total += subcache->idx_used;
cache_total += subcache->data_used;
if (subcache->idx_used) {
@@ -576,29 +578,29 @@
header->subcache_num);
/* Generate HTML */
ap_rprintf(r, "cache type: <b>SHMCB</b>, shared memory: <b>%" APR_SIZE_T_FMT "</b> "
- "bytes, current sessions: <b>%d</b><br>",
+ "bytes, current entries: <b>%d</b><br>",
ctx->shm_size, total);
ap_rprintf(r, "subcaches: <b>%d</b>, indexes per subcache: <b>%d</b><br>",
header->subcache_num, header->index_num);
if (non_empty_subcaches) {
- average_expiry = (time_t)(expiry_total / (double)non_empty_subcaches);
+ average_expiry = (apr_time_t)(expiry_total / (double)non_empty_subcaches);
ap_rprintf(r, "time left on oldest entries' objects: ");
if (now < average_expiry)
ap_rprintf(r, "avg: <b>%d</b> seconds, (range: %d...%d)<br>",
- (int)(average_expiry - now),
- (int)(min_expiry - now),
- (int)(max_expiry - now));
+ (int)apr_time_sec(average_expiry - now),
+ (int)apr_time_sec(min_expiry - now),
+ (int)apr_time_sec(max_expiry - now));
else
ap_rprintf(r, "expiry_threshold: <b>Calculation error!</b><br>");
}
ap_rprintf(r, "index usage: <b>%d%%</b>, cache usage: <b>%d%%</b><br>",
index_pct, cache_pct);
- ap_rprintf(r, "total sessions stored since starting: <b>%lu</b><br>",
+ ap_rprintf(r, "total entries stored since starting: <b>%lu</b><br>",
header->stat_stores);
- ap_rprintf(r, "total sessions expired since starting: <b>%lu</b><br>",
+ ap_rprintf(r, "total entries expired since starting: <b>%lu</b><br>",
header->stat_expiries);
- ap_rprintf(r, "total (pre-expiry) sessions scrolled out of the cache: "
+ ap_rprintf(r, "total (pre-expiry) entries scrolled out of the cache: "
"<b>%lu</b><br>", header->stat_scrolled);
ap_rprintf(r, "total retrieves since starting: <b>%lu</b> hit, "
"<b>%lu</b> miss<br>", header->stat_retrieves_hit,
@@ -614,9 +616,8 @@
*/
static void shmcb_subcache_expire(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache)
+ SHMCBSubcache *subcache, apr_time_t now)
{
- time_t now = time(NULL);
unsigned int loop = 0;
unsigned int new_idx_pos = subcache->idx_pos;
SHMCBIndex *idx = NULL;
@@ -633,7 +634,7 @@
/* Nothing to do */
return;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "will be expiring %u sessions", loop);
+ "will be expiring %u socache entries", loop);
if (loop == subcache->idx_used) {
/* We're expiring everything, piece of cake */
subcache->idx_used = 0;
@@ -652,14 +653,56 @@
}
header->stat_expiries += loop;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "we now have %u sessions", subcache->idx_used);
+ "we now have %u socache entries", subcache->idx_used);
+}
+
+static void shmcb_subcache_iterate(server_rec *s, SHMCBHeader *header,
+ SHMCBSubcache *subcache)
+{
+ apr_time_t now = apr_time_now();
+ unsigned int loop = 0;
+ unsigned int new_idx_pos = subcache->idx_pos;
+ SHMCBIndex *idx = NULL;
+
+ while (loop < subcache->idx_used) {
+ idx = SHMCB_INDEX(subcache, new_idx_pos);
+ if (idx->expires > now)
+ /* it hasn't expired yet, we're done iterating */
+ break;
+ loop++;
+ new_idx_pos = SHMCB_CYCLIC_INCREMENT(new_idx_pos, 1, header->index_num);
+ }
+ if (!loop)
+ /* Nothing to do */
+ return;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "will be expiring %u socache entries", loop);
+ if (loop == subcache->idx_used) {
+ /* We're expiring everything, piece of cake */
+ subcache->idx_used = 0;
+ subcache->data_used = 0;
+ } else {
+ /* There remain other indexes, so we can use idx to adjust 'data' */
+ unsigned int diff = SHMCB_CYCLIC_SPACE(subcache->data_pos,
+ idx->data_pos,
+ header->subcache_data_size);
+ /* Adjust the indexes */
+ subcache->idx_used -= loop;
+ subcache->idx_pos = new_idx_pos;
+ /* Adjust the data area */
+ subcache->data_used -= diff;
+ subcache->data_pos = idx->data_pos;
+ }
+ header->stat_expiries += loop;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "we now have %u socache entries", subcache->idx_used);
}
static int shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
SHMCBSubcache *subcache,
unsigned char *data, unsigned int data_len,
const unsigned char *id, unsigned int id_len,
- time_t expiry)
+ apr_time_t expiry)
{
unsigned int data_offset, new_idx, id_offset;
SHMCBIndex *idx;
@@ -668,13 +711,13 @@
/* Sanity check the input */
if (total_len > header->subcache_data_size) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "inserting session larger (%d) than subcache data area (%d)",
+ "inserting socache entry larger (%d) than subcache data area (%d)",
total_len, header->subcache_data_size);
return -1;
}
/* If there are entries to expire, ditch them first. */
- shmcb_subcache_expire(s, header, subcache);
+ shmcb_subcache_expire(s, header, subcache, apr_time_now());
/* Loop until there is enough space to insert */
if (header->subcache_data_size - subcache->data_used < total_len
@@ -718,11 +761,15 @@
* CHECKING WHETHER IT SHOULD BE GENUINELY "INSERTED" SOMEWHERE.
*
* We either fix that, or find out at a "higher" (read "mod_ssl")
- * level whether it is possible to have distinct session caches for
- * any attempted tomfoolery to do with different session timeouts.
- * Knowing in advance that we can have a cache-wide constant timeout
+ * level whether it is possible to have distinct socaches for
+ * any attempted tomfoolery to do with different socache entry expirys.
+ * Knowing in advance that we can have a cache-wide constant expiry
* would make this stuff *MUCH* more efficient. Mind you, it's very
* efficient right now because I'm ignoring this problem!!!
+ *
+ * XXX: Author didn't consider that httpd doesn't promise to perform
+ * any processing in date order (c.f. FAQ "My log entries are not in
+ * date order!")
*/
/* Insert the id */
id_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
@@ -767,8 +814,11 @@
unsigned int pos;
unsigned int loop = 0;
- /* If there are entries to expire, ditch them first. */
- shmcb_subcache_expire(s, header, subcache);
+ /* If there are entries to expire, ditch them first.
+ * XXX: Horribly inefficient to double the work, why not simply
+ * upon store when free space might be useful?
+ */
+ shmcb_subcache_expire(s, header, subcache, apr_time_now());
pos = subcache->idx_pos;
while (loop < subcache->idx_used) {
@@ -823,7 +873,7 @@
* consistent statistics where a "remove" operation may actually be the
* higher layer spotting an expiry issue prior to us. Our caller is
* handling stats, so a failure return would be inconsistent if the
- * intended session was in fact removed by an expiry run. */
+ * intended socache entry was in fact removed by an expiry run. */
pos = subcache->idx_pos;
while (loop < subcache->idx_used) {
@@ -837,10 +887,10 @@
idx->data_pos, id, idx->id_len) == 0) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"possible match at idx=%d, data=%d", pos, idx->data_pos);
- /* Found the matching session, remove it quietly. */
+ /* Found the matching entry, remove it quietly. */
idx->removed = 1;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_subcache_remove removing matching session");
+ "shmcb_subcache_remove removing matching entry");
return 0;
}
/* Increment */
@@ -851,6 +901,14 @@
return -1; /* failure */
}
+apr_status_t socache_shmcb_iterate(ap_socache_instance_t *instance,
+ server_rec *s,
+ ap_socache_iterator_t *iterator,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
static const ap_socache_provider_t socache_shmcb = {
"shmcb",
AP_SOCACHE_FLAG_NOTMPSAFE,
@@ -860,7 +918,8 @@
socache_shmcb_store,
socache_shmcb_retrieve,
socache_shmcb_remove,
- socache_shmcb_status
+ socache_shmcb_status,
+ socache_shmcb_iterate
};
static void register_hooks(apr_pool_t *p)
Re: svn commit: r907917 - in /httpd/httpd/trunk: include/ap_mmn.h
include/ap_socache.h modules/cache/mod_socache_dbm.c
modules/cache/mod_socache_dc.c modules/cache/mod_socache_memcache.c
modules/cache/mod_socache_shmcb.c
Posted by Joe Orton <jo...@redhat.com>.
On Tue, Feb 09, 2010 at 03:43:18AM -0000, William Rowe wrote:
> Author: wrowe
> Date: Tue Feb 9 03:43:18 2010
> New Revision: 907917
>
> URL: http://svn.apache.org/viewvc?rev=907917&view=rev
> Log:
> distcache already demonstrates sub-second resolutions, but much more
> importantly, let us not introduce more Y2k38 bugs?
>
> Changes the ->store method to take expiry as an apr_time_t, and introduce
> a placeholder to implement provider-specific iterators of the current
> elements of an socache store.
>
> Cleans up confusion where expiry might be confused with a timeout-period.
Thanks Bill!
> Finally clean up some hUngarian noteAtion. Someones' hands need to be slapped.
It's all Ben's fault, he started it :)
One minor comment:
> @@ -156,12 +180,28 @@
>
> /** Dump the status of a cache instance for mod_status. Will use
> * the ap_r* interfaces to produce appropriate status output.
> + * XXX: apr_r* are deprecated, bad dogfood
$ grep -i deprecated http_protocol.h
$
No they aren't ;) ... and I don't think they should be either, they are
fine interfaces which have worked forever.
joe