=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/format.c,v retrieving revision 1.130 retrieving revision 1.131 diff -c -r1.130 -r1.131 *** src/usr.bin/tmux/format.c 2017/04/21 14:01:19 1.130 --- src/usr.bin/tmux/format.c 2017/05/01 12:20:55 1.131 *************** *** 1,4 **** ! /* $OpenBSD: format.c,v 1.130 2017/04/21 14:01:19 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: format.c,v 1.131 2017/05/01 12:20:55 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott *************** *** 76,81 **** --- 76,82 ---- /* Entry in format job tree. */ struct format_job { + struct client *client; u_int tag; const char *cmd; const char *expanded; *************** *** 128,133 **** --- 129,135 ---- struct session *s; struct window_pane *wp; + struct client *client; u_int tag; int flags; *************** *** 236,242 **** struct format_job *fj = job->data; char *line, *buf; size_t len; - struct client *c; fj->job = NULL; --- 238,243 ---- *************** *** 258,265 **** free(buf); if (fj->status) { ! TAILQ_FOREACH(c, &clients, entry) ! server_status_client(c); fj->status = 0; } } --- 259,266 ---- free(buf); if (fj->status) { ! if (fj->client != NULL) ! server_status_client(fj->client); fj->status = 0; } } *************** *** 268,289 **** static char * format_job_get(struct format_tree *ft, const char *cmd) { struct format_job fj0, *fj; time_t t; char *expanded; int force; fj0.tag = ft->tag; fj0.cmd = cmd; ! if ((fj = RB_FIND(format_job_tree, &format_jobs, &fj0)) == NULL) { fj = xcalloc(1, sizeof *fj); fj->tag = ft->tag; fj->cmd = xstrdup(cmd); fj->expanded = NULL; xasprintf(&fj->out, "<'%s' not ready>", fj->cmd); ! RB_INSERT(format_job_tree, &format_jobs, fj); } expanded = format_expand(ft, cmd); --- 269,301 ---- static char * format_job_get(struct format_tree *ft, const char *cmd) { + struct format_job_tree *jobs; struct format_job fj0, *fj; time_t t; char *expanded; int force; + if (ft->client == NULL) + jobs = &format_jobs; + else if (ft->client->jobs != NULL) + jobs = ft->client->jobs; + else { + jobs = ft->client->jobs = xmalloc(sizeof *ft->client->jobs); + RB_INIT(jobs); + } + fj0.tag = ft->tag; fj0.cmd = cmd; ! if ((fj = RB_FIND(format_job_tree, jobs, &fj0)) == NULL) { fj = xcalloc(1, sizeof *fj); + fj->client = ft->client; fj->tag = ft->tag; fj->cmd = xstrdup(cmd); fj->expanded = NULL; xasprintf(&fj->out, "<'%s' not ready>", fj->cmd); ! RB_INSERT(format_job_tree, jobs, fj); } expanded = format_expand(ft, cmd); *************** *** 314,330 **** /* Remove old jobs. */ static void ! format_job_timer(__unused int fd, __unused short events, __unused void *arg) { struct format_job *fj, *fj1; time_t now; - struct timeval tv = { .tv_sec = 60 }; now = time(NULL); ! RB_FOREACH_SAFE(fj, format_job_tree, &format_jobs, fj1) { ! if (fj->last > now || now - fj->last < 3600) continue; ! RB_REMOVE(format_job_tree, &format_jobs, fj); log_debug("%s: %s", __func__, fj->cmd); --- 326,341 ---- /* Remove old jobs. */ static void ! format_job_tidy(struct format_job_tree *jobs, int force) { struct format_job *fj, *fj1; time_t now; now = time(NULL); ! RB_FOREACH_SAFE(fj, format_job_tree, jobs, fj1) { ! if (!force && (fj->last > now || now - fj->last < 3600)) continue; ! RB_REMOVE(format_job_tree, jobs, fj); log_debug("%s: %s", __func__, fj->cmd); *************** *** 337,343 **** --- 348,377 ---- free(fj); } + } + /* Remove old jobs for client. */ + void + format_lost_client(struct client *c) + { + if (c->jobs != NULL) + format_job_tidy(c->jobs, 1); + free(c->jobs); + } + + /* Remove old jobs periodically. */ + static void + format_job_timer(__unused int fd, __unused short events, __unused void *arg) + { + struct client *c; + struct timeval tv = { .tv_sec = 60 }; + + format_job_tidy(&format_jobs, 0); + TAILQ_FOREACH(c, &clients, entry) { + if (c->jobs != NULL) + format_job_tidy(c->jobs, 0); + } + evtimer_del(&format_job_event); evtimer_add(&format_job_event, &tv); } *************** *** 533,539 **** /* Create a new tree. */ struct format_tree * ! format_create(struct cmdq_item *item, int tag, int flags) { struct format_tree *ft; --- 567,573 ---- /* Create a new tree. */ struct format_tree * ! format_create(struct client *c, struct cmdq_item *item, int tag, int flags) { struct format_tree *ft; *************** *** 545,550 **** --- 579,589 ---- ft = xcalloc(1, sizeof *ft); RB_INIT(&ft->tree); + if (c != NULL) { + ft->client = c; + ft->client->references++; + } + ft->tag = tag; ft->flags = flags; *************** *** 577,582 **** --- 616,623 ---- free(fe); } + if (ft->client != NULL) + server_client_unref(ft->client); free(ft); } *************** *** 1099,1105 **** struct format_tree *ft; char *expanded; ! ft = format_create(item, FORMAT_NONE, 0); format_defaults(ft, c, s, wl, wp); expanded = format_expand(ft, fmt); --- 1140,1149 ---- struct format_tree *ft; char *expanded; ! if (item != NULL) ! ft = format_create(item->client, item, FORMAT_NONE, 0); ! else ! ft = format_create(NULL, item, FORMAT_NONE, 0); format_defaults(ft, c, s, wl, wp); expanded = format_expand(ft, fmt);