diff options
author | Wim Taymans <wtaymans@redhat.com> | 2016-11-30 19:09:09 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2016-11-30 19:09:09 +0100 |
commit | 7c292090232b986aaa9ff9d835872d35e7d5305a (patch) | |
tree | 8c9c0db87fe49ab5f85808a4d1c6cdd6b873cb4d | |
parent | 3dada4731cb8e2dc7a26116dae9253b90c395238 (diff) |
Registry: implement registry
Make GET_REGISTRY method to create a registry resource, send global
added and removed to this resource.
Use map for storing proxies and resources.
-rw-r--r-- | pinos/client/connection.c | 44 | ||||
-rw-r--r-- | pinos/client/connection.h | 33 | ||||
-rw-r--r-- | pinos/client/context.c | 35 | ||||
-rw-r--r-- | pinos/client/context.h | 1 | ||||
-rw-r--r-- | pinos/client/map.h | 16 | ||||
-rw-r--r-- | pinos/client/stream.c | 7 | ||||
-rw-r--r-- | pinos/modules/module-protocol-native.c | 80 | ||||
-rw-r--r-- | pinos/server/client-node.c | 8 | ||||
-rw-r--r-- | pinos/server/client.c | 14 | ||||
-rw-r--r-- | pinos/server/client.h | 2 | ||||
-rw-r--r-- | pinos/server/core.c | 3 | ||||
-rw-r--r-- | pinos/server/core.h | 2 | ||||
-rw-r--r-- | pinos/server/resource.c | 33 | ||||
-rw-r--r-- | pinos/server/uri.c | 1 | ||||
-rw-r--r-- | pinos/server/uri.h | 1 |
15 files changed, 221 insertions, 59 deletions
diff --git a/pinos/client/connection.c b/pinos/client/connection.c index aa9faa15..09c25bab 100644 --- a/pinos/client/connection.c +++ b/pinos/client/connection.c @@ -710,10 +710,16 @@ pinos_connection_parse_message (PinosConnection *conn, memcpy (message, conn->in.data, sizeof (PinosMessageNotifyDone)); break; - case PINOS_MESSAGE_SUBSCRIBE: - if (conn->in.size < sizeof (PinosMessageSubscribe)) + case PINOS_MESSAGE_GET_REGISTRY: + if (conn->in.size < sizeof (PinosMessageGetRegistry)) return false; - memcpy (message, conn->in.data, sizeof (PinosMessageSubscribe)); + memcpy (message, conn->in.data, sizeof (PinosMessageGetRegistry)); + break; + + case PINOS_MESSAGE_BIND: + if (conn->in.size < sizeof (PinosMessageBind)) + return false; + memcpy (message, conn->in.data, sizeof (PinosMessageBind)); break; case PINOS_MESSAGE_NOTIFY_GLOBAL: @@ -749,6 +755,17 @@ pinos_connection_parse_message (PinosConnection *conn, d->datafd = connection_get_fd (conn, d->datafd); break; } + case PINOS_MESSAGE_DESTROY: + if (conn->in.size < sizeof (PinosMessageDestroy)) + return false; + memcpy (message, conn->in.data, sizeof (PinosMessageDestroy)); + break; + + case PINOS_MESSAGE_DESTROY_DONE: + if (conn->in.size < sizeof (PinosMessageDestroyDone)) + return false; + memcpy (message, conn->in.data, sizeof (PinosMessageDestroyDone)); + break; /* C -> S */ case PINOS_MESSAGE_NODE_UPDATE: @@ -865,9 +882,14 @@ pinos_connection_add_message (PinosConnection *conn, memcpy (p, message, sizeof (PinosMessageNotifyDone)); break; - case PINOS_MESSAGE_SUBSCRIBE: - p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageSubscribe)); - memcpy (p, message, sizeof (PinosMessageSubscribe)); + case PINOS_MESSAGE_GET_REGISTRY: + p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageGetRegistry)); + memcpy (p, message, sizeof (PinosMessageGetRegistry)); + break; + + case PINOS_MESSAGE_BIND: + p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageBind)); + memcpy (p, message, sizeof (PinosMessageBind)); break; case PINOS_MESSAGE_NOTIFY_GLOBAL: @@ -900,6 +922,16 @@ pinos_connection_add_message (PinosConnection *conn, d->datafd = connection_add_fd (conn, d->datafd); break; } + case PINOS_MESSAGE_DESTROY: + p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageDestroy)); + memcpy (p, message, sizeof (PinosMessageDestroy)); + break; + + case PINOS_MESSAGE_DESTROY_DONE: + p = connection_add_message (conn, dest_id, type, sizeof (PinosMessageDestroyDone)); + memcpy (p, message, sizeof (PinosMessageDestroyDone)); + break; + /* C -> S */ case PINOS_MESSAGE_NODE_UPDATE: diff --git a/pinos/client/connection.h b/pinos/client/connection.h index 38aea487..0ff90e55 100644 --- a/pinos/client/connection.h +++ b/pinos/client/connection.h @@ -37,8 +37,9 @@ typedef enum { PINOS_MESSAGE_SYNC, PINOS_MESSAGE_NOTIFY_DONE, + PINOS_MESSAGE_GET_REGISTRY, - PINOS_MESSAGE_SUBSCRIBE, + PINOS_MESSAGE_BIND, PINOS_MESSAGE_NOTIFY_GLOBAL, PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE, @@ -48,6 +49,9 @@ typedef enum { PINOS_MESSAGE_CREATE_CLIENT_NODE, PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE, + PINOS_MESSAGE_DESTROY, + PINOS_MESSAGE_DESTROY_DONE, + /* client to server */ PINOS_MESSAGE_NODE_UPDATE, PINOS_MESSAGE_PORT_UPDATE, @@ -84,10 +88,17 @@ typedef struct { uint32_t seq; } PinosMessageNotifyDone; -/* PINOS_MESSAGE_SUBSCRIBE */ +/* PINOS_MESSAGE_GET_REGISTRY */ typedef struct { uint32_t seq; -} PinosMessageSubscribe; + uint32_t new_id; +} PinosMessageGetRegistry; + +/* PINOS_MESSAGE_BIND */ +typedef struct { + uint32_t id; + uint32_t new_id; +} PinosMessageBind; /* PINOS_MESSAGE_NOTIFY_GLOBAL */ typedef struct { @@ -106,7 +117,7 @@ typedef struct { const char *factory_name; const char *name; SpaDict *props; - uint32_t id; + uint32_t new_id; } PinosMessageCreateNode; /* PINOS_MESSAGE_CREATE_NODE_DONE */ @@ -119,7 +130,7 @@ typedef struct { uint32_t seq; const char *name; SpaDict *props; - uint32_t id; + uint32_t new_id; } PinosMessageCreateClientNode; /* PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE */ @@ -128,6 +139,18 @@ typedef struct { int datafd; } PinosMessageCreateClientNodeDone; +/* PINOS_MESSAGE_DESTROY */ +typedef struct { + uint32_t seq; + uint32_t id; +} PinosMessageDestroy; + +/* PINOS_MESSAGE_DESTROY_DONE */ +typedef struct { + uint32_t seq; + uint32_t id; +} PinosMessageDestroyDone; + /* PINOS_MESSAGE_NODE_UPDATE */ typedef struct { #define PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS (1 << 0) diff --git a/pinos/client/context.c b/pinos/client/context.c index c4c541ce..d15aa5bd 100644 --- a/pinos/client/context.c +++ b/pinos/client/context.c @@ -113,12 +113,32 @@ core_dispatch_func (void *object, context_set_state (context, PINOS_CONTEXT_STATE_CONNECTED, NULL); break; } + default: + pinos_log_warn ("unhandled message %d", type); + break; + } + return SPA_RESULT_OK; +} + +static SpaResult +registry_dispatch_func (void *object, + PinosMessageType type, + void *message, + void *data) +{ + switch (type) { case PINOS_MESSAGE_NOTIFY_GLOBAL: { PinosMessageNotifyGlobal *ng = message; pinos_log_debug ("got global %u %s", ng->id, ng->type); break; } + case PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE: + { + PinosMessageNotifyGlobalRemove *ng = message; + pinos_log_debug ("got global remove %u", ng->id); + break; + } default: pinos_log_warn ("unhandled message %d", type); break; @@ -292,7 +312,7 @@ pinos_context_connect (PinosContext *context) socklen_t size; const char *runtime_dir, *name = NULL; int name_size, fd; - PinosMessageSubscribe sm; + PinosMessageGetRegistry grm; context_set_state (context, PINOS_CONTEXT_STATE_CONNECTING, NULL); @@ -349,10 +369,17 @@ pinos_context_connect (PinosContext *context) context->core_proxy->dispatch_func = core_dispatch_func; context->core_proxy->dispatch_data = context; - sm.seq = 0; + context->registry_proxy = pinos_proxy_new (context, + SPA_ID_INVALID, + 0); + context->registry_proxy->dispatch_func = registry_dispatch_func; + context->registry_proxy->dispatch_data = context; + + grm.seq = 0; + grm.new_id = context->registry_proxy->id; pinos_proxy_send_message (context->core_proxy, - PINOS_MESSAGE_SUBSCRIBE, - &sm, + PINOS_MESSAGE_GET_REGISTRY, + &grm, true); return true; } diff --git a/pinos/client/context.h b/pinos/client/context.h index f4ebb930..cc461ec5 100644 --- a/pinos/client/context.h +++ b/pinos/client/context.h @@ -63,6 +63,7 @@ struct _PinosContext { PinosLoop *loop; PinosProxy *core_proxy; + PinosProxy *registry_proxy; PinosMap objects; diff --git a/pinos/client/map.h b/pinos/client/map.h index ffedd53f..b827a19f 100644 --- a/pinos/client/map.h +++ b/pinos/client/map.h @@ -45,7 +45,8 @@ struct _PinosMap { #define pinos_map_get_size(m) pinos_array_get_len (&(m)->items, PinosMapItem) #define pinos_map_get_item(m,id) pinos_array_get_unchecked(&(m)->items,id,PinosMapItem) -#define pinos_map_item_is_free(m,id) (pinos_map_get_item(m,id)->next & 0x1) +#define pinos_map_item_is_free(item) ((item)->next & 0x1) +#define pinos_map_id_is_free(m,id) (pinos_map_item_is_free (pinos_map_get_item(m,id))) #define pinos_map_check_id(m,id) ((id) < pinos_map_get_size (m)) #define pinos_map_has_item(m,id) (pinos_map_check_id(m,id) && !pinos_map_item_is_free(m, id)) #define pinos_map_lookup_unchecked(m,id) pinos_map_get_item(m,id)->data @@ -104,6 +105,19 @@ pinos_map_lookup (PinosMap *map, return NULL; } +static inline void +pinos_map_for_each (PinosMap *map, + void (*func) (void *, void *), + void *data) +{ + PinosMapItem *item; + + pinos_array_for_each (item, &map->items) { + if (!pinos_map_item_is_free (item)) + func (item->data, data); + } +} + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/pinos/client/stream.c b/pinos/client/stream.c index 6cc114fa..f413394a 100644 --- a/pinos/client/stream.c +++ b/pinos/client/stream.c @@ -607,7 +607,10 @@ stream_dispatch_func (void *object, switch (type) { case PINOS_MESSAGE_SYNC: - case PINOS_MESSAGE_SUBSCRIBE: + case PINOS_MESSAGE_GET_REGISTRY: + case PINOS_MESSAGE_BIND: + case PINOS_MESSAGE_DESTROY: + case PINOS_MESSAGE_DESTROY_DONE: case PINOS_MESSAGE_CREATE_NODE: case PINOS_MESSAGE_CREATE_CLIENT_NODE: case PINOS_MESSAGE_NODE_UPDATE: @@ -899,7 +902,7 @@ pinos_stream_connect (PinosStream *stream, items[0].key = "pinos.target.node"; items[0].value = port_path; ccn.props = &dict; - ccn.id = impl->node_proxy->id; + ccn.new_id = impl->node_proxy->id; pinos_proxy_send_message (stream->context->core_proxy, PINOS_MESSAGE_CREATE_CLIENT_NODE, diff --git a/pinos/modules/module-protocol-native.c b/pinos/modules/module-protocol-native.c index 9f85ddde..d595a3ba 100644 --- a/pinos/modules/module-protocol-native.c +++ b/pinos/modules/module-protocol-native.c @@ -171,6 +171,29 @@ client_destroy (PinosProtocolNativeClient *this) close (this->fd); } +static void +destroy_registry_resource (void *object) +{ + PinosResource *resource = object; + spa_list_remove (&resource->link); +} + +static SpaResult +registry_dispatch_func (void *object, + PinosMessageType type, + void *message, + void *data) +{ + switch (type) { + case PINOS_MESSAGE_BIND: + break; + default: + pinos_log_error ("unhandled message %d", type); + break; + } + return SPA_RESULT_OK; +} + static SpaResult core_dispatch_func (void *object, PinosMessageType type, @@ -182,18 +205,30 @@ core_dispatch_func (void *object, PinosClient *c = client->parent.global->object; switch (type) { - case PINOS_MESSAGE_SUBSCRIBE: + case PINOS_MESSAGE_GET_REGISTRY: { - PinosMessageSubscribe *m = message; + PinosMessageGetRegistry *m = message; PinosGlobal *global; PinosMessageNotifyDone nd; + PinosResource *registry_resource; + + registry_resource = pinos_resource_new (c, + SPA_ID_INVALID, + impl->core->uri.registry, + impl->core, + destroy_registry_resource); + + registry_resource->dispatch_func = registry_dispatch_func; + registry_resource->dispatch_data = client; + + spa_list_insert (impl->core->registry_resource_list.prev, ®istry_resource->link); spa_list_for_each (global, &impl->core->global_list, link) { PinosMessageNotifyGlobal ng; ng.id = global->id; ng.type = spa_id_map_get_uri (impl->core->uri.map, global->type); - pinos_resource_send_message (client->core_resource, + pinos_resource_send_message (registry_resource, PINOS_MESSAGE_NOTIFY_GLOBAL, &ng, false); @@ -221,7 +256,7 @@ core_dispatch_func (void *object, } node = pinos_client_node_new (c, - m->id, + m->new_id, m->name, props); @@ -267,18 +302,6 @@ client_send_func (void *object, return SPA_RESULT_OK; } -static PinosResource * -find_resource (PinosClient *client, uint32_t id) -{ - PinosResource *resource; - - spa_list_for_each (resource, &client->resource_list, link) { - if (resource->id == id) - return resource; - } - return NULL; -} - static void connection_data (SpaSource *source, int fd, @@ -290,6 +313,7 @@ connection_data (SpaSource *source, PinosMessageType type; uint32_t id; size_t size; + PinosClient *c = client->parent.global->object; if (mask & (SPA_IO_ERR | SPA_IO_HUP)) { pinos_log_debug ("protocol-native %p: got connection error", client->parent.impl); @@ -311,7 +335,7 @@ connection_data (SpaSource *source, continue; } - resource = find_resource (client->parent.global->object, id); + resource = pinos_map_lookup (&c->objects, id); if (resource == NULL) { pinos_log_error ("protocol-native %p: unknown resource %u", client->parent.impl, id); continue; @@ -376,6 +400,8 @@ on_global_added (PinosListener *listener, PinosGlobal *global) { PinosProtocolNative *impl = SPA_CONTAINER_OF (listener, PinosProtocolNative, global_added); + PinosMessageNotifyGlobal ng; + PinosResource *registry; if (global->type == impl->core->uri.client) { object_new (sizeof (PinosProtocolNativeClient), @@ -389,6 +415,16 @@ on_global_added (PinosListener *listener, NULL); } else if (global->type == impl->core->uri.link) { } + + ng.id = global->id; + ng.type = spa_id_map_get_uri (impl->core->uri.map, global->type); + + spa_list_for_each (registry, &core->registry_resource_list, link) { + pinos_resource_send_message (registry, + PINOS_MESSAGE_NOTIFY_GLOBAL, + &ng, + true); + } } static void @@ -398,10 +434,20 @@ on_global_removed (PinosListener *listener, { PinosProtocolNative *impl = SPA_CONTAINER_OF (listener, PinosProtocolNative, global_removed); PinosProtocolNativeObject *object; + PinosMessageNotifyGlobalRemove ng; + PinosResource *registry; if ((object = find_object (impl, global->object))) { object_destroy (object); } + + ng.id = global->id; + spa_list_for_each (registry, &core->registry_resource_list, link) { + pinos_resource_send_message (registry, + PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE, + &ng, + true); + } } static Socket * diff --git a/pinos/server/client-node.c b/pinos/server/client-node.c index f639cadf..2816d7a6 100644 --- a/pinos/server/client-node.c +++ b/pinos/server/client-node.c @@ -1208,6 +1208,12 @@ proxy_clear (SpaProxy *this) return SPA_RESULT_OK; } +static void +client_node_resource_destroy (PinosResource *resource) +{ + pinos_client_node_destroy (resource->object); +} + /** * pinos_client_node_new: * @daemon: a #PinosDaemon @@ -1257,7 +1263,7 @@ pinos_client_node_new (PinosClient *client, id, client->core->uri.client_node, this, - (PinosDestroy) pinos_client_node_destroy); + (PinosDestroy) client_node_resource_destroy); impl->proxy.resource = this->resource; this->resource->dispatch_func = client_node_dispatch_func; diff --git a/pinos/server/client.c b/pinos/server/client.c index 8f6eaf53..e2854e64 100644 --- a/pinos/server/client.c +++ b/pinos/server/client.c @@ -51,7 +51,7 @@ pinos_client_new (PinosCore *core, this->core = core; this->properties = properties; - spa_list_init (&this->resource_list); + pinos_map_init (&this->objects, 64); pinos_signal_init (&this->destroy_signal); spa_list_insert (core->client_list.prev, &this->link); @@ -80,6 +80,13 @@ sync_destroy (void *object, free (impl); } +static void +destroy_resource (void *object, + void *data) +{ + pinos_resource_destroy (object); +} + /** * pinos_client_destroy: * @client: a #PinosClient @@ -89,13 +96,10 @@ sync_destroy (void *object, void pinos_client_destroy (PinosClient * client) { - PinosResource *resource, *tmp; - pinos_log_debug ("client %p: destroy", client); pinos_signal_emit (&client->destroy_signal, client); - spa_list_for_each_safe (resource, tmp, &client->resource_list, link) - pinos_resource_destroy (resource); + pinos_map_for_each (&client->objects, destroy_resource, client); pinos_global_destroy (client->global); spa_list_remove (&client->link); diff --git a/pinos/server/client.h b/pinos/server/client.h index a1ac4d0f..b52634fc 100644 --- a/pinos/server/client.h +++ b/pinos/server/client.h @@ -44,7 +44,7 @@ struct _PinosClient { PinosProperties *properties; - SpaList resource_list; + PinosMap objects; PinosSendFunc send_func; void *send_data; diff --git a/pinos/server/core.c b/pinos/server/core.c index 1665d902..7ac0b341 100644 --- a/pinos/server/core.c +++ b/pinos/server/core.c @@ -56,6 +56,7 @@ pinos_core_new (PinosMainLoop *main_loop) pinos_data_loop_start (this->data_loop); + spa_list_init (&this->registry_resource_list); spa_list_init (&this->global_list); spa_list_init (&this->client_list); spa_list_init (&this->node_list); @@ -111,6 +112,8 @@ pinos_core_add_global (PinosCore *core, spa_list_insert (core->global_list.prev, &global->link); pinos_signal_emit (&core->global_added, core, global); + pinos_log_debug ("global %p: new %u", global, global->id); + return global; } diff --git a/pinos/server/core.h b/pinos/server/core.h index d68c1dd3..45b195f0 100644 --- a/pinos/server/core.h +++ b/pinos/server/core.h @@ -29,6 +29,7 @@ typedef struct _PinosGlobal PinosGlobal; #define PINOS_CORE_URI "http://pinos.org/ns/core" #define PINOS_CORE_PREFIX PINOS_CORE_URI "#" +#define PINOS_CORE_REGISTRY PINOS_CORE_PREFIX "Registry" #include <spa/include/spa/log.h> @@ -62,6 +63,7 @@ struct _PinosCore { PinosMap objects; + SpaList registry_resource_list; SpaList global_list; SpaList client_list; SpaList node_list; diff --git a/pinos/server/resource.c b/pinos/server/resource.c index 6ee693af..14055a15 100644 --- a/pinos/server/resource.c +++ b/pinos/server/resource.c @@ -28,26 +28,25 @@ pinos_resource_new (PinosClient *client, void *object, PinosDestroy destroy) { - PinosResource *resource; + PinosResource *this; - resource = calloc (1, sizeof (PinosResource)); - pinos_log_debug ("resource %p: new for client %p", resource, client); + this = calloc (1, sizeof (PinosResource)); + this->core = client->core; + this->client = client; + this->id = id; + this->type = type; + this->object = object; + this->destroy = destroy; - resource->core = client->core; - resource->client = client; - resource->id = id; - resource->type = type; - resource->object = object; - resource->destroy = destroy; + this->send_func = client->send_func; + this->send_data = client->send_data; - resource->send_func = client->send_func; - resource->send_data = client->send_data; + pinos_signal_init (&this->destroy_signal); - pinos_signal_init (&resource->destroy_signal); + this->id = pinos_map_insert_new (&client->objects, this); + pinos_log_debug ("resource %p: new for client %p id %u", this, client, this->id); - spa_list_insert (client->resource_list.prev, &resource->link); - - return resource; + return this; } static void @@ -67,10 +66,10 @@ pinos_resource_destroy (PinosResource *resource) pinos_log_debug ("resource %p: destroy", resource); pinos_signal_emit (&resource->destroy_signal, resource); - spa_list_remove (&resource->link); + pinos_map_remove (&resource->client->objects, resource->id); if (resource->destroy) - resource->destroy (resource->object); + resource->destroy (resource); pinos_main_loop_defer (resource->core->main_loop, resource, diff --git a/pinos/server/uri.c b/pinos/server/uri.c index e517727f..57f5b777 100644 --- a/pinos/server/uri.c +++ b/pinos/server/uri.c @@ -36,6 +36,7 @@ pinos_uri_init (PinosURI *uri) uri->map = pinos_id_map_get_default(); uri->core = spa_id_map_get_id (uri->map, PINOS_CORE_URI); + uri->registry = spa_id_map_get_id (uri->map, PINOS_CORE_REGISTRY); uri->node = spa_id_map_get_id (uri->map, PINOS_NODE_URI); uri->node_factory = spa_id_map_get_id (uri->map, PINOS_NODE_FACTORY_URI); uri->link = spa_id_map_get_id (uri->map, PINOS_LINK_URI); diff --git a/pinos/server/uri.h b/pinos/server/uri.h index 52eca7e4..db3f93c2 100644 --- a/pinos/server/uri.h +++ b/pinos/server/uri.h @@ -41,6 +41,7 @@ struct _PinosURI { SpaIDMap *map; uint32_t core; + uint32_t registry; uint32_t node; uint32_t node_factory; uint32_t link; |