mirror of
https://github.com/tmux/tmux.git
synced 2025-09-02 05:21:10 +00:00
Break the common process set up, event loop and imsg dispatch code
between server and client out into a separate internal API. This will make it easier to add another process.
This commit is contained in:
72
server.c
72
server.c
@ -43,6 +43,7 @@
|
||||
|
||||
struct clients clients;
|
||||
|
||||
struct tmuxproc *server_proc;
|
||||
int server_fd;
|
||||
int server_exit;
|
||||
struct event server_ev_accept;
|
||||
@ -54,11 +55,11 @@ struct window_pane *marked_window_pane;
|
||||
struct layout_cell *marked_layout_cell;
|
||||
|
||||
int server_create_socket(void);
|
||||
void server_loop(void);
|
||||
int server_loop(void);
|
||||
int server_should_exit(void);
|
||||
void server_send_exit(void);
|
||||
void server_accept_callback(int, short, void *);
|
||||
void server_signal_callback(int, short, void *);
|
||||
void server_accept(int, short, void *);
|
||||
void server_signal(int);
|
||||
void server_child_signal(void);
|
||||
void server_child_exited(pid_t, int);
|
||||
void server_child_stopped(pid_t, int);
|
||||
@ -162,17 +163,11 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
|
||||
{
|
||||
int pair[2];
|
||||
|
||||
/* The first client is special and gets a socketpair; create it. */
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
|
||||
fatal("socketpair failed");
|
||||
log_debug("starting server");
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
fatal("fork failed");
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
server_proc = proc_start("server", base, 1, server_signal);
|
||||
if (server_proc == NULL) {
|
||||
close(pair[1]);
|
||||
return (pair[0]);
|
||||
}
|
||||
@ -182,21 +177,6 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
|
||||
"ps", NULL) != 0)
|
||||
fatal("pledge failed");
|
||||
|
||||
/*
|
||||
* Must daemonise before loading configuration as the PID changes so
|
||||
* $TMUX would be wrong for sessions created in the config file.
|
||||
*/
|
||||
if (daemon(1, 0) != 0)
|
||||
fatal("daemon failed");
|
||||
|
||||
/* event_init() was called in our parent, need to reinit. */
|
||||
clear_signals(0);
|
||||
if (event_reinit(base) != 0)
|
||||
fatal("event_reinit failed");
|
||||
|
||||
logfile("server");
|
||||
log_debug("server started, pid %ld", (long) getpid());
|
||||
|
||||
RB_INIT(&windows);
|
||||
RB_INIT(&all_window_panes);
|
||||
TAILQ_INIT(&clients);
|
||||
@ -207,8 +187,6 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
|
||||
utf8_build();
|
||||
|
||||
start_time = time(NULL);
|
||||
log_debug("socket path %s", socket_path);
|
||||
setproctitle("server (%s)", socket_path);
|
||||
|
||||
server_fd = server_create_socket();
|
||||
if (server_fd == -1)
|
||||
@ -226,31 +204,19 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
|
||||
|
||||
server_add_accept(0);
|
||||
|
||||
set_signals(server_signal_callback);
|
||||
server_loop();
|
||||
proc_loop(server_proc, server_loop);
|
||||
status_prompt_save_history();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Main server loop. */
|
||||
void
|
||||
/* Server loop callback. */
|
||||
int
|
||||
server_loop(void)
|
||||
{
|
||||
while (!server_should_exit()) {
|
||||
log_debug("event dispatch enter");
|
||||
event_loop(EVLOOP_ONCE);
|
||||
log_debug("event dispatch exit");
|
||||
|
||||
server_client_loop();
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the server should exit (no more clients or sessions). */
|
||||
int
|
||||
server_should_exit(void)
|
||||
{
|
||||
struct client *c;
|
||||
|
||||
server_client_loop();
|
||||
|
||||
if (!options_get_number(&global_options, "exit-unattached")) {
|
||||
if (!RB_EMPTY(&sessions))
|
||||
return (0);
|
||||
@ -282,10 +248,10 @@ server_send_exit(void)
|
||||
cmd_wait_for_flush();
|
||||
|
||||
TAILQ_FOREACH_SAFE(c, &clients, entry, c1) {
|
||||
if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED))
|
||||
if (c->flags & CLIENT_SUSPENDED)
|
||||
server_client_lost(c);
|
||||
else
|
||||
server_write_client(c, MSG_SHUTDOWN, NULL, 0);
|
||||
proc_send(c->peer, MSG_SHUTDOWN, -1, NULL, 0);
|
||||
c->session = NULL;
|
||||
}
|
||||
|
||||
@ -331,7 +297,7 @@ server_update_socket(void)
|
||||
|
||||
/* Callback for server socket. */
|
||||
void
|
||||
server_accept_callback(int fd, short events, unused void *data)
|
||||
server_accept(int fd, short events, unused void *data)
|
||||
{
|
||||
struct sockaddr_storage sa;
|
||||
socklen_t slen = sizeof sa;
|
||||
@ -372,19 +338,19 @@ server_add_accept(int timeout)
|
||||
event_del(&server_ev_accept);
|
||||
|
||||
if (timeout == 0) {
|
||||
event_set(&server_ev_accept,
|
||||
server_fd, EV_READ, server_accept_callback, NULL);
|
||||
event_set(&server_ev_accept, server_fd, EV_READ, server_accept,
|
||||
NULL);
|
||||
event_add(&server_ev_accept, NULL);
|
||||
} else {
|
||||
event_set(&server_ev_accept,
|
||||
server_fd, EV_TIMEOUT, server_accept_callback, NULL);
|
||||
event_set(&server_ev_accept, server_fd, EV_TIMEOUT,
|
||||
server_accept, NULL);
|
||||
event_add(&server_ev_accept, &tv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Signal handler. */
|
||||
void
|
||||
server_signal_callback(int sig, unused short events, unused void *data)
|
||||
server_signal(int sig)
|
||||
{
|
||||
int fd;
|
||||
|
||||
|
Reference in New Issue
Block a user