mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
watchlist: Make re-entrant safe
This commit is contained in:
parent
d2ccc367ef
commit
42d26089e9
@ -82,6 +82,18 @@ bool watchlist_remove(struct watchlist *watchlist, unsigned int id)
|
||||
{
|
||||
struct watchlist_item *item;
|
||||
|
||||
if (watchlist->in_notify) {
|
||||
item = l_queue_find(watchlist->items, watchlist_item_match,
|
||||
L_UINT_TO_PTR(id));
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
item->id = 0; /* Mark stale */
|
||||
watchlist->stale_items = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
item = l_queue_remove_if(watchlist->items, watchlist_item_match,
|
||||
L_UINT_TO_PTR(id));
|
||||
if (!item)
|
||||
@ -105,3 +117,18 @@ void watchlist_free(struct watchlist *watchlist)
|
||||
l_queue_destroy(watchlist->items, watchlist_item_free);
|
||||
l_free(watchlist);
|
||||
}
|
||||
|
||||
void __watchlist_prune_stale(struct watchlist *watchlist)
|
||||
{
|
||||
struct watchlist_item *item;
|
||||
|
||||
while ((item = l_queue_remove_if(watchlist->items, watchlist_item_match,
|
||||
L_UINT_TO_PTR(0)))) {
|
||||
if (item->destroy)
|
||||
item->destroy(item->notify_data);
|
||||
|
||||
l_free(item);
|
||||
}
|
||||
|
||||
watchlist->stale_items = false;
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ struct watchlist_item {
|
||||
struct watchlist {
|
||||
int next_id;
|
||||
struct l_queue *items;
|
||||
bool in_notify : 1;
|
||||
bool stale_items : 1;
|
||||
};
|
||||
|
||||
struct watchlist *watchlist_new(void);
|
||||
@ -43,15 +45,21 @@ bool watchlist_remove(struct watchlist *watchlist, unsigned int id);
|
||||
void watchlist_destroy(struct watchlist *watchlist);
|
||||
void watchlist_free(struct watchlist *watchlist);
|
||||
|
||||
void __watchlist_prune_stale(struct watchlist *watchlist);
|
||||
|
||||
#define WATCHLIST_NOTIFY(watchlist, type, args...) \
|
||||
do { \
|
||||
const struct l_queue_entry *entry = \
|
||||
l_queue_get_entries((watchlist)->items);\
|
||||
\
|
||||
(watchlist)->in_notify = true; \
|
||||
for (; entry; entry = entry->next) { \
|
||||
struct watchlist_item *item = entry->data; \
|
||||
type t = item->notify; \
|
||||
t(args, item->notify_data); \
|
||||
} \
|
||||
(watchlist)->in_notify = false; \
|
||||
if ((watchlist)->stale_items) \
|
||||
__watchlist_prune_stale(watchlist); \
|
||||
} while (false) \
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user