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 06:48:58 UTC
svn commit: r907937 - in /httpd/httpd/trunk: include/ap_socache.h
modules/cache/mod_socache_shmcb.c
Author: wrowe
Date: Tue Feb 9 05:48:58 2010
New Revision: 907937
URL: http://svn.apache.org/viewvc?rev=907937&view=rev
Log:
Illustrate an ->iterator() implementation for mod_socache_shmcb.
Clarify that the iterator aught will make the users' life easier
by appending trailing \0 null chars.
Modified:
httpd/httpd/trunk/include/ap_socache.h
httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c
Modified: httpd/httpd/trunk/include/ap_socache.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_socache.h?rev=907937&r1=907936&r2=907937&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_socache.h (original)
+++ httpd/httpd/trunk/include/ap_socache.h Tue Feb 9 05:48:58 2010
@@ -39,7 +39,8 @@
* 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.
- * XXX: Even if store/retrieve/remove is atomic, isn't it useful to note
+ */
+/* 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)
@@ -62,9 +63,11 @@
* 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 id Unique ID for the object (binary blob)
+ * with a trailing null char for convenience
* @param idlen Length of id blob
- * @param data Output buffer to place retrievd data (binary blob)
+ * @param data Output buffer to place retrieved data (binary blob)
+ * with a trailing null char for convenience
* @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;
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=907937&r1=907936&r2=907937&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_socache_shmcb.c Tue Feb 9 05:48:58 2010
@@ -26,6 +26,7 @@
#include "apr_shm.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
+#include "apr_general.h"
#include "ap_socache.h"
@@ -197,8 +198,7 @@
}
}
-/* A "cyclic-to-normal" memcpy. */
-static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest,
+/* A "cyclic-to-normal" memcpy. */static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest,
const unsigned char *data, unsigned int src_offset,
unsigned int src_len)
{
@@ -255,6 +255,17 @@
static int shmcb_subcache_remove(server_rec *, SHMCBHeader *, SHMCBSubcache *,
const unsigned char *, unsigned int);
+/* Returns result of the (iterator)() call, zero is success (continue) */
+static apr_status_t shmcb_subcache_iterate(ap_socache_instance_t *instance,
+ server_rec *s,
+ SHMCBHeader *header,
+ SHMCBSubcache *subcache,
+ ap_socache_iterator_t *iterator,
+ unsigned char **buf,
+ apr_size_t *buf_len,
+ apr_pool_t *pool,
+ apr_time_t now);
+
/*
* High-Level "handlers" as per ssl_scache.c
* subcache internals are deferred to shmcb_subcache_*** functions lower down
@@ -611,6 +622,30 @@
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "leaving shmcb_status");
}
+apr_status_t socache_shmcb_iterate(ap_socache_instance_t *instance,
+ server_rec *s,
+ ap_socache_iterator_t *iterator,
+ apr_pool_t *pool)
+{
+ SHMCBHeader *header = instance->header;
+ unsigned int loop;
+ apr_time_t now = apr_time_now();
+ apr_status_t rv = APR_SUCCESS;
+ apr_size_t buflen = 0;
+ unsigned char *buf;
+
+ /* Perform the iteration inside the mutex to avoid corruption or invalid
+ * pointer arithmetic. The rest of our logic uses read-only header data so
+ * doesn't need the lock. */
+ /* Iterate over the subcaches */
+ for (loop = 0; loop < header->subcache_num && rv == APR_SUCCESS; loop++) {
+ SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
+ rv = shmcb_subcache_iterate(instance, s, header, subcache, iterator,
+ &buf, &buflen, pool, now);
+ }
+ return rv;
+}
+
/*
* Subcache-level cache operations
*/
@@ -718,16 +753,9 @@
/* HERE WE ASSUME THAT THE NEW SESSION SHOULD GO ON THE END! I'M NOT
* 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 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!")
+ * We aught to fix that. httpd (never mind third party modules)
+ * does not 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,
@@ -862,12 +890,89 @@
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)
+
+static apr_status_t shmcb_subcache_iterate(ap_socache_instance_t *instance,
+ server_rec *s,
+ SHMCBHeader *header,
+ SHMCBSubcache *subcache,
+ ap_socache_iterator_t *iterator,
+ unsigned char **buf,
+ apr_size_t *buf_len,
+ apr_pool_t *pool,
+ apr_time_t now)
{
- return APR_ENOTIMPL;
+ unsigned int pos;
+ unsigned int loop = 0;
+ apr_status_t rv;
+
+ pos = subcache->idx_pos;
+ while (loop < subcache->idx_used) {
+ SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
+
+ /* Only consider 'idx' if the "removed" flag isn't set. */
+ if (!idx->removed) {
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "iterating idx=%d, data=%d", pos, idx->data_pos);
+ if (idx->expires > now)
+ {
+ unsigned char *id = *buf;
+ unsigned char *dest;
+ unsigned int data_offset, dest_len;
+ apr_size_t buf_req;
+
+ /* Find the offset of the data segment, after the id */
+ data_offset = SHMCB_CYCLIC_INCREMENT(idx->data_pos,
+ idx->id_len,
+ header->subcache_data_size);
+
+ dest_len = idx->data_used - idx->id_len;
+
+ buf_req = APR_ALIGN_DEFAULT(idx->id_len + 1)
+ + APR_ALIGN_DEFAULT(dest_len + 1);
+
+ if (buf_req > *buf_len) {
+ /* Grow to ~150% of this buffer requirement on resize
+ * always using APR_ALIGN_DEFAULT sized pages
+ */
+ *buf_len = buf_req + APR_ALIGN_DEFAULT(buf_req / 2);
+ *buf = apr_palloc(pool, *buf_len);
+ id = *buf;
+ }
+
+ dest = *buf + APR_ALIGN_DEFAULT(idx->id_len + 1);
+
+ /* Copy out the data, because it's potentially cyclic */
+ shmcb_cyclic_cton_memcpy(header->subcache_data_size, id,
+ SHMCB_DATA(header, subcache),
+ idx->data_pos, idx->id_len);
+ id[idx->id_len] = '\0';
+
+ shmcb_cyclic_cton_memcpy(header->subcache_data_size, dest,
+ SHMCB_DATA(header, subcache),
+ data_offset, dest_len);
+ dest[dest_len] = '\0';
+
+ rv = (*iterator)(instance, s, id, idx->id_len,
+ dest, dest_len, pool);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "shmcb_subcache_iterate discarding expired entry");
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else {
+ /* Already stale, quietly remove and treat as not-found */
+ idx->removed = 1;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "shmcb_subcache_iterate discarding expired entry");
+ }
+ }
+ /* Increment */
+ loop++;
+ pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
+ }
+
+ return -1; /* failure */
}
static const ap_socache_provider_t socache_shmcb = {