From 7ad02f553a419ff61bdef9cd0ca85dd9db47596b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 9 Mar 2017 13:00:56 +0100 Subject: [PATCH] improve interfaces Make an interface structure to hold methods and events. Move interface setup to protocol --- pinos/client/context.c | 56 ++++---- pinos/client/interfaces.h | 94 +++++++------ pinos/client/protocol-native.c | 182 +++++++++++++++++-------- pinos/client/protocol-native.h | 14 +- pinos/client/proxy.c | 2 + pinos/client/proxy.h | 12 +- pinos/client/stream.c | 9 +- pinos/modules/module-protocol-native.c | 37 ++--- pinos/server/client-node.c | 5 +- pinos/server/core.c | 8 +- pinos/server/protocol-native.c | 158 ++++++++++++++------- pinos/server/protocol-native.h | 14 +- pinos/server/resource.h | 5 +- 13 files changed, 341 insertions(+), 255 deletions(-) diff --git a/pinos/client/context.c b/pinos/client/context.c index f004c3c2d..4d9b4d32d 100644 --- a/pinos/client/context.c +++ b/pinos/client/context.c @@ -158,7 +158,7 @@ core_event_remove_id (void *object, } } -static const PinosCoreEvent core_events = { +static const PinosCoreEvents core_events = { &core_event_info, &core_event_done, &core_event_error, @@ -189,7 +189,7 @@ module_event_info (void *object, proxy->id); } -static const PinosModuleEvent module_events = { +static const PinosModuleEvents module_events = { &module_event_info, }; @@ -223,7 +223,7 @@ node_event_info (void *object, proxy->id); } -static const PinosNodeEvent node_events = { +static const PinosNodeEvents node_events = { &node_event_done, &node_event_info }; @@ -252,7 +252,7 @@ client_event_info (void *object, proxy->id); } -static const PinosClientEvent client_events = { +static const PinosClientEvents client_events = { &client_event_info }; @@ -280,7 +280,7 @@ link_event_info (void *object, proxy->id); } -static const PinosLinkEvent link_events = { +static const PinosLinkEvents link_events = { &link_event_info }; @@ -302,9 +302,7 @@ registry_event_global (void *object, if (proxy == NULL) goto no_mem; - proxy->event = &node_events; - proxy->demarshal = &pinos_protocol_native_client_node_demarshal; - proxy->interface = NULL; + proxy->implementation = &node_events; } else if (!strcmp (type, PINOS_MODULE_URI)) { proxy = pinos_proxy_new (this, SPA_ID_INVALID, @@ -312,9 +310,7 @@ registry_event_global (void *object, if (proxy == NULL) goto no_mem; - proxy->event = &module_events; - proxy->demarshal = &pinos_protocol_native_client_module_demarshal; - proxy->interface = NULL; + proxy->implementation = &module_events; } else if (!strcmp (type, PINOS_CLIENT_URI)) { proxy = pinos_proxy_new (this, SPA_ID_INVALID, @@ -322,9 +318,7 @@ registry_event_global (void *object, if (proxy == NULL) goto no_mem; - proxy->event = &client_events; - proxy->demarshal = &pinos_protocol_native_client_client_demarshal; - proxy->interface = NULL; + proxy->implementation = &client_events; } else if (!strcmp (type, PINOS_LINK_URI)) { proxy = pinos_proxy_new (this, SPA_ID_INVALID, @@ -332,12 +326,11 @@ registry_event_global (void *object, if (proxy == NULL) goto no_mem; - proxy->event = &link_events; - proxy->demarshal = &pinos_protocol_native_client_link_demarshal; - proxy->interface = NULL; + proxy->implementation = &link_events; } - if (proxy) + if (proxy) { pinos_registry_do_bind (this->registry_proxy, id, proxy->id); + } return; @@ -362,11 +355,13 @@ registry_event_global_remove (void *object, id); } -static const PinosRegistryEvent registry_events = { +static const PinosRegistryEvents registry_events = { ®istry_event_global, ®istry_event_global_remove }; +typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); + static void on_context_data (SpaSource *source, int fd, @@ -375,6 +370,7 @@ on_context_data (SpaSource *source, { PinosContextImpl *impl = data; PinosContext *this = &impl->this; + PinosConnection *conn = impl->connection; if (mask & (SPA_IO_ERR | SPA_IO_HUP)) { context_set_state (this, @@ -384,7 +380,6 @@ on_context_data (SpaSource *source, } if (mask & SPA_IO_IN) { - PinosConnection *conn = impl->connection; uint8_t opcode; uint32_t id; uint32_t size; @@ -399,12 +394,19 @@ on_context_data (SpaSource *source, pinos_log_error ("context %p: could not find proxy %u", this, id); continue; } + if (opcode >= proxy->iface->n_events) { + pinos_log_error ("context %p: invalid method %u", this, opcode); + continue; + } + pinos_log_debug ("context %p: object demarshal %u, %u", this, id, opcode); - demarshal = proxy->demarshal; + demarshal = proxy->iface->events; if (demarshal[opcode]) { - if (!demarshal[opcode] (proxy, message, size)) - pinos_log_error ("context %p: invalid message received", this); + if (!demarshal[opcode] (proxy, message, size)) { + pinos_log_error ("context %p: invalid message received %u", this, opcode); + spa_debug_pod (message); + } } else pinos_log_error ("context %p: function %d not implemented", this, opcode); @@ -596,9 +598,7 @@ pinos_context_connect_fd (PinosContext *context, if (context->core_proxy == NULL) goto no_proxy; - context->core_proxy->event = &core_events; - context->core_proxy->interface = &pinos_protocol_native_client_core_interface; - context->core_proxy->demarshal = &pinos_protocol_native_client_core_demarshal; + context->core_proxy->implementation = &core_events; pinos_core_do_client_update (context->core_proxy, &context->properties->dict); @@ -609,9 +609,7 @@ pinos_context_connect_fd (PinosContext *context, if (context->registry_proxy == NULL) goto no_registry; - context->registry_proxy->event = ®istry_events; - context->registry_proxy->interface = &pinos_protocol_native_client_registry_interface; - context->registry_proxy->demarshal = &pinos_protocol_native_client_registry_demarshal; + context->registry_proxy->implementation = ®istry_events; pinos_core_do_get_registry (context->core_proxy, 0, diff --git a/pinos/client/interfaces.h b/pinos/client/interfaces.h index dcf0cac2a..ecbe16f1e 100644 --- a/pinos/client/interfaces.h +++ b/pinos/client/interfaces.h @@ -31,9 +31,17 @@ extern "C" { #include typedef struct _PinosClientNodeBuffer PinosClientNodeBuffer; +typedef struct _PinosInterface PinosInterface; #include +struct _PinosInterface { + uint32_t n_methods; + const void *methods; + uint32_t n_events; + const void *events; +}; + typedef struct { void (*client_update) (void *object, const SpaDict *props); @@ -53,13 +61,13 @@ typedef struct { const char *name, const SpaDict *props, uint32_t new_id); -} PinosCoreInterface; +} PinosCoreMethods; -#define pinos_core_do_client_update(r,...) ((PinosCoreInterface*)r->interface)->client_update(r,__VA_ARGS__) -#define pinos_core_do_sync(r,...) ((PinosCoreInterface*)r->interface)->sync(r,__VA_ARGS__) -#define pinos_core_do_get_registry(r,...) ((PinosCoreInterface*)r->interface)->get_registry(r,__VA_ARGS__) -#define pinos_core_do_create_node(r,...) ((PinosCoreInterface*)r->interface)->create_node(r,__VA_ARGS__) -#define pinos_core_do_create_client_node(r,...) ((PinosCoreInterface*)r->interface)->create_client_node(r,__VA_ARGS__) +#define pinos_core_do_client_update(r,...) ((PinosCoreMethods*)r->iface->methods)->client_update(r,__VA_ARGS__) +#define pinos_core_do_sync(r,...) ((PinosCoreMethods*)r->iface->methods)->sync(r,__VA_ARGS__) +#define pinos_core_do_get_registry(r,...) ((PinosCoreMethods*)r->iface->methods)->get_registry(r,__VA_ARGS__) +#define pinos_core_do_create_node(r,...) ((PinosCoreMethods*)r->iface->methods)->create_node(r,__VA_ARGS__) +#define pinos_core_do_create_client_node(r,...) ((PinosCoreMethods*)r->iface->methods)->create_client_node(r,__VA_ARGS__) typedef struct { void (*info) (void *object, @@ -72,20 +80,20 @@ typedef struct { const char *error, ...); void (*remove_id) (void *object, uint32_t id); -} PinosCoreEvent; +} PinosCoreEvents; -#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_core_notify_info(r,...) ((PinosCoreEvents*)r->iface->events)->info(r,__VA_ARGS__) +#define pinos_core_notify_done(r,...) ((PinosCoreEvents*)r->iface->events)->done(r,__VA_ARGS__) +#define pinos_core_notify_error(r,...) ((PinosCoreEvents*)r->iface->events)->error(r,__VA_ARGS__) +#define pinos_core_notify_remove_id(r,...) ((PinosCoreEvents*)r->iface->events)->remove_id(r,__VA_ARGS__) typedef struct { void (*bind) (void *object, uint32_t id, uint32_t new_id); -} PinosRegistryInterface; +} PinosRegistryMethods; -#define pinos_registry_do_bind(r,...) ((PinosRegistryInterface*)r->interface)->bind(r,__VA_ARGS__) +#define pinos_registry_do_bind(r,...) ((PinosRegistryMethods*)r->iface->methods)->bind(r,__VA_ARGS__) typedef struct { void (*global) (void *object, @@ -93,27 +101,27 @@ typedef struct { const char *type); void (*global_remove) (void *object, uint32_t id); -} PinosRegistryEvent; +} PinosRegistryEvents; -#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__) +#define pinos_registry_notify_global(r,...) ((PinosRegistryEvents*)r->iface->events)->global(r,__VA_ARGS__) +#define pinos_registry_notify_global_remove(r,...) ((PinosRegistryEvents*)r->iface->events)->global_remove(r,__VA_ARGS__) typedef struct { void (*info) (void *object, PinosModuleInfo *info); -} PinosModuleEvent; +} PinosModuleEvents; -#define pinos_module_notify_info(r,...) ((PinosModuleEvent*)r->event)->info(r,__VA_ARGS__) +#define pinos_module_notify_info(r,...) ((PinosModuleEvents*)r->iface->events)->info(r,__VA_ARGS__) typedef struct { void (*done) (void *object, uint32_t seq); void (*info) (void *object, PinosNodeInfo *info); -} PinosNodeEvent; +} PinosNodeEvents; -#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_node_notify_done(r,...) ((PinosNodeEvents*)r->iface->events)->done(r,__VA_ARGS__) +#define pinos_node_notify_info(r,...) ((PinosNodeEvents*)r->iface->events)->info(r,__VA_ARGS__) struct _PinosClientNodeBuffer { uint32_t mem_id; @@ -151,13 +159,13 @@ typedef struct { SpaNodeEvent *event); void (*destroy) (void *object, uint32_t seq); -} PinosClientNodeInterface; +} PinosClientNodeMethods; -#define pinos_client_node_do_update(r,...) ((PinosClientNodeInterface*)r->interface)->update(r,__VA_ARGS__) -#define pinos_client_node_do_port_update(r,...) ((PinosClientNodeInterface*)r->interface)->port_update(r,__VA_ARGS__) -#define pinos_client_node_do_state_change(r,...) ((PinosClientNodeInterface*)r->interface)->state_change(r,__VA_ARGS__) -#define pinos_client_node_do_event(r,...) ((PinosClientNodeInterface*)r->interface)->event(r,__VA_ARGS__) -#define pinos_client_node_do_destroy(r,...) ((PinosClientNodeInterface*)r->interface)->destroy(r,__VA_ARGS__) +#define pinos_client_node_do_update(r,...) ((PinosClientNodeMethods*)r->iface->methods)->update(r,__VA_ARGS__) +#define pinos_client_node_do_port_update(r,...) ((PinosClientNodeMethods*)r->iface->methods)->port_update(r,__VA_ARGS__) +#define pinos_client_node_do_state_change(r,...) ((PinosClientNodeMethods*)r->iface->methods)->state_change(r,__VA_ARGS__) +#define pinos_client_node_do_event(r,...) ((PinosClientNodeMethods*)r->iface->methods)->event(r,__VA_ARGS__) +#define pinos_client_node_do_destroy(r,...) ((PinosClientNodeMethods*)r->iface->methods)->destroy(r,__VA_ARGS__) typedef struct { void (*done) (void *object, @@ -209,33 +217,33 @@ typedef struct { int memfd, uint32_t offset, uint32_t size); -} PinosClientNodeEvent; +} PinosClientNodeEvents; -#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__) +#define pinos_client_node_notify_done(r,...) ((PinosClientNodeEvents*)r->iface->events)->done(r,__VA_ARGS__) +#define pinos_client_node_notify_event(r,...) ((PinosClientNodeEvents*)r->iface->events)->event(r,__VA_ARGS__) +#define pinos_client_node_notify_add_port(r,...) ((PinosClientNodeEvents*)r->iface->events)->add_port(r,__VA_ARGS__) +#define pinos_client_node_notify_remove_port(r,...) ((PinosClientNodeEvents*)r->iface->events)->remove_port(r,__VA_ARGS__) +#define pinos_client_node_notify_set_format(r,...) ((PinosClientNodeEvents*)r->iface->events)->set_format(r,__VA_ARGS__) +#define pinos_client_node_notify_set_property(r,...) ((PinosClientNodeEvents*)r->iface->events)->set_property(r,__VA_ARGS__) +#define pinos_client_node_notify_add_mem(r,...) ((PinosClientNodeEvents*)r->iface->events)->add_mem(r,__VA_ARGS__) +#define pinos_client_node_notify_use_buffers(r,...) ((PinosClientNodeEvents*)r->iface->events)->use_buffers(r,__VA_ARGS__) +#define pinos_client_node_notify_node_command(r,...) ((PinosClientNodeEvents*)r->iface->events)->node_command(r,__VA_ARGS__) +#define pinos_client_node_notify_port_command(r,...) ((PinosClientNodeEvents*)r->iface->events)->port_command(r,__VA_ARGS__) +#define pinos_client_node_notify_transport(r,...) ((PinosClientNodeEvents*)r->iface->events)->transport(r,__VA_ARGS__) typedef struct { void (*info) (void *object, PinosClientInfo *info); -} PinosClientEvent; +} PinosClientEvents; -#define pinos_client_notify_info(r,...) ((PinosClientEvent*)r->event)->info(r,__VA_ARGS__) +#define pinos_client_notify_info(r,...) ((PinosClientEvents*)r->iface->events)->info(r,__VA_ARGS__) typedef struct { void (*info) (void *object, PinosLinkInfo *info); -} PinosLinkEvent; +} PinosLinkEvents; -#define pinos_link_notify_info(r,...) ((PinosLinkEvent*)r->event)->info(r,__VA_ARGS__) +#define pinos_link_notify_info(r,...) ((PinosLinkEvents*)r->iface->events)->info(r,__VA_ARGS__) #ifdef __cplusplus } /* extern "C" */ diff --git a/pinos/client/protocol-native.c b/pinos/client/protocol-native.c index fe335a22a..339f23d2f 100644 --- a/pinos/client/protocol-native.c +++ b/pinos/client/protocol-native.c @@ -31,6 +31,8 @@ typedef struct { PinosConnection *connection; } Builder; +typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); + static uint32_t write_pod (SpaPODBuilder *b, uint32_t ref, const void *data, uint32_t size) { @@ -213,7 +215,7 @@ core_demarshal_info (void *object, 0)) return false; } - pinos_core_notify_info (proxy, &info); + ((PinosCoreEvents*)proxy->implementation)->info (proxy, &info); return true; } @@ -232,7 +234,7 @@ core_demarshal_done (void *object, 0)) return false; - pinos_core_notify_done (proxy, seq); + ((PinosCoreEvents*)proxy->implementation)->done (proxy, seq); return true; } @@ -254,7 +256,7 @@ core_demarshal_error (void *object, 0)) return false; - pinos_core_notify_error (proxy, id, res, error); + ((PinosCoreEvents*)proxy->implementation)->error (proxy, id, res, error); return true; } @@ -273,7 +275,7 @@ core_demarshal_remove_id (void *object, 0)) return false; - pinos_core_notify_remove_id (proxy, id); + ((PinosCoreEvents*)proxy->implementation)->remove_id (proxy, id); return true; } @@ -308,7 +310,7 @@ module_demarshal_info (void *object, 0)) return false; } - pinos_module_notify_info (proxy, &info); + ((PinosModuleEvents*)proxy->implementation)->info (proxy, &info); return true; } @@ -327,7 +329,7 @@ node_demarshal_done (void *object, 0)) return false; - pinos_node_notify_done (proxy, seq); + ((PinosNodeEvents*)proxy->implementation)->done (proxy, seq); return true; } @@ -386,7 +388,7 @@ node_demarshal_info (void *object, 0)) return false; } - pinos_node_notify_info (proxy, &info); + ((PinosNodeEvents*)proxy->implementation)->info (proxy, &info); return true; } @@ -551,7 +553,7 @@ client_node_demarshal_done (void *object, return false; fd = pinos_connection_get_fd (connection, idx); - pinos_client_node_notify_done (proxy, seq, fd); + ((PinosClientNodeEvents*)proxy->implementation)->done (proxy, seq, fd); return true; } @@ -571,7 +573,7 @@ client_node_demarshal_event (void *object, 0)) return false; - pinos_client_node_notify_event (proxy, event); + ((PinosClientNodeEvents*)proxy->implementation)->event (proxy, event); return true; } @@ -592,7 +594,7 @@ client_node_demarshal_add_port (void *object, 0)) return false; - pinos_client_node_notify_add_port (proxy, seq, direction, port_id); + ((PinosClientNodeEvents*)proxy->implementation)->add_port (proxy, seq, direction, port_id); return true; } @@ -613,7 +615,7 @@ client_node_demarshal_remove_port (void *object, 0)) return false; - pinos_client_node_notify_remove_port (proxy, seq, direction, port_id); + ((PinosClientNodeEvents*)proxy->implementation)->remove_port (proxy, seq, direction, port_id); return true; } @@ -640,7 +642,7 @@ client_node_demarshal_set_format (void *object, if (have_format && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &format, 0)) return false; - pinos_client_node_notify_set_format (proxy, seq, direction, port_id, + ((PinosClientNodeEvents*)proxy->implementation)->set_format (proxy, seq, direction, port_id, flags, format); return true; } @@ -664,7 +666,7 @@ client_node_demarshal_set_property (void *object, 0)) return false; - pinos_client_node_notify_set_property (proxy, seq, id, s, value); + ((PinosClientNodeEvents*)proxy->implementation)->set_property (proxy, seq, id, s, value); return true; } @@ -694,15 +696,15 @@ client_node_demarshal_add_mem (void *object, memfd = pinos_connection_get_fd (connection, memfd_idx); - pinos_client_node_notify_add_mem (proxy, - direction, - port_id, - mem_id, - type, - memfd, - flags, - offset, - sz); + ((PinosClientNodeEvents*)proxy->implementation)->add_mem (proxy, + direction, + port_id, + mem_id, + type, + memfd, + flags, + offset, + sz); return true; } @@ -768,12 +770,12 @@ client_node_demarshal_use_buffers (void *object, d->data = SPA_UINT32_TO_PTR (data_id); } } - pinos_client_node_notify_use_buffers (proxy, - seq, - direction, - port_id, - n_buffers, - buffers); + ((PinosClientNodeEvents*)proxy->implementation)->use_buffers (proxy, + seq, + direction, + port_id, + n_buffers, + buffers); return true; } @@ -794,7 +796,7 @@ client_node_demarshal_node_command (void *object, 0)) return false; - pinos_client_node_notify_node_command (proxy, seq, command); + ((PinosClientNodeEvents*)proxy->implementation)->node_command (proxy, seq, command); return true; } @@ -815,7 +817,7 @@ client_node_demarshal_port_command (void *object, 0)) return false; - pinos_client_node_notify_port_command (proxy, port_id, command); + ((PinosClientNodeEvents*)proxy->implementation)->port_command (proxy, port_id, command); return true; } @@ -839,7 +841,7 @@ client_node_demarshal_transport (void *object, return false; memfd = pinos_connection_get_fd (connection, memfd_idx); - pinos_client_node_notify_transport (proxy, memfd, offset, sz); + ((PinosClientNodeEvents*)proxy->implementation)->transport (proxy, memfd, offset, sz); return true; } @@ -871,7 +873,7 @@ client_demarshal_info (void *object, 0)) return false; } - pinos_client_notify_info (proxy, &info); + ((PinosClientEvents*)proxy->implementation)->info (proxy, &info); return true; } @@ -895,7 +897,7 @@ link_demarshal_info (void *object, 0)) return false; - pinos_link_notify_info (proxy, &info); + ((PinosLinkEvents*)proxy->implementation)->info (proxy, &info); return true; } @@ -916,7 +918,7 @@ registry_demarshal_global (void *object, 0)) return false; - pinos_registry_notify_global (proxy, id, type); + ((PinosRegistryEvents*)proxy->implementation)->global (proxy, id, type); return true; } @@ -935,7 +937,7 @@ registry_demarshal_global_remove (void *object, 0)) return false; - pinos_registry_notify_global_remove (proxy, id); + ((PinosRegistryEvents*)proxy->implementation)->global_remove (proxy, id); return true; } @@ -958,7 +960,7 @@ registry_marshal_bind (void *object, pinos_connection_end_write (connection, proxy->id, 0, b.b.offset); } -const PinosCoreInterface pinos_protocol_native_client_core_interface = { +static const PinosCoreMethods pinos_protocol_native_client_core_methods = { &core_marshal_client_update, &core_marshal_sync, &core_marshal_get_registry, @@ -966,11 +968,33 @@ const PinosCoreInterface pinos_protocol_native_client_core_interface = { &core_marshal_create_client_node }; -const PinosRegistryInterface pinos_protocol_native_client_registry_interface = { +static const PinosDemarshalFunc pinos_protocol_native_client_core_demarshal[] = { + &core_demarshal_info, + &core_demarshal_done, + &core_demarshal_error, + &core_demarshal_remove_id, +}; + +static const PinosInterface pinos_protocol_native_client_core_interface = { + 5, &pinos_protocol_native_client_core_methods, + 4, pinos_protocol_native_client_core_demarshal +}; + +static const PinosRegistryMethods pinos_protocol_native_client_registry_methods = { ®istry_marshal_bind }; -const PinosClientNodeInterface pinos_protocol_native_client_client_node_interface = { +static const PinosDemarshalFunc pinos_protocol_native_client_registry_demarshal[] = { + ®istry_demarshal_global, + ®istry_demarshal_global_remove, +}; + +static const PinosInterface pinos_protocol_native_client_registry_interface = { + 1, &pinos_protocol_native_client_registry_methods, + 2, pinos_protocol_native_client_registry_demarshal, +}; + +static const PinosClientNodeMethods pinos_protocol_native_client_client_node_methods = { &client_node_marshal_update, &client_node_marshal_port_update, &client_node_marshal_state_change, @@ -978,23 +1002,7 @@ const PinosClientNodeInterface pinos_protocol_native_client_client_node_interfac &client_node_marshal_destroy }; -const PinosDemarshalFunc pinos_protocol_native_client_core_demarshal[] = { - &core_demarshal_info, - &core_demarshal_done, - &core_demarshal_error, - &core_demarshal_remove_id, -}; - -const PinosDemarshalFunc pinos_protocol_native_client_module_demarshal[] = { - &module_demarshal_info, -}; - -const PinosDemarshalFunc pinos_protocol_native_client_node_demarshal[] = { - &node_demarshal_done, - &node_demarshal_info, -}; - -const PinosDemarshalFunc pinos_protocol_native_client_client_node_demarshal[] = { +static const PinosDemarshalFunc pinos_protocol_native_client_client_node_demarshal[] = { &client_node_demarshal_done, &client_node_demarshal_event, &client_node_demarshal_add_port, @@ -1008,15 +1016,69 @@ const PinosDemarshalFunc pinos_protocol_native_client_client_node_demarshal[] = &client_node_demarshal_transport }; -const PinosDemarshalFunc pinos_protocol_native_client_client_demarshal[] = { +static const PinosInterface pinos_protocol_native_client_client_node_interface = { + 5, &pinos_protocol_native_client_client_node_methods, + 11, pinos_protocol_native_client_client_node_demarshal, +}; + +static const PinosDemarshalFunc pinos_protocol_native_client_module_demarshal[] = { + &module_demarshal_info, +}; + +static const PinosInterface pinos_protocol_native_client_module_interface = { + 0, NULL, + 1, pinos_protocol_native_client_module_demarshal, +}; + +static const PinosDemarshalFunc pinos_protocol_native_client_node_demarshal[] = { + &node_demarshal_done, + &node_demarshal_info, +}; + +static const PinosInterface pinos_protocol_native_client_node_interface = { + 0, NULL, + 2, pinos_protocol_native_client_node_demarshal, +}; + +static const PinosDemarshalFunc pinos_protocol_native_client_client_demarshal[] = { &client_demarshal_info, }; -const PinosDemarshalFunc pinos_protocol_native_client_link_demarshal[] = { +static const PinosInterface pinos_protocol_native_client_client_interface = { + 0, NULL, + 1, pinos_protocol_native_client_client_demarshal, +}; + +static const PinosDemarshalFunc pinos_protocol_native_client_link_demarshal[] = { &link_demarshal_info, }; -const PinosDemarshalFunc pinos_protocol_native_client_registry_demarshal[] = { - ®istry_demarshal_global, - ®istry_demarshal_global_remove, +static const PinosInterface pinos_protocol_native_client_link_interface = { + 0, NULL, + 1, pinos_protocol_native_client_link_demarshal, }; + +bool +pinos_protocol_native_client_setup (PinosProxy *proxy) +{ + const PinosInterface *iface; + + if (proxy->type == proxy->context->uri.core) { + iface = &pinos_protocol_native_client_core_interface; + } else if (proxy->type == proxy->context->uri.registry) { + iface = &pinos_protocol_native_client_registry_interface; + } else if (proxy->type == proxy->context->uri.module) { + iface = &pinos_protocol_native_client_module_interface; + } else if (proxy->type == proxy->context->uri.node) { + iface = &pinos_protocol_native_client_node_interface; + } else if (proxy->type == proxy->context->uri.client_node) { + iface = &pinos_protocol_native_client_client_node_interface; + } else if (proxy->type == proxy->context->uri.client) { + iface = &pinos_protocol_native_client_client_interface; + } else if (proxy->type == proxy->context->uri.link) { + iface = &pinos_protocol_native_client_link_interface; + } else + return false; + proxy->iface = iface; + return true; +} diff --git a/pinos/client/protocol-native.h b/pinos/client/protocol-native.h index e153b0603..6d9f5f4d7 100644 --- a/pinos/client/protocol-native.h +++ b/pinos/client/protocol-native.h @@ -20,16 +20,4 @@ #include "pinos/client/pinos.h" #include "pinos/client/interfaces.h" -typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); - -extern const PinosCoreInterface pinos_protocol_native_client_core_interface; -extern const PinosRegistryInterface pinos_protocol_native_client_registry_interface; -extern const PinosClientNodeInterface pinos_protocol_native_client_client_node_interface; - -extern const PinosDemarshalFunc pinos_protocol_native_client_core_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_client_module_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_client_node_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_client_client_node_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_client_client_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_client_link_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_client_registry_demarshal[]; +bool pinos_protocol_native_client_setup (PinosProxy *proxy); diff --git a/pinos/client/proxy.c b/pinos/client/proxy.c index 460ea4ebe..3028589eb 100644 --- a/pinos/client/proxy.c +++ b/pinos/client/proxy.c @@ -42,6 +42,8 @@ pinos_proxy_new (PinosContext *context, pinos_signal_init (&this->destroy_signal); + pinos_protocol_native_client_setup (this); + this->id = pinos_map_insert_new (&context->objects, this); spa_list_insert (&this->context->proxy_list, &this->link); diff --git a/pinos/client/proxy.h b/pinos/client/proxy.h index aad472802..8dc06a255 100644 --- a/pinos/client/proxy.h +++ b/pinos/client/proxy.h @@ -28,19 +28,19 @@ typedef struct _PinosProxy PinosProxy; #include #include +#include struct _PinosProxy { PinosContext *context; SpaList link; - uint32_t id; - uint32_t type; + uint32_t id; + uint32_t type; - void *user_data; + const PinosInterface *iface; + const void *implementation; - const void *interface; - const void *event; - const void *demarshal; + void *user_data; PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PinosProxy *proxy)); diff --git a/pinos/client/stream.c b/pinos/client/stream.c index 5bfd97f8b..d3cfb167d 100644 --- a/pinos/client/stream.c +++ b/pinos/client/stream.c @@ -914,7 +914,7 @@ client_node_transport (void *object, pinos_log_debug ("transport update %d %p", impl->rtfd, impl->trans); } -static const PinosClientNodeEvent client_node_events = { +static const PinosClientNodeEvents client_node_events = { &client_node_done, &client_node_event, &client_node_add_port, @@ -997,9 +997,7 @@ pinos_stream_connect (PinosStream *stream, on_node_proxy_destroy); impl->node_proxy->user_data = stream; - impl->node_proxy->event = &client_node_events; - impl->node_proxy->interface = &pinos_protocol_native_client_client_node_interface; - impl->node_proxy->demarshal = &pinos_protocol_native_client_client_node_demarshal; + impl->node_proxy->implementation = &client_node_events; pinos_core_do_create_client_node (stream->context->core_proxy, ++impl->seq, @@ -1103,8 +1101,7 @@ pinos_stream_disconnect (PinosStream *stream) unhandle_socket (stream); - pinos_client_node_do_destroy (impl->node_proxy, - ++impl->seq); + pinos_client_node_do_destroy (impl->node_proxy, ++impl->seq); return true; } diff --git a/pinos/modules/module-protocol-native.c b/pinos/modules/module-protocol-native.c index e3928821c..92ac5085d 100644 --- a/pinos/modules/module-protocol-native.c +++ b/pinos/modules/module-protocol-native.c @@ -52,6 +52,8 @@ #define LOCK_SUFFIX ".lock" #define LOCK_SUFFIXLEN 5 +typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); + typedef struct { int fd; int fd_lock; @@ -101,34 +103,7 @@ on_resource_added (PinosListener *listener, PinosClient *client, PinosResource *resource) { - if (resource->type == resource->core->uri.core) { - resource->event = &pinos_protocol_native_server_core_event; - resource->demarshal = &pinos_protocol_native_server_core_demarshal; - } - else if (resource->type == resource->core->uri.registry) { - resource->event = &pinos_protocol_native_server_registry_event; - resource->demarshal = &pinos_protocol_native_server_registry_demarshal; - } - else if (resource->type == resource->core->uri.module) { - resource->event = &pinos_protocol_native_server_module_event; - resource->demarshal = NULL; - } - else if (resource->type == resource->core->uri.node) { - resource->event = &pinos_protocol_native_server_node_event; - resource->demarshal = NULL; - } - else if (resource->type == resource->core->uri.client) { - resource->event = &pinos_protocol_native_server_client_event; - resource->demarshal = NULL; - } - else if (resource->type == resource->core->uri.client_node) { - resource->event = &pinos_protocol_native_server_client_node_events; - resource->demarshal = &pinos_protocol_native_server_client_node_demarshal; - } - else if (resource->type == resource->core->uri.link) { - resource->event = &pinos_protocol_native_server_link_event; - resource->demarshal = NULL; - } + pinos_protocol_native_server_setup (resource); } static void @@ -162,7 +137,11 @@ connection_data (SpaSource *source, pinos_log_error ("protocol-native %p: unknown resource %u", client->impl, id); continue; } - demarshal = resource->demarshal; + if (opcode >= resource->iface->n_methods) { + pinos_log_error ("protocol-native %p: invalid method %u", client->impl, opcode); + continue; + } + demarshal = resource->iface->methods; if (demarshal[opcode]) { if (!demarshal[opcode] (resource, message, size)) pinos_log_error ("protocol-native %p: invalid message received", client->impl); diff --git a/pinos/server/client-node.c b/pinos/server/client-node.c index 77b8546ce..5d35ddd38 100644 --- a/pinos/server/client-node.c +++ b/pinos/server/client-node.c @@ -979,7 +979,7 @@ client_node_destroy (void *object, pinos_client_node_destroy (node); } -static PinosClientNodeInterface client_node_interface = { +static PinosClientNodeMethods client_node_methods = { &client_node_update, &client_node_port_update, &client_node_state_change, @@ -1147,7 +1147,6 @@ client_node_resource_destroy (PinosResource *resource) if (proxy->data_source.fd != -1) { spa_loop_remove_source (proxy->data_loop, &proxy->data_source); close (proxy->data_source.fd); - proxy->data_source.fd = -1; } pinos_node_destroy (this->node); @@ -1239,7 +1238,7 @@ pinos_client_node_new (PinosClient *client, &impl->global_added, on_global_added); - this->resource->interface = &client_node_interface; + this->resource->implementation = &client_node_methods; return this; diff --git a/pinos/server/core.c b/pinos/server/core.c index e55fa8f53..bc7d4d87d 100644 --- a/pinos/server/core.c +++ b/pinos/server/core.c @@ -66,7 +66,7 @@ no_id: "unknown object id %u", id); } -static PinosRegistryInterface registry_interface = { +static PinosRegistryMethods registry_methods = { ®istry_bind }; @@ -114,7 +114,7 @@ core_get_registry (void *object, if (registry_resource == NULL) goto no_mem; - registry_resource->interface = ®istry_interface; + registry_resource->implementation = ®istry_methods; spa_list_insert (this->registry_resource_list.prev, ®istry_resource->link); @@ -202,7 +202,7 @@ no_mem: return; } -static PinosCoreInterface core_interface = { +static PinosCoreMethods core_methods = { &core_client_update, &core_sync, &core_get_registry, @@ -235,7 +235,7 @@ core_bind_func (PinosGlobal *global, if (resource == NULL) goto no_mem; - resource->interface = &core_interface; + resource->implementation = &core_methods; spa_list_insert (this->resource_list.prev, &resource->link); client->core_resource = resource; diff --git a/pinos/server/protocol-native.c b/pinos/server/protocol-native.c index 64bef14a2..102d95c52 100644 --- a/pinos/server/protocol-native.c +++ b/pinos/server/protocol-native.c @@ -24,6 +24,7 @@ #include "pinos/server/resource.h" #include "pinos/server/protocol-native.h" +typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); typedef struct { SpaPODBuilder b; @@ -164,7 +165,7 @@ core_demarshal_client_update (void *object, 0)) return false; } - pinos_core_do_client_update (resource, &props); + ((PinosCoreMethods*)resource->implementation)->client_update (resource, &props); return true; } @@ -183,7 +184,7 @@ core_demarshal_sync (void *object, 0)) return false; - pinos_core_do_sync (resource, seq); + ((PinosCoreMethods*)resource->implementation)->sync (resource, seq); return true; } @@ -203,7 +204,7 @@ core_demarshal_get_registry (void *object, 0)) return false; - pinos_core_do_get_registry (resource, seq, new_id); + ((PinosCoreMethods*)resource->implementation)->get_registry (resource, seq, new_id); return true; } @@ -238,12 +239,12 @@ core_demarshal_create_node (void *object, if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &new_id, 0)) return false; - pinos_core_do_create_node (resource, - seq, - factory_name, - name, - &props, - new_id); + ((PinosCoreMethods*)resource->implementation)->create_node (resource, + seq, + factory_name, + name, + &props, + new_id); return true; } @@ -277,11 +278,11 @@ core_demarshal_create_client_node (void *object, if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &new_id, 0)) return false; - pinos_core_do_create_client_node (resource, - seq, - name, - &props, - new_id); + ((PinosCoreMethods*)resource->implementation)->create_client_node (resource, + seq, + name, + &props, + new_id); return true; } @@ -337,7 +338,7 @@ registry_demarshal_bind (void *object, 0)) return false; - pinos_registry_do_bind (resource, id, new_id); + ((PinosRegistryMethods*)resource->implementation)->bind (resource, id, new_id); return true; } @@ -757,7 +758,7 @@ client_node_demarshal_update (void *object, if (have_props && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &props, 0)) return false; - pinos_client_node_do_update (resource, change_mask, max_input_ports, max_output_ports, props); + ((PinosClientNodeMethods*)resource->implementation)->update (resource, change_mask, max_input_ports, max_output_ports, props); return true; } @@ -829,7 +830,7 @@ client_node_demarshal_port_update (void *object, } } - pinos_client_node_do_port_update (resource, + ((PinosClientNodeMethods*)resource->implementation)->port_update (resource, direction, port_id, change_mask, @@ -854,7 +855,7 @@ client_node_demarshal_state_change (void *object, !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &state, 0)) return false; - pinos_client_node_do_state_change (resource, state); + ((PinosClientNodeMethods*)resource->implementation)->state_change (resource, state); return true; } @@ -872,7 +873,7 @@ client_node_demarshal_event (void *object, !spa_pod_iter_get (&it, SPA_POD_TYPE_BYTES, &event, &sz, 0)) return false; - pinos_client_node_do_event (resource, event); + ((PinosClientNodeMethods*)resource->implementation)->event (resource, event); return true; } @@ -889,7 +890,7 @@ client_node_demarshal_destroy (void *object, !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &seq, 0)) return false; - pinos_client_node_do_destroy (resource, seq); + ((PinosClientNodeMethods*)resource->implementation)->destroy (resource, seq); return true; } @@ -906,23 +907,16 @@ link_marshal_info (void *object, SPA_POD_TYPE_STRUCT, &f, SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_LONG, info->change_mask, - SPA_POD_TYPE_LONG, info->output_node_id, - SPA_POD_TYPE_LONG, info->output_port_id, - SPA_POD_TYPE_LONG, info->input_node_id, - SPA_POD_TYPE_LONG, info->input_port_id, + SPA_POD_TYPE_INT, info->output_node_id, + SPA_POD_TYPE_INT, info->output_port_id, + SPA_POD_TYPE_INT, info->input_node_id, + SPA_POD_TYPE_INT, info->input_port_id, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } -const PinosCoreEvent pinos_protocol_native_server_core_event = { - &core_marshal_info, - &core_marshal_done, - &core_marshal_error, - &core_marshal_remove_id -}; - -const PinosDemarshalFunc pinos_protocol_native_server_core_demarshal[] = { +static const PinosDemarshalFunc pinos_protocol_native_server_core_demarshal[] = { &core_demarshal_client_update, &core_demarshal_sync, &core_demarshal_get_registry, @@ -930,29 +924,69 @@ const PinosDemarshalFunc pinos_protocol_native_server_core_demarshal[] = { &core_demarshal_create_client_node }; -const PinosRegistryEvent pinos_protocol_native_server_registry_event = { +static const PinosCoreEvents pinos_protocol_native_server_core_events = { + &core_marshal_info, + &core_marshal_done, + &core_marshal_error, + &core_marshal_remove_id +}; + +const PinosInterface pinos_protocol_native_server_core_interface = { + 5, pinos_protocol_native_server_core_demarshal, + 4, &pinos_protocol_native_server_core_events, +}; + +static const PinosDemarshalFunc pinos_protocol_native_server_registry_demarshal[] = { + ®istry_demarshal_bind, +}; + +static const PinosRegistryEvents pinos_protocol_native_server_registry_events = { ®istry_marshal_global, ®istry_marshal_global_remove, }; -const PinosDemarshalFunc pinos_protocol_native_server_registry_demarshal[] = { - ®istry_demarshal_bind, +const PinosInterface pinos_protocol_native_server_registry_interface = { + 1, pinos_protocol_native_server_registry_demarshal, + 2, &pinos_protocol_native_server_registry_events, }; -const PinosModuleEvent pinos_protocol_native_server_module_event = { +static const PinosModuleEvents pinos_protocol_native_server_module_events = { &module_marshal_info, }; -const PinosNodeEvent pinos_protocol_native_server_node_event = { +const PinosInterface pinos_protocol_native_server_module_interface = { + 0, NULL, + 1, &pinos_protocol_native_server_module_events, +}; + +static const PinosNodeEvents pinos_protocol_native_server_node_events = { &node_marshal_done, &node_marshal_info, }; -const PinosClientEvent pinos_protocol_native_server_client_event = { +const PinosInterface pinos_protocol_native_server_node_interface = { + 0, NULL, + 2, &pinos_protocol_native_server_node_events, +}; + +static const PinosClientEvents pinos_protocol_native_server_client_events = { &client_marshal_info, }; -const PinosClientNodeEvent pinos_protocol_native_server_client_node_events = { +const PinosInterface pinos_protocol_native_server_client_interface = { + 0, NULL, + 2, &pinos_protocol_native_server_client_events, +}; + +static const PinosDemarshalFunc pinos_protocol_native_server_client_node_demarshal[] = { + &client_node_demarshal_update, + &client_node_demarshal_port_update, + &client_node_demarshal_state_change, + &client_node_demarshal_event, + &client_node_demarshal_destroy, +}; + +static const PinosClientNodeEvents pinos_protocol_native_server_client_node_events = { &client_node_marshal_done, &client_node_marshal_event, &client_node_marshal_add_port, @@ -966,14 +1000,46 @@ const PinosClientNodeEvent pinos_protocol_native_server_client_node_events = { &client_node_marshal_transport, }; -const PinosDemarshalFunc pinos_protocol_native_server_client_node_demarshal[] = { - &client_node_demarshal_update, - &client_node_demarshal_port_update, - &client_node_demarshal_state_change, - &client_node_demarshal_event, - &client_node_demarshal_destroy, +const PinosInterface pinos_protocol_native_server_client_node_interface = { + 5, &pinos_protocol_native_server_client_node_demarshal, + 11, &pinos_protocol_native_server_client_node_events, }; -const PinosLinkEvent pinos_protocol_native_server_link_event = { +static const PinosLinkEvents pinos_protocol_native_server_link_events = { &link_marshal_info, }; + +const PinosInterface pinos_protocol_native_server_link_interface = { + 0, NULL, + 1, &pinos_protocol_native_server_link_events, +}; + +bool +pinos_protocol_native_server_setup (PinosResource *resource) +{ + const PinosInterface *iface; + if (resource->type == resource->core->uri.core) { + iface = &pinos_protocol_native_server_core_interface; + } + else if (resource->type == resource->core->uri.registry) { + iface = &pinos_protocol_native_server_registry_interface; + } + else if (resource->type == resource->core->uri.module) { + iface = &pinos_protocol_native_server_module_interface; + } + else if (resource->type == resource->core->uri.node) { + iface = &pinos_protocol_native_server_node_interface; + } + else if (resource->type == resource->core->uri.client) { + iface = &pinos_protocol_native_server_client_interface; + } + else if (resource->type == resource->core->uri.client_node) { + iface = &pinos_protocol_native_server_client_node_interface; + } + else if (resource->type == resource->core->uri.link) { + iface = &pinos_protocol_native_server_link_interface; + } else + return false; + resource->iface = iface; + return true; +} diff --git a/pinos/server/protocol-native.h b/pinos/server/protocol-native.h index cff412cfe..8e81b15f1 100644 --- a/pinos/server/protocol-native.h +++ b/pinos/server/protocol-native.h @@ -19,16 +19,4 @@ #include "pinos/client/pinos.h" -typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); - -extern const PinosCoreEvent pinos_protocol_native_server_core_event; -extern const PinosRegistryEvent pinos_protocol_native_server_registry_event; -extern const PinosModuleEvent pinos_protocol_native_server_module_event; -extern const PinosNodeEvent pinos_protocol_native_server_node_event; -extern const PinosClientEvent pinos_protocol_native_server_client_event; -extern const PinosClientNodeEvent pinos_protocol_native_server_client_node_events; -extern const PinosLinkEvent pinos_protocol_native_server_link_event; - -extern const PinosDemarshalFunc pinos_protocol_native_server_core_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_server_registry_demarshal[]; -extern const PinosDemarshalFunc pinos_protocol_native_server_client_node_demarshal[]; +bool pinos_protocol_native_server_setup (PinosResource *resource); diff --git a/pinos/server/resource.h b/pinos/server/resource.h index 798be19ba..88d1db2ac 100644 --- a/pinos/server/resource.h +++ b/pinos/server/resource.h @@ -48,9 +48,8 @@ struct _PinosResource { void *object; PinosDestroy destroy; - const void *interface; - const void *event; - const void *demarshal; + const PinosInterface *iface; + const void *implementation; PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PinosResource *resource));