1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
/*++
/* NAME
/* master_wakeup 3
/* SUMMARY
/* Postfix master - start/stop service wakeup timers
/* SYNOPSIS
/* #include "master.h"
/*
/* void master_wakeup_init(serv)
/* MASTER_SERV *serv;
/*
/* void master_wakeup_cleanup(serv)
/* MASTER_SERV *serv;
/* DESCRIPTION
/* This module implements automatic service wakeup. In order to
/* wakeup a service, a wakeup trigger is sent to the corresponding
/* service port or FIFO, and a timer is started to repeat this sequence
/* after a configurable amount of time.
/*
/* master_wakeup_init() wakes up the named service. No wakeup
/* is done or scheduled when a zero wakeup time is given, or when
/* the service has been throttled in the mean time.
/* It is OK to call master_wakeup_init() while a timer is already
/* running for the named service. The effect is to restart the
/* wakeup timer.
/*
/* master_wakeup_cleanup() cancels the wakeup timer for the named
/* service. It is an error to disable a service while it still has
/* an active wakeup timer (doing so would cause a dangling reference
/* to a non-existent service).
/* It is OK to call master_wakeup_cleanup() even when no timer is
/* active for the named service.
/* DIAGNOSTICS
/* BUGS
/* SEE ALSO
/* inet_trigger(3), internet-domain client
/* unix_trigger(3), unix-domain client
/* fifo_trigger(3), fifo client
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <unistd.h>
#include <string.h>
/* Utility library. */
#include <msg.h>
#include <trigger.h>
#include <events.h>
/* Global library. */
#include <mail_proto.h> /* triggers */
/* Application-specific. */
#include "mail_server.h"
#include "master.h"
/* master_wakeup_timer_event - wakeup event handler */
static void master_wakeup_timer_event(int unused_event, char *context)
{
char *myname = "master_wakeup_timer_event";
MASTER_SERV *serv = (MASTER_SERV *) context;
int status;
static char wakeup = TRIGGER_REQ_WAKEUP;
/*
* Don't wakeup services whose automatic wakeup feature was turned off in
* the mean time.
*/
if (serv->wakeup_time == 0)
return;
/*
* Don't wake up services that are throttled. Find out what transport to
* use. We can't block here so we choose a short timeout.
*/
#define BRIEFLY 1
if (MASTER_THROTTLED(serv) == 0) {
if (msg_verbose)
msg_info("%s: service %s", myname, serv->name);
switch (serv->type) {
case MASTER_SERV_TYPE_INET:
status = inet_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
break;
case MASTER_SERV_TYPE_UNIX:
status = LOCAL_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
break;
case MASTER_SERV_TYPE_FIFO:
status = fifo_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
break;
default:
msg_panic("%s: unknown service type: %d", myname, serv->type);
}
if (status < 0)
msg_warn("%s: service %s: %m", myname, serv->name);
}
/*
* Schedule another wakeup event.
*/
event_request_timer(master_wakeup_timer_event, (char *) serv,
serv->wakeup_time);
}
/* master_wakeup_init - start automatic service wakeup */
void master_wakeup_init(MASTER_SERV *serv)
{
char *myname = "master_wakeup_init";
if (serv->wakeup_time == 0)
return;
if (msg_verbose)
msg_info("%s: service %s time %d",
myname, serv->name, serv->wakeup_time);
master_wakeup_timer_event(0, (char *) serv);
}
/* master_wakeup_cleanup - cancel wakeup timer */
void master_wakeup_cleanup(MASTER_SERV *serv)
{
char *myname = "master_wakeup_cleanup";
/*
* Cleanup, even when the wakeup feature has been turned off. There might
* still be a pending timer. Don't depend on the code that reloads the
* config file to reset the wakeup timer when things change.
*/
if (msg_verbose)
msg_info("%s: service %s", myname, serv->name);
event_cancel_timer(master_wakeup_timer_event, (char *) serv);
}
|