diff --git a/src/watchlist.c b/src/watchlist.c index 4f4d8259..a14476bd 100644 --- a/src/watchlist.c +++ b/src/watchlist.c @@ -127,6 +127,11 @@ static void __watchlist_clear(struct watchlist *watchlist) void watchlist_destroy(struct watchlist *watchlist) { + if (watchlist->in_notify) { + watchlist->pending_destroy = true; + return; + } + __watchlist_clear(watchlist); l_queue_destroy(watchlist->items, NULL); watchlist->items = NULL; diff --git a/src/watchlist.h b/src/watchlist.h index cd408ac8..c3632859 100644 --- a/src/watchlist.h +++ b/src/watchlist.h @@ -38,6 +38,7 @@ struct watchlist { struct l_queue *items; bool in_notify : 1; bool stale_items : 1; + bool pending_destroy : 1; const struct watchlist_ops *ops; }; @@ -69,9 +70,13 @@ void __watchlist_prune_stale(struct watchlist *watchlist); if (item->id == 0) \ continue; \ t(args, item->notify_data); \ + if ((watchlist)->pending_destroy) \ + break; \ } \ (watchlist)->in_notify = false; \ - if ((watchlist)->stale_items) \ + if ((watchlist)->pending_destroy) \ + watchlist_destroy(watchlist); \ + else if ((watchlist)->stale_items) \ __watchlist_prune_stale(watchlist); \ } while (false) \ @@ -91,9 +96,14 @@ void __watchlist_prune_stale(struct watchlist *watchlist); continue; \ \ t(args, item->notify_data); \ + \ + if ((watchlist)->pending_destroy) \ + break; \ } \ (watchlist)->in_notify = false; \ - if ((watchlist)->stale_items) \ + if ((watchlist)->pending_destroy) \ + watchlist_destroy(watchlist); \ + else if ((watchlist)->stale_items) \ __watchlist_prune_stale(watchlist); \ } while (false) @@ -108,9 +118,13 @@ void __watchlist_prune_stale(struct watchlist *watchlist); type t = item->notify; \ if (item->id == 0) \ continue; \ - t(item->notify_data); \ + t(item->notify_data); \ + if ((watchlist)->pending_destroy) \ + break; \ } \ (watchlist)->in_notify = false; \ - if ((watchlist)->stale_items) \ + if ((watchlist)->pending_destroy) \ + watchlist_destroy(watchlist); \ + else if ((watchlist)->stale_items) \ __watchlist_prune_stale(watchlist); \ } while (false)