Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postfix/src/master/   (Postfix Mailserver Version 3.11©)  Datei vom 21.10.2024 mit Größe 8 kB image not shown  

Quelle  master_avail.c

  Sprache: C
 

/*++
/* NAME
/* master_avail 3
/* SUMMARY
/* Postfix master - process creation policy
/* SYNOPSIS
/* #include "master.h"
/*
/* void master_avail_listen(serv)
/* MASTER_SERV *serv;
/*
/* void master_avail_cleanup(serv)
/* MASTER_SERV *serv;
/*
/* void master_avail_more(serv, proc)
/* MASTER_SERV *serv;
/* MASTER_PROC *proc;
/*
/* void master_avail_less(serv, proc)
/* MASTER_SERV *serv;
/* MASTER_PROC *proc;
/* DESCRIPTION
/* This module implements the process creation policy. As long as
/* the allowed number of processes for the given service is not
/* exceeded, a connection request is either handled by an existing
/* available process, or this module causes a new process to be
/* created to service the request.
/*
/* When the service runs out of process slots, and the service
/* is eligible for stress-mode operation, a warning is logged,
/* servers are asked to restart at their convenience, and new
/* servers are created with stress mode enabled.
/*
/* master_avail_listen() ensures that someone monitors the service's
/* listen socket for connection requests (as long as resources
/* to handle connection requests are available).  This function may
/* be called at random times, but it must be called after each status
/* change of a service (throttled, process limit, etc.) or child
/* process (taken, available, dead, etc.).
/*
/* master_avail_cleanup() should be called when the named service
/* is taken out of operation. It terminates child processes by
/* sending SIGTERM.
/*
/* master_avail_more() should be called when the named process
/* has become available for servicing new connection requests.
/* This function updates the process availability status and
/* counter, and implicitly calls master_avail_listen().
/*
/* master_avail_less() should be called when the named process
/* has become unavailable for servicing new connection requests.
/* This function updates the process availability status and
/* counter, and implicitly calls master_avail_listen().
/* DIAGNOSTICS
/* Panic: internal inconsistencies.
/* BUGS
/* SEE ALSO
/* master_spawn(3), child process birth and death
/* 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 libraries. */

#include <sys_defs.h>

/* Utility library. */

#include <events.h>
#include <msg.h>

/* Application-specific. */

#include "master_proto.h"
#include "master.h"

/* master_avail_event - create child process to handle connection request */

static void master_avail_event(int event, void *context)
{
    MASTER_SERV *serv = (MASTER_SERV *) context;
    time_t  now;

    if (event == 0)    /* XXX Can this happen? */
 msg_panic("master_avail_event: null event");
    else {

 /*
  * When all servers for a public internet service are busy, we start
  * creating server processes with "-o stress=yes" on the command
  * line, and keep creating such processes until the process count is
  * below the limit for at least 1000 seconds. This provides a minimal
  * solution that can be adopted into legacy and stable Postfix
  * releases.
  * 
  * This is not the right place to update serv->stress_param_val in
  * response to stress level changes. Doing so would would contaminate
  * the "postfix reload" code with stress management implementation
  * details, creating a source of future bugs. Instead, we update
  * simple counters or flags here, and use their values to determine
  * the proper serv->stress_param_val value when exec-ing a server
  * process.
 */

 if (serv->stress_param_val != 0
     && !MASTER_LIMIT_OK(serv->max_proc, serv->total_proc + 1)) {
     now = event_time();
     if (serv->stress_expire_time < now)
  master_restart_service(serv, NO_CONF_RELOAD);
     serv->stress_expire_time = now + 1000;
 }
 master_spawn(serv);
    }
}

/* master_avail_listen - enforce the socket monitoring policy */

