From: NeilBrown Date: Wed, 13 Sep 2023 22:32:17 +0000 (+1000) Subject: Introduce closed_ok flag on commands. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=fe509bd687080aa9ee10a58a4cf06a2485e74dfd;p=edlib.git Introduce closed_ok flag on commands. If closed_ok is set, then it is safe to call the command even if ->home is DAMAGED_CLOSED. This will eventually replace checks on "Close". For now it allows doc_pass_on to pass commands on to the doc even when the display stack is shutting down. notmuch needs this to ask the query doc to refresh when a view is closed. Signed-off-by: NeilBrown --- diff --git a/core-doc.c b/core-doc.c index 645d2825..1e154290 100644 --- a/core-doc.c +++ b/core-doc.c @@ -639,7 +639,7 @@ DEF_CMD(doc_request_notify) return 1; } -DEF_CMD(doc_notify) +DEF_CMD_CLOSED(doc_notify) { /* Key is "doc:notify:..." */ int ret = pane_notify(ksuffix(ci, "doc:notify:"), @@ -679,7 +679,8 @@ static int do_del_view(struct doc *d safe, int v, call("editor:notify:Message:broadcast", owner, 0, NULL, "WARNING mark not freed by Close:mark"); - LOG("WARNING Mark not freed by Close:mark"); + LOG("WARNING Mark on %s not freed by Close:mark", + owner->name); warned = True; } m->mdata = NULL; @@ -1165,7 +1166,7 @@ DEF_CMD(doc_clip) return 1; } -DEF_CMD(doc_pass_on) +DEF_CMD_CLOSED(doc_pass_on) { struct doc_data *dd = ci->home->data; int ret = home_call(dd->doc, ci->key, ci->focus, ci->num, diff --git a/core-keymap.c b/core-keymap.c index d766953e..14a5e520 100644 --- a/core-keymap.c +++ b/core-keymap.c @@ -558,7 +558,9 @@ int key_handle(const struct cmd_info *ci safe) while (p) { int ret = Efallthrough; - if (p->handle && !(p->damaged & DAMAGED_CLOSED)) { + if (p->handle && + (p->handle->closed_ok || + !(p->damaged & DAMAGED_CLOSED))) { vci->home = p; vci->comm = p->handle; /* Don't add this to the call stack as it diff --git a/core-pane.h b/core-pane.h index 6c323c44..ebc27fa0 100644 --- a/core-pane.h +++ b/core-pane.h @@ -132,6 +132,7 @@ static inline int do_call_val(enum target_type type, struct pane *home, if (home) ci.home = home; if ((home->damaged & DAMAGED_CLOSED) && + !home->handle->closed_ok && ci.key[0] != 'C' && /* Compile will often optimise * the strncmp away */ @@ -148,7 +149,8 @@ static inline int do_call_val(enum target_type type, struct pane *home, return Efail; if (home) ci.home = home; - if (ci.home->damaged & DAMAGED_CLOSED) + if (ci.home->damaged & DAMAGED_CLOSED && + !comm2a->closed_ok) return Efallthrough; ci.comm = comm2a; ci.comm2 = comm2b; diff --git a/core.h b/core.h index af62ada0..25fcb925 100644 --- a/core.h +++ b/core.h @@ -64,10 +64,11 @@ void LOG_BT(void); struct pane ; struct command { - int (*func)(const struct cmd_info *ci safe); - int refcnt; /* only if 'free' is not NULL */ - void (*free)(struct command *c safe); - const char *name; + int (*func)(const struct cmd_info *ci safe); + unsigned int refcnt; /* only if 'free' is not NULL */ + unsigned int closed_ok:1; + void (*free)(struct command *c safe); + const char *name; }; enum edlib_errors { @@ -92,7 +93,7 @@ static inline struct command *safe command_get(struct command * safe c) static inline void command_put(struct command *c) { - if (c && c->free && c->refcnt-- == 1) + if (c && c->free && --c->refcnt == 0) c->free(c); } @@ -300,13 +301,23 @@ struct lookup_cmd { struct map **m safe; }; -#define CMD(_name) {.func = _name ## _func , \ - .refcnt = 0, \ - .free = NULL, \ - .name = # _name, \ +#define CMD(_name) { \ + .func = _name ## _func , \ + .refcnt = 0, \ + .closed_ok = 0, \ + .free = NULL, \ + .name = # _name, \ + } +#define CMD_CLOSED(_name) { \ + .func = _name ## _func , \ + .refcnt = 0, \ + .closed_ok = 1, \ + .free = NULL, \ + .name = # _name, \ } #define CB(_name) {.func = _name ## _func , \ .refcnt = 0, \ + .closed_ok = 0, \ .free = NULL, \ .name = # _name, \ } @@ -315,6 +326,10 @@ struct lookup_cmd { static int _name ## _func(const struct cmd_info *ci safe); \ static struct command _name = CMD(_name); \ static int _name ## _func(const struct cmd_info *ci safe) +#define DEF_CMD_CLOSED(_name) \ + static int _name ## _func(const struct cmd_info *ci safe); \ + static struct command _name = CMD_CLOSED(_name); \ + static int _name ## _func(const struct cmd_info *ci safe) #define REDEF_CMD(_name) \ static int _name ## _func(const struct cmd_info *ci safe) #define DEF_EXTERN_CMD(_name) \ @@ -334,6 +349,7 @@ struct lookup_cmd { static struct lookup_cmd _name = { \ .c.func = key_lookup_cmd_func, \ .c.refcnt = 0, \ + .c.closed_ok = 1, \ .c.free = NULL, \ .c.name = #_name, \ .m = &_map, \ @@ -354,6 +370,7 @@ int key_pfx_func(const struct cmd_info *ci safe); static struct pfx_cmd _name = { \ .c.func = key_pfx_func, \ .c.refcnt = 0, \ + .c.closed_ok = 1, \ .c.free = NULL, \ .c.name = "prefix" #_pfx, \ .pfx = _pfx, \ diff --git a/lang-python.c b/lang-python.c index 2152dcd7..6c8ccd1c 100644 --- a/lang-python.c +++ b/lang-python.c @@ -114,6 +114,7 @@ static struct python_command *export_callable(PyObject *callable safe) c->c = python_call; c->c.free = python_free_command; c->c.refcnt = 0; + c->c.closed_ok = 0; command_get(&c->c); Py_INCREF(callable); c->callable = callable; @@ -722,6 +723,7 @@ static int do_Pane_init(Pane *self safe, PyObject *args, PyObject *kwds, self->map = key_alloc(); key_add(self->map, "Close:mark", &python_close_mark); self->cmd = python_pane_call; + self->cmd.closed_ok = 1; self->cmd.free = python_pane_free; if (self->ob_base.ob_type) self->cmd.name = self->ob_base.ob_type->tp_name;