In debian 5.0, _FFR_WORKERS_POOL is enabled by default. I'm running this for many years on
some OSs, including Debian Etch and Lenny. There is a bug in the WORKERS_POOL feature
which can segfaults and kill the filter when old staled connections are closed.
I'm attaching a patch which corrects this bug and also some other minor
harmless bugs.
This patch will be included in the next release of sendmail.
--- worker.c.org 2007-12-03 23:06:05.000000000 +0100
+++ worker.c 2009-06-12 19:46:17.000000000 +0200
@@ -328,6 +328,7 @@
int dim_pfd = 0;
bool rebuild_set = true;
int pcnt = 0; /* error count for poll() failures */
+ time_t lastcheck;
Tskmgr.tm_tid = sthread_get_id();
if (pthread_detach(Tskmgr.tm_tid) != 0)
@@ -345,12 +346,12 @@
}
dim_pfd = PFD_STEP;
+ lastcheck = time(NULL);
for (;;)
{
SMFICTX_PTR ctx;
- int nfd, rfd, i;
+ int nfd = 0, rfd, i;
time_t now;
- time_t lastcheck;
POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN));
@@ -364,20 +365,20 @@
/* check for timed out sessions? */
if (lastcheck + DT_CHECK_OLD_SESSIONS < now)
{
- SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
+ ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD);
+ while (ctx != SM_TAILQ_END(&WRK_CTX_HEAD))
{
+ SMFICTX_PTR ctx_nxt;
+
+ ctx_nxt = SM_TAILQ_NEXT(ctx, ctx_link);
if (ctx->ctx_wstate == WKST_WAITING)
{
if (ctx->ctx_wait == 0)
- {
ctx->ctx_wait = now;
- continue;
- }
-
- /* if session timed out, close it */
- if (ctx->ctx_wait + OLD_SESSION_TIMEOUT
- < now)
+ else if (ctx->ctx_wait +
OLD_SESSION_TIMEOUT
+ < now)
{
+ /* if session timed out, close
it */
sfsistat (*fi_close)
__P((SMFICTX *));
POOL_LEV_DPRINTF(4,
@@ -389,10 +390,9 @@
(void) (*fi_close)(ctx);
mi_close_session(ctx);
- ctx =
SM_TAILQ_FIRST(&WRK_CTX_HEAD);
- continue;
}
}
+ ctx = ctx_nxt;
}
lastcheck = now;
}
@@ -465,6 +465,7 @@
}
}
}
+ rebuild_set = false;
}
TASKMGR_UNLOCK();