diff options
author | Joe Orton <jorton@apache.org> | 2008-04-08 15:47:48 +0000 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2008-04-08 15:47:48 +0000 |
commit | 2e2731f3f9ec93ee7b7863d8983cb5193900157f (patch) | |
tree | 16067f77df9d472b3d6670b5fbb2a344dbb47c23 | |
parent | ed2ab3d8e6fd7b87424ff8afc2eeeaa382511d6c (diff) | |
download | httpd-2e2731f3f9ec93ee7b7863d8983cb5193900157f.tar.gz |
Adjust socache init interface to take sizing hints, and namespace tag
for memcache:
* modules/cache/ap_socache.h (struct ap_socache_hints): New structure.
Change init callback to take namespace string and hints structure pointer.
* modules/cache/mod_socache_dc.c (socache_dc_init): Adjust accordingly.
* modules/cache/mod_socache_dbm.c (struct ap_socache_instance_t): Rename
timeout field to expiry_interval.
(socache_dbm_init, socache_dbm_create): Take expiry interval from
hints rather than hard-code to 30.
(socache_dbm_expire): Update for timeout field rename.
* modules/cache/mod_socache_shmcb.c (socache_shmcb_init): Adjust for
hints and namespace; adjust subcache index sizing heuristics to use
passed-in hints.
* modules/cache/mod_socache_memcache.c (struct ap_socache_instance_t):
Add tag, taglen fields.
(socache_mc_init): Store the passed-in namespace in instance
structure.
(mc_session_id2sz): Adjust to not take context, use configured
tag as string prefix, and not use a return value.
(socache_mc_store, socache_mc_retrieve, socache_mc_remove):
Adjust for mc_session_id2sz interface changes.
* modules/ssl/ssl_scache.c (ssl_scache_init): Pass namespace and hints
to socache provider init function.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@645978 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | modules/cache/ap_socache.h | 19 | ||||
-rw-r--r-- | modules/cache/mod_socache_dbm.c | 11 | ||||
-rw-r--r-- | modules/cache/mod_socache_dc.c | 5 | ||||
-rw-r--r-- | modules/cache/mod_socache_memcache.c | 55 | ||||
-rw-r--r-- | modules/cache/mod_socache_shmcb.c | 17 | ||||
-rw-r--r-- | modules/ssl/ssl_scache.c | 8 |
6 files changed, 63 insertions, 52 deletions
diff --git a/modules/cache/ap_socache.h b/modules/cache/ap_socache.h index 7f263903b1..c72790d839 100644 --- a/modules/cache/ap_socache.h +++ b/modules/cache/ap_socache.h @@ -39,6 +39,18 @@ /* A cache instance. */ typedef struct ap_socache_instance_t ap_socache_instance_t; +/* Hints which may be passed to the init function; providers may + * ignore some or all of these hints. */ +struct ap_socache_hints { + /* Approximate average length of IDs: */ + 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 + * necessary. */ + time_t expiry_interval; +}; + typedef struct ap_socache_provider_t { /* Canonical provider name: */ const char *name; @@ -56,8 +68,11 @@ typedef struct ap_socache_provider_t { * first argument to subsequent invocations. */ const char *(*create)(ap_socache_instance_t **instance, const char *arg, apr_pool_t *tmp, apr_pool_t *p); - /* Initialize the cache. Return APR error code. */ - apr_status_t (*init)(ap_socache_instance_t *instance, /* hints, namespace */ + /* Initialize the cache. NAMESPACE must given a unique string + * prefix for use with memcached; if hints is non-NULL, it gives a + * set of hints for the provider. Return APR error code. */ + apr_status_t (*init)(ap_socache_instance_t *instance, const char *namespace, + const struct ap_socache_hints *hints, server_rec *s, apr_pool_t *pool); /* Destroy a given cache context. */ void (*destroy)(ap_socache_instance_t *instance, server_rec *s); diff --git a/modules/cache/mod_socache_dbm.c b/modules/cache/mod_socache_dbm.c index 0228c96f29..dfc1194a59 100644 --- a/modules/cache/mod_socache_dbm.c +++ b/modules/cache/mod_socache_dbm.c @@ -41,7 +41,7 @@ struct ap_socache_instance_t { /* Pool must only be used with the mutex held. */ apr_pool_t *pool; time_t last_expiry; - time_t timeout; + time_t expiry_interval; }; /** @@ -81,13 +81,15 @@ static const char *socache_dbm_create(ap_socache_instance_t **context, if (!ctx->data_file) { return apr_psprintf(tmp, "Invalid cache file path %s", arg); } - ctx->timeout = 30; /* ### take as hint in _init */ + apr_pool_create(&ctx->pool, p); return NULL; } static apr_status_t socache_dbm_init(ap_socache_instance_t *ctx, + const char *namespace, + const struct ap_socache_hints *hints, server_rec *s, apr_pool_t *p) { apr_dbm_t *dbm; @@ -112,6 +114,9 @@ static apr_status_t socache_dbm_init(ap_socache_instance_t *ctx, } apr_dbm_close(dbm); + ctx->expiry_interval = (hints && hints->expiry_interval + ? hints->expiry_interval : 30); + #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) /* * We have to make sure the Apache child processes have access to @@ -345,7 +350,7 @@ static void socache_dbm_expire(ap_socache_instance_t *ctx, server_rec *s) */ tNow = time(NULL); - if (tNow < ctx->last_expiry + ctx->timeout) { + if (tNow < ctx->last_expiry + ctx->expiry_interval) { return; } diff --git a/modules/cache/mod_socache_dc.c b/modules/cache/mod_socache_dc.c index b2c2e0abb0..c77da78d13 100644 --- a/modules/cache/mod_socache_dc.c +++ b/modules/cache/mod_socache_dc.c @@ -51,7 +51,10 @@ static const char *socache_dc_create(ap_socache_instance_t **context, return NULL; } -static apr_status_t socache_dc_init(ap_socache_instance_t *ctx, server_rec *s, apr_pool_t *p) +static apr_status_t socache_dc_init(ap_socache_instance_t *ctx, + const char *namespace, + const struct ap_socache_hints *hints, + server_rec *s, apr_pool_t *p) { #if 0 /* If a "persistent connection" mode of operation is preferred, you *must* diff --git a/modules/cache/mod_socache_memcache.c b/modules/cache/mod_socache_memcache.c index 2acf6f7200..2cea41c124 100644 --- a/modules/cache/mod_socache_memcache.c +++ b/modules/cache/mod_socache_memcache.c @@ -35,10 +35,6 @@ #include "apr_memcache.h" /* The underlying apr_memcache system is thread safe.. */ -#define MC_TAG "mod_ssl:" -#define MC_TAG_LEN \ - (sizeof(MC_TAG)) - #define MC_KEY_LEN 254 #ifndef MC_DEFAULT_SERVER_PORT @@ -61,6 +57,8 @@ struct ap_socache_instance_t { const char *servers; apr_memcache_t *mc; + const char *tag; + apr_size_t taglen; }; static const char *socache_mc_create(ap_socache_instance_t **context, @@ -77,6 +75,8 @@ static const char *socache_mc_create(ap_socache_instance_t **context, } static apr_status_t socache_mc_init(ap_socache_instance_t *ctx, + const char *namespace, + const struct ap_socache_hints *hints, server_rec *s, apr_pool_t *p) { apr_status_t rv; @@ -156,6 +156,9 @@ static apr_status_t socache_mc_init(ap_socache_instance_t *ctx, split = apr_strtok(NULL,",", &tok); } + ctx->tag = apr_pstrcat(p, namespace, ":", NULL); + ctx->taglen = strlen(ctx->tag); + return APR_SUCCESS; } @@ -164,22 +167,21 @@ static void socache_mc_kill(ap_socache_instance_t *context, server_rec *s) /* noop. */ } -static char *mc_session_id2sz(const unsigned char *id, unsigned int idlen, - char *str, int strsize) +static void mc_session_id2sz(ap_socache_instance_t *ctx, + const unsigned char *id, unsigned int idlen, + char *buf, apr_size_t buflen) { + apr_size_t maxlen = (buflen - ctx->taglen) / 2; char *cp; int n; - int maxlen = (strsize - MC_TAG_LEN)/2; - cp = apr_cpystrn(str, MC_TAG, MC_TAG_LEN); + cp = apr_cpystrn(buf, ctx->tag, ctx->taglen); for (n = 0; n < idlen && n < maxlen; n++) { apr_snprintf(cp, 3, "%02X", (unsigned) id[n]); cp += 2; } *cp = '\0'; - - return str; } static apr_status_t socache_mc_store(ap_socache_instance_t *ctx, server_rec *s, @@ -188,21 +190,16 @@ static apr_status_t socache_mc_store(ap_socache_instance_t *ctx, server_rec *s, unsigned char *ucaData, unsigned int nData) { char buf[MC_KEY_LEN]; - char *strkey = NULL; apr_status_t rv; - strkey = mc_session_id2sz(id, idlen, buf, sizeof(buf)); - if(!strkey) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "scache_mc: Key generation borked."); - return APR_EGENERAL; - } + mc_session_id2sz(ctx, id, idlen, buf, sizeof(buf)); - rv = apr_memcache_set(ctx->mc, strkey, (char*)ucaData, nData, timeout, 0); + rv = apr_memcache_set(ctx->mc, buf, (char*)ucaData, nData, timeout, 0); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, "scache_mc: error setting key '%s' " - "with %d bytes of data", strkey, nData); + "with %d bytes of data", buf, nData); return rv; } @@ -217,21 +214,14 @@ static apr_status_t socache_mc_retrieve(ap_socache_instance_t *ctx, { apr_size_t der_len; char buf[MC_KEY_LEN], *der; - char *strkey = NULL; apr_status_t rv; - strkey = mc_session_id2sz(id, idlen, buf, sizeof(buf)); - - if (!strkey) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "scache_mc: Key generation borked."); - return APR_EGENERAL; - } + mc_session_id2sz(ctx, id, idlen, buf, sizeof(buf)); /* ### this could do with a subpool, but _getp looks like it will * eat memory like it's going out of fashion anyway. */ - rv = apr_memcache_getp(ctx->mc, p, strkey, + rv = apr_memcache_getp(ctx->mc, p, buf, &der, &der_len, NULL); if (rv) { if (rv != APR_NOTFOUND) { @@ -257,21 +247,16 @@ static void socache_mc_remove(ap_socache_instance_t *ctx, server_rec *s, apr_pool_t *p) { char buf[MC_KEY_LEN]; - char* strkey = NULL; apr_status_t rv; - strkey = mc_session_id2sz(id, idlen, buf, sizeof(buf)); - if(!strkey) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "scache_mc: Key generation borked."); - return; - } + mc_session_id2sz(ctx, id, idlen, buf, sizeof(buf)); - rv = apr_memcache_delete(ctx->mc, strkey, 0); + rv = apr_memcache_delete(ctx->mc, buf, 0); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, "scache_mc: error deleting key '%s' ", - strkey); + buf); return; } } diff --git a/modules/cache/mod_socache_shmcb.c b/modules/cache/mod_socache_shmcb.c index 7c97274ab8..87c38ea738 100644 --- a/modules/cache/mod_socache_shmcb.c +++ b/modules/cache/mod_socache_shmcb.c @@ -302,6 +302,8 @@ static const char *socache_shmcb_create(ap_socache_instance_t **context, } static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx, + const char *namespace, + const struct ap_socache_hints *hints, server_rec *s, apr_pool_t *p) { void *shm_segment; @@ -309,6 +311,7 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx, apr_status_t rv; SHMCBHeader *header; unsigned int num_subcache, num_idx, loop; + apr_size_t avg_obj_size, avg_id_len; /* Create shared memory segment */ if (ctx->data_file == NULL) { @@ -348,16 +351,10 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx, shm_segsize); /* Discount the header */ shm_segsize -= sizeof(SHMCBHeader); - /* Select the number of subcaches to create and how many indexes each - * should contain based on the size of the memory (the header has already - * been subtracted). Typical non-client-auth sslv3/tlsv1 sessions are - * around 180 bytes (148 bytes data and 32 bytes for the id), so - * erring to division by 150 helps ensure we would exhaust data - * storage before index storage (except sslv2, where it's - * *slightly* the other way). From there, we select the number of - * subcaches to be a power of two, such that the number of indexes - * per subcache at least twice the number of subcaches. */ - num_idx = (shm_segsize) / 150; + /* Select index size based on average object size hints, if given. */ + avg_obj_size = hints && hints->avg_obj_size ? hints->avg_obj_size : 150; + avg_id_len = hints && hints->avg_id_len ? hints->avg_id_len : 30; + num_idx = (shm_segsize) / (avg_obj_size + avg_id_len); num_subcache = 256; while ((num_idx / num_subcache) < (2 * num_subcache)) num_subcache /= 2; diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c index 585958ea1e..83e40053ac 100644 --- a/modules/ssl/ssl_scache.c +++ b/modules/ssl/ssl_scache.c @@ -43,6 +43,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p) apr_status_t rv; void *data; const char *userdata_key = "ssl_scache_init"; + struct ap_socache_hints hints; /* The very first invocation of this function will be the * post_config invocation during server startup; do nothing for @@ -67,7 +68,12 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p) return; } - rv = mc->sesscache->init(mc->sesscache_context, s, p); + memset(&hints, 0, sizeof hints); + hints.avg_obj_size = 150; + hints.avg_id_len = 30; + hints.expiry_interval = 30; + + rv = mc->sesscache->init(mc->sesscache_context, "mod_ssl", &hints, s, p); if (rv) { /* ABORT ABORT etc. */ ssl_die(); |