058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck * Copyright (c) 2003-2004, 2007, 2009 Sendmail, Inc. and its suppliers.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck * All rights reserved.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck *
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck * By using this file, you agree to the terms and conditions set
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck * forth in the LICENSE file which can be found at the top level of
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck * the sendmail distribution.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck *
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck * Contributed by Jose Marcio Martins da Cruz - Ecole des Mines de Paris
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck * Jose-Marcio.Martins@ensmp.fr
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#include <sm/gen.h>
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn BeckSM_RCSID("@(#)$Id: worker.c,v 8.17 2009/06/15 15:34:54 ca Exp $")
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#include "libmilter.h"
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#if _FFR_WORKERS_POOL
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbecktypedef struct taskmgr_S taskmgr_T;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define TM_SIGNATURE 0x23021957
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstruct taskmgr_S
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck long tm_signature; /* has the controller been initialized */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sthread_t tm_tid; /* thread id of controller */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smfi_hd_T tm_ctx_head; /* head of the linked list of contexts */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int tm_nb_workers; /* number of workers in the pool */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int tm_nb_idle; /* number of workers waiting */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int tm_p[2]; /* poll control pipe */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smutex_t tm_w_mutex; /* linked list access mutex */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck scond_t tm_w_cond; /* */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck};
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic taskmgr_T Tskmgr = {0};
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WRK_CTX_HEAD Tskmgr.tm_ctx_head
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define RD_PIPE (Tskmgr.tm_p[0])
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WR_PIPE (Tskmgr.tm_p[1])
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define PIPE_SEND_SIGNAL() \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck do \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck char evt = 0x5a; \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int fd = WR_PIPE; \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (write(fd, &evt, sizeof(evt)) != sizeof(evt)) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck "Error writing to event pipe: %s", \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sm_errstring(errno)); \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck } while (0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#ifndef USE_PIPE_WAKE_POLL
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck# define USE_PIPE_WAKE_POLL 1
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#endif /* USE_PIPE_WAKE_POLL */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/* poll check periodicity (default 10000 - 10 s) */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define POLL_TIMEOUT 10000
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/* worker conditional wait timeout (default 10 s) */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define COND_TIMEOUT 10
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/* functions */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic int mi_close_session __P((SMFICTX_PTR));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic void *mi_worker __P((void *));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic void *mi_pool_controller __P((void *));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic int mi_list_add_ctx __P((SMFICTX_PTR));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic int mi_list_del_ctx __P((SMFICTX_PTR));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** periodicity of cleaning up old sessions (timedout)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** sessions list will be checked to find old inactive
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** sessions each DT_CHECK_OLD_SESSIONS sec
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define DT_CHECK_OLD_SESSIONS 600
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#ifndef OLD_SESSION_TIMEOUT
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck# define OLD_SESSION_TIMEOUT ctx->ctx_timeout
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#endif /* OLD_SESSION_TIMEOUT */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/* session states - with respect to the pool of workers */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WKST_INIT 0 /* initial state */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WKST_READY_TO_RUN 1 /* command ready do be read */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WKST_RUNNING 2 /* session running on a worker */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WKST_READY_TO_WAIT 3 /* session just finished by a worker */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WKST_WAITING 4 /* waiting for new command */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WKST_CLOSING 5 /* session finished */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#ifndef MIN_WORKERS
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck# define MIN_WORKERS 2 /* minimum number of threads to keep around */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#endif
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define MIN_IDLE 1 /* minimum number of idle threads */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Macros for threads and mutex management
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define TASKMGR_LOCK() \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck do \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (!smutex_lock(&Tskmgr.tm_w_mutex)) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "TASKMGR_LOCK error"); \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck } while (0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define TASKMGR_UNLOCK() \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck do \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (!smutex_unlock(&Tskmgr.tm_w_mutex)) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "TASKMGR_UNLOCK error"); \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck } while (0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define TASKMGR_COND_WAIT() \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck scond_timedwait(&Tskmgr.tm_w_cond, &Tskmgr.tm_w_mutex, COND_TIMEOUT)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define TASKMGR_COND_SIGNAL() \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck do \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (scond_signal(&Tskmgr.tm_w_cond) != 0) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "TASKMGR_COND_SIGNAL error"); \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck } while (0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define LAUNCH_WORKER(ctx) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck do \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int r; \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sthread_t tid; \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((r = thread_create(&tid, mi_worker, ctx)) != 0) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "LAUNCH_WORKER error: %s",\
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sm_errstring(r)); \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck } while (0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#if POOL_DEBUG
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck# define POOL_LEV_DPRINTF(lev, x) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck do { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((lev) < ctx->ctx_dbg) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sm_dprintf x; \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck } while (0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#else /* POOL_DEBUG */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck# define POOL_LEV_DPRINTF(lev, x)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#endif /* POOL_DEBUG */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_START_SESSION -- Start a session in the pool of workers
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Parameters:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** ctx -- context structure
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Returns:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_SUCCESS/MI_FAILURE
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckint
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckmi_start_session(ctx)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SMFICTX_PTR ctx;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck static long id = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_ASSERT(Tskmgr.tm_signature == TM_SIGNATURE);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_ASSERT(ctx != NULL);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4, ("PIPE r=[%d] w=[%d]", RD_PIPE, WR_PIPE));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_LOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (mi_list_add_ctx(ctx) != MI_SUCCESS)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_FAILURE;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_sid = id++;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* if there is an idle worker, signal it, otherwise start new worker */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (Tskmgr.tm_nb_idle > 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_READY_TO_RUN;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_COND_SIGNAL();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck else
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_RUNNING;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck LAUNCH_WORKER(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_SUCCESS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck}
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_CLOSE_SESSION -- Close a session and clean up data structures
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Parameters:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** ctx -- context structure
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Returns:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_SUCCESS/MI_FAILURE
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic int
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckmi_close_session(ctx)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SMFICTX_PTR ctx;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_ASSERT(ctx != NULL);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck (void) mi_list_del_ctx(ctx);
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck mi_clr_ctx(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_SUCCESS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck}
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_POOL_CONTROLER_INIT -- Launch the worker pool controller
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Must be called before starting sessions.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Parameters:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** none
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Returns:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_SUCCESS/MI_FAILURE
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckint
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckmi_pool_controller_init()
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sthread_t tid;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int r, i;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (Tskmgr.tm_signature == TM_SIGNATURE)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_SUCCESS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_TAILQ_INIT(&WRK_CTX_HEAD);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_tid = (sthread_t) -1;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_workers = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_idle = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (pipe(Tskmgr.tm_p) != 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "can't create event pipe: %s",
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck sm_errstring(errno));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_FAILURE;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck (void) smutex_init(&Tskmgr.tm_w_mutex);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck (void) scond_init(&Tskmgr.tm_w_cond);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* Launch the pool controller */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((r = thread_create(&tid, mi_pool_controller, (void *) NULL)) != 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "can't create controller thread: %s",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sm_errstring(r));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_FAILURE;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_tid = tid;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_signature = TM_SIGNATURE;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* Create the pool of workers */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck for (i = 0; i < MIN_WORKERS; i++)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((r = thread_create(&tid, mi_worker, (void *) NULL)) != 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "can't create workers crew: %s",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sm_errstring(r));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_FAILURE;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_SUCCESS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck}
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_POOL_CONTROLLER -- manage the pool of workers
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** This thread must be running when listener begins
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** starting sessions
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Parameters:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** arg -- unused
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Returns:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** NULL
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Control flow:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** for (;;)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Look for timed out sessions
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Select sessions to wait for sendmail command
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Poll set of file descriptors
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** if timeout
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** continue
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** For each file descriptor ready
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** launch new thread if no worker available
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** else
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** signal waiting worker
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/* Poll structure array (pollfd) size step */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define PFD_STEP 256
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WAIT_FD(i) (pfd[i].fd)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define WAITFN "POLL"
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic void *
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckmi_pool_controller(arg)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck void *arg;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck struct pollfd *pfd = NULL;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int dim_pfd = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck bool rebuild_set = true;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int pcnt = 0; /* error count for poll() failures */
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck time_t lastcheck;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_tid = sthread_get_id();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (pthread_detach(Tskmgr.tm_tid) != 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "Failed to detach pool controller thread");
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return NULL;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd = (struct pollfd *) malloc(PFD_STEP * sizeof(struct pollfd));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (pfd == NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "Failed to malloc pollfd array: %s",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sm_errstring(errno));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return NULL;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck dim_pfd = PFD_STEP;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck lastcheck = time(NULL);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck for (;;)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SMFICTX_PTR ctx;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int nfd, rfd, i;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck time_t now;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (mi_stop() != MILTER_CONT)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck break;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_LOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck now = time(NULL);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* check for timed out sessions? */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (lastcheck + DT_CHECK_OLD_SESSIONS < now)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD);
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck while (ctx != SM_TAILQ_END(&WRK_CTX_HEAD))
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck SMFICTX_PTR ctx_nxt;
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck ctx_nxt = SM_TAILQ_NEXT(ctx, ctx_link);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx->ctx_wstate == WKST_WAITING)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx->ctx_wait == 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wait = now;
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck else if (ctx->ctx_wait + OLD_SESSION_TIMEOUT
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck < now)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck /* if session timed out, close it */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sfsistat (*fi_close) __P((SMFICTX *));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("Closing old connection: sd=%d id=%d",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_sd,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_sid));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck (void) (*fi_close)(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck mi_close_session(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck ctx = ctx_nxt;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck lastcheck = now;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (rebuild_set)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** Initialize poll set.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** Insert into the poll set the file descriptors of
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** all sessions waiting for a command from sendmail.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck nfd = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* begin with worker pipe */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd[nfd].fd = RD_PIPE;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd[nfd].events = MI_POLL_RD_FLAGS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd[nfd].revents = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck nfd++;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** update ctx_wait - start of wait moment -
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** for timeout
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx->ctx_wstate == WKST_READY_TO_WAIT)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wait = now;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* add the session to the pollfd array? */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((ctx->ctx_wstate == WKST_READY_TO_WAIT) ||
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck (ctx->ctx_wstate == WKST_WAITING))
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** Resize the pollfd array if it
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** isn't large enough.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (nfd >= dim_pfd)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck struct pollfd *tpfd;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck size_t new;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck new = (dim_pfd + PFD_STEP) *
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sizeof(*tpfd);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck tpfd = (struct pollfd *)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck realloc(pfd, new);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (tpfd != NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd = tpfd;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck dim_pfd += PFD_STEP;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck else
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck "Failed to realloc pollfd array:%s",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sm_errstring(errno));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* add the session to pollfd array */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (nfd < dim_pfd)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_WAITING;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd[nfd].fd = ctx->ctx_sd;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd[nfd].events = MI_POLL_RD_FLAGS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd[nfd].revents = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck nfd++;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9beJohn Beck rebuild_set = false;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* Everything is ready, let's wait for an event */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck rfd = poll(pfd, nfd, POLL_TIMEOUT);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4, ("%s returned: at epoch %d value %d",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck WAITFN, now, nfd));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* timeout */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (rfd == 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck continue;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck rebuild_set = true;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* error */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (rfd < 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (errno == EINTR)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck continue;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pcnt++;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck "%s() failed (%s), %s",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck WAITFN, sm_errstring(errno),
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pcnt >= MAX_FAILS_S ? "abort" : "try again");
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (pcnt >= MAX_FAILS_S)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck goto err;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pcnt = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* something happened */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck for (i = 0; i < nfd; i++)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (pfd[i].revents == 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck continue;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4, ("%s event on pfd[%d/%d]=%d ",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck WAITFN, i, nfd,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck WAIT_FD(i)));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* has a worker signaled an end of task ? */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (WAIT_FD(i) == RD_PIPE)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck char evt = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int r = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("PIPE WILL READ evt = %08X %08X",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck pfd[i].events, pfd[i].revents));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((pfd[i].revents & MI_POLL_RD_FLAGS) != 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck r = read(RD_PIPE, &evt, sizeof(evt));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (r == sizeof(evt))
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* Do nothing */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("PIPE DONE READ i=[%d] fd=[%d] r=[%d] evt=[%d]",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck i, RD_PIPE, r, evt));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if ((pfd[i].revents & ~MI_POLL_RD_FLAGS) != 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* Exception handling */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck continue;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* no ! sendmail wants to send a command */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx->ctx_wstate != WKST_WAITING)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck continue;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("Checking context sd=%d - fd=%d ",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_sd , WAIT_FD(i)));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx->ctx_sd == pfd[i].fd)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_LOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("TASK: found %d for fd[%d]=%d",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_sid, i, WAIT_FD(i)));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (Tskmgr.tm_nb_idle > 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_READY_TO_RUN;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_COND_SIGNAL();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck else
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_RUNNING;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck LAUNCH_WORKER(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck break;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("TASK %s FOUND - Checking PIPE for fd[%d]",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx != NULL ? "" : "NOT", WAIT_FD(i)));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck err:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (pfd != NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck free(pfd);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_signature = 0;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck for (;;)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SMFICTX_PTR ctx;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx == NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck break;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck mi_close_session(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck (void) smutex_destroy(&Tskmgr.tm_w_mutex);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck (void) scond_destroy(&Tskmgr.tm_w_cond);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return NULL;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck}
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Look for a task ready to run.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Value of ctx is NULL or a pointer to a task ready to run.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#define GET_TASK_READY_TO_RUN() \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx->ctx_wstate == WKST_READY_TO_RUN) \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck { \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_RUNNING; \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck break; \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck } \
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_WORKER -- worker thread
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** executes tasks distributed by the mi_pool_controller
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** or by mi_start_session
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Parameters:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** arg -- pointer to context structure
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Returns:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** NULL pointer
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic void *
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckmi_worker(arg)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck void *arg;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SMFICTX_PTR ctx;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck bool done;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck sthread_t t_id;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int r;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx = (SMFICTX_PTR) arg;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck done = false;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx != NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_RUNNING;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck t_id = sthread_get_id();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (pthread_detach(t_id) != 0)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck smi_log(SMI_LOG_ERR, "Failed to detach worker thread");
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx != NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_READY_TO_RUN;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return NULL;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_LOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_workers++;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck while (!done)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (mi_stop() != MILTER_CONT)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck break;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* let's handle next task... */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx != NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck int res;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("worker %d: new task -> let's handle it",
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck t_id));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck res = mi_engine(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("worker %d: mi_engine returned %d", t_id, res));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_LOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (res != MI_CONTINUE)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_CLOSING;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** Delete context from linked list of
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** sessions and close session.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck mi_close_session(ctx);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck else
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx->ctx_wstate = WKST_READY_TO_WAIT;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ("writing to event pipe..."));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** Signal task controller to add new session
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** to poll set.
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck PIPE_SEND_SIGNAL();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ctx = NULL;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* check if there is any task waiting to be served */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_LOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck GET_TASK_READY_TO_RUN();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* Got a task? */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (ctx != NULL)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck continue;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** if not, let's check if there is enough idle workers
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** if yes: quit
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (Tskmgr.tm_nb_workers > MIN_WORKERS &&
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_idle > MIN_IDLE)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck done = true;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4, ("worker %d: checking ... %d %d", t_id,
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_workers, Tskmgr.tm_nb_idle + 1));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (done)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck {
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck POOL_LEV_DPRINTF(4, ("worker %d: quitting... ", t_id));
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_workers--;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck continue;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck ** if no task ready to run, wait for another one
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_idle++;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_COND_WAIT();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck Tskmgr.tm_nb_idle--;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck /* look for a task */
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck GET_TASK_READY_TO_RUN();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck TASKMGR_UNLOCK();
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck }
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return NULL;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck}
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_LIST_ADD_CTX -- add new session to linked list
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Parameters:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** ctx -- context structure
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Returns:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_FAILURE/MI_SUCCESS
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic int
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckmi_list_add_ctx(ctx)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SMFICTX_PTR ctx;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_ASSERT(ctx != NULL);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_TAILQ_INSERT_TAIL(&WRK_CTX_HEAD, ctx, ctx_link);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_SUCCESS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck}
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck/*
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_LIST_DEL_CTX -- remove session from linked list when finished
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Parameters:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** ctx -- context structure
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck**
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** Returns:
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck** MI_FAILURE/MI_SUCCESS
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck*/
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckstatic int
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeckmi_list_del_ctx(ctx)
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SMFICTX_PTR ctx;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck{
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_ASSERT(ctx != NULL);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck if (SM_TAILQ_EMPTY(&WRK_CTX_HEAD))
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_FAILURE;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck SM_TAILQ_REMOVE(&WRK_CTX_HEAD, ctx, ctx_link);
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck return MI_SUCCESS;
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck}
058561cbaa119a6f2659bc27ef343e1b47266bb2jbeck#endif /* _FFR_WORKERS_POOL */