mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-07 13:30:09 -05:00
node: use spa_list_for_each_safe() for pw_node_events_*
Introduce spa_hook_list_call_simple_safe() as a new helper that uses spa_list_for_each_safe() and use it for pw_node_events_* This way multiple threads can iterate at the same time and, if only one thread is active, the current list entry can be safely removed (e.g. in pw_node_events_destroy()). Without this the node listener_list may be corrupted when the main and data loop iterate over the list at the same time (See #143).
This commit is contained in:
parent
323917ab4b
commit
6b269cce35
2 changed files with 14 additions and 1 deletions
|
|
@ -94,6 +94,19 @@ static inline void spa_hook_remove(struct spa_hook *hook)
|
||||||
} \
|
} \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define spa_hook_list_call_simple_safe(l,type,method,vers,...) \
|
||||||
|
({ \
|
||||||
|
struct spa_hook_list *list = l; \
|
||||||
|
struct spa_hook *ci; \
|
||||||
|
struct spa_hook *tmp; \
|
||||||
|
spa_list_for_each_safe(ci, tmp, &list->list, link) { \
|
||||||
|
const type *cb = ci->funcs; \
|
||||||
|
if (cb && cb->version >= vers && cb->method) { \
|
||||||
|
cb->method(ci->data, ## __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
/** Call all hooks in a list, starting from the given one and optionally stopping
|
/** Call all hooks in a list, starting from the given one and optionally stopping
|
||||||
* after calling the first non-NULL function, returns the number of methods
|
* after calling the first non-NULL function, returns the number of methods
|
||||||
* called */
|
* called */
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ struct pw_module {
|
||||||
void *user_data; /**< module user_data */
|
void *user_data; /**< module user_data */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define pw_node_events_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_node_events, m, v, ##__VA_ARGS__)
|
#define pw_node_events_emit(o,m,v,...) spa_hook_list_call_simple_safe(&o->listener_list, struct pw_node_events, m, v, ##__VA_ARGS__)
|
||||||
#define pw_node_events_destroy(n) pw_node_events_emit(n, destroy, 0)
|
#define pw_node_events_destroy(n) pw_node_events_emit(n, destroy, 0)
|
||||||
#define pw_node_events_free(n) pw_node_events_emit(n, free, 0)
|
#define pw_node_events_free(n) pw_node_events_emit(n, free, 0)
|
||||||
#define pw_node_events_initialized(n) pw_node_events_emit(n, initialized, 0)
|
#define pw_node_events_initialized(n) pw_node_events_emit(n, initialized, 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue