mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-19 08:57:14 -05:00
loop: simplify before and after events
Because the signal can't be removed from the callback we can simply iterate backwards and then forwards. The first added hook (the unlock/lock pair) is called last before going into the poll and first when leaving. This executes all other callbacks inside a locked situation. And removing them with the lock is not going to cause problems.
This commit is contained in:
parent
854d019343
commit
e5f7e040dc
3 changed files with 28 additions and 16 deletions
|
|
@ -113,7 +113,9 @@ struct spa_loop_methods {
|
||||||
#define spa_loop_invoke(l,...) spa_loop_method(l,invoke,0,##__VA_ARGS__)
|
#define spa_loop_invoke(l,...) spa_loop_method(l,invoke,0,##__VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
/** Control hooks */
|
/** Control hooks. These hooks can't be removed from their
|
||||||
|
* callbacks and must be removed from a safe place (when the loop
|
||||||
|
* is not running or when it is locked). */
|
||||||
struct spa_loop_control_hooks {
|
struct spa_loop_control_hooks {
|
||||||
#define SPA_VERSION_LOOP_CONTROL_HOOKS 0
|
#define SPA_VERSION_LOOP_CONTROL_HOOKS 0
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
@ -125,8 +127,21 @@ struct spa_loop_control_hooks {
|
||||||
void (*after) (void *data);
|
void (*after) (void *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define spa_loop_control_hook_before(l) spa_hook_list_call_simple(l, struct spa_loop_control_hooks, before, 0)
|
#define spa_loop_control_hook_before(l) \
|
||||||
#define spa_loop_control_hook_after(l) spa_hook_list_call_simple(l, struct spa_loop_control_hooks, after, 0)
|
({ \
|
||||||
|
struct spa_hook_list *_l = l; \
|
||||||
|
struct spa_hook *_h; \
|
||||||
|
spa_list_for_each_reverse(_h, &_l->list, link) \
|
||||||
|
spa_callbacks_call(&_h->cb, struct spa_loop_control_hooks, before, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define spa_loop_control_hook_after(l) \
|
||||||
|
({ \
|
||||||
|
struct spa_hook_list *_l = l; \
|
||||||
|
struct spa_hook *_h; \
|
||||||
|
spa_list_for_each(_h, &_l->list, link) \
|
||||||
|
spa_callbacks_call(&_h->cb, struct spa_loop_control_hooks, after, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control an event loop
|
* Control an event loop
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,17 @@ static inline void spa_list_remove(struct spa_list *elem)
|
||||||
!spa_list_is_end(pos, head, member); \
|
!spa_list_is_end(pos, head, member); \
|
||||||
pos = spa_list_next(pos, member))
|
pos = spa_list_next(pos, member))
|
||||||
|
|
||||||
|
#define spa_list_for_each_prev(pos, head, curr, member) \
|
||||||
|
for (pos = spa_list_last(curr, __typeof__(*pos), member); \
|
||||||
|
!spa_list_is_end(pos, head, member); \
|
||||||
|
pos = spa_list_prev(pos, member))
|
||||||
|
|
||||||
#define spa_list_for_each(pos, head, member) \
|
#define spa_list_for_each(pos, head, member) \
|
||||||
spa_list_for_each_next(pos, head, head, member)
|
spa_list_for_each_next(pos, head, head, member)
|
||||||
|
|
||||||
|
#define spa_list_for_each_reverse(pos, head, member) \
|
||||||
|
spa_list_for_each_prev(pos, head, head, member)
|
||||||
|
|
||||||
#define spa_list_for_each_safe_next(pos, tmp, head, curr, member) \
|
#define spa_list_for_each_safe_next(pos, tmp, head, curr, member) \
|
||||||
for (pos = spa_list_first(curr, __typeof__(*pos), member); \
|
for (pos = spa_list_first(curr, __typeof__(*pos), member); \
|
||||||
tmp = spa_list_next(pos, member), \
|
tmp = spa_list_next(pos, member), \
|
||||||
|
|
|
||||||
|
|
@ -278,24 +278,13 @@ static int loop_iterate(void *object, int timeout)
|
||||||
struct impl *impl = object;
|
struct impl *impl = object;
|
||||||
struct spa_loop *loop = &impl->loop;
|
struct spa_loop *loop = &impl->loop;
|
||||||
struct spa_poll_event ep[32];
|
struct spa_poll_event ep[32];
|
||||||
struct spa_list save;
|
|
||||||
struct spa_hook *hook;
|
|
||||||
int i, nfds;
|
int i, nfds;
|
||||||
|
|
||||||
spa_list_init(&save);
|
spa_loop_control_hook_before(&impl->hooks_list);
|
||||||
spa_list_consume(hook, &impl->hooks_list.list, link) {
|
|
||||||
spa_list_remove(&hook->link);
|
|
||||||
spa_list_prepend(&save, &hook->link);
|
|
||||||
spa_callbacks_call(&hook->cb, struct spa_loop_control_hooks, before, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
nfds = spa_system_pollfd_wait(impl->system, impl->poll_fd, ep, SPA_N_ELEMENTS(ep), timeout);
|
nfds = spa_system_pollfd_wait(impl->system, impl->poll_fd, ep, SPA_N_ELEMENTS(ep), timeout);
|
||||||
|
|
||||||
spa_list_consume(hook, &save, link) {
|
spa_loop_control_hook_after(&impl->hooks_list);
|
||||||
spa_list_remove(&hook->link);
|
|
||||||
spa_list_append(&impl->hooks_list.list, &hook->link);
|
|
||||||
spa_callbacks_call(&hook->cb, struct spa_loop_control_hooks, after, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SPA_UNLIKELY(nfds < 0))
|
if (SPA_UNLIKELY(nfds < 0))
|
||||||
return nfds;
|
return nfds;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue