You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dirk-Willem van Gulik <di...@webweaving.org> on 1999/04/05 19:44:51 UTC
[patch] proxy child management / needless forks
At some moment in the past; this has crept in. We are
forking off a garbage collector after each and every request
prior to checking if that is actually useful.
See proposed patch. I am not entirely familiar with this;
so cry faul if there was a reason behind this. Otherwise I'll
comit this later today.
Note that there is a bit of a catch; I mark the .time file
prior to being sure that I can actually fork and all that.
Dw.
Index: proxy_cache.c
===================================================================
RCS file: /x3/home/cvs/apache-1.3/src/modules/proxy/proxy_cache.c,v
retrieving revision 1.56
diff -u -r1.56 proxy_cache.c
--- proxy_cache.c 1999/03/23 14:48:09 1.56
+++ proxy_cache.c 1999/04/05 17:41:13
@@ -102,7 +102,7 @@
#define ROUNDUP2BLOCKS(_bytes) (((_bytes)+block_size-1) & ~(block_size-1))
static long block_size = 512; /* this must be a power of 2 */
static long61_t curbytes, cachesize;
-static time_t every, garbage_now, garbage_expire;
+static time_t garbage_now, garbage_expire;
static char *filename;
static mutex *garbage_mutex = NULL;
@@ -119,6 +119,7 @@
static int sub_garbage_coll(request_rec *r, array_header *files,
const char *cachedir, const char *cachesubdir);
static void help_proxy_garbage_coll(request_rec *r);
+static int should_proxy_garbage_coll(request_rec *r);
#if !defined(WIN32) && !defined(MPE) && !defined(OS2)
static void detached_proxy_garbage_coll(request_rec *r);
#endif
@@ -138,10 +139,11 @@
(void) ap_release_mutex(garbage_mutex);
ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */
+ if (should_proxy_garbage_coll(r))
#if !defined(WIN32) && !defined(MPE) && !defined(OS2)
- detached_proxy_garbage_coll(r);
+ detached_proxy_garbage_coll(r);
#else
- help_proxy_garbage_coll(r);
+ help_proxy_garbage_coll(r);
#endif
ap_unblock_alarms();
@@ -264,27 +268,25 @@
}
#endif /* ndef WIN32 */
-static void help_proxy_garbage_coll(request_rec *r)
+#define DOT_TIME "/.time" /* marker */
+
+static int should_proxy_garbage_coll(request_rec *r)
{
- const char *cachedir;
void *sconf = r->server->module_config;
proxy_server_conf *pconf =
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
const struct cache_conf *conf = &pconf->cache;
- array_header *files;
- struct stat buf;
- struct gc_ent *fent;
- int i, timefd;
- static time_t lastcheck = BAD_DATE; /* static (per-process) data!!! */
- cachedir = conf->root;
- /* configured size is given in kB. Make it bytes, convert to long61_t: */
- cachesize.lower = cachesize.upper = 0;
- add_long61(&cachesize, conf->space << 10);
- every = conf->gcinterval;
+ const char *cachedir = conf->root;
+ char filename[ strlen(cachedir) + strlen( DOT_TIME ) +1];
+ struct stat buf;
+ int timefd;
+ time_t every = conf->gcinterval;
+ static time_t lastcheck = BAD_DATE; /* static (per-process) data!!! */
if (cachedir == NULL || every == -1)
- return;
+ return 0;
+
garbage_now = time(NULL);
/* Usually, the modification time of <cachedir>/.time can only increase.
* Thus, even with several child processes having their own copy of
@@ -292,41 +294,68 @@
* for GC yet.
*/
if (garbage_now != -1 && lastcheck != BAD_DATE && garbage_now < lastcheck + every)
- return;
+ return 0;
- ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */
+ strcpy(filename,cachedir);
+ strcat(filename,DOT_TIME);
- filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2);
- strcpy(filename, cachedir);
- strcat(filename, "/.time");
- if (stat(filename, &buf) == -1) { /* does not exist */
- if (errno != ENOENT) {
- ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
- "proxy: stat(%s)", filename);
- ap_unblock_alarms();
- return;
- }
- if ((timefd = creat(filename, 0666)) == -1) {
- if (errno != EEXIST)
- ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
- "proxy: creat(%s)", filename);
- else
- lastcheck = garbage_now; /* someone else got in there */
- ap_unblock_alarms();
- return;
- }
- close(timefd);
+ /* At this point we have a bit of an engineering compromise. We could either
+ * create and/or mark the .time file (prior to the fork which might
+ * fail on a resource issue) or wait until we are safely forked. The
+ * advantage of doing it now in this process is that we get some
+ * usefull live out of the global last check variable. (XXX which
+ * should go scoreboard IMHO.) Note that the actual counting is
+ * at a later moment.
+ */
+ if (stat(filename, &buf) == -1) { /* does not exist */
+ if (errno != ENOENT) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
+ "proxy: stat(%s)", filename);
+ return 0;
+ }
+ if ((timefd = creat(filename, 0666)) == -1) {
+ if (errno != EEXIST)
+ ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
+ "proxy: creat(%s)", filename);
+ else
+ lastcheck = garbage_now; /* someone else got in there */
+ return 0;
+ }
+ close(timefd);
}
else {
- lastcheck = buf.st_mtime; /* save the time */
- if (garbage_now < lastcheck + every) {
- ap_unblock_alarms();
- return;
- }
- if (utime(filename, NULL) == -1)
- ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
- "proxy: utimes(%s)", filename);
+ lastcheck = buf.st_mtime; /* save the time */
+ if (garbage_now < lastcheck + every) {
+ ap_unblock_alarms();
+ return 0;
+ }
+ if (utime(filename, NULL) == -1)
+ ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
+ "proxy: utimes(%s)", filename);
}
+
+ return 1;
+}
+
+static void help_proxy_garbage_coll(request_rec *r)
+{
+ const char *cachedir;
+ void *sconf = r->server->module_config;
+ proxy_server_conf *pconf =
+ (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
+ const struct cache_conf *conf = &pconf->cache;
+ array_header *files;
+ struct gc_ent *fent;
+ int i;
+ char filename[ strlen(cachedir) + HASH_LEN + 2];
+
+ cachedir = conf->root;
+ /* configured size is given in kB. Make it bytes, convert to long61_t: */
+ cachesize.lower = cachesize.upper = 0;
+ add_long61(&cachesize, conf->space << 10);
+
+ ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */
+
files = ap_make_array(r->pool, 100, sizeof(struct gc_ent));
curbytes.upper = curbytes.lower = 0L;