Ejemplo n.º 1
0
static void single_server_accept_local(int unused_event, void *context)
{
    int     listen_fd = CAST_ANY_PTR_TO_INT(context);
    int     time_left = -1;
    int     fd;

    /*
     * Be prepared for accept() to fail because some other process already
     * got the connection. We use select() + accept(), instead of simply
     * blocking in accept(), because we must be able to detect that the
     * master process has gone away unexpectedly.
     */
    if (var_idle_limit > 0)
	time_left = event_cancel_timer(single_server_timeout, (void *) 0);

    if (single_server_pre_accept)
	single_server_pre_accept(single_server_name, single_server_argv);
    fd = LOCAL_ACCEPT(listen_fd);
    if (single_server_lock != 0
	&& myflock(vstream_fileno(single_server_lock), INTERNAL_LOCK,
		   MYFLOCK_OP_NONE) < 0)
	msg_fatal("select unlock: %m");
    if (fd < 0) {
	if (errno != EAGAIN)
	    msg_error("accept connection: %m");
	if (time_left >= 0)
	    event_request_timer(single_server_timeout, (void *) 0, time_left);
	return;
    }
    single_server_wakeup(fd, (HTABLE *) 0);
}
Ejemplo n.º 2
0
static void multi_server_accept_local(int unused_event, char *context)
{
    int     listen_fd = CAST_CHAR_PTR_TO_INT(context);
    int     time_left = -1;
    int     fd;

    /*
     * Be prepared for accept() to fail because some other process already
     * got the connection (the number of processes competing for clients is
     * kept small, so this is not a "thundering herd" problem). If the
     * accept() succeeds, be sure to disable non-blocking I/O, in order to
     * minimize confusion.
     */
    if (client_count == 0 && var_idle_limit > 0)
	time_left = event_cancel_timer(multi_server_timeout, (char *) 0);

    if (multi_server_pre_accept)
	multi_server_pre_accept(multi_server_name, multi_server_argv);
    fd = LOCAL_ACCEPT(listen_fd);
    if (multi_server_lock != 0
	&& myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
		   MYFLOCK_OP_NONE) < 0)
	msg_fatal("select unlock: %m");
    if (fd < 0) {
	if (errno != EAGAIN)
	    msg_error("accept connection: %m");
	if (time_left >= 0)
	    event_request_timer(multi_server_timeout, (char *) 0, time_left);
	return;
    }
    multi_server_wakeup(fd, (HTABLE *) 0);
}
Ejemplo n.º 3
0
static void trigger_server_accept_local(int unused_event, char *context)
{
    const char *myname = "trigger_server_accept_local";
    int     listen_fd = CAST_CHAR_PTR_TO_INT(context);
    int     time_left = 0;
    int     fd;

    if (msg_verbose)
	msg_info("%s: trigger arrived", myname);

    /*
     * Read a message from a socket. Be prepared for accept() to fail because
     * some other process already got the connection. The socket is
     * non-blocking so we won't get stuck when multiple processes wake up.
     * Don't get stuck when the client connects but sends no data. Restart
     * the idle timer if this was a false alarm.
     */
    if (var_idle_limit > 0)
	time_left = event_cancel_timer(trigger_server_timeout, (char *) 0);

    if (trigger_server_pre_accept)
	trigger_server_pre_accept(trigger_server_name, trigger_server_argv);
    fd = LOCAL_ACCEPT(listen_fd);
    if (trigger_server_lock != 0
	&& myflock(vstream_fileno(trigger_server_lock), INTERNAL_LOCK,
		   MYFLOCK_OP_NONE) < 0)
	msg_fatal("select unlock: %m");
    if (fd < 0) {
	if (errno != EAGAIN)
	    msg_error("accept connection: %m");
	if (time_left >= 0)
	    event_request_timer(trigger_server_timeout, (char *) 0, time_left);
	return;
    }
    close_on_exec(fd, CLOSE_ON_EXEC);
    if (read_wait(fd, 10) == 0)
	trigger_server_wakeup(fd);
    else if (time_left >= 0)
	event_request_timer(trigger_server_timeout, (char *) 0, time_left);
    close(fd);
}