3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-10-06 03:18:46 +02:00

watchlist: Make re-entrant safe

This commit is contained in:
Denis Kenzior 2016-09-22 15:28:29 -05:00
parent d2ccc367ef
commit 42d26089e9
2 changed files with 35 additions and 0 deletions

View File

@ -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;
}

View File

@ -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) \