Use an explicit job state instead of avoid closing our side of the

socketpair and setting it to -1 to mark when the other side is
closed. This avoids closing it while the libevent bufferevent still has
it (it could try to add it to the polled set which some mechanisms don't
like). Fixes part a problem reported by Bruno Sutic.
This commit is contained in:
nicm 2015-06-17 16:44:49 +00:00
parent d96ab34019
commit 021cdbe1c0
2 changed files with 14 additions and 5 deletions

13
job.c
View File

@ -100,6 +100,8 @@ job_run(const char *cmd, struct session *s, int cwd,
close(out[1]); close(out[1]);
job = xmalloc(sizeof *job); job = xmalloc(sizeof *job);
job->state = JOB_RUNNING;
job->cmd = xstrdup(cmd); job->cmd = xstrdup(cmd);
job->pid = pid; job->pid = pid;
job->status = 0; job->status = 0;
@ -167,14 +169,13 @@ job_callback(unused struct bufferevent *bufev, unused short events, void *data)
log_debug("job error %p: %s, pid %ld", job, job->cmd, (long) job->pid); log_debug("job error %p: %s, pid %ld", job, job->cmd, (long) job->pid);
if (job->pid == -1) { if (job->state == JOB_DEAD) {
if (job->callbackfn != NULL) if (job->callbackfn != NULL)
job->callbackfn(job); job->callbackfn(job);
job_free(job); job_free(job);
} else { } else {
bufferevent_disable(job->event, EV_READ); bufferevent_disable(job->event, EV_READ);
close(job->fd); job->state = JOB_CLOSED;
job->fd = -1;
} }
} }
@ -186,10 +187,12 @@ job_died(struct job *job, int status)
job->status = status; job->status = status;
if (job->fd == -1) { if (job->state == JOB_CLOSED) {
if (job->callbackfn != NULL) if (job->callbackfn != NULL)
job->callbackfn(job); job->callbackfn(job);
job_free(job); job_free(job);
} else } else {
job->pid = -1; job->pid = -1;
job->state = JOB_DEAD;
}
} }

6
tmux.h
View File

@ -714,6 +714,12 @@ struct options {
/* Scheduled job. */ /* Scheduled job. */
struct job { struct job {
enum {
JOB_RUNNING,
JOB_DEAD,
JOB_CLOSED
} state;
char *cmd; char *cmd;
pid_t pid; pid_t pid;
int status; int status;