From 7711b06b6b05761172d45a984399b890d708fd32 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Thu, 30 Apr 2020 15:48:44 +0200 Subject: [PATCH] watchlist: Save the watchlist pointer in WATCHLIST_NOTIFY_* Save the value of the watchlist pointer at the beginning of the WATCHLIST_NOTIFY_* macros as if it was a function. This will fix a frame-xchg.c scenario in which one of the watch callback removes the frame watch group and the memory where the watchlist pointer was becomes unallocated but the macro still needs to access it ones or twice while it destroys the watchlist. Another option would be for the pointer to be copied in frame-xchg.c itself. --- src/watchlist.h | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/watchlist.h b/src/watchlist.h index c3632859..7f5f557a 100644 --- a/src/watchlist.h +++ b/src/watchlist.h @@ -58,34 +58,36 @@ void watchlist_free(struct watchlist *watchlist); void __watchlist_prune_stale(struct watchlist *watchlist); -#define WATCHLIST_NOTIFY(watchlist, type, args...) \ +#define WATCHLIST_NOTIFY(list, type, args...) \ do { \ + struct watchlist *watchlist = (list); \ const struct l_queue_entry *entry = \ - l_queue_get_entries((watchlist)->items);\ + l_queue_get_entries(watchlist->items); \ \ - (watchlist)->in_notify = true; \ + watchlist->in_notify = true; \ for (; entry; entry = entry->next) { \ struct watchlist_item *item = entry->data; \ type t = item->notify; \ if (item->id == 0) \ continue; \ t(args, item->notify_data); \ - if ((watchlist)->pending_destroy) \ + if (watchlist->pending_destroy) \ break; \ } \ - (watchlist)->in_notify = false; \ - if ((watchlist)->pending_destroy) \ + watchlist->in_notify = false; \ + if (watchlist->pending_destroy) \ watchlist_destroy(watchlist); \ - else if ((watchlist)->stale_items) \ + else if (watchlist->stale_items) \ __watchlist_prune_stale(watchlist); \ } while (false) \ -#define WATCHLIST_NOTIFY_MATCHES(watchlist, match, match_data, type, args...) \ +#define WATCHLIST_NOTIFY_MATCHES(list, match, match_data, type, args...) \ do { \ + struct watchlist *watchlist = (list); \ const struct l_queue_entry *entry = \ - l_queue_get_entries((watchlist)->items);\ + l_queue_get_entries(watchlist->items); \ \ - (watchlist)->in_notify = true; \ + watchlist->in_notify = true; \ for (; entry; entry = entry->next) { \ struct watchlist_item *item = entry->data; \ type t = item->notify; \ @@ -97,34 +99,35 @@ void __watchlist_prune_stale(struct watchlist *watchlist); \ t(args, item->notify_data); \ \ - if ((watchlist)->pending_destroy) \ + if (watchlist->pending_destroy) \ break; \ } \ - (watchlist)->in_notify = false; \ - if ((watchlist)->pending_destroy) \ + watchlist->in_notify = false; \ + if (watchlist->pending_destroy) \ watchlist_destroy(watchlist); \ - else if ((watchlist)->stale_items) \ + else if (watchlist->stale_items) \ __watchlist_prune_stale(watchlist); \ } while (false) -#define WATCHLIST_NOTIFY_NO_ARGS(watchlist, type) \ +#define WATCHLIST_NOTIFY_NO_ARGS(list, type) \ do { \ + struct watchlist *watchlist = (list); \ const struct l_queue_entry *entry = \ - l_queue_get_entries((watchlist)->items);\ + l_queue_get_entries(watchlist->items); \ \ - (watchlist)->in_notify = true; \ + watchlist->in_notify = true; \ for (; entry; entry = entry->next) { \ struct watchlist_item *item = entry->data; \ type t = item->notify; \ if (item->id == 0) \ continue; \ t(item->notify_data); \ - if ((watchlist)->pending_destroy) \ + if (watchlist->pending_destroy) \ break; \ } \ - (watchlist)->in_notify = false; \ - if ((watchlist)->pending_destroy) \ + watchlist->in_notify = false; \ + if (watchlist->pending_destroy) \ watchlist_destroy(watchlist); \ - else if ((watchlist)->stale_items) \ + else if (watchlist->stale_items) \ __watchlist_prune_stale(watchlist); \ } while (false)