void    master_avail_listen(MASTER_SERV *serv)
{
    const char *myname = "master_avail_listen";
    int     listen_flag;
    time_t  now;
    int     n;

    /*
     * Caution: several other master_XXX modules call master_avail_listen(),
     * master_avail_more() or master_avail_less(). To avoid mutual dependency
     * problems, the code below invokes no code in other master_XXX modules,
     * and modifies no data that is maintained by other master_XXX modules.
     * 
     * When no-one else is monitoring the service's listen socket, start
     * monitoring the socket for connection requests. All this under the
     * restriction that we have sufficient resources to service a connection
     * request.
     */

    if (msg_verbose)
 msg_info("%s: %s avail %d total %d max %d", myname, serv->name,
   serv->avail_proc, serv->total_proc, serv->max_proc);
    if (MASTER_THROTTLED(serv) || serv->avail_proc > 0) {
 listen_flag = 0;
    } else if (MASTER_LIMIT_OK(serv->max_proc, serv->total_proc)) {
 listen_flag = 1;
    } else {
 listen_flag = 0;
 if (serv->stress_param_val != 0) {
     now = event_time();
     if (serv->busy_warn_time < now - 1000) {
  serv->busy_warn_time = now;
  msg_warn("service \"%s\" (%s) has reached its process limit \"%d\": "
    "new clients may experience noticeable delays",
    serv->ext_name, serv->name, serv->max_proc);
  msg_warn("to avoid this condition, increase the process count "
        "in master.cf or reduce the service time per client");
  msg_warn("see https://www.postfix.org/STRESS_README.html for "
        "examples of stress-adapting configuration settings");
     }
 }
    }
    if (listen_flag && !MASTER_LISTENING(serv)) {
 if (msg_verbose)
     msg_info("%s: enable events %s", myname, serv->name);
 for (n = 0; n < serv->listen_fd_count; n++)
     event_enable_read(serv->listen_fd[n], master_avail_event,
         (void *) serv);
 serv->flags |= MASTER_FLAG_LISTEN;
    } else if (!listen_flag && MASTER_LISTENING(serv)) {
 if (msg_verbose)
     msg_info("%s: disable events %s", myname, serv->name);
 for (n = 0; n < serv->listen_fd_count; n++)
     event_disable_readwrite(serv->listen_fd[n]);
 serv->flags &= ~MASTER_FLAG_LISTEN;
    }
}

/* master_avail_cleanup - cleanup */

void    master_avail_cleanup(MASTER_SERV *serv)
{
    int     n;

    master_delete_children(serv);  /* XXX calls
 * master_avail_listen */


    /*
     * This code is redundant because master_delete_children() throttles the
     * service temporarily before calling master_avail_listen/less(), which
     * then turn off read events. This temporary throttling is not documented
     * (it is only an optimization), and therefore we must not depend on it.
     */

    if (MASTER_LISTENING(serv)) {
 for (n = 0; n < serv->listen_fd_count; n++)
     event_disable_readwrite(serv->listen_fd[n]);
 serv->flags &= ~MASTER_FLAG_LISTEN;
    }
}

/* master_avail_more - one more available child process */

void    master_avail_more(MASTER_SERV *serv, MASTER_PROC *proc)
{
    const char *myname = "master_avail_more";

    /*
     * Caution: several other master_XXX modules call master_avail_listen(),
     * master_avail_more() or master_avail_less(). To avoid mutual dependency
     * problems, the code below invokes no code in other master_XXX modules,
     * and modifies no data that is maintained by other master_XXX modules.
     * 
     * This child process has become available for servicing connection
     * requests, so we can stop monitoring the service's listen socket. The
     * child will do it for us.
     */

    if (msg_verbose)
 msg_info("%s: pid %d (%s)", myname, proc->pid, proc->serv->name);
    if (proc->avail == MASTER_STAT_AVAIL)
 msg_panic("%s: process already available", myname);
    serv->avail_proc++;
    proc->avail = MASTER_STAT_AVAIL;
    master_avail_listen(serv);
}

/* master_avail_less - one less available child process */

void    master_avail_less(MASTER_SERV *serv, MASTER_PROC *proc)
{
    const char *myname = "master_avail_less";

    /*
     * Caution: several other master_XXX modules call master_avail_listen(),
     * master_avail_more() or master_avail_less(). To avoid mutual dependency
     * problems, the code below invokes no code in other master_XXX modules,
     * and modifies no data that is maintained by other master_XXX modules.
     * 
     * This child is no longer available for servicing connection requests. When
     * no child processes are available, start monitoring the service's
     * listen socket for new connection requests.
     */

    if (msg_verbose)
 msg_info("%s: pid %d (%s)", myname, proc->pid, proc->serv->name);
    if (proc->avail != MASTER_STAT_AVAIL)
 msg_panic("%s: process not available", myname);
    serv->avail_proc--;
    proc->avail = MASTER_STAT_TAKEN;
    master_avail_listen(serv);
}

Messung V0.5 in Prozent
C=75 H=95 G=85

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.