mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-23 06:02:37 +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)
|
void watchlist_destroy(struct watchlist *watchlist)
|
||||||
{
|
{
|
||||||
|
if (watchlist->in_notify) {
|
||||||
|
watchlist->pending_destroy = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
__watchlist_clear(watchlist);
|
__watchlist_clear(watchlist);
|
||||||
l_queue_destroy(watchlist->items, NULL);
|
l_queue_destroy(watchlist->items, NULL);
|
||||||
watchlist->items = NULL;
|
watchlist->items = NULL;
|
||||||
|
@ -38,6 +38,7 @@ struct watchlist {
|
|||||||
struct l_queue *items;
|
struct l_queue *items;
|
||||||
bool in_notify : 1;
|
bool in_notify : 1;
|
||||||
bool stale_items : 1;
|
bool stale_items : 1;
|
||||||
|
bool pending_destroy : 1;
|
||||||
const struct watchlist_ops *ops;
|
const struct watchlist_ops *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -69,9 +70,13 @@ void __watchlist_prune_stale(struct watchlist *watchlist);
|
|||||||
if (item->id == 0) \
|
if (item->id == 0) \
|
||||||
continue; \
|
continue; \
|
||||||
t(args, item->notify_data); \
|
t(args, item->notify_data); \
|
||||||
|
if ((watchlist)->pending_destroy) \
|
||||||
|
break; \
|
||||||
} \
|
} \
|
||||||
(watchlist)->in_notify = false; \
|
(watchlist)->in_notify = false; \
|
||||||
if ((watchlist)->stale_items) \
|
if ((watchlist)->pending_destroy) \
|
||||||
|
watchlist_destroy(watchlist); \
|
||||||
|
else if ((watchlist)->stale_items) \
|
||||||
__watchlist_prune_stale(watchlist); \
|
__watchlist_prune_stale(watchlist); \
|
||||||
} while (false) \
|
} while (false) \
|
||||||
|
|
||||||
@ -91,9 +96,14 @@ void __watchlist_prune_stale(struct watchlist *watchlist);
|
|||||||
continue; \
|
continue; \
|
||||||
\
|
\
|
||||||
t(args, item->notify_data); \
|
t(args, item->notify_data); \
|
||||||
|
\
|
||||||
|
if ((watchlist)->pending_destroy) \
|
||||||
|
break; \
|
||||||
} \
|
} \
|
||||||
(watchlist)->in_notify = false; \
|
(watchlist)->in_notify = false; \
|
||||||
if ((watchlist)->stale_items) \
|
if ((watchlist)->pending_destroy) \
|
||||||
|
watchlist_destroy(watchlist); \
|
||||||
|
else if ((watchlist)->stale_items) \
|
||||||
__watchlist_prune_stale(watchlist); \
|
__watchlist_prune_stale(watchlist); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
@ -109,8 +119,12 @@ void __watchlist_prune_stale(struct watchlist *watchlist);
|
|||||||
if (item->id == 0) \
|
if (item->id == 0) \
|
||||||
continue; \
|
continue; \
|
||||||
t(item->notify_data); \
|
t(item->notify_data); \
|
||||||
|
if ((watchlist)->pending_destroy) \
|
||||||
|
break; \
|
||||||
} \
|
} \
|
||||||
(watchlist)->in_notify = false; \
|
(watchlist)->in_notify = false; \
|
||||||
if ((watchlist)->stale_items) \
|
if ((watchlist)->pending_destroy) \
|
||||||
|
watchlist_destroy(watchlist); \
|
||||||
|
else if ((watchlist)->stale_items) \
|
||||||
__watchlist_prune_stale(watchlist); \
|
__watchlist_prune_stale(watchlist); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
Loading…
Reference in New Issue
Block a user