PipeWire: SPA Hooks

PipeWire 0.3.37

Data Structures | Macros | Functions
SPA Hooks

A SPA Hook is a data structure to keep track of callbacks. More...

## Data Structures
struct | spa_hook_list
| A list of hooks. More...
struct | spa_hook
| A hook, contains the structure with functions and the data passed to the functions. More...

## Macros
#define | spa_hook_list_call_simple(l, type, method, vers, ...)
#define | spa_hook_list_do_call(l, start, type, method, vers, once, ...)
| 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. More...
#define | spa_hook_list_call(l, t, m, v, ...) spa_hook_list_do_call(l,NULL,t,m,v,false,##__VA_ARGS__)
| Call the method named m for each element in list l. More...
#define | spa_hook_list_call_once(l, t, m, v, ...) spa_hook_list_do_call(l,NULL,t,m,v,true,##__VA_ARGS__)
| Call the method named m for each element in list l, stopping after the first invocation. More...
#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__)

## Functions
void | spa_hook_list_init (struct spa_hook_list *list)
| Initialize a hook list to the empty list. More...
bool | spa_hook_list_is_empty (struct spa_hook_list *list)
void | spa_hook_list_append (struct spa_hook_list *list, struct spa_hook *hook, const void *funcs, void *data)
| Append a hook. More...
void | spa_hook_list_prepend (struct spa_hook_list *list, struct spa_hook *hook, const void *funcs, void *data)
| Prepend a hook. More...
void | spa_hook_remove (struct spa_hook *hook)
| Remove a hook. More...
void | spa_hook_list_clean (struct spa_hook_list *list)
| Remove all hooks from the list. More...
void | spa_hook_list_isolate (struct spa_hook_list *list, struct spa_hook_list *save, struct spa_hook *hook, const void *funcs, void *data)
void | spa_hook_list_join (struct spa_hook_list *list, struct spa_hook_list *save)

## Detailed Description

A SPA Hook is a data structure to keep track of callbacks.

It is similar to the SPA Interfaces and typically used where an implementation allows for multiple external callback functions. For example, an implementation may use a hook list to implement signals with each caller using a hook to register callbacks to be invoked on those signals.

The below (pseudo)code is a minimal example outlining the use of hooks:

// the public interface
struct bar_events {
uint32_t version;
void (*boom)(void *data, const char *msg);
};
// private implementation
struct party {
struct spa_hook_list bar_list;
};
void party_add_event_listener(struct party *p, struct spa_hook *listener,
struct bar_events *events, void *data)
{
spa_hook_list_append(&p->bar_list, listener, events, data);
}
static void party_on(struct party *p)
{
spa_hook_list_call(&p->list, struct bar_events,
boom, // function name
0 // hardcoded version,
"party on, wayne");
}
spa_hook_list_call
#define spa_hook_list_call(l, t, m, v,...)
Call the method named m for each element in list l.
Definition: hook.h:407
spa_hook_list_append
void spa_hook_list_append(struct spa_hook_list *list, struct spa_hook *hook, const void *funcs, void *data)
Append a hook.
Definition: hook.h:316
data
user data to add to an object
Definition: media-session.c:110
spa_hook_list
A list of hooks.
Definition: hook.h:284
spa_hook
A hook, contains the structure with functions and the data passed to the functions.
Definition: hook.h:295

In the caller, the hooks can be used like this:

static void boom_cb(void *data, const char *msg) {
// data is userdata from main()
printf("%s", msg);
}
static const struct bar_events {
.boom = boom_cb,
};
void main(void) {
void *userdata = whatever;
struct spa_hook hook;
struct party *p = start_the_party();
party_add_event_listener(p, &hook, boom_cb, userdata);
mainloop();
return 0;
}
main
int main(int argc, char *argv[])
Definition: media-session.c:2433

## Macro Definition Documentation

## ◆ spa_hook_list_call

#define spa_hook_list_call | ( |  | l,
|  |  | t,
|  |  | m,
|  |  | v,
|  |  | ...
| ) |  | spa_hook_list_do_call(l,NULL,t,m,v,false,##__VA_ARGS__)

Call the method named m for each element in list l.

t specifies the type of the callback struct.

## ◆ spa_hook_list_call_once

#define spa_hook_list_call_once | ( |  | l,
|  |  | t,
|  |  | m,
|  |  | v,
|  |  | ...
| ) |  | spa_hook_list_do_call(l,NULL,t,m,v,true,##__VA_ARGS__)

Call the method named m for each element in list l, stopping after the first invocation.

t specifies the type of the callback struct.

## ◆ spa_hook_list_call_once_start

#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__)

## ◆ spa_hook_list_call_simple

#define spa_hook_list_call_simple | ( |  | l,
|  |  | type,
|  |  | method,
|  |  | vers,
|  |  | ...
| ) |  |

Value:
({ \
struct spa_hook_list *_l = l; \
struct spa_hook *_h, *_t; \
spa_list_for_each_safe(_h, _t, &_l->list, link) \
spa_callbacks_call(&_h->cb,type,method,vers, ## __VA_ARGS__); \
})
link
Definition: media-session.c:183

## ◆ spa_hook_list_call_start

#define spa_hook_list_call_start | ( |  | l,
|  |  | s,
|  |  | t,
|  |  | m,
|  |  | v,
|  |  | ...
| ) |  | spa_hook_list_do_call(l,s,t,m,v,false,##__VA_ARGS__)

## ◆ spa_hook_list_do_call

#define spa_hook_list_do_call | ( |  | l,
|  |  | start,
|  |  | type,
|  |  | method,
|  |  | vers,
|  |  | once,
|  |  | ...
| ) |  |

