From e0813b679dee7f7f6d6680b526a6dcda7e882a23 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 2 Mar 2017 16:06:45 +0100 Subject: [PATCH] Use interfaces Add interfaces and events on objects. Use this to communicate with the objects and transparently convert/marshall to network in the protocols. --- pinos/client/connection.c | 10 +- pinos/client/connection.h | 29 +- pinos/client/interfaces.h | 245 ++++++++++ pinos/modules/module-autolink.c | 13 +- pinos/modules/module-protocol-native.c | 639 ++++++++++++++++++++++++- pinos/server/client-node.c | 383 +++++++-------- pinos/server/client.c | 164 +------ pinos/server/client.h | 19 +- pinos/server/core.c | 375 +++++++-------- pinos/server/core.h | 2 + pinos/server/link.c | 33 +- pinos/server/module.c | 70 +-- pinos/server/module.h | 4 +- pinos/server/node.c | 47 +- pinos/server/resource.c | 79 +-- pinos/server/resource.h | 17 +- 16 files changed, 1307 insertions(+), 822 deletions(-) create mode 100644 pinos/client/interfaces.h diff --git a/pinos/client/connection.c b/pinos/client/connection.c index 0d0540233..35a89ce08 100644 --- a/pinos/client/connection.c +++ b/pinos/client/connection.c @@ -312,7 +312,7 @@ connection_parse_use_buffers (PinosConnection *conn, PinosMessageUseBuffers *cmd p = conn->in.data; memcpy (cmd, p, sizeof (PinosMessageUseBuffers)); if (cmd->buffers) - cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), PinosMessageBuffer); + cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), PinosClientNodeBuffer); for (i = 0; i < cmd->n_buffers; i++) { if (cmd->buffers[i].buffer) @@ -886,12 +886,12 @@ connection_add_use_buffers (PinosConnection *conn, uint32_t dest_id, PinosMessag size_t len; int i; PinosMessageUseBuffers *d; - PinosMessageBuffer *b; + PinosClientNodeBuffer *b; void *p; /* calculate length */ len = sizeof (PinosMessageUseBuffers); - len += ub->n_buffers * sizeof (PinosMessageBuffer); + len += ub->n_buffers * sizeof (PinosClientNodeBuffer); for (i = 0; i < ub->n_buffers; i++) len += pinos_serialize_buffer_get_size (ub->buffers[i].buffer); @@ -899,7 +899,7 @@ connection_add_use_buffers (PinosConnection *conn, uint32_t dest_id, PinosMessag memcpy (d, ub, sizeof (PinosMessageUseBuffers)); b = SPA_MEMBER (d, sizeof (PinosMessageUseBuffers), void); - p = SPA_MEMBER (b, ub->n_buffers * sizeof (PinosMessageBuffer), void); + p = SPA_MEMBER (b, ub->n_buffers * sizeof (PinosClientNodeBuffer), void); if (d->n_buffers) d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (b, d)); @@ -907,7 +907,7 @@ connection_add_use_buffers (PinosConnection *conn, uint32_t dest_id, PinosMessag d->buffers = 0; for (i = 0; i < ub->n_buffers; i++) { - memcpy (&b[i], &ub->buffers[i], sizeof (PinosMessageBuffer)); + memcpy (&b[i], &ub->buffers[i], sizeof (PinosClientNodeBuffer)); len = pinos_serialize_buffer_serialize (p, b[i].buffer); b[i].buffer = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d)); p += len; diff --git a/pinos/client/connection.h b/pinos/client/connection.h index 21722082a..6493c677b 100644 --- a/pinos/client/connection.h +++ b/pinos/client/connection.h @@ -30,6 +30,8 @@ extern "C" { #include #include +#include + typedef struct _PinosConnection PinosConnection; typedef enum { @@ -253,7 +255,7 @@ typedef struct { SpaDirection direction; uint32_t port_id; SpaPortFormatFlags flags; - SpaFormat *format; + const SpaFormat *format; } PinosMessageSetFormat; /* PINOS_MESSAGE_SET_PROPERTY */ @@ -295,20 +297,13 @@ typedef struct { size_t size; } PinosMessageAddMem; -typedef struct { - SpaBuffer *buffer; - uint32_t mem_id; - off_t offset; - size_t size; -} PinosMessageBuffer; - /* PINOS_MESSAGE_USE_BUFFERS */ typedef struct { uint32_t seq; SpaDirection direction; uint32_t port_id; unsigned int n_buffers; - PinosMessageBuffer *buffers; + PinosClientNodeBuffer *buffers; } PinosMessageUseBuffers; PinosConnection * pinos_connection_new (int fd); @@ -318,15 +313,15 @@ bool pinos_connection_get_next (PinosConnection *conn, PinosMessageType *type, uint32_t *dest_id, size_t *size); -bool pinos_connection_parse_message (PinosConnection *conn, - void *msg); -bool pinos_connection_add_message (PinosConnection *conn, - uint32_t dest_id, - PinosMessageType type, - void *msg); +bool pinos_connection_parse_message (PinosConnection *conn, + void *msg); +bool pinos_connection_add_message (PinosConnection *conn, + uint32_t dest_id, + PinosMessageType type, + void *msg); -bool pinos_connection_flush (PinosConnection *conn); -bool pinos_connection_clear (PinosConnection *conn); +bool pinos_connection_flush (PinosConnection *conn); +bool pinos_connection_clear (PinosConnection *conn); #ifdef __cplusplus } /* extern "C" */ diff --git a/pinos/client/interfaces.h b/pinos/client/interfaces.h new file mode 100644 index 000000000..17467c48f --- /dev/null +++ b/pinos/client/interfaces.h @@ -0,0 +1,245 @@ +/* Simple Plugin API + * Copyright (C) 2016 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PINOS_INTERFACES_H__ +#define __PINOS_INTERFACES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +typedef struct _PinosClientNodeBuffer PinosClientNodeBuffer; + +#include + +#define PINOS_CORE_CLIENT_UPDATE 0 +#define PINOS_CORE_SYNC 1 +#define PINOS_CORE_GET_REGISTRY 2 +#define PINOS_CORE_CREATE_NODE 3 +#define PINOS_CORE_CREATE_CLIENT_NODE 4 + +typedef struct { + void (*client_update) (void *object, + const SpaDict *props); + void (*sync) (void *object, + uint32_t seq); + void (*get_registry) (void *object, + uint32_t seq, + uint32_t new_id); + void (*create_node) (void *object, + uint32_t seq, + const char *factory_name, + const char *name, + const SpaDict *props, + uint32_t new_id); + void (*create_client_node) (void *object, + uint32_t seq, + const char *name, + const SpaDict *props, + uint32_t new_id); +} PinosCoreInterface; + +typedef struct { + void (*info) (void *object, + PinosCoreInfo *info); + void (*done) (void *object, + uint32_t seq); + void (*error) (void *object, + uint32_t id, + SpaResult res, + const char *error, ...); + void (*remove_id) (void *object, + uint32_t id); +} PinosCoreEvent; + +#define pinos_core_notify_info(r,...) ((PinosCoreEvent*)r->event)->info(r,__VA_ARGS__) +#define pinos_core_notify_done(r,...) ((PinosCoreEvent*)r->event)->done(r,__VA_ARGS__) +#define pinos_core_notify_error(r,...) ((PinosCoreEvent*)r->event)->error(r,__VA_ARGS__) +#define pinos_core_notify_remove_id(r,...) ((PinosCoreEvent*)r->event)->remove_id(r,__VA_ARGS__) + +#define PINOS_REGISTRY_BIND 0 + +typedef struct { + void (*bind) (void *object, + uint32_t id, + uint32_t new_id); +} PinosRegistryInterface; + +typedef struct { + void (*global) (void *object, + uint32_t id, + const char *type); + void (*global_remove) (void *object, + uint32_t id); +} PinosRegistryEvent; + +#define pinos_registry_notify_global(r,...) ((PinosRegistryEvent*)r->event)->global(r,__VA_ARGS__) +#define pinos_registry_notify_global_remove(r,...) ((PinosRegistryEvent*)r->event)->global_remove(r,__VA_ARGS__) + +typedef struct { + void (*info) (void *object, + PinosModuleInfo *info); +} PinosModuleEvent; + +#define pinos_module_notify_info(r,...) ((PinosModuleEvent*)r->event)->info(r,__VA_ARGS__) + +typedef struct { + void (*done) (void *object, + uint32_t seq); + void (*info) (void *object, + PinosNodeInfo *info); +} PinosNodeEvent; + +#define pinos_node_notify_done(r,...) ((PinosNodeEvent*)r->event)->done(r,__VA_ARGS__) +#define pinos_node_notify_info(r,...) ((PinosNodeEvent*)r->event)->info(r,__VA_ARGS__) + +#define PINOS_CLIENT_NODE_UPDATE 0 +#define PINOS_CLIENT_NODE_PORT_UPDATE 1 +#define PINOS_CLIENT_NODE_STATE_CHANGE 2 +#define PINOS_CLIENT_NODE_EVENT 3 +#define PINOS_CLIENT_NODE_DESTROY 4 + +struct _PinosClientNodeBuffer { + SpaBuffer *buffer; + uint32_t mem_id; + off_t offset; + size_t size; +}; + +typedef struct { + void (*update) (void *object, +#define PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS (1 << 0) +#define PINOS_MESSAGE_NODE_UPDATE_MAX_OUTPUTS (1 << 1) +#define PINOS_MESSAGE_NODE_UPDATE_PROPS (1 << 2) + uint32_t change_mask, + unsigned int max_input_ports, + unsigned int max_output_ports, + const SpaProps *props); + + void (*port_update) (void *object, + SpaDirection direction, + uint32_t port_id, +#define PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0) +#define PINOS_MESSAGE_PORT_UPDATE_FORMAT (1 << 1) +#define PINOS_MESSAGE_PORT_UPDATE_PROPS (1 << 2) +#define PINOS_MESSAGE_PORT_UPDATE_INFO (1 << 3) + uint32_t change_mask, + unsigned int n_possible_formats, + SpaFormat **possible_formats, + SpaFormat *format, + const SpaProps *props, + const SpaPortInfo *info); + void (*state_change) (void *object, + SpaNodeState state); + void (*event) (void *object, + SpaNodeEvent *event); + void (*destroy) (void *object, + uint32_t seq); +} PinosClientNodeInterface; + + +typedef struct { + void (*done) (void *object, + uint32_t seq, + int datafd); + void (*event) (void *object, + SpaNodeEvent *event); + void (*add_port) (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id); + void (*remove_port) (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id); + void (*set_format) (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id, + SpaPortFormatFlags flags, + const SpaFormat *format); + void (*set_property) (void *object, + uint32_t seq, + uint32_t id, + size_t size, + void *value); + void (*add_mem) (void *object, + SpaDirection direction, + uint32_t port_id, + uint32_t mem_id, + SpaDataType type, + int memfd, + uint32_t flags, + off_t offset, + size_t size); + void (*use_buffers) (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id, + unsigned int n_buffers, + PinosClientNodeBuffer *buffers); + void (*node_command) (void *object, + uint32_t seq, + SpaNodeCommand *command); + void (*port_command) (void *object, + uint32_t port_id, + SpaNodeCommand *command); + void (*transport) (void *object, + int memfd, + off_t offset, + size_t size); +} PinosClientNodeEvent; + +#define pinos_client_node_notify_done(r,...) ((PinosClientNodeEvent*)r->event)->done(r,__VA_ARGS__) +#define pinos_client_node_notify_event(r,...) ((PinosClientNodeEvent*)r->event)->event(r,__VA_ARGS__) +#define pinos_client_node_notify_add_port(r,...) ((PinosClientNodeEvent*)r->event)->add_port(r,__VA_ARGS__) +#define pinos_client_node_notify_remove_port(r,...) ((PinosClientNodeEvent*)r->event)->remove_port(r,__VA_ARGS__) +#define pinos_client_node_notify_set_format(r,...) ((PinosClientNodeEvent*)r->event)->set_format(r,__VA_ARGS__) +#define pinos_client_node_notify_set_property(r,...) ((PinosClientNodeEvent*)r->event)->set_property(r,__VA_ARGS__) +#define pinos_client_node_notify_add_mem(r,...) ((PinosClientNodeEvent*)r->event)->add_mem(r,__VA_ARGS__) +#define pinos_client_node_notify_use_buffers(r,...) ((PinosClientNodeEvent*)r->event)->use_buffers(r,__VA_ARGS__) +#define pinos_client_node_notify_node_command(r,...) ((PinosClientNodeEvent*)r->event)->node_command(r,__VA_ARGS__) +#define pinos_client_node_notify_port_command(r,...) ((PinosClientNodeEvent*)r->event)->port_command(r,__VA_ARGS__) +#define pinos_client_node_notify_transport(r,...) ((PinosClientNodeEvent*)r->event)->transport(r,__VA_ARGS__) + +typedef struct { + void (*info) (void *object, + PinosClientInfo *info); +} PinosClientEvent; + +#define pinos_client_notify_info(r,...) ((PinosClientEvent*)r->event)->info(r,__VA_ARGS__) + +typedef struct { + void (*info) (void *object, + PinosLinkInfo *info); +} PinosLinkEvent; + +#define pinos_link_notify_info(r,...) ((PinosLinkEvent*)r->event)->info(r,__VA_ARGS__) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __PINOS_INTERFACES_H__ */ diff --git a/pinos/modules/module-autolink.c b/pinos/modules/module-autolink.c index 2ba642d67..dbc2b1517 100644 --- a/pinos/modules/module-autolink.c +++ b/pinos/modules/module-autolink.c @@ -23,6 +23,7 @@ #include "config.h" +#include "pinos/client/interfaces.h" #include "pinos/server/core.h" #include "pinos/server/module.h" #include "pinos/server/client-node.h" @@ -136,14 +137,14 @@ on_link_state_changed (PinosListener *listener, pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error); spa_list_for_each (resource, &link->resource_list, link) { - pinos_client_send_error (resource->client, - resource, + pinos_core_notify_error (resource->client->core_resource, + resource->id, SPA_RESULT_ERROR, link->error); } if (info->info->client) { - pinos_client_send_error (info->info->client, - info->resource, + pinos_core_notify_error (info->info->client->core_resource, + info->resource->id, SPA_RESULT_ERROR, link->error); } @@ -219,8 +220,8 @@ error: { pinos_log_error ("module %p: can't link node '%s'", impl, error); if (info->info->client) { - pinos_client_send_error (info->info->client, - info->resource, + pinos_core_notify_error (info->info->client->core_resource, + info->resource->id, SPA_RESULT_ERROR, error); } diff --git a/pinos/modules/module-protocol-native.c b/pinos/modules/module-protocol-native.c index 3efde2d22..f0afc57cf 100644 --- a/pinos/modules/module-protocol-native.c +++ b/pinos/modules/module-protocol-native.c @@ -31,6 +31,7 @@ #include "pinos/client/pinos.h" #include "pinos/client/log.h" +#include "pinos/client/interfaces.h" #include "pinos/server/core.h" #include "pinos/server/node.h" @@ -78,6 +79,7 @@ typedef struct { int fd; SpaSource *source; PinosConnection *connection; + PinosListener resource_added; } PinosProtocolNativeClient; static void @@ -93,27 +95,610 @@ client_destroy (PinosProtocolNativeClient *this) free (this); } -static SpaResult -client_send_func (void *object, - uint32_t id, - PinosMessageType type, - void *message, - bool flush, - void *data) -{ - PinosProtocolNativeClient *client = data; +typedef void (*MarshallFunc) (void *object, void *data, size_t size); - pinos_log_debug ("protocol-native %p: sending message %d to %u of client %p", - client->impl, type, id, client); +static void +core_event_info (void *object, + PinosCoreInfo *info) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageCoreInfo m; + + m.info = info; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_CORE_INFO, + &m); + pinos_connection_flush (client->connection); +} + +static void +core_event_done (void *object, + uint32_t seq) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageNotifyDone m; + + m.seq = seq; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_NOTIFY_DONE, + &m); + pinos_connection_flush (client->connection); +} + +static void +core_event_error (void *object, + uint32_t id, + SpaResult res, + const char *error, ...) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageError m; + char buffer[128]; + va_list ap; + + va_start (ap, error); + vsnprintf (buffer, sizeof (buffer), error, ap); + va_end (ap); + + m.id = id; + m.res = res; + m.error = buffer; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_ERROR, + &m); + pinos_connection_flush (client->connection); +} + +static void +core_event_remove_id (void *object, + uint32_t id) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageRemoveId m; + + m.id = id; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_REMOVE_ID, + &m); + pinos_connection_flush (client->connection); +} + +static void +core_client_update (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageClientUpdate *m = data; + + ((PinosCoreInterface*)resource->interface)->client_update (resource, m->props); +} + +static void +core_sync (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageSync *m = data; + + ((PinosCoreInterface*)resource->interface)->sync (resource, m->seq); +} + +static void +core_get_registry (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageGetRegistry *m = data; + + ((PinosCoreInterface*)resource->interface)->get_registry (resource, m->seq, m->new_id); +} + +static void +core_create_node (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageCreateNode *m = data; + + ((PinosCoreInterface*)resource->interface)->create_node (resource, + m->seq, + m->factory_name, + m->name, + m->props, + m->new_id); +} + +static void +core_create_client_node (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageCreateClientNode *m = data; + + ((PinosCoreInterface*)resource->interface)->create_client_node (resource, + m->seq, + m->name, + m->props, + m->new_id); +} + +static void +registry_event_global (void *object, + uint32_t id, + const char *type) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageNotifyGlobal m; + + m.id = id; + m.type = type; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_NOTIFY_GLOBAL, + &m); + pinos_connection_flush (client->connection); +} + +static void +registry_event_global_remove (void *object, + uint32_t id) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageNotifyGlobalRemove m; + + m.id = id; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE, + &m); + pinos_connection_flush (client->connection); +} + +static void +registry_bind (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageBind *m = data; + + ((PinosRegistryInterface*)resource->interface)->bind (resource, + m->id, + m->new_id); +} + +static void +module_event_info (void *object, + PinosModuleInfo *info) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageModuleInfo m; + + m.info = info; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_MODULE_INFO, + &m); + pinos_connection_flush (client->connection); +} + +static void +node_event_done (void *object, + uint32_t seq) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageCreateNodeDone m; + + m.seq = seq; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_CREATE_NODE_DONE, + &m); + pinos_connection_flush (client->connection); +} + +static void +node_event_info (void *object, + PinosNodeInfo *info) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageNodeInfo m; + + m.info = info; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_NODE_INFO, + &m); + pinos_connection_flush (client->connection); +} + +static void +client_event_info (void *object, + PinosClientInfo *info) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageClientInfo m; + + m.info = info; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_CLIENT_INFO, + &m); + pinos_connection_flush (client->connection); +} + +static void +client_node_event_done (void *object, + uint32_t seq, + int datafd) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageCreateClientNodeDone m = { seq, datafd }; pinos_connection_add_message (client->connection, - id, - type, - message); - if (flush) - pinos_connection_flush (client->connection); + resource->id, + PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE, + &m); + pinos_connection_flush (client->connection); +} - return SPA_RESULT_OK; +static void +client_node_event_event (void *object, + SpaNodeEvent *event) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageNodeEvent m = { event }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_NODE_EVENT, + &m); + pinos_connection_flush (client->connection); +} + +static void +client_node_event_add_port (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageAddPort m = { seq, direction, port_id }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_ADD_PORT, + &m); + pinos_connection_flush (client->connection); +} +static void +client_node_event_remove_port (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageRemovePort m = { seq, direction, port_id }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_REMOVE_PORT, + &m); + pinos_connection_flush (client->connection); +} +static void +client_node_event_set_format (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id, + SpaPortFormatFlags flags, + const SpaFormat *format) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageSetFormat m = { seq, direction, port_id, flags, format }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_SET_FORMAT, + &m); + pinos_connection_flush (client->connection); +} + +static void +client_node_event_set_property (void *object, + uint32_t seq, + uint32_t id, + size_t size, + void *value) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageSetProperty m = { seq, id, size, value }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_SET_PROPERTY, + &m); + pinos_connection_flush (client->connection); +} +static void +client_node_event_add_mem (void *object, + SpaDirection direction, + uint32_t port_id, + uint32_t mem_id, + SpaDataType type, + int memfd, + uint32_t flags, + off_t offset, + size_t size) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageAddMem m = { direction, port_id, mem_id, type, memfd, flags, offset, size }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_ADD_MEM, + &m); + pinos_connection_flush (client->connection); +} +static void +client_node_event_use_buffers (void *object, + uint32_t seq, + SpaDirection direction, + uint32_t port_id, + unsigned int n_buffers, + PinosClientNodeBuffer *buffers) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageUseBuffers m = { seq, direction, port_id, n_buffers, buffers }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_USE_BUFFERS, + &m); + pinos_connection_flush (client->connection); +} +static void +client_node_event_node_command (void *object, + uint32_t seq, + SpaNodeCommand *command) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageNodeCommand m = { seq, command }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_NODE_COMMAND, + &m); + pinos_connection_flush (client->connection); +} +static void +client_node_event_port_command (void *object, + uint32_t port_id, + SpaNodeCommand *command) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessagePortCommand m = { port_id, command }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_PORT_COMMAND, + &m); + pinos_connection_flush (client->connection); +} + +static void +client_node_event_transport (void *object, + int memfd, + off_t offset, + size_t size) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageTransportUpdate m = { memfd, offset, size }; + + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_TRANSPORT_UPDATE, + &m); + pinos_connection_flush (client->connection); +} + +static void +client_node_update (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageNodeUpdate *m = data; + ((PinosClientNodeInterface*)resource->interface)->update (object, + m->change_mask, + m->max_input_ports, + m->max_output_ports, + m->props); +} + +static void +client_node_port_update (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessagePortUpdate *m = data; + ((PinosClientNodeInterface*)resource->interface)->port_update (object, + m->direction, + m->port_id, + m->change_mask, + m->n_possible_formats, + m->possible_formats, + m->format, + m->props, + m->info); +} + +static void +client_node_state_change (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageNodeStateChange *m = data; + ((PinosClientNodeInterface*)resource->interface)->state_change (object, + m->state); +} + +static void +client_node_event (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageNodeEvent *m = data; + ((PinosClientNodeInterface*)resource->interface)->event (object, + m->event); +} + +static void +client_node_destroy (void *object, + void *data, + size_t size) +{ + PinosResource *resource = object; + PinosMessageDestroy *m = data; + ((PinosClientNodeInterface*)resource->interface)->destroy (object, + m->seq); +} + +static void +link_event_info (void *object, + PinosLinkInfo *info) +{ + PinosResource *resource = object; + PinosProtocolNativeClient *client = resource->client->protocol_private; + PinosMessageLinkInfo m; + + m.info = info; + pinos_connection_add_message (client->connection, + resource->id, + PINOS_MESSAGE_LINK_INFO, + &m); + pinos_connection_flush (client->connection); +} + +static void +on_resource_added (PinosListener *listener, + PinosClient *client, + PinosResource *resource) +{ + if (resource->type == resource->core->uri.core) { + static const PinosCoreEvent core_event = { + &core_event_info, + &core_event_done, + &core_event_error, + &core_event_remove_id + }; + static const MarshallFunc core_marshall[] = { + [PINOS_MESSAGE_CLIENT_UPDATE] = &core_client_update, + [PINOS_MESSAGE_SYNC] = &core_sync, + [PINOS_MESSAGE_GET_REGISTRY] = &core_get_registry, + [PINOS_MESSAGE_CREATE_NODE] = &core_create_node, + [PINOS_MESSAGE_CREATE_CLIENT_NODE] = &core_create_client_node + }; + resource->event = &core_event; + resource->marshall = &core_marshall; + } + else if (resource->type == resource->core->uri.registry) { + static const PinosRegistryEvent registry_event = { + ®istry_event_global, + ®istry_event_global_remove, + }; + static const MarshallFunc registry_marshall[] = { + [PINOS_MESSAGE_BIND] = ®istry_bind, + }; + resource->event = ®istry_event; + resource->marshall = ®istry_marshall; + } + else if (resource->type == resource->core->uri.module) { + static const PinosModuleEvent module_event = { + &module_event_info, + }; + resource->event = &module_event; + resource->marshall = NULL; + } + else if (resource->type == resource->core->uri.node) { + static const PinosNodeEvent node_event = { + &node_event_done, + &node_event_info, + }; + resource->event = &node_event; + resource->marshall = NULL; + } + else if (resource->type == resource->core->uri.client) { + static const PinosClientEvent client_event = { + &client_event_info, + }; + resource->event = &client_event; + resource->marshall = NULL; + } + else if (resource->type == resource->core->uri.client_node) { + static const PinosClientNodeEvent client_node_events = { + &client_node_event_done, + &client_node_event_event, + &client_node_event_add_port, + &client_node_event_remove_port, + &client_node_event_set_format, + &client_node_event_set_property, + &client_node_event_add_mem, + &client_node_event_use_buffers, + &client_node_event_node_command, + &client_node_event_port_command, + &client_node_event_transport, + }; + static const MarshallFunc client_node_marshall[] = { + [PINOS_MESSAGE_NODE_UPDATE] = &client_node_update, + [PINOS_MESSAGE_PORT_UPDATE] = &client_node_port_update, + [PINOS_MESSAGE_NODE_STATE_CHANGE] = &client_node_state_change, + [PINOS_MESSAGE_NODE_EVENT] = &client_node_event, + [PINOS_MESSAGE_DESTROY] = &client_node_destroy, + }; + resource->event = &client_node_events; + resource->marshall = &client_node_marshall; + } + else if (resource->type == resource->core->uri.link) { + static const PinosLinkEvent link_event = { + &link_event_info, + }; + resource->event = &link_event; + resource->marshall = NULL; + } } static void @@ -138,6 +723,7 @@ connection_data (SpaSource *source, while (pinos_connection_get_next (conn, &type, &id, &size)) { PinosResource *resource; void *message = alloca (size); + const MarshallFunc *marshall; pinos_log_debug ("protocol-native %p: got message %d from %u", client->impl, type, id); @@ -151,10 +737,11 @@ connection_data (SpaSource *source, pinos_log_error ("protocol-native %p: unknown resource %u", client->impl, id); continue; } - - pinos_resource_dispatch (resource, - type, - message); + marshall = resource->marshall; + if (marshall[type]) + marshall[type] (resource, message, size); + else + pinos_log_error ("protocol-native %p: function %d not implemented", client->impl, type); } } @@ -198,14 +785,16 @@ client_new (PinosProtocolNative *impl, if (client == NULL) goto no_client; + client->protocol_private = this; + this->client = client; - pinos_client_set_send (client, - client_send_func, - this); - spa_list_insert (impl->client_list.prev, &this->link); + pinos_signal_add (&client->resource_added, + &this->resource_added, + on_resource_added); + pinos_global_bind (impl->core->global, client, 0, diff --git a/pinos/server/client-node.c b/pinos/server/client-node.c index 91b5a938b..9264857fe 100644 --- a/pinos/server/client-node.c +++ b/pinos/server/client-node.c @@ -29,7 +29,7 @@ #include #include "pinos/client/pinos.h" -#include "pinos/client/connection.h" +#include "pinos/client/interfaces.h" #include "pinos/client/serialize.h" #include "pinos/client/transport.h" @@ -216,37 +216,21 @@ spa_proxy_node_send_command (SpaNode *node, case SPA_NODE_COMMAND_FLUSH: case SPA_NODE_COMMAND_DRAIN: case SPA_NODE_COMMAND_MARKER: - { - PinosMessageNodeCommand cnc; - /* send start */ - cnc.seq = this->seq++; - cnc.command = command; - pinos_client_send_message (this->resource->client, - this->resource, - PINOS_MESSAGE_NODE_COMMAND, - &cnc, - true); + pinos_client_node_notify_node_command (this->resource, + this->seq, + command); if (command->type == SPA_NODE_COMMAND_START) send_need_input (this); - res = SPA_RESULT_RETURN_ASYNC (cnc.seq); + res = SPA_RESULT_RETURN_ASYNC (this->seq++); break; - } case SPA_NODE_COMMAND_CLOCK_UPDATE: - { - PinosMessageNodeCommand cnc; - - /* send start */ - cnc.command = command; - pinos_client_send_message (this->resource->client, - this->resource, - PINOS_MESSAGE_NODE_COMMAND, - &cnc, - true); + pinos_client_node_notify_node_command (this->resource, + this->seq++, + command); break; - } } return res; } @@ -325,23 +309,30 @@ spa_proxy_node_get_port_ids (SpaNode *node, } static void -do_update_port (SpaProxy *this, - PinosMessagePortUpdate *pu) +do_update_port (SpaProxy *this, + SpaDirection direction, + uint32_t port_id, + uint32_t change_mask, + unsigned int n_possible_formats, + SpaFormat **possible_formats, + SpaFormat *format, + const SpaProps *props, + const SpaPortInfo *info) { SpaProxyPort *port; unsigned int i; size_t size; - if (pu->direction == SPA_DIRECTION_INPUT) { - port = &this->in_ports[pu->port_id]; + if (direction == SPA_DIRECTION_INPUT) { + port = &this->in_ports[port_id]; } else { - port = &this->out_ports[pu->port_id]; + port = &this->out_ports[port_id]; } - if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS) { + if (change_mask & PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS) { for (i = 0; i < port->n_formats; i++) free (port->formats[i]); - port->n_formats = pu->n_possible_formats; + port->n_formats = n_possible_formats; if (port->n_formats) port->formats = realloc (port->formats, port->n_formats * sizeof (SpaFormat *)); else { @@ -349,33 +340,33 @@ do_update_port (SpaProxy *this, port->formats = NULL; } for (i = 0; i < port->n_formats; i++) { - size = pinos_serialize_format_get_size (pu->possible_formats[i]); - port->formats[i] = size ? pinos_serialize_format_copy_into (malloc (size), pu->possible_formats[i]) : NULL; + size = pinos_serialize_format_get_size (possible_formats[i]); + port->formats[i] = size ? pinos_serialize_format_copy_into (malloc (size), possible_formats[i]) : NULL; } } - if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_FORMAT) { + if (change_mask & PINOS_MESSAGE_PORT_UPDATE_FORMAT) { if (port->format) free (port->format); - size = pinos_serialize_format_get_size (pu->format); - port->format = size ? pinos_serialize_format_copy_into (malloc (size), pu->format) : NULL; + size = pinos_serialize_format_get_size (format); + port->format = size ? pinos_serialize_format_copy_into (malloc (size), format) : NULL; } - if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_PROPS) { + if (change_mask & PINOS_MESSAGE_PORT_UPDATE_PROPS) { } - if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_INFO && pu->info) { + if (change_mask & PINOS_MESSAGE_PORT_UPDATE_INFO && info) { if (port->info) free (port->info); - size = pinos_serialize_port_info_get_size (pu->info); - port->info = size ? pinos_serialize_port_info_copy_into (malloc (size), pu->info) : NULL; + size = pinos_serialize_port_info_get_size (info); + port->info = size ? pinos_serialize_port_info_copy_into (malloc (size), info) : NULL; } if (!port->valid) { - spa_log_info (this->log, "proxy %p: adding port %d", this, pu->port_id); + spa_log_info (this->log, "proxy %p: adding port %d", this, port_id); port->format = NULL; port->valid = true; - if (pu->direction == SPA_DIRECTION_INPUT) + if (direction == SPA_DIRECTION_INPUT) this->n_inputs++; else this->n_outputs++; @@ -388,20 +379,18 @@ clear_port (SpaProxy *this, SpaDirection direction, uint32_t port_id) { - PinosMessagePortUpdate pu; - - pu.change_mask = PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS | - PINOS_MESSAGE_PORT_UPDATE_FORMAT | - PINOS_MESSAGE_PORT_UPDATE_PROPS | - PINOS_MESSAGE_PORT_UPDATE_INFO; - pu.direction = direction; - pu.port_id = port_id; - pu.n_possible_formats = 0; - pu.possible_formats = NULL; - pu.format = NULL; - pu.props = NULL; - pu.info = NULL; - do_update_port (this, &pu); + do_update_port (this, + direction, + port_id, + PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS | + PINOS_MESSAGE_PORT_UPDATE_FORMAT | + PINOS_MESSAGE_PORT_UPDATE_PROPS | + PINOS_MESSAGE_PORT_UPDATE_INFO, + 0, + NULL, + NULL, + NULL, + NULL); clear_buffers (this, port); } @@ -503,7 +492,6 @@ spa_proxy_node_port_set_format (SpaNode *node, const SpaFormat *format) { SpaProxy *this; - PinosMessageSetFormat sf; if (node == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -516,17 +504,14 @@ spa_proxy_node_port_set_format (SpaNode *node, if (this->resource == NULL) return SPA_RESULT_OK; - sf.seq = this->seq++; - sf.direction = direction; - sf.port_id = port_id; - sf.flags = flags; - sf.format = (SpaFormat *) format; - pinos_client_send_message (this->resource->client, - this->resource, - PINOS_MESSAGE_SET_FORMAT, - &sf, - true); - return SPA_RESULT_RETURN_ASYNC (sf.seq); + pinos_client_node_notify_set_format (this->resource, + this->seq, + direction, + port_id, + flags, + format); + + return SPA_RESULT_RETURN_ASYNC (this->seq++); } static SpaResult @@ -648,10 +633,8 @@ spa_proxy_node_port_use_buffers (SpaNode *node, SpaProxy *this; SpaProxyPort *port; unsigned int i, j; - PinosMessageAddMem am; - PinosMessageUseBuffers ub; size_t n_mem; - PinosMessageBuffer *mb; + PinosClientNodeBuffer *mb; SpaMetaShared *msh; if (node == NULL) @@ -671,7 +654,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node, clear_buffers (this, port); if (n_buffers > 0) { - mb = alloca (n_buffers * sizeof (PinosMessageBuffer)); + mb = alloca (n_buffers * sizeof (PinosClientNodeBuffer)); } else { mb = NULL; } @@ -696,24 +679,20 @@ spa_proxy_node_port_use_buffers (SpaNode *node, b->buffer.datas = b->datas; b->buffer.metas = b->metas; - am.direction = direction; - am.port_id = port_id; - am.mem_id = n_mem++; - am.type = SPA_DATA_TYPE_MEMFD; - am.memfd = msh->fd; - am.flags = msh->flags; - am.offset = msh->offset; - am.size = msh->size; - pinos_client_send_message (this->resource->client, - this->resource, - PINOS_MESSAGE_ADD_MEM, - &am, - false); - mb[i].buffer = &b->buffer; - mb[i].mem_id = am.mem_id; + mb[i].mem_id = n_mem++; mb[i].offset = 0; - mb[i].size = am.size; + mb[i].size = msh->size; + + pinos_client_node_notify_add_mem (this->resource, + direction, + port_id, + mb[i].mem_id, + SPA_DATA_TYPE_MEMFD, + msh->fd, + msh->flags, + msh->offset, + msh->size); for (j = 0; j < buffers[i]->n_metas; j++) { memcpy (&b->buffer.metas[j], &buffers[i]->metas[j], sizeof (SpaMeta)); @@ -727,19 +706,15 @@ spa_proxy_node_port_use_buffers (SpaNode *node, switch (d->type) { case SPA_DATA_TYPE_DMABUF: case SPA_DATA_TYPE_MEMFD: - am.direction = direction; - am.port_id = port_id; - am.mem_id = n_mem; - am.type = d->type; - am.memfd = d->fd; - am.flags = d->flags; - am.offset = d->mapoffset; - am.size = d->maxsize; - pinos_client_send_message (this->resource->client, - this->resource, - PINOS_MESSAGE_ADD_MEM, - &am, - false); + pinos_client_node_notify_add_mem (this->resource, + direction, + port_id, + n_mem, + d->type, + d->fd, + d->flags, + d->mapoffset, + d->maxsize); b->buffer.datas[j].type = SPA_DATA_TYPE_ID; b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem); n_mem++; @@ -757,18 +732,14 @@ spa_proxy_node_port_use_buffers (SpaNode *node, } } - ub.seq = this->seq++; - ub.direction = direction; - ub.port_id = port_id; - ub.n_buffers = n_buffers; - ub.buffers = mb; - pinos_client_send_message (this->resource->client, - this->resource, - PINOS_MESSAGE_USE_BUFFERS, - &ub, - true); + pinos_client_node_notify_use_buffers (this->resource, + this->seq, + direction, + port_id, + n_buffers, + mb); - return SPA_RESULT_RETURN_ASYNC (ub.seq); + return SPA_RESULT_RETURN_ASYNC (this->seq++); } static SpaResult @@ -914,86 +885,110 @@ handle_node_event (SpaProxy *this, return SPA_RESULT_OK; } -static SpaResult -client_node_dispatch_func (void *object, - PinosMessageType type, - void *message, - void *data) +static void +client_node_update (void *object, + uint32_t change_mask, + unsigned int max_input_ports, + unsigned int max_output_ports, + const SpaProps *props) { - PinosClientNode *node = data; + PinosResource *resource = object; + PinosClientNode *node = resource->object; PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this); SpaProxy *this = &impl->proxy; - switch (type) { - default: - spa_log_error (this->log, "proxy %p: got unexpected command %d", this, type); - break; + if (change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS) + this->max_inputs = max_input_ports; + if (change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_OUTPUTS) + this->max_outputs = max_output_ports; - case PINOS_MESSAGE_NODE_UPDATE: - { - PinosMessageNodeUpdate *nu = message; - - if (nu->change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS) - this->max_inputs = nu->max_input_ports; - if (nu->change_mask & PINOS_MESSAGE_NODE_UPDATE_MAX_OUTPUTS) - this->max_outputs = nu->max_output_ports; - - spa_log_info (this->log, "proxy %p: got node update %d, max_in %u, max_out %u", this, type, - this->max_inputs, this->max_outputs); - - break; - } - - case PINOS_MESSAGE_PORT_UPDATE: - { - PinosMessagePortUpdate *pu = message; - bool remove; - - spa_log_info (this->log, "proxy %p: got port update %d", this, type); - if (!CHECK_PORT_ID (this, pu->direction, pu->port_id)) - break; - - remove = (pu->change_mask == 0); - - if (remove) { - do_uninit_port (this, pu->direction, pu->port_id); - } else { - do_update_port (this, pu); - } - break; - } - - case PINOS_MESSAGE_NODE_STATE_CHANGE: - { - PinosMessageNodeStateChange *sc = message; - SpaNodeState old = this->node.state; - - spa_log_info (this->log, "proxy %p: got node state change %d -> %d", this, old, sc->state); - this->node.state = sc->state; - if (old == SPA_NODE_STATE_INIT) - send_async_complete (this, 0, SPA_RESULT_OK); - - break; - } - - case PINOS_MESSAGE_ADD_MEM: - break; - case PINOS_MESSAGE_USE_BUFFERS: - break; - - case PINOS_MESSAGE_NODE_EVENT: - { - PinosMessageNodeEvent *cne = message; - handle_node_event (this, cne->event); - break; - } - case PINOS_MESSAGE_DESTROY: - pinos_client_node_destroy (node); - break; - } - return SPA_RESULT_OK; + spa_log_info (this->log, "proxy %p: got node update max_in %u, max_out %u", this, + this->max_inputs, this->max_outputs); } +static void +client_node_port_update (void *object, + SpaDirection direction, + uint32_t port_id, + uint32_t change_mask, + unsigned int n_possible_formats, + SpaFormat **possible_formats, + SpaFormat *format, + const SpaProps *props, + const SpaPortInfo *info) +{ + PinosResource *resource = object; + PinosClientNode *node = resource->object; + PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this); + SpaProxy *this = &impl->proxy; + bool remove; + + spa_log_info (this->log, "proxy %p: got port update", this); + if (!CHECK_PORT_ID (this, direction, port_id)) + return; + + remove = (change_mask == 0); + + if (remove) { + do_uninit_port (this, direction, port_id); + } else { + do_update_port (this, + direction, + port_id, + change_mask, + n_possible_formats, + possible_formats, + format, + props, + info); + } +} + +static void +client_node_state_change (void *object, + SpaNodeState state) +{ + PinosResource *resource = object; + PinosClientNode *node = resource->object; + PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this); + SpaProxy *this = &impl->proxy; + SpaNodeState old = this->node.state; + + spa_log_info (this->log, "proxy %p: got node state change %d -> %d", this, old, state); + this->node.state = state; + if (old == SPA_NODE_STATE_INIT) + send_async_complete (this, 0, SPA_RESULT_OK); +} + +static void +client_node_event (void *object, + SpaNodeEvent *event) +{ + PinosResource *resource = object; + PinosClientNode *node = resource->object; + PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this); + SpaProxy *this = &impl->proxy; + + handle_node_event (this, event); +} + +static void +client_node_destroy (void *object, + uint32_t seq) +{ + PinosResource *resource = object; + PinosClientNode *node = resource->object; + pinos_client_node_destroy (node); +} + +static PinosClientNodeInterface client_node_interface = { + &client_node_update, + &client_node_port_update, + &client_node_state_change, + &client_node_event, + &client_node_destroy, +}; + static void proxy_on_data_fd_events (SpaSource *source) { @@ -1088,21 +1083,15 @@ on_transport_changed (PinosListener *listener, PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, transport_changed); PinosClientNode *this = &impl->this; PinosTransportInfo info; - PinosMessageTransportUpdate tu; if (this->resource == NULL) return; pinos_transport_get_info (node->transport, &info); - - tu.memfd = info.memfd; - tu.offset = info.offset; - tu.size = info.size; - pinos_client_send_message (this->resource->client, - this->resource, - PINOS_MESSAGE_TRANSPORT_UPDATE, - &tu, - true); + pinos_client_node_notify_transport (this->resource, + info.memfd, + info.offset, + info.size); } static void @@ -1249,9 +1238,7 @@ pinos_client_node_new (PinosClient *client, &impl->global_added, on_global_added); - pinos_resource_set_dispatch (this->resource, - client_node_dispatch_func, - this); + this->resource->interface = &client_node_interface; return this; diff --git a/pinos/server/client.c b/pinos/server/client.c index b2b71dd23..01d7d3fec 100644 --- a/pinos/server/client.c +++ b/pinos/server/client.c @@ -18,7 +18,9 @@ */ #include + #include "pinos/client/pinos.h" +#include "pinos/client/interfaces.h" #include "pinos/server/client.h" #include "pinos/server/resource.h" @@ -26,29 +28,8 @@ typedef struct { PinosClient this; - - PinosSendFunc send_func; - void *send_data; } PinosClientImpl; - -static SpaResult -client_dispatch_func (void *object, - PinosMessageType type, - void *message, - void *data) -{ - PinosResource *resource = object; - PinosClient *client = resource->object; - - switch (type) { - default: - pinos_log_warn ("client %p: unhandled message %d", client, type); - break; - } - return SPA_RESULT_OK; -} - static void client_unbind_func (void *data) { @@ -64,8 +45,6 @@ client_bind_func (PinosGlobal *global, { PinosClient *this = global->object; PinosResource *resource; - PinosMessageClientInfo m; - PinosClientInfo info; resource = pinos_resource_new (client, id, @@ -75,27 +54,18 @@ client_bind_func (PinosGlobal *global, if (resource == NULL) goto no_mem; - pinos_resource_set_dispatch (resource, - client_dispatch_func, - global); - pinos_log_debug ("client %p: bound to %d", global->object, resource->id); spa_list_insert (this->resource_list.prev, &resource->link); - m.info = &info; - info.id = global->id; - info.change_mask = ~0; - info.props = this->properties ? &this->properties->dict : NULL; + this->info.change_mask = ~0; + pinos_client_notify_info (resource, &this->info); + + return SPA_RESULT_OK; - return pinos_client_send_message (client, - resource, - PINOS_MESSAGE_CLIENT_INFO, - &m, - true); no_mem: - pinos_client_send_error (client, - client->core_resource, + pinos_core_notify_error (client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; @@ -146,6 +116,9 @@ pinos_client_new (PinosCore *core, this, client_bind_func); + this->info.id = this->global->id; + this->info.props = this->properties ? &this->properties->dict : NULL; + return this; } @@ -188,113 +161,10 @@ pinos_client_destroy (PinosClient * client) free (impl); } -void -pinos_client_set_send (PinosClient *client, - PinosSendFunc func, - void *data) -{ - PinosClientImpl *impl = SPA_CONTAINER_OF (client, PinosClientImpl, this); - - impl->send_func = func; - impl->send_data = data; -} - -static SpaResult -do_send_message (PinosAccessData *data) -{ - PinosClientImpl *impl = SPA_CONTAINER_OF (data->client, PinosClientImpl, this); - - if (data->res == SPA_RESULT_SKIPPED) { - data->res = SPA_RESULT_OK; - } else if (data->res == SPA_RESULT_NO_PERMISSION) { - pinos_client_send_error (data->client, - data->resource, - data->res, - "no permission"); - } else if (SPA_RESULT_IS_ERROR (data->res)) { - pinos_client_send_error (data->client, - data->resource, - data->res, - "error %d", data->res); - } else { - data->res = impl->send_func (data->resource, - data->resource->id, - data->opcode, - data->message, - data->flush, - impl->send_data); - } - return data->res; -} - -SpaResult -pinos_client_send_message (PinosClient *client, - PinosResource *resource, - uint32_t opcode, - void *message, - bool flush) -{ - PinosClientImpl *impl = SPA_CONTAINER_OF (client, PinosClientImpl, this); - - if (impl->send_func) { - PinosAccessData data; - - data.client = client; - data.resource = resource; - data.opcode = opcode; - data.message = message; - data.flush = flush; - - data.res = SPA_RESULT_OK; - pinos_signal_emit (&client->core->access.check_send, - do_send_message, - &data); - - if (SPA_RESULT_IS_ASYNC (data.res)) - return data.res; - - return do_send_message (&data); - } - - pinos_log_error ("client %p: send func not implemented", client); - - return SPA_RESULT_NOT_IMPLEMENTED; -} - -SpaResult -pinos_client_send_error (PinosClient *client, - PinosResource *resource, - SpaResult res, - const char *message, - ...) -{ - PinosMessageError m; - char buffer[128]; - va_list ap; - - va_start (ap, message); - vsnprintf (buffer, sizeof (buffer), message, ap); - va_end (ap); - - m.id = resource->id; - m.res = res; - m.error = buffer; - - pinos_log_error ("client %p: %u send error %d (%s)", client, resource->id, res, buffer); - - return pinos_client_send_message (client, - client->core_resource, - PINOS_MESSAGE_ERROR, - &m, - true); -} - void pinos_client_update_properties (PinosClient *client, const SpaDict *dict) { - PinosMessageClientInfo m; - PinosClientInfo info; PinosResource *resource; if (client->properties == NULL) { @@ -309,16 +179,10 @@ pinos_client_update_properties (PinosClient *client, dict->items[i].value); } - m.info = &info; - info.id = client->global->id; - info.change_mask = 1 << 0; - info.props = client->properties ? &client->properties->dict : NULL; + client->info.change_mask = 1 << 0; + client->info.props = client->properties ? &client->properties->dict : NULL; spa_list_for_each (resource, &client->resource_list, link) { - pinos_client_send_message (client, - resource, - PINOS_MESSAGE_CLIENT_INFO, - &m, - true); + pinos_client_notify_info (resource, &client->info); } } diff --git a/pinos/server/client.h b/pinos/server/client.h index 168274f1c..25df7fdaa 100644 --- a/pinos/server/client.h +++ b/pinos/server/client.h @@ -28,6 +28,7 @@ typedef struct _PinosClient PinosClient; #include +#include #include #include @@ -52,9 +53,12 @@ struct _PinosClient { PinosGlobal *global; PinosProperties *properties; + PinosClientInfo info; bool ucred_valid; struct ucred ucred; + void *protocol_private; + PinosResource *core_resource; PinosMap objects; @@ -76,21 +80,6 @@ PinosClient * pinos_client_new (PinosCore *core, PinosProperties *properties); void pinos_client_destroy (PinosClient *client); -void pinos_client_set_send (PinosClient *client, - PinosSendFunc func, - void *data); - -SpaResult pinos_client_send_message (PinosClient *client, - PinosResource *resource, - uint32_t opcode, - void *message, - bool flush); - -SpaResult pinos_client_send_error (PinosClient *client, - PinosResource *resource, - SpaResult res, - const char *message, ...); - void pinos_client_update_properties (PinosClient *client, const SpaDict *dict); diff --git a/pinos/server/core.c b/pinos/server/core.c index a58042471..d937b6bc9 100644 --- a/pinos/server/core.c +++ b/pinos/server/core.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -36,46 +37,39 @@ typedef struct { } PinosCoreImpl; -static SpaResult -registry_dispatch_func (void *object, - PinosMessageType type, - void *message, - void *data) +static void +registry_bind (void *object, + uint32_t id, + uint32_t new_id) { - SpaResult res; PinosResource *resource = object; PinosClient *client = resource->client; - PinosCore *this = data; + PinosCore *core = resource->core; + PinosGlobal *global; - switch (type) { - case PINOS_MESSAGE_BIND: - { - PinosMessageBind *m = message; - PinosGlobal *global; - - spa_list_for_each (global, &this->global_list, link) - if (global->id == m->id) - break; - - if (&global->link == &this->global_list) { - pinos_client_send_error (client, - resource, - SPA_RESULT_INVALID_OBJECT_ID, - "unknown object id %u", m->id); - return SPA_RESULT_ERROR; - } - pinos_log_debug ("global %p: bind object id %d to %d", global, m->id, m->new_id); - res = pinos_global_bind (global, client, 0, m->new_id); + spa_list_for_each (global, &core->global_list, link) + if (global->id == id) break; - } - default: - pinos_log_error ("unhandled message %d", type); - res = SPA_RESULT_NOT_IMPLEMENTED; - break; - } - return res; + + if (&global->link == &core->global_list) + goto no_id; + + pinos_log_debug ("global %p: bind object id %d to %d", global, id, new_id); + pinos_global_bind (global, client, 0, new_id); + + return; + +no_id: + pinos_core_notify_error (client->core_resource, + resource->id, + SPA_RESULT_INVALID_OBJECT_ID, + "unknown object id %u", id); } +static PinosRegistryInterface registry_interface = { + ®istry_bind +}; + static void destroy_registry_resource (void *object) { @@ -83,135 +77,139 @@ destroy_registry_resource (void *object) spa_list_remove (&resource->link); } -static SpaResult -core_dispatch_func (void *object, - PinosMessageType type, - void *message, - void *data) +static void +core_client_update (void *object, + const SpaDict *props) +{ + PinosResource *resource = object; + + pinos_client_update_properties (resource->client, props); +} + +static void +core_sync (void *object, + uint32_t seq) +{ + PinosResource *resource = object; + + pinos_core_notify_done (resource, seq); +} + +static void +core_get_registry (void *object, + uint32_t seq, + uint32_t new_id) { PinosResource *resource = object; PinosClient *client = resource->client; - PinosCore *this = data; + PinosCore *this = resource->core; + PinosGlobal *global; + PinosResource *registry_resource; - switch (type) { - case PINOS_MESSAGE_CLIENT_UPDATE: - { - PinosMessageClientUpdate *m = message; + registry_resource = pinos_resource_new (client, + new_id, + this->uri.registry, + this, + destroy_registry_resource); + if (registry_resource == NULL) + goto no_mem; - pinos_client_update_properties (client, - m->props); - break; - } - case PINOS_MESSAGE_SYNC: - { - PinosMessageSync *m = message; - PinosMessageNotifyDone r; + registry_resource->interface = ®istry_interface; - r.seq = m->seq; - pinos_client_send_message (client, - resource, - PINOS_MESSAGE_NOTIFY_DONE, - &r, - true); - break; - } + spa_list_insert (this->registry_resource_list.prev, ®istry_resource->link); - case PINOS_MESSAGE_GET_REGISTRY: - { - PinosMessageGetRegistry *m = message; - PinosGlobal *global; - PinosMessageNotifyDone nd; - PinosResource *registry_resource; + spa_list_for_each (global, &this->global_list, link) + pinos_registry_notify_global (registry_resource, + global->id, + spa_id_map_get_uri (this->uri.map, global->type)); - registry_resource = pinos_resource_new (resource->client, - m->new_id, - this->uri.registry, - this, - destroy_registry_resource); - if (registry_resource == NULL) - goto no_mem; + pinos_core_notify_done (client->core_resource, seq); - pinos_resource_set_dispatch (registry_resource, - registry_dispatch_func, - this); - - spa_list_insert (this->registry_resource_list.prev, ®istry_resource->link); - - spa_list_for_each (global, &this->global_list, link) { - PinosMessageNotifyGlobal ng; - - ng.id = global->id; - ng.type = spa_id_map_get_uri (this->uri.map, global->type); - pinos_client_send_message (client, - registry_resource, - PINOS_MESSAGE_NOTIFY_GLOBAL, - &ng, - false); - } - nd.seq = m->seq; - pinos_client_send_message (client, - client->core_resource, - PINOS_MESSAGE_NOTIFY_DONE, - &nd, - true); - break; - } - case PINOS_MESSAGE_CREATE_CLIENT_NODE: - { - PinosMessageCreateClientNode *m = message; - PinosClientNode *node; - SpaResult res; - int data_fd, i; - PinosMessageCreateClientNodeDone r; - PinosProperties *props; - - props = pinos_properties_new (NULL, NULL); - if (props == NULL) - goto no_mem; - - for (i = 0; i < m->props->n_items; i++) { - pinos_properties_set (props, m->props->items[i].key, - m->props->items[i].value); - } - - node = pinos_client_node_new (client, - m->new_id, - m->name, - props); - if (node == NULL) - goto no_mem; - - if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) { - pinos_client_send_error (client, - resource, - SPA_RESULT_ERROR, - "can't get data fd"); - break; - } - - r.seq = m->seq; - r.datafd = data_fd; - pinos_client_send_message (client, - node->resource, - PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE, - &r, - true); - break; - } - default: - pinos_log_error ("unhandled message %d", type); - break; - } - return SPA_RESULT_OK; + return; no_mem: - pinos_client_send_error (client, - resource, + pinos_core_notify_error (client->core_resource, + resource->id, SPA_RESULT_NO_MEMORY, "no memory"); - return SPA_RESULT_NO_MEMORY; } +static void +core_create_node (void *object, + uint32_t seq, + const char *factory_name, + const char *name, + const SpaDict *props, + uint32_t new_id) +{ + PinosResource *resource = object; + PinosClient *client = resource->client; + + pinos_core_notify_error (client->core_resource, + resource->id, + SPA_RESULT_NOT_IMPLEMENTED, + "not implemented"); +} + +static void +core_create_client_node (void *object, + uint32_t seq, + const char *name, + const SpaDict *props, + uint32_t new_id) +{ + PinosResource *resource = object; + PinosClient *client = resource->client; + PinosClientNode *node; + SpaResult res; + int data_fd, i; + PinosProperties *properties; + + properties = pinos_properties_new (NULL, NULL); + if (properties == NULL) + goto no_mem; + + for (i = 0; i < props->n_items; i++) { + pinos_properties_set (properties, props->items[i].key, + props->items[i].value); + } + + node = pinos_client_node_new (client, + new_id, + name, + properties); + if (node == NULL) + goto no_mem; + + if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) { + pinos_core_notify_error (client->core_resource, + resource->id, + SPA_RESULT_ERROR, + "can't get data fd"); + return; + } + + pinos_client_node_notify_done (node->resource, + seq, + data_fd); + return; + +no_mem: + pinos_core_notify_error (client->core_resource, + resource->id, + SPA_RESULT_NO_MEMORY, + "no memory"); + return; +} + +static PinosCoreInterface core_interface = { + &core_client_update, + &core_sync, + &core_get_registry, + &core_create_node, + &core_create_client_node +}; + static void core_unbind_func (void *data) { @@ -228,8 +226,6 @@ core_bind_func (PinosGlobal *global, { PinosCore *this = global->object; PinosResource *resource; - PinosMessageCoreInfo m; - PinosCoreInfo info; resource = pinos_resource_new (client, id, @@ -239,31 +235,18 @@ core_bind_func (PinosGlobal *global, if (resource == NULL) goto no_mem; - pinos_resource_set_dispatch (resource, - core_dispatch_func, - this); + resource->interface = &core_interface; spa_list_insert (this->resource_list.prev, &resource->link); client->core_resource = resource; pinos_log_debug ("core %p: bound to %d", global->object, resource->id); - m.info = &info; - info.id = global->id; - info.change_mask = PINOS_CORE_CHANGE_MASK_ALL; - info.user_name = pinos_get_user_name (); - info.host_name = pinos_get_host_name (); - info.version = "0"; - info.name = "pinos-0"; - srandom (time (NULL)); - info.cookie = random (); - info.props = this->properties ? &this->properties->dict : NULL; + this->info.change_mask = PINOS_CORE_CHANGE_MASK_ALL; + pinos_core_notify_info (resource, &this->info); + + return SPA_RESULT_OK; - return pinos_client_send_message (resource->client, - resource, - PINOS_MESSAGE_CORE_INFO, - &m, - true); no_mem: pinos_log_error ("can't create core resource"); return SPA_RESULT_NO_MEMORY; @@ -323,6 +306,16 @@ pinos_core_new (PinosMainLoop *main_loop, this, core_bind_func); + this->info.id = this->global->id; + this->info.change_mask = 0; + this->info.user_name = pinos_get_user_name (); + this->info.host_name = pinos_get_host_name (); + this->info.version = "0"; + this->info.name = "pinos-0"; + srandom (time (NULL)); + this->info.cookie = random (); + this->info.props = this->properties ? &this->properties->dict : NULL; + return this; no_data_loop: @@ -357,7 +350,7 @@ pinos_core_add_global (PinosCore *core, PinosGlobalImpl *impl; PinosGlobal *this; PinosResource *registry; - PinosMessageNotifyGlobal ng; + const char *type_uri; impl = calloc (1, sizeof (PinosGlobalImpl)); if (impl == NULL) @@ -379,18 +372,14 @@ pinos_core_add_global (PinosCore *core, spa_list_insert (core->global_list.prev, &this->link); pinos_signal_emit (&core->global_added, core, this); - ng.id = this->id; - ng.type = spa_id_map_get_uri (core->uri.map, this->type); + type_uri = spa_id_map_get_uri (core->uri.map, this->type); + pinos_log_debug ("global %p: new %u %s", this, this->id, type_uri); - pinos_log_debug ("global %p: new %u %s", this, ng.id, ng.type); + spa_list_for_each (registry, &core->registry_resource_list, link) + pinos_registry_notify_global (registry, + this->id, + type_uri); - spa_list_for_each (registry, &core->registry_resource_list, link) { - pinos_client_send_message (registry->client, - registry, - PINOS_MESSAGE_NOTIFY_GLOBAL, - &ng, - true); - } return this; } @@ -404,12 +393,11 @@ pinos_global_bind (PinosGlobal *global, PinosGlobalImpl *impl = SPA_CONTAINER_OF (global, PinosGlobalImpl, this); if (impl->bind) { - res = impl->bind (global, client, version, id); } else { res = SPA_RESULT_NOT_IMPLEMENTED; - pinos_client_send_error (client, - client->core_resource, + pinos_core_notify_error (client->core_resource, + client->core_resource->id, res, "can't bind object id %d", id); } @@ -421,19 +409,12 @@ pinos_global_destroy (PinosGlobal *global) { PinosCore *core = global->core; PinosResource *registry; - PinosMessageNotifyGlobalRemove ng; pinos_log_debug ("global %p: destroy %u", global, global->id); pinos_signal_emit (&global->destroy_signal, global); - ng.id = global->id; - spa_list_for_each (registry, &core->registry_resource_list, link) { - pinos_client_send_message (registry->client, - registry, - PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE, - &ng, - true); - } + spa_list_for_each (registry, &core->registry_resource_list, link) + pinos_registry_notify_global_remove (registry, global->id); pinos_map_remove (&core->objects, global->id); @@ -448,8 +429,6 @@ void pinos_core_update_properties (PinosCore *core, const SpaDict *dict) { - PinosMessageCoreInfo m; - PinosCoreInfo info; PinosResource *resource; if (core->properties == NULL) { @@ -464,17 +443,11 @@ pinos_core_update_properties (PinosCore *core, dict->items[i].value); } - m.info = &info; - info.id = core->global->id; - info.change_mask = PINOS_CORE_CHANGE_MASK_PROPS; - info.props = core->properties ? &core->properties->dict : NULL; + core->info.change_mask = PINOS_CORE_CHANGE_MASK_PROPS; + core->info.props = core->properties ? &core->properties->dict : NULL; spa_list_for_each (resource, &core->resource_list, link) { - pinos_client_send_message (resource->client, - resource, - PINOS_MESSAGE_CORE_INFO, - &m, - true); + pinos_core_notify_info (resource, &core->info); } } diff --git a/pinos/server/core.h b/pinos/server/core.h index ff4dc568e..82f1a8b7f 100644 --- a/pinos/server/core.h +++ b/pinos/server/core.h @@ -64,6 +64,8 @@ struct _PinosGlobal { struct _PinosCore { PinosGlobal *global; + PinosCoreInfo info; + PinosProperties *properties; PinosURI uri; diff --git a/pinos/server/link.c b/pinos/server/link.c index 0f18c89cd..61630533b 100644 --- a/pinos/server/link.c +++ b/pinos/server/link.c @@ -23,6 +23,7 @@ #include #include "pinos/client/pinos.h" +#include "pinos/client/interfaces.h" #include "pinos/server/link.h" #include "pinos/server/work-queue.h" @@ -693,19 +694,6 @@ pinos_pinos_link_deactivate (PinosLink *this) return true; } -static SpaResult -link_dispatch_func (void *object, - PinosMessageType type, - void *message, - void *data) -{ - switch (type) { - default: - break; - } - return SPA_RESULT_OK; -} - static void pinos_link_free (PinosLink *link) { @@ -744,7 +732,6 @@ link_bind_func (PinosGlobal *global, PinosLink *this = global->object; PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this); PinosResource *resource; - PinosMessageLinkInfo m; PinosLinkInfo info; resource = pinos_resource_new (client, @@ -757,15 +744,10 @@ link_bind_func (PinosGlobal *global, impl->refcount++; - pinos_resource_set_dispatch (resource, - link_dispatch_func, - global); - pinos_log_debug ("link %p: bound to %d", global->object, resource->id); spa_list_insert (this->resource_list.prev, &resource->link); - m.info = &info; info.id = global->id; info.change_mask = ~0; info.output_node_id = this->output ? this->output->node->global->id : -1; @@ -773,14 +755,13 @@ link_bind_func (PinosGlobal *global, info.input_node_id = this->input ? this->input->node->global->id : -1; info.input_port_id = this->input ? this->input->port_id : -1; - return pinos_client_send_message (resource->client, - resource, - PINOS_MESSAGE_LINK_INFO, - &m, - true); + pinos_link_notify_info (resource, &info); + + return SPA_RESULT_OK; + no_mem: - pinos_client_send_error (client, - client->core_resource, + pinos_core_notify_error (client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; diff --git a/pinos/server/module.c b/pinos/server/module.c index bd4263ca1..771e409e9 100644 --- a/pinos/server/module.c +++ b/pinos/server/module.c @@ -29,6 +29,7 @@ #include "pinos/client/pinos.h" +#include "pinos/client/interfaces.h" #include "pinos/client/utils.h" #include "pinos/server/module.h" @@ -37,7 +38,6 @@ typedef struct { PinosModule this; - void *hnd; } PinosModuleImpl; @@ -90,23 +90,6 @@ find_module (const char * path, const char *name) return filename; } -static SpaResult -module_dispatch_func (void *object, - PinosMessageType type, - void *message, - void *data) -{ - PinosResource *resource = object; - PinosModule *module = resource->object; - - switch (type) { - default: - pinos_log_warn ("module %p: unhandled message %d", module, type); - break; - } - return SPA_RESULT_OK; -} - static SpaResult module_bind_func (PinosGlobal *global, PinosClient *client, @@ -115,8 +98,6 @@ module_bind_func (PinosGlobal *global, { PinosModule *this = global->object; PinosResource *resource; - PinosMessageModuleInfo m; - PinosModuleInfo info; resource = pinos_resource_new (client, id, @@ -126,28 +107,16 @@ module_bind_func (PinosGlobal *global, if (resource == NULL) goto no_mem; - pinos_resource_set_dispatch (resource, - module_dispatch_func, - global); - pinos_log_debug ("module %p: bound to %d", global->object, resource->id); - m.info = &info; - info.id = global->id; - info.change_mask = ~0; - info.name = this->name; - info.filename = this->filename; - info.args = this->args; - info.props = NULL; + this->info.change_mask = ~0; + pinos_module_notify_info (resource, &this->info); + + return SPA_RESULT_OK; - return pinos_client_send_message (client, - resource, - PINOS_MESSAGE_MODULE_INFO, - &m, - true); no_mem: - pinos_client_send_error (client, - client->core_resource, + pinos_core_notify_error (client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; @@ -217,16 +186,11 @@ pinos_module_load (PinosCore *core, impl->hnd = hnd; this = &impl->this; - this->name = name ? strdup (name) : NULL; - this->filename = filename; - this->args = args ? strdup (args) : NULL; this->core = core; if (!init_func (this, (char *) args)) goto init_failed; - pinos_log_debug ("loaded module: %s", this->name); - this->global = pinos_core_add_global (core, NULL, core->uri.module, @@ -234,6 +198,14 @@ pinos_module_load (PinosCore *core, impl, module_bind_func); + this->info.id = this->global->id; + this->info.name = name ? strdup (name) : NULL; + this->info.filename = filename; + this->info.args = args ? strdup (args) : NULL; + this->info.props = NULL; + + pinos_log_debug ("loaded module: %s", this->info.name); + return this; not_found: @@ -270,12 +242,12 @@ pinos_module_destroy (PinosModule *this) pinos_signal_emit (&this->destroy_signal, this); - if (this->name) - free (this->name); - if (this->filename) - free (this->filename); - if (this->args) - free (this->args); + if (this->info.name) + free ((char*)this->info.name); + if (this->info.filename) + free ((char*)this->info.filename); + if (this->info.args) + free ((char*)this->info.args); dlclose (impl->hnd); free (impl); } diff --git a/pinos/server/module.h b/pinos/server/module.h index f500fa01b..b413500d2 100644 --- a/pinos/server/module.h +++ b/pinos/server/module.h @@ -34,9 +34,7 @@ struct _PinosModule { SpaList link; PinosGlobal *global; - char *name; - char *filename; - char *args; + PinosModuleInfo info; void *user_data; diff --git a/pinos/server/node.c b/pinos/server/node.c index f234c4847..90810ae21 100644 --- a/pinos/server/node.c +++ b/pinos/server/node.c @@ -22,6 +22,7 @@ #include #include "pinos/client/pinos.h" +#include "pinos/client/interfaces.h" #include "pinos/client/serialize.h" #include "pinos/server/node.h" @@ -366,24 +367,6 @@ on_node_event (SpaNode *node, SpaNodeEvent *event, void *user_data) } } -static SpaResult -node_dispatch_func (void *object, - PinosMessageType type, - void *message, - void *data) -{ - PinosResource *resource = object; - PinosNode *node = resource->object; - - switch (type) { - default: - pinos_log_warn ("node %p: unhandled message %d", node, type); - break; - } - return SPA_RESULT_OK; -} - - static void node_unbind_func (void *data) { @@ -399,7 +382,6 @@ node_bind_func (PinosGlobal *global, { PinosNode *this = global->object; PinosResource *resource; - PinosMessageNodeInfo m; PinosNodeInfo info; resource = pinos_resource_new (client, @@ -410,15 +392,10 @@ node_bind_func (PinosGlobal *global, if (resource == NULL) goto no_mem; - pinos_resource_set_dispatch (resource, - node_dispatch_func, - global); - pinos_log_debug ("node %p: bound to %d", this, resource->id); spa_list_insert (this->resource_list.prev, &resource->link); - m.info = &info; info.id = global->id; info.change_mask = ~0; info.name = this->name; @@ -466,14 +443,13 @@ node_bind_func (PinosGlobal *global, info.error = this->error; info.props = this->properties ? &this->properties->dict : NULL; - return pinos_client_send_message (client, - resource, - PINOS_MESSAGE_NODE_INFO, - &m, - true); + pinos_node_notify_info (resource, &info); + + return SPA_RESULT_OK; + no_mem: - pinos_client_send_error (client, - client->core_resource, + pinos_core_notify_error (client->core_resource, + client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory"); return SPA_RESULT_NO_MEMORY; @@ -828,7 +804,6 @@ pinos_node_update_state (PinosNode *node, old = node->state; if (old != state) { - PinosMessageNodeInfo m; PinosNodeInfo info; PinosResource *resource; @@ -844,18 +819,14 @@ pinos_node_update_state (PinosNode *node, pinos_signal_emit (&node->state_changed, node, old, state); spa_zero (info); - m.info = &info; info.change_mask = 1 << 5; info.state = node->state; info.error = node->error; spa_list_for_each (resource, &node->resource_list, link) { + /* global is only set when there are resources */ info.id = node->global->id; - pinos_client_send_message (resource->client, - resource, - PINOS_MESSAGE_NODE_INFO, - &m, - true); + pinos_node_notify_info (resource, &info); } } } diff --git a/pinos/server/resource.c b/pinos/server/resource.c index 4fe741fed..6bf06b292 100644 --- a/pinos/server/resource.c +++ b/pinos/server/resource.c @@ -19,6 +19,7 @@ #include +#include "pinos/client/interfaces.h" #include "pinos/server/resource.h" typedef struct { @@ -77,83 +78,9 @@ pinos_resource_destroy (PinosResource *resource) if (resource->destroy) resource->destroy (resource); - if (client->core_resource) { - PinosMessageRemoveId m; - m.id = resource->id; - pinos_client_send_message (client, - client->core_resource, - PINOS_MESSAGE_REMOVE_ID, - &m, - true); - } + if (client->core_resource) + pinos_core_notify_remove_id (client->core_resource, resource->id); pinos_log_debug ("resource %p: free", resource); free (resource); } - -void -pinos_resource_set_dispatch (PinosResource *resource, - PinosDispatchFunc func, - void *data) -{ - PinosResourceImpl *impl = SPA_CONTAINER_OF (resource, PinosResourceImpl, this); - - impl->dispatch_func = func; - impl->dispatch_data = data; -} - -static SpaResult -do_dispatch_message (PinosAccessData *data) -{ - PinosResourceImpl *impl = SPA_CONTAINER_OF (data->resource, PinosResourceImpl, this); - - if (data->res == SPA_RESULT_NO_PERMISSION) { - pinos_client_send_error (data->client, - data->resource, - data->res, - "no permission"); - } else if (SPA_RESULT_IS_ERROR (data->res)) { - pinos_client_send_error (data->client, - data->resource, - data->res, - "error %d", data->res); - } else { - data->res = impl->dispatch_func (data->resource, - data->opcode, - data->message, - impl->dispatch_data); - } - return data->res; -} - -SpaResult -pinos_resource_dispatch (PinosResource *resource, - uint32_t opcode, - void *message) -{ - PinosResourceImpl *impl = SPA_CONTAINER_OF (resource, PinosResourceImpl, this); - - if (impl->dispatch_func) { - PinosAccessData data; - - data.client = resource->client; - data.resource = resource; - data.opcode = opcode; - data.message = message; - data.flush = false; - - data.res = SPA_RESULT_OK; - pinos_signal_emit (&resource->core->access.check_dispatch, - do_dispatch_message, - &data); - - if (SPA_RESULT_IS_ASYNC (data.res)) - return data.res; - - return do_dispatch_message (&data); - } - - pinos_log_error ("resource %p: dispatch func not implemented", resource); - - return SPA_RESULT_NOT_IMPLEMENTED; -} diff --git a/pinos/server/resource.h b/pinos/server/resource.h index ac76dd966..582dd7ef9 100644 --- a/pinos/server/resource.h +++ b/pinos/server/resource.h @@ -37,11 +37,6 @@ typedef struct _PinosResource PinosResource; typedef void (*PinosDestroy) (void *object); -typedef SpaResult (*PinosDispatchFunc) (void *object, - uint32_t opcode, - void *message, - void *data); - struct _PinosResource { PinosCore *core; SpaList link; @@ -53,6 +48,10 @@ struct _PinosResource { void *object; PinosDestroy destroy; + const void *interface; + const void *event; + const void *marshall; + PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PinosResource *resource)); }; @@ -64,14 +63,6 @@ PinosResource * pinos_resource_new (PinosClient *client, PinosDestroy destroy); void pinos_resource_destroy (PinosResource *resource); -void pinos_resource_set_dispatch (PinosResource *resource, - PinosDispatchFunc func, - void *data); - -SpaResult pinos_resource_dispatch (PinosResource *resource, - uint32_t opcode, - void *message); - #ifdef __cplusplus } #endif