mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-31 23:42:52 +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;
|
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,
|
item = l_queue_remove_if(watchlist->items, watchlist_item_match,
|
||||||
L_UINT_TO_PTR(id));
|
L_UINT_TO_PTR(id));
|
||||||
if (!item)
|
if (!item)
|
||||||
@ -105,3 +117,18 @@ void watchlist_free(struct watchlist *watchlist)
|
|||||||
l_queue_destroy(watchlist->items, watchlist_item_free);
|
l_queue_destroy(watchlist->items, watchlist_item_free);
|
||||||
l_free(watchlist);
|
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 {
|
struct watchlist {
|
||||||
int next_id;
|
int next_id;
|
||||||
struct l_queue *items;
|
struct l_queue *items;
|
||||||
|
bool in_notify : 1;
|
||||||
|
bool stale_items : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct watchlist *watchlist_new(void);
|
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_destroy(struct watchlist *watchlist);
|
||||||
void watchlist_free(struct watchlist *watchlist);
|
void watchlist_free(struct watchlist *watchlist);
|
||||||
|
|
||||||
|
void __watchlist_prune_stale(struct watchlist *watchlist);
|
||||||
|
|
||||||
#define WATCHLIST_NOTIFY(watchlist, type, args...) \
|
#define WATCHLIST_NOTIFY(watchlist, type, args...) \
|
||||||
do { \
|
do { \
|
||||||
const struct l_queue_entry *entry = \
|
const struct l_queue_entry *entry = \
|
||||||
l_queue_get_entries((watchlist)->items);\
|
l_queue_get_entries((watchlist)->items);\
|
||||||
\
|
\
|
||||||
|
(watchlist)->in_notify = true; \
|
||||||
for (; entry; entry = entry->next) { \
|
for (; entry; entry = entry->next) { \
|
||||||
struct watchlist_item *item = entry->data; \
|
struct watchlist_item *item = entry->data; \
|
||||||
type t = item->notify; \
|
type t = item->notify; \
|
||||||
t(args, item->notify_data); \
|
t(args, item->notify_data); \
|
||||||
} \
|
} \
|
||||||
|
(watchlist)->in_notify = false; \
|
||||||
|
if ((watchlist)->stale_items) \
|
||||||
|
__watchlist_prune_stale(watchlist); \
|
||||||
} while (false) \
|
} while (false) \
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user