Make native protocol

Remove DBus and work towards something like wayland.
Remove more glib stuff from the client code
This commit is contained in:
Wim Taymans 2016-11-24 17:00:42 +01:00
parent efae64a759
commit 27bba6f587
55 changed files with 3089 additions and 4969 deletions

View file

@ -29,7 +29,6 @@
#include <sys/eventfd.h>
#include "pinos/client/pinos.h"
#include "pinos/client/private.h"
#include "pinos/client/connection.h"
#include "pinos/client/serialize.h"
#include "pinos/client/transport.h"
@ -99,8 +98,7 @@ struct _SpaProxy
SpaNodeEventCallback event_cb;
void *user_data;
SpaSource ctrl_source;
PinosConnection *conn;
PinosResource *resource;
SpaSource data_source;
@ -125,7 +123,6 @@ typedef struct
PinosListener transport_changed;
PinosListener loop_changed;
int ctrl_fd;
int data_fd;
} PinosClientNodeImpl;
@ -195,13 +192,11 @@ spa_proxy_node_send_command (SpaNode *node,
/* send start */
cnc.seq = this->seq++;
cnc.command = command;
pinos_connection_add_message (this->conn, PINOS_MESSAGE_NODE_COMMAND, &cnc);
if (!pinos_connection_flush (this->conn)) {
spa_log_error (this->log, "proxy %p: error writing connection", this);
res = SPA_RESULT_ERROR;
} else
res = SPA_RESULT_RETURN_ASYNC (cnc.seq);
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_NODE_COMMAND,
&cnc,
true);
res = SPA_RESULT_RETURN_ASYNC (cnc.seq);
break;
}
@ -211,12 +206,10 @@ spa_proxy_node_send_command (SpaNode *node,
/* send start */
cnc.command = command;
pinos_connection_add_message (this->conn, PINOS_MESSAGE_NODE_COMMAND, &cnc);
if (!pinos_connection_flush (this->conn)) {
spa_log_error (this->log, "proxy %p: error writing connection", this);
res = SPA_RESULT_ERROR;
}
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_NODE_COMMAND,
&cnc,
true);
break;
}
}
@ -489,11 +482,10 @@ spa_proxy_node_port_set_format (SpaNode *node,
sf.port_id = port_id;
sf.flags = flags;
sf.format = (SpaFormat *) format;
pinos_connection_add_message (this->conn, PINOS_MESSAGE_SET_FORMAT, &sf);
if (!pinos_connection_flush (this->conn))
spa_log_error (this->log, "proxy %p: error writing connection", this);
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_SET_FORMAT,
&sf,
true);
return SPA_RESULT_RETURN_ASYNC (sf.seq);
}
@ -668,12 +660,14 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
am.port_id = port_id;
am.mem_id = n_mem;
am.type = d->type;
am.fd_index = pinos_connection_add_fd (this->conn, d->fd, false);
am.memfd = d->fd;
am.flags = d->flags;
am.offset = d->offset;
am.size = d->maxsize;
pinos_connection_add_message (this->conn, PINOS_MESSAGE_ADD_MEM, &am);
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_ADD_MEM,
&am,
false);
b->buffer.datas[j].type = SPA_DATA_TYPE_ID;
b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
n_mem++;
@ -732,11 +726,14 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
am.port_id = port_id;
am.mem_id = port->buffer_mem_id;
am.type = SPA_DATA_TYPE_MEMFD;
am.fd_index = pinos_connection_add_fd (this->conn, port->buffer_mem.fd, false);
am.memfd = port->buffer_mem.fd;
am.flags = 0;
am.offset = 0;
am.size = size;
pinos_connection_add_message (this->conn, PINOS_MESSAGE_ADD_MEM, &am);
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_ADD_MEM,
&am,
false);
memref = alloca (n_buffers * sizeof (PinosMessageMemRef));
for (i = 0; i < n_buffers; i++) {
@ -754,11 +751,10 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
ub.port_id = port_id;
ub.n_buffers = n_buffers;
ub.buffers = memref;
pinos_connection_add_message (this->conn, PINOS_MESSAGE_USE_BUFFERS, &ub);
if (!pinos_connection_flush (this->conn))
spa_log_error (this->log, "proxy %p: error writing connection", this);
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_USE_BUFFERS,
&ub,
true);
return SPA_RESULT_RETURN_ASYNC (ub.seq);
}
@ -983,118 +979,95 @@ handle_node_event (SpaProxy *this,
}
static SpaResult
parse_connection (SpaProxy *this)
client_node_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosConnection *conn = this->conn;
PinosClientNode *node = data;
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (node, PinosClientNodeImpl, this);
SpaProxy *this = &impl->proxy;
while (pinos_connection_has_next (conn)) {
PinosMessageType type = pinos_connection_get_type (conn);
switch (type) {
case PINOS_MESSAGE_INVALID:
case PINOS_MESSAGE_ADD_PORT:
case PINOS_MESSAGE_REMOVE_PORT:
case PINOS_MESSAGE_SET_FORMAT:
case PINOS_MESSAGE_SET_PROPERTY:
case PINOS_MESSAGE_NODE_COMMAND:
case PINOS_MESSAGE_PORT_COMMAND:
case PINOS_MESSAGE_TRANSPORT_UPDATE:
spa_log_error (this->log, "proxy %p: got unexpected command %d", this, type);
break;
switch (type) {
case PINOS_MESSAGE_INVALID:
case PINOS_MESSAGE_ADD_PORT:
case PINOS_MESSAGE_REMOVE_PORT:
case PINOS_MESSAGE_SET_FORMAT:
case PINOS_MESSAGE_SET_PROPERTY:
case PINOS_MESSAGE_NODE_COMMAND:
case PINOS_MESSAGE_PORT_COMMAND:
case PINOS_MESSAGE_PROCESS_BUFFER:
case PINOS_MESSAGE_TRANSPORT_UPDATE:
spa_log_error (this->log, "proxy %p: got unexpected command %d", this, type);
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;
case PINOS_MESSAGE_NODE_UPDATE:
{
PinosMessageNodeUpdate nu;
remove = (pu->change_mask == 0);
if (!pinos_connection_parse_message (conn, &nu))
break;
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;
if (remove) {
do_uninit_port (this, pu->direction, pu->port_id);
} else {
do_update_port (this, pu);
}
break;
}
case PINOS_MESSAGE_PORT_UPDATE:
{
PinosMessagePortUpdate pu;
bool remove;
case PINOS_MESSAGE_PORT_STATUS_CHANGE:
{
spa_log_warn (this->log, "proxy %p: command not implemented %d", this, type);
break;
}
spa_log_info (this->log, "proxy %p: got port update %d", this, type);
if (!pinos_connection_parse_message (conn, &pu))
break;
case PINOS_MESSAGE_NODE_STATE_CHANGE:
{
PinosMessageNodeStateChange *sc = message;
SpaNodeState old = this->node.state;
if (!CHECK_PORT_ID (this, pu.direction, pu.port_id))
break;
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);
remove = (pu.change_mask == 0);
break;
}
if (remove) {
do_uninit_port (this, pu.direction, pu.port_id);
} else {
do_update_port (this, &pu);
}
break;
}
case PINOS_MESSAGE_ADD_MEM:
break;
case PINOS_MESSAGE_USE_BUFFERS:
break;
case PINOS_MESSAGE_PORT_STATUS_CHANGE:
{
spa_log_warn (this->log, "proxy %p: command not implemented %d", this, type);
break;
}
case PINOS_MESSAGE_NODE_STATE_CHANGE:
{
PinosMessageNodeStateChange sc;
SpaNodeState old = this->node.state;
if (!pinos_connection_parse_message (conn, &sc))
break;
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;
if (!pinos_connection_parse_message (conn, &cne))
break;
handle_node_event (this, cne.event);
break;
}
case PINOS_MESSAGE_NODE_EVENT:
{
PinosMessageNodeEvent *cne = message;
handle_node_event (this, cne->event);
break;
}
}
return SPA_RESULT_OK;
}
static void
proxy_on_fd_events (SpaSource *source)
{
SpaProxy *this = source->data;
if (source->rmask & SPA_IO_IN)
parse_connection (this);
}
static void
proxy_on_data_fd_events (SpaSource *source)
{
@ -1184,16 +1157,10 @@ proxy_init (SpaProxy *this,
this->node = proxy_node;
this->ctrl_source.func = proxy_on_fd_events;
this->ctrl_source.data = this;
this->ctrl_source.fd = -1;
this->ctrl_source.mask = SPA_IO_IN | SPA_IO_ERR;
this->ctrl_source.rmask = 0;
this->data_source.func = proxy_on_data_fd_events;
this->data_source.data = this;
this->data_source.fd = -1;
this->data_source.mask = SPA_IO_IN | SPA_IO_ERR;
this->data_source.mask = SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP;
this->data_source.rmask = 0;
return SPA_RESULT_RETURN_ASYNC (this->seq++);
@ -1207,17 +1174,16 @@ on_transport_changed (PinosListener *listener,
PinosClientNode *this = &impl->this;
PinosTransportInfo info;
PinosMessageTransportUpdate tu;
PinosConnection *conn = impl->proxy.conn;
pinos_transport_get_info (node->transport, &info);
tu.memfd_index = pinos_connection_add_fd (conn, info.memfd, false);
tu.memfd = info.memfd;
tu.offset = info.offset;
tu.size = info.size;
pinos_connection_add_message (conn, PINOS_MESSAGE_TRANSPORT_UPDATE, &tu);
if (!pinos_connection_flush (conn))
pinos_log_error ("client-node %p: error writing connection", this);
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_TRANSPORT_UPDATE,
&tu,
true);
}
static void
@ -1241,10 +1207,6 @@ proxy_clear (SpaProxy *this)
if (this->out_ports[i].valid)
clear_port (this, &this->out_ports[i], SPA_DIRECTION_OUTPUT, i);
}
if (this->ctrl_source.fd != -1) {
spa_loop_remove_source (this->main_loop, &this->ctrl_source);
close (this->ctrl_source.fd);
}
if (this->data_source.fd != -1) {
spa_loop_remove_source (this->data_loop, &this->data_source);
close (this->data_source.fd);
@ -1264,25 +1226,25 @@ proxy_clear (SpaProxy *this)
* Returns: a new #PinosNode
*/
PinosClientNode *
pinos_client_node_new (PinosCore *core,
const gchar *name,
pinos_client_node_new (PinosClient *client,
uint32_t id,
const char *name,
PinosProperties *properties)
{
PinosClientNodeImpl *impl;
PinosClientNode *this;
impl = calloc (1, sizeof (PinosClientNodeImpl));
impl->core = core;
impl->ctrl_fd = -1;
impl->data_fd = -1;
this = &impl->this;
impl->core = client->core;
impl->data_fd = -1;
pinos_log_debug ("client-node %p: new", impl);
pinos_signal_init (&this->destroy_signal);
proxy_init (&impl->proxy, NULL, core->support, core->n_support);
proxy_init (&impl->proxy, NULL, client->core->support, client->core->n_support);
this->node = pinos_node_new (core,
this->node = pinos_node_new (client->core,
name,
&impl->proxy.node,
NULL,
@ -1298,12 +1260,22 @@ pinos_client_node_new (PinosCore *core,
&impl->loop_changed,
on_loop_changed);
this->resource = pinos_resource_new (client,
id,
client->core->uri.client_node,
this,
(PinosDestroy) pinos_client_node_destroy);
impl->proxy.resource = this->resource;
this->resource->dispatch_func = client_node_dispatch_func;
this->resource->dispatch_data = this;
return this;
}
static void
on_node_remove (PinosNode *node,
gpointer data,
void *data,
SpaResult res)
{
PinosClientNode *this = data;
@ -1312,8 +1284,6 @@ on_node_remove (PinosNode *node,
pinos_log_debug ("client-node %p: finalize", node);
proxy_clear (&impl->proxy);
if (impl->ctrl_fd != -1)
close (impl->ctrl_fd);
if (impl->data_fd != -1)
close (impl->data_fd);
free (impl);
@ -1340,37 +1310,6 @@ pinos_client_node_destroy (PinosClientNode * this)
return res;
}
/**
* pinos_client_node_get_ctrl_socket:
* @node: a #PinosClientNode
* @fd: a result socket
*
* Create or return a previously create socket pair for @node. The
* socket for the other end is returned.
*
* Returns: %SPA_RESULT_OK on success
*/
SpaResult
pinos_client_node_get_ctrl_socket (PinosClientNode *this,
int *fd)
{
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
if (impl->ctrl_fd == -1) {
int fd[2];
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, fd) != 0)
return SPA_RESULT_ERRNO;
impl->proxy.ctrl_source.fd = fd[0];
impl->proxy.conn = pinos_connection_new (impl->proxy.ctrl_source.fd);
spa_loop_add_source (impl->proxy.main_loop, &impl->proxy.ctrl_source);
impl->ctrl_fd = fd[1];
}
*fd = impl->ctrl_fd;
return SPA_RESULT_OK;
}
/**
* pinos_client_node_get_data_socket:
* @node: a #PinosClientNode
@ -1390,11 +1329,12 @@ pinos_client_node_get_data_socket (PinosClientNode *this,
if (impl->data_fd == -1) {
int fd[2];
if (socketpair (AF_UNIX, SOCK_STREAM, 0, fd) != 0)
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fd) != 0)
return SPA_RESULT_ERRNO;
impl->proxy.data_source.fd = fd[0];
spa_loop_add_source (impl->proxy.data_loop, &impl->proxy.data_source);
pinos_log_debug ("client-node %p: add data fd %d", this, fd[0]);
impl->data_fd = fd[1];
}
*fd = impl->data_fd;

View file

@ -39,18 +39,25 @@ typedef struct _PinosClientNode PinosClientNode;
struct _PinosClientNode {
PinosNode *node;
PinosClient *client;
PinosResource *resource;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosClientNode *node));
};
PinosClientNode * pinos_client_node_new (PinosCore *core,
const gchar *name,
PinosClientNode * pinos_client_node_new (PinosClient *client,
uint32_t id,
const char *name,
PinosProperties *properties);
SpaResult pinos_client_node_destroy (PinosClientNode *node);
SpaResult pinos_client_node_get_ctrl_socket (PinosClientNode *node, int *fd);
SpaResult pinos_client_node_get_data_socket (PinosClientNode *node, int *fd);
SpaResult pinos_client_node_dispatch_message (PinosClientNode *node,
PinosMessageType type,
void *message);
#ifdef __cplusplus
}
#endif

View file

@ -21,55 +21,13 @@
#include "pinos/client/pinos.h"
#include "pinos/server/client.h"
#include "pinos/dbus/org-pinos.h"
#include "pinos/server/resource.h"
typedef struct
{
PinosClient this;
} PinosClientImpl;
PinosResource *
pinos_client_add_resource (PinosClient *client,
uint32_t type,
void *object,
PinosDestroy destroy)
{
PinosResource *resource;
resource = calloc (1, sizeof (PinosResource));
resource->core = client->core;
resource->client = client;
resource->id = 0;
resource->type = type;
resource->object = object;
resource->destroy = destroy;
pinos_signal_init (&resource->destroy_signal);
pinos_log_debug ("client %p: add resource %p", client, resource);
spa_list_insert (client->resource_list.prev, &resource->link);
return resource;
}
SpaResult
pinos_resource_destroy (PinosResource *resource)
{
pinos_log_debug ("resource %p: destroy", resource);
pinos_signal_emit (&resource->destroy_signal, resource);
spa_list_remove (&resource->link);
if (resource->destroy)
resource->destroy (resource->object);
free (resource);
return SPA_RESULT_OK;
}
/**
* pinos_client_new:
* @daemon: a #PinosDaemon

View file

@ -28,26 +28,9 @@ extern "C" {
#define PINOS_CLIENT_PREFIX PINOS_CLIENT_URI "#"
typedef struct _PinosClient PinosClient;
typedef struct _PinosResource PinosResource;
typedef void (*PinosDestroy) (void *object);
#include <pinos/server/core.h>
struct _PinosResource {
PinosCore *core;
SpaList link;
PinosClient *client;
uint32_t id;
uint32_t type;
void *object;
PinosDestroy destroy;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosResource *resource));
};
#include <pinos/server/resource.h>
/**
* PinosClient:
@ -63,6 +46,9 @@ struct _PinosClient {
SpaList resource_list;
PinosSendFunc send_func;
void *send_data;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosClient *client));
};
@ -71,14 +57,6 @@ PinosClient * pinos_client_new (PinosCore *core,
PinosProperties *properties);
SpaResult pinos_client_destroy (PinosClient *client);
PinosResource * pinos_client_add_resource (PinosClient *client,
uint32_t type,
void *object,
PinosDestroy destroy);
SpaResult pinos_resource_destroy (PinosResource *resource);
#ifdef __cplusplus
}
#endif

View file

@ -27,17 +27,17 @@
#include "command.h"
typedef bool (*PinosCommandFunc) (PinosCommand *command,
PinosCore *core,
char **err);
PinosCore *core,
char **err);
static bool execute_command_module_load (PinosCommand *command,
PinosCore *core,
PinosCore *core,
char **err);
typedef PinosCommand * (*PinosCommandParseFunc) (const char *line,
char **err);
typedef PinosCommand * (*PinosCommandParseFunc) (const gchar *line,
char **err);
static PinosCommand * parse_command_module_load (const gchar *line,
static PinosCommand * parse_command_module_load (const char *line,
char **err);
typedef struct
@ -51,7 +51,7 @@ typedef struct
typedef struct _CommandParse
{
const gchar *name;
const char *name;
PinosCommandParseFunc func;
} CommandParse;
@ -60,7 +60,7 @@ static const CommandParse parsers[] = {
{NULL, NULL}
};
static const gchar whitespace[] = " \t";
static const char whitespace[] = " \t";
static PinosCommand *
parse_command_module_load (const char * line, char ** err)
@ -130,8 +130,8 @@ pinos_command_parse (const char *line,
{
PinosCommand *command = NULL;
const CommandParse *parse;
gchar *name;
gsize len;
char *name;
size_t len;
len = strcspn (line, whitespace);

View file

@ -73,6 +73,10 @@ pinos_core_new (PinosMainLoop *main_loop)
pinos_signal_init (&this->node_unlink);
pinos_signal_init (&this->node_unlink_done);
this->global = pinos_core_add_global (this,
this->uri.core,
this);
return this;
}

View file

@ -27,6 +27,9 @@ 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 "#"
#include <spa/include/spa/log.h>
#include <pinos/server/main-loop.h>
@ -53,6 +56,8 @@ struct _PinosGlobal {
* Pinos core object class.
*/
struct _PinosCore {
PinosGlobal *global;
PinosURI uri;
PinosMap objects;

View file

@ -95,9 +95,21 @@ do_add_source (SpaLoop *loop,
GIOChannel *channel;
GSource *s;
LoopData *data;
GIOCondition cond;
channel = g_io_channel_unix_new (source->fd);
s = g_io_create_watch (channel, G_IO_IN);
cond = 0;
if (source->mask & SPA_IO_IN)
cond |= G_IO_IN;
if (source->mask & SPA_IO_OUT)
cond |= G_IO_OUT;
if (source->mask & SPA_IO_ERR)
cond |= G_IO_ERR;
if (source->mask & SPA_IO_HUP)
cond |= G_IO_HUP;
s = g_io_create_watch (channel, cond);
g_io_channel_unref (channel);
data = g_new0 (LoopData, 1);

View file

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

View file

@ -23,6 +23,7 @@
#endif
#include <dlfcn.h>
#include <glib.h>
#include "pinos/client/pinos.h"
#include "pinos/client/utils.h"
@ -40,7 +41,7 @@ typedef struct
static char *
find_module (const char * path, const char *name)
{
gchar *filename;
char *filename;
GDir *dir;
const gchar *entry;
GError *err = NULL;

View file

@ -27,6 +27,9 @@ 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 {
@ -52,8 +55,8 @@ struct _PinosModule {
typedef bool (*PinosModuleInitFunc) (PinosModule *module, char *args);
PinosModule * pinos_module_load (PinosCore *core,
const gchar *name,
const gchar *args,
const char *name,
const char *args,
char **err);
void pinos_module_destroy (PinosModule *module);

86
pinos/server/resource.c Normal file
View file

@ -0,0 +1,86 @@
/* 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/server/resource.h"
PinosResource *
pinos_resource_new (PinosClient *client,
uint32_t id,
uint32_t type,
void *object,
PinosDestroy destroy)
{
PinosResource *resource;
resource = calloc (1, sizeof (PinosResource));
pinos_log_debug ("resource %p: new for client %p", resource, client);
resource->core = client->core;
resource->client = client;
resource->id = id;
resource->type = type;
resource->object = object;
resource->destroy = destroy;
resource->send_func = client->send_func;
resource->send_data = client->send_data;
pinos_signal_init (&resource->destroy_signal);
spa_list_insert (client->resource_list.prev, &resource->link);
return resource;
}
SpaResult
pinos_resource_destroy (PinosResource *resource)
{
pinos_log_debug ("resource %p: destroy", resource);
pinos_signal_emit (&resource->destroy_signal, resource);
spa_list_remove (&resource->link);
if (resource->destroy)
resource->destroy (resource->object);
free (resource);
return SPA_RESULT_OK;
}
SpaResult
pinos_resource_send_message (PinosResource *resource,
PinosMessageType type,
void *message,
bool flush)
{
if (resource->send_func)
return resource->send_func (resource,
resource->id,
type,
message,
flush,
resource->send_data);
pinos_log_error ("resource %p: send func not implemented", resource);
return SPA_RESULT_NOT_IMPLEMENTED;
}

84
pinos/server/resource.h Normal file
View file

@ -0,0 +1,84 @@
/* 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_RESOURCE_H__
#define __PINOS_RESOURCE_H__
#ifdef __cplusplus
extern "C" {
#endif
#define PINOS_RESOURCE_URI "http://pinos.org/ns/resource"
#define PINOS_RESOURCE_PREFIX PINOS_RESOURCE_URI "#"
typedef struct _PinosResource PinosResource;
#include <pinos/server/core.h>
typedef void (*PinosDestroy) (void *object);
typedef SpaResult (*PinosSendFunc) (void *object,
uint32_t id,
PinosMessageType type,
void *message,
bool flush,
void *data);
typedef SpaResult (*PinosDispatchFunc) (void *object,
PinosMessageType type,
void *message,
void *data);
struct _PinosResource {
PinosCore *core;
SpaList link;
PinosClient *client;
uint32_t id;
uint32_t type;
void *object;
PinosDestroy destroy;
PinosSendFunc send_func;
void *send_data;
PinosDispatchFunc dispatch_func;
void *dispatch_data;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosResource *resource));
};
PinosResource * pinos_resource_new (PinosClient *client,
uint32_t id,
uint32_t type,
void *object,
PinosDestroy destroy);
SpaResult pinos_resource_destroy (PinosResource *resource);
SpaResult pinos_resource_send_message (PinosResource *resource,
PinosMessageType type,
void *message,
bool flush);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_RESOURCE_H__ */

View file

@ -26,6 +26,7 @@
#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"
@ -34,11 +35,13 @@ 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->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);

View file

@ -40,11 +40,13 @@ typedef struct _PinosURI PinosURI;
struct _PinosURI {
SpaIDMap *map;
uint32_t core;
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;