common: don't free a busy nl_pid_watch_t. v0.0.37 v0.0.38
authorKrisztian Litkey <kli@iki.fi>
Mon, 30 Sep 2013 15:53:43 +0000 (18:53 +0300)
committerKrisztian Litkey <kli@iki.fi>
Tue, 1 Oct 2013 05:22:23 +0000 (08:22 +0300)
Mark an nl_pid_watch_t busy while it is being scanned. If a
client callback destroys the last watch, check if the pid
watch is busy. If it is, just unhash it and mark it dead,
otherwise unhash and destroy it right away. Each time a watch
scan finishes, check and destroy the watch if it has been
marked dead.

src/common/process.c

index 697a112..840480d 100644 (file)
@@ -78,6 +78,8 @@ typedef struct {
 
     mrp_list_hook_t clients;
     int n_clients;
+    int busy : 1;
+    int dead : 1;
 } nl_pid_watch_t;
 
 /* murphy pid file directory notify */
@@ -144,7 +146,10 @@ static void htbl_free_nl_watch(void *key, void *object)
 
     MRP_UNUSED(key);
 
-    mrp_free(w);
+    if (!w->busy)
+        mrp_free(w);
+    else
+        w->dead = TRUE;
 }
 
 
@@ -386,6 +391,7 @@ static void nl_watch(mrp_io_watch_t *w, int fd, mrp_io_event_t events,
                         break;
                     }
 
+                    nl_w->busy = TRUE;
                     mrp_list_foreach(&nl_w->clients, p, n) {
                         nl_pid_client_t *client;
 
@@ -393,6 +399,10 @@ static void nl_watch(mrp_io_watch_t *w, int fd, mrp_io_event_t events,
                         client->cb(nl_w->pid, MRP_PROCESS_STATE_NOT_READY,
                                 client->user_data);
                     }
+                    if (nl_w->dead)
+                        mrp_free(nl_w);
+                    else
+                        nl_w->busy = FALSE;
 
                     /* TODO: should we automatically free the wathces? Or let
                      * client do that to preserver symmetricity? */