mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
hooks: enforce version on hook emission
Pass the minimum required version to the hook emission and only call events when the handler is recent enough. Add some macros to make event emission easier to read.
This commit is contained in:
parent
a72e3cefd7
commit
a63523650d
27 changed files with 250 additions and 155 deletions
|
|
@ -113,6 +113,9 @@ struct spa_loop_control_hooks {
|
|||
void (*after) (void *data);
|
||||
};
|
||||
|
||||
#define spa_loop_control_hook_before(l) spa_hook_list_call(l, struct spa_loop_control_hooks, before, 0)
|
||||
#define spa_loop_control_hook_after(l) spa_hook_list_call(l, struct spa_loop_control_hooks, after, 0)
|
||||
|
||||
/**
|
||||
* Control an event loop
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ struct spa_hook {
|
|||
struct spa_list link;
|
||||
const void *funcs;
|
||||
void *data;
|
||||
void *priv[2]; /**< private data for the hook list */
|
||||
void *priv; /**< private data for the hook list */
|
||||
void (*removed) (struct spa_hook *hook);
|
||||
|
||||
};
|
||||
|
||||
/** Initialize a hook list */
|
||||
|
|
@ -76,12 +78,14 @@ static inline void spa_hook_list_prepend(struct spa_hook_list *list,
|
|||
static inline void spa_hook_remove(struct spa_hook *hook)
|
||||
{
|
||||
spa_list_remove(&hook->link);
|
||||
if (hook->removed)
|
||||
hook->removed(hook);
|
||||
}
|
||||
|
||||
/** 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
|
||||
* called */
|
||||
#define spa_hook_list_do_call(l,start,type,method,once,...) \
|
||||
#define spa_hook_list_do_call(l,start,type,method,vers,once,...) \
|
||||
({ \
|
||||
struct spa_hook_list *list = l; \
|
||||
struct spa_list *s = start ? (struct spa_list *)start : &list->list; \
|
||||
|
|
@ -95,7 +99,7 @@ static inline void spa_hook_remove(struct spa_hook *hook)
|
|||
const type *cb = ci->funcs; \
|
||||
spa_list_remove(&ci->link); \
|
||||
spa_list_append(&cursor.link, &ci->link); \
|
||||
if (cb && cb->method) { \
|
||||
if (cb && cb->version >= vers && cb->method) { \
|
||||
cb->method(ci->data, ## __VA_ARGS__); \
|
||||
count++; \
|
||||
if (once) \
|
||||
|
|
@ -106,11 +110,11 @@ static inline void spa_hook_remove(struct spa_hook *hook)
|
|||
count; \
|
||||
})
|
||||
|
||||
#define spa_hook_list_call(l,t,m,...) spa_hook_list_do_call(l,NULL,t,m,false,##__VA_ARGS__)
|
||||
#define spa_hook_list_call_once(l,t,m,...) spa_hook_list_do_call(l,NULL,t,m,true,##__VA_ARGS__)
|
||||
#define spa_hook_list_call(l,t,m,v,...) spa_hook_list_do_call(l,NULL,t,m,v,false,##__VA_ARGS__)
|
||||
#define spa_hook_list_call_once(l,t,m,v,...) spa_hook_list_do_call(l,NULL,t,m,v,true,##__VA_ARGS__)
|
||||
|
||||
#define spa_hook_list_call_start(l,s,t,m,...) spa_hook_list_do_call(l,s,t,m,false,##__VA_ARGS__)
|
||||
#define spa_hook_list_call_once_start(l,s,t,m,...) spa_hook_list_do_call(l,s,t,m,true,##__VA_ARGS__)
|
||||
#define spa_hook_list_call_start(l,s,t,m,v,...) spa_hook_list_do_call(l,s,t,m,v,false,##__VA_ARGS__)
|
||||
#define spa_hook_list_call_once_start(l,s,t,m,v,...) spa_hook_list_do_call(l,s,t,m,v,true,##__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,13 +250,13 @@ loop_invoke(struct spa_loop *loop,
|
|||
if (block) {
|
||||
uint64_t count = 1;
|
||||
|
||||
spa_hook_list_call(&impl->hooks_list, struct spa_loop_control_hooks, before);
|
||||
spa_loop_control_hook_before(&impl->hooks_list);
|
||||
|
||||
if (read(impl->ack_fd, &count, sizeof(uint64_t)) != sizeof(uint64_t))
|
||||
spa_log_warn(impl->log, NAME " %p: failed to read event fd: %s",
|
||||
impl, strerror(errno));
|
||||
|
||||
spa_hook_list_call(&impl->hooks_list, struct spa_loop_control_hooks, after);
|
||||
spa_loop_control_hook_after(&impl->hooks_list);
|
||||
|
||||
res = item->res;
|
||||
}
|
||||
|
|
@ -340,12 +340,12 @@ static int loop_iterate(struct spa_loop_control *ctrl, int timeout)
|
|||
struct epoll_event ep[32];
|
||||
int i, nfds, save_errno = 0;
|
||||
|
||||
spa_hook_list_call(&impl->hooks_list, struct spa_loop_control_hooks, before);
|
||||
spa_loop_control_hook_before(&impl->hooks_list);
|
||||
|
||||
if (SPA_UNLIKELY((nfds = epoll_wait(impl->epoll_fd, ep, SPA_N_ELEMENTS(ep), timeout)) < 0))
|
||||
save_errno = errno;
|
||||
|
||||
spa_hook_list_call(&impl->hooks_list, struct spa_loop_control_hooks, after);
|
||||
spa_loop_control_hook_after(&impl->hooks_list);
|
||||
|
||||
if (SPA_UNLIKELY(nfds < 0))
|
||||
return save_errno;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue