summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_worker_process.c
blob: 6407c734ec54e8f82bca9b682393747a1f3b63ed (plain) (blame)
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

/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) NGINX, Inc.
 */

#include <nxt_main.h>
#include <nxt_runtime.h>
#include <nxt_port.h>
#include <nxt_master_process.h>


static void nxt_worker_process_quit(nxt_task_t *task);
static void nxt_worker_process_quit_handler(nxt_task_t *task,
    nxt_port_recv_msg_t *msg);
static void nxt_worker_process_signal_handler(nxt_task_t *task, void *obj,
    void *data);
static void nxt_worker_process_sigterm_handler(nxt_task_t *task, void *obj,
    void *data);
static void nxt_worker_process_sigquit_handler(nxt_task_t *task, void *obj,
    void *data);


nxt_port_handler_t  nxt_worker_process_port_handlers[] = {
    nxt_worker_process_quit_handler,
    nxt_port_new_port_handler,
    nxt_port_change_log_file_handler,
    nxt_port_mmap_handler,
    nxt_port_data_handler,
};


const nxt_sig_event_t  nxt_worker_process_signals[] = {
    nxt_event_signal(SIGHUP,  nxt_worker_process_signal_handler),
    nxt_event_signal(SIGINT,  nxt_worker_process_sigterm_handler),
    nxt_event_signal(SIGQUIT, nxt_worker_process_sigterm_handler),
    nxt_event_signal(SIGTERM, nxt_worker_process_sigquit_handler),
    nxt_event_signal(SIGCHLD, nxt_worker_process_signal_handler),
    nxt_event_signal(SIGUSR1, nxt_worker_process_signal_handler),
    nxt_event_signal(SIGUSR2, nxt_worker_process_signal_handler),
    nxt_event_signal_end,
};


static void
nxt_worker_process_quit(nxt_task_t *task)
{
    nxt_uint_t           n;
    nxt_queue_t          *listen;
    nxt_runtime_t        *rt;
    nxt_queue_link_t     *link, *next;
    nxt_listen_event_t   *lev;
    nxt_listen_socket_t  *ls;

    rt = task->thread->runtime;

    nxt_debug(task, "close listen connections");

    listen = &task->thread->engine->listen_connections;

    for (link = nxt_queue_first(listen);
         link != nxt_queue_tail(listen);
         link = next)
    {
        next = nxt_queue_next(link);
        lev = nxt_queue_link_data(link, nxt_listen_event_t, link);
        nxt_queue_remove(link);

        nxt_fd_event_close(task->thread->engine, &lev->socket);
    }

    if (rt->listen_sockets != NULL) {

        ls = rt->listen_sockets->elts;
        n = rt->listen_sockets->nelts;

        while (n != 0) {
            nxt_socket_close(task, ls->socket);
            ls->socket = -1;

            ls++;
            n--;
        }

        rt->listen_sockets->nelts = 0;
    }

    nxt_runtime_quit(task);
}


static void
nxt_worker_process_signal_handler(nxt_task_t *task, void *obj, void *data)
{
    nxt_trace(task, "signal signo:%d (%s) recevied, ignored",
              (int) (uintptr_t) obj, data);
}


static void
nxt_worker_process_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
{
    nxt_worker_process_quit(task);
}


static void
nxt_worker_process_sigterm_handler(nxt_task_t *task, void *obj, void *data)
{
    nxt_debug(task, "sigterm handler signo:%d (%s)",
              (int) (uintptr_t) obj, data);

    /* A fast exit. */

    nxt_runtime_quit(task);
}


static void
nxt_worker_process_sigquit_handler(nxt_task_t *task, void *obj, void *data)
{
    nxt_debug(task, "sigquit handler signo:%d (%s)",
              (int) (uintptr_t) obj, data);

    /* A graceful exit. */

    nxt_worker_process_quit(task);
}