Use a socketpair to synchronise server startup.

pull/1/head
Nicholas Marriott 2008-06-07 07:27:28 +00:00
parent 958069575d
commit d51f075a4e
5 changed files with 41 additions and 22 deletions

View File

@ -1,4 +1,4 @@
/* $Id: client.c,v 1.28 2008-06-02 21:08:36 nicm Exp $ */
/* $Id: client.c,v 1.29 2008-06-07 07:27:28 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -51,11 +51,9 @@ client_init(const char *path, struct client_ctx *cctx, int start_server)
retries = 0;
retry:
if (stat(path, &sb) != 0) {
if (start_server && errno == ENOENT && retries < 10) {
if (pid == 0)
pid = server_start(path);
usleep(10000);
retries++;
if (start_server && errno == ENOENT) {
if (server_start(path) != 0)
goto no_start;
goto retry;
}
goto fail;
@ -81,9 +79,8 @@ retry:
if (start_server && errno == ECONNREFUSED && retries < 10) {
if (unlink(path) != 0)
goto fail;
usleep(10000);
retries++;
goto retry;
if (server_start(path) != 0)
goto no_start;
}
goto fail;
}
@ -112,6 +109,10 @@ retry:
return (0);
no_start:
log_warnx("server failed to start");
return (1);
fail:
log_warn("server not found");
return (1);

View File

@ -1,4 +1,4 @@
/* $Id: server.c,v 1.58 2008-06-07 07:13:08 nicm Exp $ */
/* $Id: server.c,v 1.59 2008-06-07 07:27:28 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -58,24 +58,37 @@ void server_check_redraw(struct client *);
void server_check_status(struct client *);
/* Fork new server. */
pid_t
int
server_start(const char *path)
{
struct sockaddr_un sa;
size_t size;
mode_t mask;
int n, fd, mode;
pid_t pid;
int n, fd, pair[2], mode;
char *cause;
u_char ch;
switch (pid = fork()) {
/* Make a little socketpair to wait for the server to be ready. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
fatal("socketpair failed");
switch (fork()) {
case -1:
fatal("fork");
fatal("fork failed");
case 0:
break;
default:
return (pid);
close(pair[1]);
ch = 0;
if (read(pair[0], &ch, 1) == 1 && ch == 0xff) {
close(pair[0]);
return (0);
}
close(pair[0]);
return (1);
}
close(pair[0]);
#ifdef DEBUG
xmalloc_clear();
@ -130,6 +143,11 @@ server_start(const char *path)
fatal("fcntl failed");
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
ch = 0xff;
if (write(pair[1], &ch, 1) != 1)
fatal("write failed");
/* Don't close the socketpair fd on success. */
n = server_main(path, fd);
#ifdef DEBUG

View File

@ -1,4 +1,4 @@
/* $Id: session.c,v 1.36 2008-06-06 17:55:27 nicm Exp $ */
/* $Id: session.c,v 1.37 2008-06-07 07:27:28 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -116,7 +116,7 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy)
s = xmalloc(sizeof *s);
if (clock_gettime(CLOCK_REALTIME, &s->ts) != 0)
fatal("clock_gettime");
fatal("clock_gettime failed");
s->curw = s->lastw = NULL;
RB_INIT(&s->windows);
TAILQ_INIT(&s->alerts);

View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.23 2008-06-07 06:13:21 nicm Exp $ */
/* $Id: status.c,v 1.24 2008-06-07 07:27:28 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -43,7 +43,7 @@ status_write_client(struct client *c)
return;
if (clock_gettime(CLOCK_REALTIME, &c->status_ts) != 0)
fatal("clock_gettime");
fatal("clock_gettime failed");
left = options_get_string(&c->session->options, "status-left");
strftime(lbuf, sizeof lbuf, left, localtime(&(c->status_ts.tv_sec)));

4
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.138 2008-06-07 07:13:08 nicm Exp $ */
/* $Id: tmux.h,v 1.139 2008-06-07 07:27:28 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -895,7 +895,7 @@ const char *key_string_lookup_key(int);
/* server.c */
extern struct clients clients;
pid_t server_start(const char *);
int server_start(const char *);
/* server-msg.c */
int server_msg_dispatch(struct client *);