Work on introspection

This commit is contained in:
Wim Taymans 2016-12-02 13:38:43 +01:00
parent 7c29209023
commit b969623ec8
39 changed files with 1726 additions and 574 deletions

View file

@ -28,6 +28,57 @@ typedef struct
PinosClient this;
} 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_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosClient *this = global->object;
PinosResource *resource;
PinosMessageClientInfo m;
PinosClientInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.client,
global->object,
NULL);
resource->dispatch_func = client_dispatch_func;
resource->dispatch_data = global;
pinos_log_debug ("client %p: bound to %d", global->object, resource->id);
m.info = &info;
info.id = resource->id;
info.change_mask = ~0;
info.props = this->properties ? &this->properties->dict : NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_CLIENT_INFO,
&m,
true);
}
/**
* pinos_client_new:
* @daemon: a #PinosDaemon
@ -58,7 +109,9 @@ pinos_client_new (PinosCore *core,
this->global = pinos_core_add_global (core,
core->uri.client,
this);
0,
this,
client_bind_func);
return this;
}

View file

@ -24,9 +24,6 @@
extern "C" {
#endif
#define PINOS_CLIENT_URI "http://pinos.org/ns/client"
#define PINOS_CLIENT_PREFIX PINOS_CLIENT_URI "#"
typedef struct _PinosClient PinosClient;
#include <pinos/server/core.h>
@ -44,6 +41,8 @@ struct _PinosClient {
PinosProperties *properties;
PinosResource *core_resource;
PinosMap objects;
PinosSendFunc send_func;

View file

@ -20,6 +20,7 @@
#include <pinos/client/pinos.h>
#include <pinos/server/core.h>
#include <pinos/server/data-loop.h>
#include <pinos/server/client-node.h>
typedef struct {
PinosCore this;
@ -28,6 +29,179 @@ typedef struct {
} PinosCoreImpl;
static SpaResult
registry_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosResource *resource = object;
PinosClient *client = resource->client;
PinosCore *this = data;
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_log_error ("unknown object id %d", m->id);
return SPA_RESULT_ERROR;
}
if (global->bind == NULL) {
pinos_log_error ("can't bind object id %d", m->id);
return SPA_RESULT_ERROR;
}
pinos_log_error ("global %p: bind object id %d", global, m->id);
global->bind (global, client, 0, m->id);
break;
}
default:
pinos_log_error ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static void
destroy_registry_resource (void *object)
{
PinosResource *resource = object;
spa_list_remove (&resource->link);
}
static SpaResult
core_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosResource *resource = object;
PinosClient *client = resource->client;
PinosCore *this = data;
switch (type) {
case PINOS_MESSAGE_GET_REGISTRY:
{
PinosMessageGetRegistry *m = message;
PinosGlobal *global;
PinosMessageNotifyDone nd;
PinosResource *registry_resource;
registry_resource = pinos_resource_new (resource->client,
SPA_ID_INVALID,
this->uri.registry,
this,
destroy_registry_resource);
registry_resource->dispatch_func = registry_dispatch_func;
registry_resource->dispatch_data = this;
spa_list_insert (this->registry_resource_list.prev, &registry_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_resource_send_message (registry_resource,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
false);
}
nd.seq = m->seq;
pinos_resource_send_message (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);
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 ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) {
pinos_log_error ("can't get data fd");
break;
}
r.seq = m->seq;
r.datafd = data_fd;
pinos_resource_send_message (node->resource,
PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
&r,
true);
break;
}
default:
pinos_log_error ("unhandled message %d", type);
break;
}
return SPA_RESULT_OK;
}
static void
core_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosCore *this = global->object;
PinosResource *resource;
PinosMessageCoreInfo m;
PinosCoreInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.core,
global->object,
NULL);
resource->dispatch_func = core_dispatch_func;
resource->dispatch_data = this;
client->core_resource = resource;
pinos_log_debug ("core %p: bound to %d", global->object, resource->id);
m.info = &info;
info.id = resource->id;
info.change_mask = ~0;
info.user_name = "wim";
info.host_name = "wtay";
info.version = 0;
info.name = "pinos-0";
info.cookie = 0;
info.props = NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_CORE_INFO,
&m,
true);
}
PinosCore *
pinos_core_new (PinosMainLoop *main_loop)
{
@ -76,7 +250,9 @@ pinos_core_new (PinosMainLoop *main_loop)
this->global = pinos_core_add_global (this,
this->uri.core,
this);
0,
this,
core_bind_func);
return this;
}
@ -96,14 +272,18 @@ pinos_core_destroy (PinosCore *core)
PinosGlobal *
pinos_core_add_global (PinosCore *core,
uint32_t type,
void *object)
uint32_t version,
void *object,
PinosBindFunc bind)
{
PinosGlobal *global;
global = calloc (1, sizeof (PinosGlobal));
global->core = core;
global->type = type;
global->version = version;
global->object = object;
global->bind = bind;
pinos_signal_init (&global->destroy_signal);
@ -166,6 +346,9 @@ pinos_core_find_port (PinosCore *core,
pinos_log_debug ("id \"%u\", %d", id, have_id);
spa_list_for_each (n, &core->node_list, link) {
if (n->global == NULL)
continue;
pinos_log_debug ("node id \"%d\"", n->global->id);
if (have_id) {

View file

@ -27,26 +27,31 @@ extern "C" {
typedef struct _PinosCore PinosCore;
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>
#include <pinos/client/uri.h>
#include <pinos/server/main-loop.h>
#include <pinos/server/data-loop.h>
#include <pinos/server/uri.h>
#include <pinos/server/node.h>
#include <pinos/server/link.h>
#include <pinos/server/node-factory.h>
typedef void (*PinosBindFunc) (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id);
struct _PinosGlobal {
PinosCore *core;
SpaList link;
uint32_t id;
uint32_t type;
uint32_t version;
void *object;
PinosBindFunc bind;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosGlobal *global));
};
@ -116,7 +121,9 @@ void pinos_core_destroy (PinosCore *core);
PinosGlobal * pinos_core_add_global (PinosCore *core,
uint32_t type,
void *object);
uint32_t version,
void *object,
PinosBindFunc bind);
void pinos_global_destroy (PinosGlobal *global);

View file

@ -668,6 +668,39 @@ 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
link_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosResource *resource;
resource = pinos_resource_new (client,
id,
global->core->uri.link,
global->object,
NULL);
resource->dispatch_func = link_dispatch_func;
resource->dispatch_data = client;
pinos_log_debug ("link %p: bound to %d", global->object, resource->id);
}
PinosLink *
pinos_link_new (PinosCore *core,
PinosPort *output,
@ -717,7 +750,9 @@ pinos_link_new (PinosCore *core,
this->global = pinos_core_add_global (core,
core->uri.link,
this);
0,
this,
link_bind_func);
return this;
}

View file

@ -26,9 +26,6 @@ extern "C" {
typedef struct _PinosLink PinosLink;
#define PINOS_LINK_URI "http://pinos.org/ns/link"
#define PINOS_LINK_PREFIX PINOS_LINK_URI "#"
#include <spa/include/spa/ringbuffer.h>
#include <pinos/client/mem.h>

View file

@ -11,7 +11,6 @@ pinoscore_headers = [
'node-factory.h',
'port.h',
'resource.h',
'uri.h',
]
pinoscore_sources = [
@ -27,7 +26,6 @@ pinoscore_sources = [
'node-factory.c',
'port.c',
'resource.c',
'uri.c',
]
libpinoscore_c_args = [

View file

@ -90,6 +90,59 @@ 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 void
module_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosModule *this = global->object;
PinosResource *resource;
PinosMessageModuleInfo m;
PinosModuleInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.module,
global->object,
NULL);
resource->dispatch_func = module_dispatch_func;
resource->dispatch_data = global;
pinos_log_debug ("module %p: bound to %d", global->object, resource->id);
m.info = &info;
info.id = resource->id;
info.change_mask = ~0;
info.name = this->name;
info.filename = this->filename;
info.args = this->args;
info.props = NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_MODULE_INFO,
&m,
true);
}
/**
* pinos_module_load:
* @core: a #PinosCore
@ -140,7 +193,6 @@ pinos_module_load (PinosCore *core,
pinos_log_debug ("trying to load module: %s (%s)", name, filename);
hnd = dlopen (filename, RTLD_NOW | RTLD_LOCAL);
free (filename);
if (hnd == NULL)
goto open_failed;
@ -152,7 +204,9 @@ pinos_module_load (PinosCore *core,
impl->hnd = hnd;
this = &impl->this;
this->name = strdup (name);
this->name = name ? strdup (name) : NULL;
this->filename = filename;
this->args = args ? strdup (args) : NULL;
this->core = core;
if (!init_func (this, (char *) args))
@ -160,6 +214,12 @@ pinos_module_load (PinosCore *core,
pinos_log_debug ("loaded module: %s", this->name);
this->global = pinos_core_add_global (core,
core->uri.module,
0,
impl,
module_bind_func);
return this;
not_found:
@ -170,12 +230,14 @@ not_found:
open_failed:
{
asprintf (err, "Failed to open module: %s", dlerror ());
free (filename);
return NULL;
}
no_pinos_module:
{
asprintf (err, "\"%s\" is not a pinos module", name);
dlclose (hnd);
free (filename);
return NULL;
}
init_failed:
@ -193,7 +255,12 @@ pinos_module_destroy (PinosModule *this)
pinos_signal_emit (&this->destroy_signal, this);
free (this->name);
if (this->name)
free (this->name);
if (this->filename)
free (this->filename);
if (this->args)
free (this->args);
dlclose (impl->hnd);
free (impl);
}

View file

@ -27,16 +27,16 @@ extern "C" {
#include <pinos/server/core.h>
#define PINOS_MODULE_URI "http://pinos.org/ns/module"
#define PINOS_MODULE_PREFIX PINOS_MODULE_URI "#"
typedef struct _PinosModule PinosModule;
struct _PinosModule {
PinosCore *core;
SpaList link;
PinosGlobal *global;
char *name;
char *filename;
char *args;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosModule *module));

View file

@ -382,6 +382,68 @@ 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)
{
PinosResource *resource = data;
spa_list_remove (&resource->link);
}
static void
node_bind_func (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id)
{
PinosNode *this = global->object;
PinosResource *resource;
PinosMessageNodeInfo m;
PinosNodeInfo info;
resource = pinos_resource_new (client,
id,
global->core->uri.registry,
global->object,
node_unbind_func);
resource->dispatch_func = node_dispatch_func;
resource->dispatch_data = 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 = resource->id;
info.change_mask = ~0;
info.name = this->name;
info.state = this->state;
info.props = this->properties ? &this->properties->dict : NULL;
pinos_resource_send_message (resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
}
static void
init_complete (PinosNode *this)
{
@ -391,7 +453,15 @@ init_complete (PinosNode *this)
pinos_log_debug ("node %p: init completed", this);
impl->async_init = false;
spa_list_insert (this->core->node_list.prev, &this->link);
pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED, NULL);
this->global = pinos_core_add_global (this->core,
this->core->uri.node,
0,
this,
node_bind_func);
}
void
@ -424,6 +494,8 @@ pinos_node_new (PinosCore *core,
this->clock = clock;
this->data_loop = core->data_loop;
spa_list_init (&this->resource_list);
if (spa_node_set_event_callback (this->node, on_node_event, this) < 0)
pinos_log_warn ("node %p: error setting callback", this);
@ -459,11 +531,7 @@ pinos_node_new (PinosCore *core,
(PinosDeferFunc) init_complete,
NULL);
}
spa_list_insert (core->node_list.prev, &this->link);
this->global = pinos_core_add_global (core,
core->uri.node,
this);
return this;
}
@ -724,6 +792,10 @@ pinos_node_update_state (PinosNode *node,
old = node->state;
if (old != state) {
PinosMessageNodeInfo m;
PinosNodeInfo info;
PinosResource *resource;
pinos_log_debug ("node %p: update state from %s -> %s", node,
pinos_node_state_as_string (old),
pinos_node_state_as_string (state));
@ -732,6 +804,20 @@ pinos_node_update_state (PinosNode *node,
free (node->error);
node->error = error;
node->state = state;
pinos_signal_emit (&node->core->node_state_changed, node, old, state);
spa_zero (info);
m.info = &info;
info.change_mask = 1 << 1;
info.state = node->state;
spa_list_for_each (resource, &node->resource_list, link) {
info.id = resource->id;
pinos_resource_send_message (resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
}
}
}

View file

@ -62,6 +62,8 @@ struct _PinosNode {
bool live;
SpaClock *clock;
SpaList resource_list;
SpaList input_ports;
SpaList output_ports;

View file

@ -82,14 +82,14 @@ pinos_resource_destroy (PinosResource *resource)
SpaResult
pinos_resource_send_message (PinosResource *resource,
PinosMessageType type,
uint32_t opcode,
void *message,
bool flush)
{
if (resource->send_func)
return resource->send_func (resource,
resource->id,
type,
opcode,
message,
flush,
resource->send_data);

View file

@ -35,13 +35,13 @@ typedef void (*PinosDestroy) (void *object);
typedef SpaResult (*PinosSendFunc) (void *object,
uint32_t id,
PinosMessageType type,
uint32_t opcode,
void *message,
bool flush,
void *data);
typedef SpaResult (*PinosDispatchFunc) (void *object,
PinosMessageType type,
uint32_t opcode,
void *message,
void *data);
@ -73,7 +73,7 @@ PinosResource * pinos_resource_new (PinosClient *client,
SpaResult pinos_resource_destroy (PinosResource *resource);
SpaResult pinos_resource_send_message (PinosResource *resource,
PinosMessageType type,
uint32_t opcode,
void *message,
bool flush);

View file

@ -1,51 +0,0 @@
/* Pinos
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* 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.
*/
#include <string.h>
#include "pinos/client/pinos.h"
#include "pinos/server/core.h"
#include "pinos/server/uri.h"
#include "pinos/server/node.h"
#include "pinos/server/node-factory.h"
#include "pinos/server/client.h"
#include "pinos/server/client-node.h"
#include "pinos/server/module.h"
#include "spa/include/spa/monitor.h"
void
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);
uri->client = spa_id_map_get_id (uri->map, PINOS_CLIENT_URI);
uri->client_node = spa_id_map_get_id (uri->map, PINOS_CLIENT_NODE_URI);
uri->module = spa_id_map_get_id (uri->map, PINOS_MODULE_URI);
uri->spa_node = spa_id_map_get_id (uri->map, SPA_NODE_URI);
uri->spa_clock = spa_id_map_get_id (uri->map, SPA_CLOCK_URI);
uri->spa_monitor = spa_id_map_get_id (uri->map, SPA_MONITOR_URI);
}

View file

@ -1,63 +0,0 @@
/* Pinos
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* 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_URI_H__
#define __PINOS_URI_H__
#ifdef __cplusplus
extern "C" {
#endif
#define PINOS_URI_URI "http://pinos.org/ns/uri"
#define PINOS_URI_PREFIX PINOS_URI_URI "#"
#include <pinos/client/map.h>
#include <spa/include/spa/id-map.h>
typedef struct _PinosURI PinosURI;
/**
* PinosURI:
*
* Pinos URI support struct.
*/
struct _PinosURI {
SpaIDMap *map;
uint32_t core;
uint32_t registry;
uint32_t node;
uint32_t node_factory;
uint32_t link;
uint32_t client;
uint32_t client_node;
uint32_t module;
uint32_t spa_node;
uint32_t spa_clock;
uint32_t spa_monitor;
};
void pinos_uri_init (PinosURI *uri);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_URI_H__ */