| 45 |
#include <sys/wait.h> |
#include <sys/wait.h> |
| 46 |
#include <systemd/sd-daemon.h> |
#include <systemd/sd-daemon.h> |
| 47 |
|
|
| 48 |
|
#define WAIT_CHILD_PROCESS_EXIT_TIMEOUT 5 // second |
| 49 |
|
#define WAIT_CHILD_PROCESS_KILL_TIMEOUT 1 // second |
| 50 |
|
|
| 51 |
struct process_sockaddr_t |
struct process_sockaddr_t |
| 52 |
{ |
{ |
| 53 |
pid_t pid; |
pid_t pid; |
| 261 |
struct epoll_event ev, events[MAX_EVENTS]; |
struct epoll_event ev, events[MAX_EVENTS]; |
| 262 |
int nfds, epollfd; |
int nfds, epollfd; |
| 263 |
siginfo_t siginfo; |
siginfo_t siginfo; |
| 264 |
|
int notify_child_exit = 0; |
| 265 |
|
time_t tm_notify_child_exit = time(NULL); |
| 266 |
int sd_notify_stopping = 0; |
int sd_notify_stopping = 0; |
| 267 |
MENU_SET bbs_menu_new; |
MENU_SET bbs_menu_new; |
| 268 |
int i, j; |
int i, j; |
| 405 |
|
|
| 406 |
if (SYS_server_exit && !SYS_child_exit && SYS_child_process_count > 0) |
if (SYS_server_exit && !SYS_child_exit && SYS_child_process_count > 0) |
| 407 |
{ |
{ |
| 408 |
log_common("Notify %d child process to exit\n", SYS_child_process_count); |
if (notify_child_exit == 0) |
|
if (kill(0, SIGTERM) < 0) |
|
| 409 |
{ |
{ |
| 410 |
log_error("Send SIGTERM signal failed (%d)\n", errno); |
sd_notifyf(0, "STATUS=Notify %d child process to exit", SYS_child_process_count); |
| 411 |
|
log_common("Notify %d child process to exit\n", SYS_child_process_count); |
| 412 |
|
|
| 413 |
|
if (kill(0, SIGTERM) < 0) |
| 414 |
|
{ |
| 415 |
|
log_error("Send SIGTERM signal failed (%d)\n", errno); |
| 416 |
|
} |
| 417 |
|
|
| 418 |
|
notify_child_exit = 1; |
| 419 |
|
tm_notify_child_exit = time(NULL); |
| 420 |
} |
} |
| 421 |
|
else if (notify_child_exit == 1 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_EXIT_TIMEOUT) |
| 422 |
|
{ |
| 423 |
|
sd_notifyf(0, "STATUS=Kill %d child process", SYS_child_process_count); |
| 424 |
|
|
| 425 |
sd_notifyf(0, "STATUS=Waiting for %d child process to exit", SYS_child_process_count); |
for (i = 0; i < BBS_max_client; i++) |
| 426 |
|
{ |
| 427 |
|
if (process_sockaddr_pool[i].pid != 0) |
| 428 |
|
{ |
| 429 |
|
log_error("Kill child process (pid=%d)\n", process_sockaddr_pool[i].pid); |
| 430 |
|
if (kill(process_sockaddr_pool[i].pid, SIGKILL) < 0) |
| 431 |
|
{ |
| 432 |
|
log_error("Send SIGKILL signal failed (%d)\n", errno); |
| 433 |
|
} |
| 434 |
|
} |
| 435 |
|
} |
| 436 |
|
|
| 437 |
sleep(1); // Sleep for a while to avoid notifying child processes too frequently |
notify_child_exit = 2; |
| 438 |
|
tm_notify_child_exit = time(NULL); |
| 439 |
|
} |
| 440 |
|
else if (notify_child_exit == 2 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_KILL_TIMEOUT) |
| 441 |
|
{ |
| 442 |
|
log_error("Main process prepare to exit without waiting for %d child process any longer\n", SYS_child_process_count); |
| 443 |
|
SYS_child_process_count = 0; |
| 444 |
|
} |
| 445 |
} |
} |
| 446 |
|
|
| 447 |
if (SYS_conf_reload && !SYS_server_exit) |
if (SYS_conf_reload && !SYS_server_exit) |