mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
watchlist: Allow watch CBs to call watchlist_destroy
If during WATCHLIST_NOTIFY{,_MATCHES,_NO_ARGS} one of the watch notify callback triggers a call to watchlist_destroy, give up calling remaining watches and destroy the watchlist without crashing. This is useful in frame-xchg.c (P2P use case) where a frame watch may trigger a move to a new state after receiving a specific frame, and remove one group of frame watches (including its watchlist) to create a different group.
This commit is contained in:
parent
a2006a3d29
commit
9e18552fe7
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user