]> git.neil.brown.name Git - edlib.git/commitdiff
Delay freeing of pane->handle
authorNeilBrown <neil@brown.name>
Fri, 7 Feb 2020 05:54:10 +0000 (16:54 +1100)
committerNeilBrown <neil@brown.name>
Fri, 7 Feb 2020 05:54:10 +0000 (16:54 +1100)
Next patch will need to call on a pane very late, to get it
to free ->data.  So we need the handle to persist to the very end.

This means we need a new DAMAGED_DEAD to be set after 'Close' to ensure
nothing else gets called on the pane in the interim.

Signed-off-by: NeilBrown <neil@brown.name>
core-editor.c
core-keymap.c
core-pane.c
core.h

index ba0172d4a0a2b4c75be767250ef841920137644d..ad270f611e8577ee5acffabb71fc875dd06c38da 100644 (file)
@@ -225,6 +225,8 @@ DEF_CMD(editor_clean_up)
        while (ei->freelist) {
                struct pane *p = ei->freelist;
                ei->freelist = p->focus;
+               command_put(p->handle);
+               p->handle = NULL;
                attr_free(&p->attrs);
                free(p);
        }
@@ -333,6 +335,8 @@ void editor_delayed_free(struct pane *ed safe, struct pane *p safe)
 {
        struct ed_info *ei = ed->data;
        if (!ei) {
+               command_put(p->handle);
+               p->handle = NULL;
                attr_free(&p->attrs);
                free(p);
                return;
index 52a820fae6847dd4ed777b4eff91a947cf033d85..c0ccc64b6b133ab5b7c64520df27c88ef6114dda 100644 (file)
@@ -483,7 +483,7 @@ int key_handle(const struct cmd_info *ci safe)
 
        while (p) {
                int ret = 0;
-               if (p->handle) {
+               if (p->handle && !(p->damaged & DAMAGED_DEAD)) {
                        vci->home = p;
                        vci->comm = p->handle;
                        ret = p->handle->func(ci);
index 91dcddfd607c68c84fb34b72998f434a9ba1b657..96dadad425105b2d0d929ce4b2ff4a6a2a1bd355 100644 (file)
@@ -419,11 +419,12 @@ restart:
         * ->parent in place so a full range of commands are available.
         */
        // p->parent = p;
-       command_put(p->handle);
-       p->handle = NULL;
+       p->damaged |= DAMAGED_DEAD;
        if (ed != p)
                editor_delayed_free(ed, p);
        else {
+               command_put(p->handle);
+               p->handle = NULL;
                attr_free(&p->attrs);
                free(p);
        }
diff --git a/core.h b/core.h
index b140e50c771a15a7acf9d0274ab96a14e6e4e6ac..755825ac00cde89fb053ff40192e567bdc053dd5 100644 (file)
--- a/core.h
+++ b/core.h
@@ -15,7 +15,6 @@
 #include <limits.h>
 #include <sys/stat.h>
 #include <stdlib.h>
-
 #include "safe.h"
 
 #include "list.h"
@@ -392,6 +391,7 @@ enum {
 
        DAMAGED_POSTORDER= 512,
        DAMAGED_CLOSED  = 1024,
+       DAMAGED_DEAD    = 2048, /* Fully closed, but not freed yet */
 };
 #define DAMAGED_NEED_CALL (DAMAGED_SIZE | DAMAGED_CONTENT | DAMAGED_CURSOR)
 
@@ -671,7 +671,7 @@ static inline int do_call_val(enum target_type type, struct pane *home,
                ret = key_handle(&ci);
                break;
        case TYPE_pane:
-               if (!home->handle)
+               if (!home->handle || (home->damaged & DAMAGED_DEAD))
                        return Efail;
                ci.comm = home->handle;
                ret = ci.comm->func(&ci);