Exemplo n.º 1
0
static void connect_event(int unused_event, void *context)
{
    int     sock = CAST_ANY_PTR_TO_INT(context);
    struct sockaddr_storage ss;
    SOCKADDR_SIZE len = sizeof(ss);
    struct sockaddr *sa = (struct sockaddr *) &ss;
    SINK_STATE *state;
    int     fd;

    if ((fd = accept(sock, sa, &len)) >= 0) {
	if (msg_verbose)
	    msg_info("connect (%s)",
#ifdef AF_LOCAL
		     sa->sa_family == AF_LOCAL ? "AF_LOCAL" :
#else
		     sa->sa_family == AF_UNIX ? "AF_UNIX" :
#endif
		     sa->sa_family == AF_INET ? "AF_INET" :
#ifdef AF_INET6
		     sa->sa_family == AF_INET6 ? "AF_INET6" :
#endif
		     "unknown protocol family");
	non_blocking(fd, NON_BLOCKING);
	state = (SINK_STATE *) mymalloc(sizeof(*state));
	state->stream = vstream_fdopen(fd, O_RDWR);
	vstream_tweak_sock(state->stream);
	netstring_setup(state->stream, var_tmout);
	event_enable_read(fd, read_length, (void *) state);
    }
}
Exemplo n.º 2
0
static void single_server_accept_inet(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 = inet_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);
}
Exemplo n.º 3
0
static void multi_server_accept_inet(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 (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, (void *) 0);

    if (multi_server_pre_accept)
        multi_server_pre_accept(multi_server_name, multi_server_argv);
    fd = inet_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, (void *) 0, time_left);
        return;
    }
    multi_server_wakeup(fd, (HTABLE *) 0);
}
Exemplo n.º 4
0
static void trigger_server_accept_pass(int unused_event, void *context)
{
    const char *myname = "trigger_server_accept_pass";
    int     listen_fd = CAST_ANY_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, (void *) 0);

    if (trigger_server_pre_accept)
        trigger_server_pre_accept(trigger_server_name, trigger_server_argv);
    fd = pass_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, (void *) 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, (void *) 0, time_left);
    close(fd);
}
Exemplo n.º 5
0
static void trigger_server_accept_fifo(int unused_event, void *context)
{
    const char *myname = "trigger_server_accept_fifo";
    int     listen_fd = CAST_ANY_PTR_TO_INT(context);

    if (trigger_server_lock != 0
            && myflock(vstream_fileno(trigger_server_lock), INTERNAL_LOCK,
                       MYFLOCK_OP_NONE) < 0)
        msg_fatal("select unlock: %m");

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

    /*
     * Read whatever the other side wrote into the FIFO. The FIFO read end is
     * non-blocking so we won't get stuck when multiple processes wake up.
     */
    if (trigger_server_pre_accept)
        trigger_server_pre_accept(trigger_server_name, trigger_server_argv);
    trigger_server_wakeup(listen_fd);
}