Value:
({ \
struct spa_hook_list *list = l; \
struct spa_list *s = start ? (struct spa_list *)start : &list->list; \
struct spa_hook cursor = { 0 }, *ci; \
int count = 0; \
spa_list_cursor_start(cursor, s, link); \
spa_list_for_each_cursor(ci, cursor, &list->list, link) { \
const type *_f = (const type *)ci->cb.funcs; \
if (SPA_LIKELY(SPA_CALLBACK_CHECK(_f,method,vers))) { \
_f->method(ci->cb.data, ## __VA_ARGS__); \
count++; \
if (once) \
break; \
} \
} \
spa_list_cursor_end(cursor, link); \
count; \
})
SPA_CALLBACK_CHECK
#define SPA_CALLBACK_CHECK(c, m, v)
Check if a callback c has method m of version v.
Definition: hook.h:136
SPA_LIKELY
#define SPA_LIKELY(x)
Definition: defs.h:241
start
int(* start)(struct sm_media_session *sess)
Definition: media-session.c:2382
spa_list
Definition: list.h:37

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.

## Function Documentation

## ◆ spa_hook_list_append()

void spa_hook_list_append | ( | struct spa_hook_list * | list,
|  | struct spa_hook * | hook,
|  | const void * | funcs,
|  | void * | data
| ) |  |
| inline

Append a hook.

References spa_hook::cb, spa_hook::link, spa_hook_list::list, SPA_CALLBACKS_INIT, spa_list_append, and spa_zero.

Referenced by pw_context_add_listener(), pw_control_add_listener(), pw_data_loop_add_listener(), pw_filter_add_listener(), pw_global_add_listener(), pw_impl_client_add_listener(), pw_impl_core_add_listener(), pw_impl_device_add_listener(), pw_impl_factory_add_listener(), pw_impl_link_add_listener(), pw_impl_metadata_add_listener(), pw_impl_module_add_listener(), pw_impl_node_add_listener(), pw_impl_port_add_listener(), pw_main_loop_add_listener(), pw_mempool_add_listener(), pw_protocol_add_listener(), pw_proxy_add_listener(), pw_proxy_add_object_listener(), pw_resource_add_listener(), pw_resource_add_object_listener(), pw_stream_add_listener(), pw_thread_loop_add_listener(), sm_object_add_listener(), and spa_hook_list_isolate().

## ◆ spa_hook_list_clean()

void spa_hook_list_clean | ( | struct spa_hook_list * | list | ) |
| inline

Remove all hooks from the list.

References spa_hook_list::list, spa_hook_remove(), and spa_list_consume.

Referenced by pw_control_destroy(), pw_data_loop_destroy(), pw_impl_core_destroy(), pw_impl_factory_destroy(), pw_impl_module_destroy(), pw_main_loop_destroy(), pw_mempool_destroy(), pw_protocol_destroy(), and pw_thread_loop_destroy().

## ◆ spa_hook_list_init()

void spa_hook_list_init | ( | struct spa_hook_list * | list | ) |
| inline

Initialize a hook list to the empty list.

References spa_hook_list::list, and spa_list_init().

Referenced by pw_context_create_core(), pw_context_create_device(), pw_context_create_factory(), pw_context_create_metadata(), pw_context_create_port(), pw_control_new(), pw_mempool_new(), pw_protocol_new(), pw_resource_new(), and spa_hook_list_isolate().

## ◆ spa_hook_list_is_empty()

bool spa_hook_list_is_empty | ( | struct spa_hook_list * | list | ) |
| inline

References spa_hook_list::list, and spa_list_is_empty.

## ◆ spa_hook_list_isolate()

void spa_hook_list_isolate | ( | struct spa_hook_list * | list,
|  | struct spa_hook_list * | save,
|  | struct spa_hook * | hook,
|  | const void * | funcs,
|  | void * | data
| ) |  |
| inline

References spa_hook_list::list, spa_hook_list_append(), spa_hook_list_init(), and spa_list_insert_list().

Referenced by sm_media_session_add_listener().

## ◆ spa_hook_list_join()

void spa_hook_list_join | ( | struct spa_hook_list * | list,
|  | struct spa_hook_list * | save
| ) |  |
| inline

References spa_hook_list::list, and spa_list_insert_list().

Referenced by sm_media_session_add_listener().

## ◆ spa_hook_list_prepend()

void spa_hook_list_prepend | ( | struct spa_hook_list * | list,
|  | struct spa_hook * | hook,
|  | const void * | funcs,
|  | void * | data
| ) |  |
| inline

Prepend a hook.

References spa_hook::cb, spa_hook::link, spa_hook_list::list, SPA_CALLBACKS_INIT, spa_list_prepend, and spa_zero.

## ◆ spa_hook_remove()

void spa_hook_remove | ( | struct spa_hook * | hook | ) |
| inline

Remove a hook.

References spa_hook::link, spa_hook::removed, and spa_list_remove().

Referenced by pw_filter_destroy(), pw_filter_disconnect(), pw_impl_client_destroy(), pw_impl_core_destroy(), pw_impl_factory_destroy(), pw_impl_metadata_destroy(), pw_impl_metadata_set_implementation(), pw_impl_module_destroy(), pw_stream_destroy(), pw_stream_disconnect(), pw_thread_loop_destroy(), and spa_hook_list_clean().