Print this page
XXXX update sendmail to 8.14.9
*** 1,7 ****
/*
! * Copyright (c) 2003-2004, 2007, 2009 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
--- 1,7 ----
/*
! * Copyright (c) 2003-2004, 2007, 2009-2012 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*** 9,19 ****
* Contributed by Jose Marcio Martins da Cruz - Ecole des Mines de Paris
* Jose-Marcio.Martins@ensmp.fr
*/
#include <sm/gen.h>
! SM_RCSID("@(#)$Id: worker.c,v 8.17 2009/06/15 15:34:54 ca Exp $")
#include "libmilter.h"
#if _FFR_WORKERS_POOL
--- 9,19 ----
* Contributed by Jose Marcio Martins da Cruz - Ecole des Mines de Paris
* Jose-Marcio.Martins@ensmp.fr
*/
#include <sm/gen.h>
! SM_RCSID("@(#)$Id: worker.c,v 8.25 2013-11-22 20:51:37 ca Exp $")
#include "libmilter.h"
#if _FFR_WORKERS_POOL
*** 139,149 ****
sm_errstring(r)); \
} while (0)
#if POOL_DEBUG
# define POOL_LEV_DPRINTF(lev, x) \
! do { \
if ((lev) < ctx->ctx_dbg) \
sm_dprintf x; \
} while (0)
#else /* POOL_DEBUG */
# define POOL_LEV_DPRINTF(lev, x)
--- 139,150 ----
sm_errstring(r)); \
} while (0)
#if POOL_DEBUG
# define POOL_LEV_DPRINTF(lev, x) \
! do \
! { \
if ((lev) < ctx->ctx_dbg) \
sm_dprintf x; \
} while (0)
#else /* POOL_DEBUG */
# define POOL_LEV_DPRINTF(lev, x)
*** 163,173 ****
mi_start_session(ctx)
SMFICTX_PTR ctx;
{
static long id = 0;
! SM_ASSERT(Tskmgr.tm_signature == TM_SIGNATURE);
SM_ASSERT(ctx != NULL);
POOL_LEV_DPRINTF(4, ("PIPE r=[%d] w=[%d]", RD_PIPE, WR_PIPE));
TASKMGR_LOCK();
if (mi_list_add_ctx(ctx) != MI_SUCCESS)
--- 164,176 ----
mi_start_session(ctx)
SMFICTX_PTR ctx;
{
static long id = 0;
! /* this can happen if the milter is shutting down */
! if (Tskmgr.tm_signature != TM_SIGNATURE)
! return MI_FAILURE;
SM_ASSERT(ctx != NULL);
POOL_LEV_DPRINTF(4, ("PIPE r=[%d] w=[%d]", RD_PIPE, WR_PIPE));
TASKMGR_LOCK();
if (mi_list_add_ctx(ctx) != MI_SUCCESS)
*** 214,223 ****
--- 217,261 ----
return MI_SUCCESS;
}
/*
+ ** NONBLOCKING -- set nonblocking mode for a file descriptor.
+ **
+ ** Parameters:
+ ** fd -- file descriptor
+ ** name -- name for (error) logging
+ **
+ ** Returns:
+ ** MI_SUCCESS/MI_FAILURE
+ */
+
+ static int
+ nonblocking(int fd, const char *name)
+ {
+ int r;
+
+ errno = 0;
+ r = fcntl(fd, F_GETFL, 0);
+ if (r == -1)
+ {
+ smi_log(SMI_LOG_ERR, "fcntl(%s, F_GETFL)=%s",
+ name, sm_errstring(errno));
+ return MI_FAILURE;
+ }
+ errno = 0;
+ r = fcntl(fd, F_SETFL, r | O_NONBLOCK);
+ if (r == -1)
+ {
+ smi_log(SMI_LOG_ERR, "fcntl(%s, F_SETFL, O_NONBLOCK)=%s",
+ name, sm_errstring(errno));
+ return MI_FAILURE;
+ }
+ return MI_SUCCESS;
+ }
+
+ /*
** MI_POOL_CONTROLER_INIT -- Launch the worker pool controller
** Must be called before starting sessions.
**
** Parameters:
** none
*** 244,253 ****
--- 282,297 ----
{
smi_log(SMI_LOG_ERR, "can't create event pipe: %s",
sm_errstring(errno));
return MI_FAILURE;
}
+ r = nonblocking(WR_PIPE, "WR_PIPE");
+ if (r != MI_SUCCESS)
+ return r;
+ r = nonblocking(RD_PIPE, "RD_PIPE");
+ if (r != MI_SUCCESS)
+ return r;
(void) smutex_init(&Tskmgr.tm_w_mutex);
(void) scond_init(&Tskmgr.tm_w_cond);
/* Launch the pool controller */
*** 332,342 ****
lastcheck = time(NULL);
for (;;)
{
SMFICTX_PTR ctx;
! int nfd, rfd, i;
time_t now;
POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN));
if (mi_stop() != MILTER_CONT)
--- 376,386 ----
lastcheck = time(NULL);
for (;;)
{
SMFICTX_PTR ctx;
! int nfd, r, i;
time_t now;
POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN));
if (mi_stop() != MILTER_CONT)
*** 453,475 ****
}
TASKMGR_UNLOCK();
/* Everything is ready, let's wait for an event */
! rfd = poll(pfd, nfd, POLL_TIMEOUT);
POOL_LEV_DPRINTF(4, ("%s returned: at epoch %d value %d",
WAITFN, now, nfd));
/* timeout */
! if (rfd == 0)
continue;
rebuild_set = true;
/* error */
! if (rfd < 0)
{
if (errno == EINTR)
continue;
pcnt++;
smi_log(SMI_LOG_ERR,
--- 497,519 ----
}
TASKMGR_UNLOCK();
/* Everything is ready, let's wait for an event */
! r = poll(pfd, nfd, POLL_TIMEOUT);
POOL_LEV_DPRINTF(4, ("%s returned: at epoch %d value %d",
WAITFN, now, nfd));
/* timeout */
! if (r == 0)
continue;
rebuild_set = true;
/* error */
! if (r < 0)
{
if (errno == EINTR)
continue;
pcnt++;
smi_log(SMI_LOG_ERR,
*** 477,486 ****
--- 521,531 ----
WAITFN, sm_errstring(errno),
pcnt >= MAX_FAILS_S ? "abort" : "try again");
if (pcnt >= MAX_FAILS_S)
goto err;
+ continue;
}
pcnt = 0;
/* something happened */
for (i = 0; i < nfd; i++)
*** 490,530 ****
POOL_LEV_DPRINTF(4, ("%s event on pfd[%d/%d]=%d ",
WAITFN, i, nfd,
WAIT_FD(i)));
! /* has a worker signaled an end of task ? */
if (WAIT_FD(i) == RD_PIPE)
{
! char evt = 0;
! int r = 0;
POOL_LEV_DPRINTF(4,
("PIPE WILL READ evt = %08X %08X",
pfd[i].events, pfd[i].revents));
! if ((pfd[i].revents & MI_POLL_RD_FLAGS) != 0)
{
! r = read(RD_PIPE, &evt, sizeof(evt));
! if (r == sizeof(evt))
! {
! /* Do nothing */
}
- }
POOL_LEV_DPRINTF(4,
("PIPE DONE READ i=[%d] fd=[%d] r=[%d] evt=[%d]",
! i, RD_PIPE, r, evt));
if ((pfd[i].revents & ~MI_POLL_RD_FLAGS) != 0)
{
/* Exception handling */
}
continue;
}
! /* no ! sendmail wants to send a command */
SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
{
if (ctx->ctx_wstate != WKST_WAITING)
continue;
--- 535,578 ----
POOL_LEV_DPRINTF(4, ("%s event on pfd[%d/%d]=%d ",
WAITFN, i, nfd,
WAIT_FD(i)));
! /* has a worker signaled an end of task? */
if (WAIT_FD(i) == RD_PIPE)
{
! char evts[256];
! ssize_t r;
POOL_LEV_DPRINTF(4,
("PIPE WILL READ evt = %08X %08X",
pfd[i].events, pfd[i].revents));
! r = 1;
! while ((pfd[i].revents & MI_POLL_RD_FLAGS) != 0
! && r != -1)
{
! r = read(RD_PIPE, evts, sizeof(evts));
}
POOL_LEV_DPRINTF(4,
("PIPE DONE READ i=[%d] fd=[%d] r=[%d] evt=[%d]",
! i, RD_PIPE, (int) r, evts[0]));
if ((pfd[i].revents & ~MI_POLL_RD_FLAGS) != 0)
{
/* Exception handling */
}
continue;
}
! /*
! ** Not the pipe for workers waking us,
! ** so must be something on an MTA connection.
! */
!
! TASKMGR_LOCK();
SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
{
if (ctx->ctx_wstate != WKST_WAITING)
continue;
*** 532,542 ****
("Checking context sd=%d - fd=%d ",
ctx->ctx_sd , WAIT_FD(i)));
if (ctx->ctx_sd == pfd[i].fd)
{
- TASKMGR_LOCK();
POOL_LEV_DPRINTF(4,
("TASK: found %d for fd[%d]=%d",
ctx->ctx_sid, i, WAIT_FD(i)));
--- 580,589 ----
*** 548,561 ****
else
{
ctx->ctx_wstate = WKST_RUNNING;
LAUNCH_WORKER(ctx);
}
- TASKMGR_UNLOCK();
break;
}
}
POOL_LEV_DPRINTF(4,
("TASK %s FOUND - Checking PIPE for fd[%d]",
ctx != NULL ? "" : "NOT", WAIT_FD(i)));
}
--- 595,608 ----
else
{
ctx->ctx_wstate = WKST_RUNNING;
LAUNCH_WORKER(ctx);
}
break;
}
}
+ TASKMGR_UNLOCK();
POOL_LEV_DPRINTF(4,
("TASK %s FOUND - Checking PIPE for fd[%d]",
ctx != NULL ? "" : "NOT", WAIT_FD(i)));
}
*** 564,582 ****
--- 611,638 ----
err:
if (pfd != NULL)
free(pfd);
Tskmgr.tm_signature = 0;
+ #if 0
+ /*
+ ** Do not clean up ctx -- it can cause double-free()s.
+ ** The program is shutting down anyway, so it's not worth the trouble.
+ ** There is a more complex solution that prevents race conditions
+ ** while accessing ctx, but that's maybe for a later version.
+ */
+
for (;;)
{
SMFICTX_PTR ctx;
ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD);
if (ctx == NULL)
break;
mi_close_session(ctx);
}
+ #endif
(void) smutex_destroy(&Tskmgr.tm_w_mutex);
(void) scond_destroy(&Tskmgr.tm_w_cond);
return NULL;