interface: add an interface struct

The interface struct has the type,version and methods of the
interface.
Make spa interfaces extend from spa_interface and make a
separate structure for the methods.
Pass a generic void* as the first argument of methods, like
we don in PipeWire.
Bundle the methods + implementation in a versioned inteface
and use that to invoke methods. This way we can do version
checks on the methods.
Make resource and proxy interfaces that we can can call. We
can then make the core interfaces independent on proxy/resource and
hide them in the lower layers.
Add add_listener method to methods of core interfaces, just
like SPA.
This commit is contained in:
Wim Taymans 2019-05-20 16:11:23 +02:00
parent eb6481efb3
commit ff946e3d4b
85 changed files with 3051 additions and 3000 deletions

View file

@ -33,6 +33,7 @@
#include <spa/support/cpu.h>
#include <spa/support/plugin.h>
#include <spa/utils/type.h>
#include <spa/utils/hook.h>
#define NAME "cpu"
@ -57,18 +58,18 @@ struct impl {
#endif
static uint32_t
impl_cpu_get_flags(struct spa_cpu *cpu)
impl_cpu_get_flags(void *object)
{
struct impl *impl = SPA_CONTAINER_OF(cpu, struct impl, cpu);
struct impl *impl = object;
if (impl->force != SPA_CPU_FORCE_AUTODETECT)
return impl->force;
return impl->flags;
}
static int
impl_cpu_force_flags(struct spa_cpu *cpu, uint32_t flags)
impl_cpu_force_flags(void *object, uint32_t flags)
{
struct impl *impl = SPA_CONTAINER_OF(cpu, struct impl, cpu);
struct impl *impl = object;
impl->force = flags;
return 0;
}
@ -83,26 +84,25 @@ static uint32_t get_count(struct impl *this)
}
static uint32_t
impl_cpu_get_count(struct spa_cpu *cpu)
impl_cpu_get_count(void *object)
{
struct impl *impl = SPA_CONTAINER_OF(cpu, struct impl, cpu);
struct impl *impl = object;
return impl->count;
}
static uint32_t
impl_cpu_get_max_align(struct spa_cpu *cpu)
impl_cpu_get_max_align(void *object)
{
struct impl *impl = SPA_CONTAINER_OF(cpu, struct impl, cpu);
struct impl *impl = object;
return impl->max_align;
}
static const struct spa_cpu impl_cpu = {
SPA_VERSION_CPU,
NULL,
impl_cpu_get_flags,
impl_cpu_force_flags,
impl_cpu_get_count,
impl_cpu_get_max_align,
static const struct spa_cpu_methods impl_cpu = {
SPA_VERSION_CPU_METHODS,
.get_flags = impl_cpu_get_flags,
.force_flags = impl_cpu_force_flags,
.get_count = impl_cpu_get_count,
.get_max_align = impl_cpu_get_max_align,
};
static int impl_get_interface(struct spa_handle *handle, uint32_t type, void **interface)
@ -152,7 +152,10 @@ impl_init(const struct spa_handle_factory *factory,
this = (struct impl *) handle;
this->cpu = impl_cpu;
this->cpu.iface = SPA_INTERFACE_INIT(
SPA_TYPE_INTERFACE_CPU,
SPA_VERSION_CPU,
&impl_cpu, this);
for (i = 0; i < n_support; i++) {
if (support[i].type == SPA_TYPE_INTERFACE_Log)

View file

@ -280,10 +280,10 @@ static const struct spa_dbus_connection impl_connection = {
};
static struct spa_dbus_connection *
impl_get_connection(struct spa_dbus *dbus,
impl_get_connection(void *object,
enum spa_dbus_type type)
{
struct impl *impl = SPA_CONTAINER_OF(dbus, struct impl, dbus);
struct impl *impl = object;
struct connection *conn;
DBusError error;
@ -318,9 +318,9 @@ impl_get_connection(struct spa_dbus *dbus,
return NULL;
}
static const struct spa_dbus impl_dbus = {
SPA_VERSION_DBUS,
impl_get_connection,
static const struct spa_dbus_methods impl_dbus = {
SPA_VERSION_DBUS_METHODS,
.get_connection = impl_get_connection,
};
static int impl_get_interface(struct spa_handle *handle, uint32_t type, void **interface)
@ -372,7 +372,10 @@ impl_init(const struct spa_handle_factory *factory,
this = (struct impl *) handle;
spa_list_init(&this->connection_list);
this->dbus = impl_dbus;
this->dbus.iface = SPA_INTERFACE_INIT(
SPA_TYPE_INTERFACE_DBus,
SPA_VERSION_DBUS,
&impl_dbus, this);
for (i = 0; i < n_support; i++) {
if (support[i].type == SPA_TYPE_INTERFACE_Log)

View file

@ -56,7 +56,7 @@ struct impl {
};
static void
impl_log_logv(struct spa_log *log,
impl_log_logv(void *object,
enum spa_log_level level,
const char *file,
int line,
@ -64,7 +64,7 @@ impl_log_logv(struct spa_log *log,
const char *fmt,
va_list args)
{
struct impl *impl = SPA_CONTAINER_OF(log, struct impl, log);
struct impl *impl = object;
char text[512], location[1024];
static const char *levels[] = { "-", "E", "W", "I", "D", "T", "*T*" };
const char *prefix = "", *suffix = "";
@ -107,7 +107,7 @@ impl_log_logv(struct spa_log *log,
static void
impl_log_log(struct spa_log *log,
impl_log_log(void *object,
enum spa_log_level level,
const char *file,
int line,
@ -116,7 +116,7 @@ impl_log_log(struct spa_log *log,
{
va_list args;
va_start(args, fmt);
impl_log_logv(log, level, file, line, func, fmt, args);
impl_log_logv(object, level, file, line, func, fmt, args);
va_end(args);
}
@ -149,12 +149,10 @@ static void on_trace_event(struct spa_source *source)
}
}
static const struct spa_log impl_log = {
SPA_VERSION_LOG,
DEFAULT_LOG_LEVEL,
NULL,
impl_log_log,
impl_log_logv,
static const struct spa_log_methods impl_log = {
SPA_VERSION_LOG_METHODS,
.log = impl_log_log,
.logv = impl_log_logv,
};
static int impl_get_interface(struct spa_handle *handle, uint32_t type, void **interface)
@ -217,7 +215,11 @@ impl_init(const struct spa_handle_factory *factory,
this = (struct impl *) handle;
this->log = impl_log;
this->log.iface = SPA_INTERFACE_INIT(
SPA_TYPE_INTERFACE_Log,
SPA_VERSION_LOG,
&impl_log, this);
this->log.level = DEFAULT_LOG_LEVEL;
for (i = 0; i < n_support; i++) {
if (support[i].type == SPA_TYPE_INTERFACE_MainLoop)
@ -281,7 +283,7 @@ const struct spa_handle_factory spa_support_logger_factory = {
SPA_VERSION_HANDLE_FACTORY,
NAME,
NULL,
impl_get_size,
impl_init,
impl_enum_interface_info,
.get_size = impl_get_size,
.init = impl_init,
.enum_interface_info = impl_enum_interface_info,
};

View file

@ -59,7 +59,7 @@ struct invoke_item {
int res;
};
static void loop_signal_event(struct spa_source *source);
static void loop_signal_event(void *object, struct spa_source *source);
struct impl {
struct spa_handle handle;
@ -134,11 +134,11 @@ static inline enum spa_io spa_epoll_to_io(uint32_t events)
return mask;
}
static int loop_add_source(struct spa_loop *loop, struct spa_source *source)
static int loop_add_source(void *object, struct spa_source *source)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, loop);
struct impl *impl = object;
source->loop = loop;
source->loop = (struct spa_loop*) &impl->loop;
if (source->fd != -1) {
struct epoll_event ep;
@ -153,10 +153,9 @@ static int loop_add_source(struct spa_loop *loop, struct spa_source *source)
return 0;
}
static int loop_update_source(struct spa_source *source)
static int loop_update_source(void *object, struct spa_source *source)
{
struct spa_loop *loop = source->loop;
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, loop);
struct impl *impl = object;
if (source->fd != -1) {
struct epoll_event ep;
@ -171,19 +170,19 @@ static int loop_update_source(struct spa_source *source)
return 0;
}
static void loop_remove_source(struct spa_source *source)
static int loop_remove_source(void *object, struct spa_source *source)
{
struct spa_loop *loop = source->loop;
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, loop);
struct impl *impl = object;
if (source->fd != -1)
epoll_ctl(impl->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
source->loop = NULL;
return 0;
}
static int
loop_invoke(struct spa_loop *loop,
loop_invoke(void *object,
spa_invoke_func_t func,
uint32_t seq,
const void *data,
@ -191,13 +190,13 @@ loop_invoke(struct spa_loop *loop,
bool block,
void *user_data)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, loop);
struct impl *impl = object;
bool in_thread = pthread_equal(impl->thread, pthread_self());
struct invoke_item *item;
int res;
if (in_thread) {
res = func(loop, false, seq, data, size, user_data);
res = func(object, false, seq, data, size, user_data);
} else {
int32_t filled;
uint32_t avail, idx, offset, l0;
@ -236,7 +235,7 @@ loop_invoke(struct spa_loop *loop,
spa_ringbuffer_write_update(&impl->buffer, idx + item->item_size);
spa_loop_utils_signal_event(&impl->utils, impl->wakeup);
spa_loop_utils_signal_event((struct spa_loop_utils*)&impl->utils, impl->wakeup);
if (block) {
uint64_t count = 1;
@ -272,7 +271,8 @@ static void wakeup_func(void *data, uint64_t count)
item = SPA_MEMBER(impl->buffer_data, index & (DATAS_SIZE - 1), struct invoke_item);
block = item->block;
item->res = item->func(&impl->loop, true, item->seq, item->data, item->size,
item->res = item->func((struct spa_loop *)&impl->loop,
true, item->seq, item->data, item->size,
item->user_data);
spa_ringbuffer_read_update(&impl->buffer, index + item->item_size);
@ -286,33 +286,31 @@ static void wakeup_func(void *data, uint64_t count)
}
}
static int loop_get_fd(struct spa_loop_control *ctrl)
static int loop_get_fd(void *object)
{
struct impl *impl = SPA_CONTAINER_OF(ctrl, struct impl, control);
struct impl *impl = object;
return impl->epoll_fd;
}
static void
loop_add_hooks(struct spa_loop_control *ctrl,
struct spa_hook *hook,
const struct spa_loop_control_hooks *hooks,
void *data)
loop_add_hook(void *object,
struct spa_hook *hook,
const struct spa_loop_control_hooks *hooks,
void *data)
{
struct impl *impl = SPA_CONTAINER_OF(ctrl, struct impl, control);
struct impl *impl = object;
spa_hook_list_append(&impl->hooks_list, hook, hooks, data);
}
static void loop_enter(struct spa_loop_control *ctrl)
static void loop_enter(void *object)
{
struct impl *impl = SPA_CONTAINER_OF(ctrl, struct impl, control);
struct impl *impl = object;
impl->thread = pthread_self();
}
static void loop_leave(struct spa_loop_control *ctrl)
static void loop_leave(void *object)
{
struct impl *impl = SPA_CONTAINER_OF(ctrl, struct impl, control);
struct impl *impl = object;
impl->thread = 0;
}
@ -324,10 +322,10 @@ static inline void process_destroy(struct impl *impl)
spa_list_init(&impl->destroy_list);
}
static int loop_iterate(struct spa_loop_control *ctrl, int timeout)
static int loop_iterate(void *object, int timeout)
{
struct impl *impl = SPA_CONTAINER_OF(ctrl, struct impl, control);
struct spa_loop *loop = &impl->loop;
struct impl *impl = object;
struct spa_loop *loop = (struct spa_loop *)&impl->loop;
struct epoll_event ep[32];
int i, nfds, save_errno = 0;
@ -364,19 +362,19 @@ static void source_io_func(struct spa_source *source)
impl->func.io(source->data, source->fd, source->rmask);
}
static struct spa_source *loop_add_io(struct spa_loop_utils *utils,
static struct spa_source *loop_add_io(void *object,
int fd,
enum spa_io mask,
bool close, spa_source_io_func_t func, void *data)
{
struct impl *impl = SPA_CONTAINER_OF(utils, struct impl, utils);
struct impl *impl = object;
struct source_impl *source;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
source->source.loop = &impl->loop;
source->source.loop = (struct spa_loop *) &impl->loop;
source->source.func = source_io_func;
source->source.data = data;
source->source.fd = fd;
@ -385,14 +383,14 @@ static struct spa_source *loop_add_io(struct spa_loop_utils *utils,
source->close = close;
source->func.io = func;
spa_loop_add_source(&impl->loop, &source->source);
spa_loop_add_source(source->source.loop, &source->source);
spa_list_insert(&impl->source_list, &source->link);
return &source->source;
}
static int loop_update_io(struct spa_source *source, enum spa_io mask)
static int loop_update_io(void *object, struct spa_source *source, enum spa_io mask)
{
source->mask = mask;
return spa_loop_update_source(source->loop, source);
@ -405,17 +403,17 @@ static void source_idle_func(struct spa_source *source)
impl->func.idle(source->data);
}
static struct spa_source *loop_add_idle(struct spa_loop_utils *utils,
static struct spa_source *loop_add_idle(void *object,
bool enabled, spa_source_idle_func_t func, void *data)
{
struct impl *impl = SPA_CONTAINER_OF(utils, struct impl, utils);
struct impl *impl = object;
struct source_impl *source;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
source->source.loop = &impl->loop;
source->source.loop = (struct spa_loop *)&impl->loop;
source->source.func = source_idle_func;
source->source.data = data;
source->source.fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
@ -424,19 +422,20 @@ static struct spa_source *loop_add_idle(struct spa_loop_utils *utils,
source->source.mask = SPA_IO_IN;
source->func.idle = func;
spa_loop_add_source(&impl->loop, &source->source);
spa_loop_add_source(source->source.loop, &source->source);
spa_list_insert(&impl->source_list, &source->link);
if (enabled)
spa_loop_utils_enable_idle(&impl->utils, &source->source, true);
spa_loop_utils_enable_idle((struct spa_loop_utils*)&impl->utils,
&source->source, true);
return &source->source;
}
static void loop_enable_idle(struct spa_source *source, bool enabled)
static void loop_enable_idle(void *object, struct spa_source *source, bool enabled)
{
struct source_impl *impl = SPA_CONTAINER_OF(source, struct source_impl, source);
struct source_impl *impl = object;
uint64_t count;
if (enabled && !impl->enabled) {
@ -464,17 +463,17 @@ static void source_event_func(struct spa_source *source)
impl->func.event(source->data, count);
}
static struct spa_source *loop_add_event(struct spa_loop_utils *utils,
static struct spa_source *loop_add_event(void *object,
spa_source_event_func_t func, void *data)
{
struct impl *impl = SPA_CONTAINER_OF(utils, struct impl, utils);
struct impl *impl = object;
struct source_impl *source;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
source->source.loop = &impl->loop;
source->source.loop = (struct spa_loop *)&impl->loop;
source->source.func = source_event_func;
source->source.data = data;
source->source.fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
@ -483,14 +482,14 @@ static struct spa_source *loop_add_event(struct spa_loop_utils *utils,
source->close = true;
source->func.event = func;
spa_loop_add_source(&impl->loop, &source->source);
spa_loop_add_source(source->source.loop, &source->source);
spa_list_insert(&impl->source_list, &source->link);
return &source->source;
}
static void loop_signal_event(struct spa_source *source)
static void loop_signal_event(void *object, struct spa_source *source)
{
struct source_impl *impl = SPA_CONTAINER_OF(source, struct source_impl, source);
uint64_t count = 1;
@ -512,17 +511,17 @@ static void source_timer_func(struct spa_source *source)
impl->func.timer(source->data, expirations);
}
static struct spa_source *loop_add_timer(struct spa_loop_utils *utils,
static struct spa_source *loop_add_timer(void *object,
spa_source_timer_func_t func, void *data)
{
struct impl *impl = SPA_CONTAINER_OF(utils, struct impl, utils);
struct impl *impl = object;
struct source_impl *source;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
source->source.loop = &impl->loop;
source->source.loop = (struct spa_loop*)&impl->loop;
source->source.func = source_timer_func;
source->source.data = data;
source->source.fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
@ -531,7 +530,7 @@ static struct spa_source *loop_add_timer(struct spa_loop_utils *utils,
source->close = true;
source->func.timer = func;
spa_loop_add_source(&impl->loop, &source->source);
spa_loop_add_source(source->source.loop, &source->source);
spa_list_insert(&impl->source_list, &source->link);
@ -539,7 +538,7 @@ static struct spa_source *loop_add_timer(struct spa_loop_utils *utils,
}
static int
loop_update_timer(struct spa_source *source,
loop_update_timer(void *object, struct spa_source *source,
struct timespec *value, struct timespec *interval, bool absolute)
{
struct itimerspec its;
@ -577,11 +576,11 @@ static void source_signal_func(struct spa_source *source)
impl->func.signal(source->data, impl->signal_number);
}
static struct spa_source *loop_add_signal(struct spa_loop_utils *utils,
static struct spa_source *loop_add_signal(void *object,
int signal_number,
spa_source_signal_func_t func, void *data)
{
struct impl *impl = SPA_CONTAINER_OF(utils, struct impl, utils);
struct impl *impl = object;
struct source_impl *source;
sigset_t mask;
@ -589,7 +588,7 @@ static struct spa_source *loop_add_signal(struct spa_loop_utils *utils,
if (source == NULL)
return NULL;
source->source.loop = &impl->loop;
source->source.loop = (struct spa_loop *)&impl->loop;
source->source.func = source_signal_func;
source->source.data = data;
@ -604,14 +603,14 @@ static struct spa_source *loop_add_signal(struct spa_loop_utils *utils,
source->func.signal = func;
source->signal_number = signal_number;
spa_loop_add_source(&impl->loop, &source->source);
spa_loop_add_source(source->source.loop, &source->source);
spa_list_insert(&impl->source_list, &source->link);
return &source->source;
}
static void loop_destroy_source(struct spa_source *source)
static void loop_destroy_source(void *object, struct spa_source *source)
{
struct source_impl *impl = SPA_CONTAINER_OF(source, struct source_impl, source);
@ -627,35 +626,35 @@ static void loop_destroy_source(struct spa_source *source)
spa_list_insert(&impl->impl->destroy_list, &impl->link);
}
static const struct spa_loop impl_loop = {
SPA_VERSION_LOOP,
loop_add_source,
loop_update_source,
loop_remove_source,
loop_invoke,
static const struct spa_loop_methods impl_loop = {
SPA_VERSION_LOOP_METHODS,
.add_source = loop_add_source,
.update_source = loop_update_source,
.remove_source = loop_remove_source,
.invoke = loop_invoke,
};
static const struct spa_loop_control impl_loop_control = {
SPA_VERSION_LOOP_CONTROL,
loop_get_fd,
loop_add_hooks,
loop_enter,
loop_leave,
loop_iterate,
static const struct spa_loop_control_methods impl_loop_control = {
SPA_VERSION_LOOP_CONTROL_METHODS,
.get_fd = loop_get_fd,
.add_hook = loop_add_hook,
.enter = loop_enter,
.leave = loop_leave,
.iterate = loop_iterate,
};
static const struct spa_loop_utils impl_loop_utils = {
SPA_VERSION_LOOP_UTILS,
loop_add_io,
loop_update_io,
loop_add_idle,
loop_enable_idle,
loop_add_event,
loop_signal_event,
loop_add_timer,
loop_update_timer,
loop_add_signal,
loop_destroy_source,
static const struct spa_loop_utils_methods impl_loop_utils = {
SPA_VERSION_LOOP_UTILS_METHODS,
.add_io = loop_add_io,
.update_io = loop_update_io,
.add_idle = loop_add_idle,
.enable_idle = loop_enable_idle,
.add_event = loop_add_event,
.signal_event = loop_signal_event,
.add_timer = loop_add_timer,
.update_timer = loop_update_timer,
.add_signal = loop_add_signal,
.destroy_source = loop_destroy_source,
};
static int impl_get_interface(struct spa_handle *handle, uint32_t type, void **interface)
@ -693,7 +692,7 @@ static int impl_clear(struct spa_handle *handle)
impl = (struct impl *) handle;
spa_list_consume(source, &impl->source_list, link)
loop_destroy_source(&source->source);
loop_destroy_source(impl, &source->source);
process_destroy(impl);
@ -727,9 +726,18 @@ impl_init(const struct spa_handle_factory *factory,
handle->clear = impl_clear;
impl = (struct impl *) handle;
impl->loop = impl_loop;
impl->control = impl_loop_control;
impl->utils = impl_loop_utils;
impl->loop.iface = SPA_INTERFACE_INIT(
SPA_TYPE_INTERFACE_Loop,
SPA_VERSION_LOOP,
&impl_loop, impl);
impl->control.iface = SPA_INTERFACE_INIT(
SPA_TYPE_INTERFACE_LoopControl,
SPA_VERSION_LOOP_CONTROL,
&impl_loop_control, impl);
impl->utils.iface = SPA_INTERFACE_INIT(
SPA_TYPE_INTERFACE_LoopUtils,
SPA_VERSION_LOOP_UTILS,
&impl_loop_utils, impl);
for (i = 0; i < n_support; i++) {
if (support[i].type == SPA_TYPE_INTERFACE_Log)
@ -746,7 +754,7 @@ impl_init(const struct spa_handle_factory *factory,
spa_ringbuffer_init(&impl->buffer);
impl->wakeup = spa_loop_utils_add_event(&impl->utils, wakeup_func, impl);
impl->wakeup = spa_loop_utils_add_event((struct spa_loop_utils*)&impl->utils, wakeup_func, impl);
impl->ack_fd = eventfd(0, EFD_SEMAPHORE | EFD_CLOEXEC);
spa_log_debug(impl->log, NAME " %p: initialized", impl);