Provide an accessor for the running queue item and use it to not let

hooks recurse.
This commit is contained in:
nicm 2020-04-14 06:00:52 +00:00
parent fc83517913
commit 63ec791854
3 changed files with 33 additions and 13 deletions

View File

@ -64,7 +64,7 @@ struct cmdq_item {
TAILQ_ENTRY(cmdq_item) entry; TAILQ_ENTRY(cmdq_item) entry;
}; };
TAILQ_HEAD(cmdq_list, cmdq_item); TAILQ_HEAD(cmdq_item_list, cmdq_item);
/* /*
* Command queue state. This is the context for commands on the command queue. * Command queue state. This is the context for commands on the command queue.
@ -83,6 +83,12 @@ struct cmdq_state {
struct cmd_find_state current; struct cmd_find_state current;
}; };
/* Command queue. */
struct cmdq_list {
struct cmdq_item *item;
struct cmdq_item_list list;
};
/* Get command queue name. */ /* Get command queue name. */
static const char * static const char *
cmdq_name(struct client *c) cmdq_name(struct client *c)
@ -119,7 +125,7 @@ cmdq_new(void)
struct cmdq_list *queue; struct cmdq_list *queue;
queue = xcalloc (1, sizeof *queue); queue = xcalloc (1, sizeof *queue);
TAILQ_INIT (queue); TAILQ_INIT (&queue->list);
return (queue); return (queue);
} }
@ -127,7 +133,7 @@ cmdq_new(void)
void void
cmdq_free(struct cmdq_list *queue) cmdq_free(struct cmdq_list *queue)
{ {
if (!TAILQ_EMPTY(queue)) if (!TAILQ_EMPTY(&queue->list))
fatalx("queue not empty"); fatalx("queue not empty");
free(queue); free(queue);
} }
@ -289,12 +295,12 @@ cmdq_append(struct client *c, struct cmdq_item *item)
item->client = c; item->client = c;
item->queue = queue; item->queue = queue;
TAILQ_INSERT_TAIL(queue, item, entry); TAILQ_INSERT_TAIL(&queue->list, item, entry);
log_debug("%s %s: %s", __func__, cmdq_name(c), item->name); log_debug("%s %s: %s", __func__, cmdq_name(c), item->name);
item = next; item = next;
} while (item != NULL); } while (item != NULL);
return (TAILQ_LAST(queue, cmdq_list)); return (TAILQ_LAST(&queue->list, cmdq_item_list));
} }
/* Insert an item. */ /* Insert an item. */
@ -315,7 +321,7 @@ cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
item->client = c; item->client = c;
item->queue = queue; item->queue = queue;
TAILQ_INSERT_AFTER(queue, after, item, entry); TAILQ_INSERT_AFTER(&queue->list, after, item, entry);
log_debug("%s %s: %s after %s", __func__, cmdq_name(c), log_debug("%s %s: %s after %s", __func__, cmdq_name(c),
item->name, after->name); item->name, after->name);
@ -399,7 +405,7 @@ cmdq_remove(struct cmdq_item *item)
cmd_list_free(item->cmdlist); cmd_list_free(item->cmdlist);
cmdq_free_state(item->state); cmdq_free_state(item->state);
TAILQ_REMOVE(item->queue, item, entry); TAILQ_REMOVE(&item->queue->list, item, entry);
free(item->name); free(item->name);
free(item); free(item);
@ -621,18 +627,18 @@ cmdq_next(struct client *c)
u_int items = 0; u_int items = 0;
static u_int number; static u_int number;
if (TAILQ_EMPTY(queue)) { if (TAILQ_EMPTY(&queue->list)) {
log_debug("%s %s: empty", __func__, name); log_debug("%s %s: empty", __func__, name);
return (0); return (0);
} }
if (TAILQ_FIRST(queue)->flags & CMDQ_WAITING) { if (TAILQ_FIRST(&queue->list)->flags & CMDQ_WAITING) {
log_debug("%s %s: waiting", __func__, name); log_debug("%s %s: waiting", __func__, name);
return (0); return (0);
} }
log_debug("%s %s: enter", __func__, name); log_debug("%s %s: enter", __func__, name);
for (;;) { for (;;) {
item = TAILQ_FIRST(queue); item = queue->item = TAILQ_FIRST(&queue->list);
if (item == NULL) if (item == NULL)
break; break;
log_debug("%s %s: %s (%d), flags %x", __func__, name, log_debug("%s %s: %s (%d), flags %x", __func__, name,
@ -682,6 +688,7 @@ cmdq_next(struct client *c)
} }
cmdq_remove(item); cmdq_remove(item);
} }
queue->item = NULL;
log_debug("%s %s: exit (empty)", __func__, name); log_debug("%s %s: exit (empty)", __func__, name);
return (items); return (items);
@ -691,6 +698,15 @@ waiting:
return (items); return (items);
} }
/* Get running item if any. */
struct cmdq_item *
cmdq_running(struct client *c)
{
struct cmdq_list *queue = cmdq_get(c);
return (queue->item);
}
/* Print a guard line. */ /* Print a guard line. */
void void
cmdq_guard(struct cmdq_item *item, const char *guard, int flags) cmdq_guard(struct cmdq_item *item, const char *guard, int flags)

View File

@ -158,7 +158,11 @@ notify_add(const char *name, struct cmd_find_state *fs, struct client *c,
struct session *s, struct window *w, struct window_pane *wp) struct session *s, struct window *w, struct window_pane *wp)
{ {
struct notify_entry *ne; struct notify_entry *ne;
struct cmdq_item *new_item; struct cmdq_item *item;
item = cmdq_running(NULL);
if (item != NULL && (cmdq_get_flags(item) & CMDQ_STATE_NOHOOKS))
return;
ne = xcalloc(1, sizeof *ne); ne = xcalloc(1, sizeof *ne);
ne->name = xstrdup(name); ne->name = xstrdup(name);
@ -183,8 +187,7 @@ notify_add(const char *name, struct cmd_find_state *fs, struct client *c,
if (ne->fs.s != NULL) /* cmd_find_valid_state needs session */ if (ne->fs.s != NULL) /* cmd_find_valid_state needs session */
session_add_ref(ne->fs.s, __func__); session_add_ref(ne->fs.s, __func__);
new_item = cmdq_get_callback(notify_callback, ne); cmdq_append(NULL, cmdq_get_callback(notify_callback, ne));
cmdq_append(NULL, new_item);
} }
void void

1
tmux.h
View File

@ -2132,6 +2132,7 @@ void cmdq_insert_hook(struct session *, struct cmdq_item *,
struct cmd_find_state *, const char *, ...); struct cmd_find_state *, const char *, ...);
void cmdq_continue(struct cmdq_item *); void cmdq_continue(struct cmdq_item *);
u_int cmdq_next(struct client *); u_int cmdq_next(struct client *);
struct cmdq_item *cmdq_running(struct client *);
void cmdq_guard(struct cmdq_item *, const char *, int); void cmdq_guard(struct cmdq_item *, const char *, int);
void printflike(2, 3) cmdq_print(struct cmdq_item *, const char *, ...); void printflike(2, 3) cmdq_print(struct cmdq_item *, const char *, ...);
void printflike(2, 3) cmdq_error(struct cmdq_item *, const char *, ...); void printflike(2, 3) cmdq_error(struct cmdq_item *, const char *, ...);