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

@ -26,18 +26,11 @@
#include "pinos/server/core.h"
#include "pinos/server/module.h"
#define MODULE_URI "http://pinos.org/ns/module-autolink"
#define MODULE_PREFIX MODULE_URI "#"
typedef struct {
PinosCore *core;
PinosProperties *properties;
PinosGlobal *global;
struct {
uint32_t module;
} uri;
PinosListener global_added;
PinosListener global_removed;
PinosListener port_added;
@ -57,8 +50,10 @@ try_link_port (PinosNode *node, PinosPort *port, ModuleImpl *impl)
PinosLink *link;
props = node->properties;
if (props == NULL)
if (props == NULL) {
pinos_log_debug ("module %p: node has no properties", impl);
return;
}
path = pinos_properties_get (props, "pinos.target.node");
@ -275,10 +270,8 @@ module_new (PinosCore *core,
pinos_signal_add (&core->port_unlinked, &impl->port_unlinked, on_link_port_unlinked);
pinos_signal_add (&core->link_state_changed, &impl->link_state_changed, on_link_state_changed);
impl->uri.module = spa_id_map_get_id (core->uri.map, MODULE_URI);
impl->global = pinos_core_add_global (core,
impl->uri.module,
core->uri.module,
impl);
return impl;
}
@ -306,5 +299,5 @@ bool
pinos__module_init (PinosModule * module, const char * args)
{
module_new (module->core, NULL);
return TRUE;
return true;
}

View file

@ -20,6 +20,7 @@
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
@ -34,6 +35,7 @@
#include "pinos/server/module.h"
#include "pinos/server/client-node.h"
#include "pinos/server/client.h"
#include "pinos/server/resource.h"
#include "pinos/server/link.h"
#include "pinos/server/node-factory.h"
#include "pinos/server/data-loop.h"
@ -41,9 +43,6 @@
#include "pinos/dbus/org-pinos.h"
#define PINOS_PROTOCOL_DBUS_URI "http://pinos.org/ns/protocol-dbus"
#define PINOS_PROTOCOL_DBUS_PREFIX PINOS_PROTOCOL_DBUS_URI "#"
typedef struct {
PinosCore *core;
SpaList link;
@ -51,10 +50,6 @@ typedef struct {
PinosProperties *properties;
struct {
uint32_t protocol_dbus;
} uri;
GDBusConnection *connection;
GDBusObjectManagerServer *server_manager;
@ -162,6 +157,51 @@ find_object (PinosProtocolDBus *impl,
return NULL;
}
struct _PinosProperties {
GHashTable *hashtable;
};
static void
add_to_variant (const gchar *key, const gchar *value, GVariantBuilder *b)
{
g_variant_builder_add (b, "{sv}", key, g_variant_new_string (value));
}
static void
pinos_properties_init_builder (PinosProperties *properties,
GVariantBuilder *builder)
{
g_variant_builder_init (builder, G_VARIANT_TYPE ("a{sv}"));
g_hash_table_foreach (properties->hashtable, (GHFunc) add_to_variant, builder);
}
static GVariant *
pinos_properties_to_variant (PinosProperties *properties)
{
GVariantBuilder builder;
pinos_properties_init_builder (properties, &builder);
return g_variant_builder_end (&builder);
}
static PinosProperties *
pinos_properties_from_variant (GVariant *variant)
{
PinosProperties *props;
GVariantIter iter;
GVariant *value;
gchar *key;
props = pinos_properties_new (NULL, NULL);
g_variant_iter_init (&iter, variant);
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
g_hash_table_replace (props->hashtable,
g_strdup (key),
g_variant_dup_string (value, NULL));
return props;
}
static void
client_name_appeared_handler (GDBusConnection *connection,
const gchar *name,
@ -176,8 +216,10 @@ client_name_appeared_handler (GDBusConnection *connection,
static void
client_destroy (PinosProtocolDBusClient *this)
{
spa_list_remove (&this->link);
free (this->sender);
if (this->sender) {
spa_list_remove (&this->link);
free (this->sender);
}
}
static void
@ -279,10 +321,11 @@ handle_create_node (PinosDaemon1 *interface,
if (object == NULL)
goto object_failed;
pinos_client_add_resource (client,
impl->core->uri.node,
node,
(PinosDestroy) pinos_node_destroy);
pinos_resource_new (client,
SPA_ID_INVALID,
impl->core->uri.node,
node,
(PinosDestroy) pinos_node_destroy);
object_path = object->object_path;
pinos_log_debug ("protocol-dbus %p: added node %p with path %s", impl, node, object_path);
@ -350,6 +393,7 @@ handle_create_client_node (PinosDaemon1 *interface,
int ctrl_fd, data_fd;
int ctrl_idx, data_idx;
PinosProtocolDBusObject *object;
int fd[2];
sender = g_dbus_method_invocation_get_sender (invocation);
client = sender_get_client (impl, sender, TRUE);
@ -364,8 +408,13 @@ handle_create_client_node (PinosDaemon1 *interface,
}
}
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, fd) != 0)
goto no_socket_pair;
node = pinos_client_node_new (impl->core,
ctrl_fd = fd[1];
node = pinos_client_node_new (client,
SPA_ID_INVALID,
arg_name,
props);
@ -373,17 +422,9 @@ handle_create_client_node (PinosDaemon1 *interface,
if (object == NULL)
goto object_failed;
if ((res = pinos_client_node_get_ctrl_socket (node, &ctrl_fd)) < 0)
goto no_socket;
if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0)
goto no_socket;
pinos_client_add_resource (client,
impl->core->uri.client_node,
node,
(PinosDestroy) pinos_client_node_destroy);
object_path = object->object_path;
pinos_log_debug ("protocol-dbus %p: add client-node %p, %s", impl, node, object_path);
@ -402,6 +443,11 @@ object_failed:
pinos_log_debug ("protocol-dbus %p: could not create object", impl);
goto exit_error;
}
no_socket_pair:
{
pinos_log_debug ("protocol-dbus %p: could not create socketpair: %s", impl, strerror (errno));
goto exit_error;
}
no_socket:
{
pinos_log_debug ("protocol-dbus %p: could not create socket: %s", impl, strerror (errno));
@ -519,7 +565,7 @@ on_global_added (PinosListener *listener,
true,
NULL);
}
else if (global->type == impl->uri.protocol_dbus) {
else if (global->object == impl) {
PinosProtocolDBus *proto = global->object;
PinosProtocolDBusServer *server;
PinosDaemon1 *iface;
@ -631,10 +677,8 @@ pinos_protocol_dbus_new (PinosCore *core,
impl->server_manager = g_dbus_object_manager_server_new (PINOS_DBUS_OBJECT_PREFIX);
impl->uri.protocol_dbus = spa_id_map_get_id (core->uri.map, PINOS_PROTOCOL_DBUS_URI);
impl->global = pinos_core_add_global (core,
impl->uri.protocol_dbus,
core->uri.module,
impl);
return impl;
}

View file

@ -19,6 +19,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
@ -36,14 +37,12 @@
#include "pinos/server/module.h"
#include "pinos/server/client-node.h"
#include "pinos/server/client.h"
#include "pinos/server/resource.h"
#include "pinos/server/link.h"
#include "pinos/server/node-factory.h"
#include "pinos/server/data-loop.h"
#include "pinos/server/main-loop.h"
#define PINOS_PROTOCOL_NATIVE_URI "http://pinos.org/ns/protocol-native"
#define PINOS_PROTOCOL_NATIVE_PREFIX PINOS_PROTOCOL_NATIVE_URI "#"
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 108
#endif
@ -69,10 +68,6 @@ typedef struct {
PinosProperties *properties;
struct {
uint32_t protocol_native;
} uri;
SpaList socket_list;
SpaList client_list;
@ -102,6 +97,7 @@ typedef struct {
struct ucred ucred;
SpaSource *source;
PinosConnection *connection;
PinosResource *core_resource;
} PinosProtocolNativeClient;
typedef struct {
@ -153,9 +149,120 @@ static void
client_destroy (PinosProtocolNativeClient *this)
{
spa_list_remove (&this->link);
pinos_loop_destroy_source (this->parent.impl->core->main_loop->loop,
this->source);
pinos_connection_destroy (this->connection);
close (this->fd);
}
static SpaResult
core_dispatch_func (void *object,
PinosMessageType type,
void *message,
void *data)
{
PinosProtocolNativeClient *client = data;
PinosProtocolNative *impl = client->parent.impl;
PinosClient *c = client->parent.global->object;
switch (type) {
case PINOS_MESSAGE_SUBSCRIBE:
{
PinosMessageSubscribe *m = message;
PinosGlobal *global;
PinosMessageNotifyDone nd;
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_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 (c,
m->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 SpaResult
client_send_func (void *object,
uint32_t id,
PinosMessageType type,
void *message,
bool flush,
void *data)
{
PinosProtocolNativeClient *client = data;
pinos_log_debug ("protocol-native %p: sending message %d to %u", client->parent.impl, type, id);
pinos_connection_add_message (client->connection,
id,
type,
message);
if (flush)
pinos_connection_flush (client->connection);
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,
@ -164,15 +271,36 @@ connection_data (SpaSource *source,
{
PinosProtocolNativeClient *client = data;
PinosConnection *conn = client->connection;
PinosMessageType type;
uint32_t id;
size_t size;
while (pinos_connection_has_next (conn)) {
PinosMessageType type = pinos_connection_get_type (conn);
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
pinos_client_destroy (client->parent.global->object);
return;
}
switch (type) {
default:
pinos_log_error ("unhandled message %d", type);
break;
while (pinos_connection_get_next (conn, &type, &id, &size)) {
PinosResource *resource;
void *message = alloca (size);
pinos_log_debug ("protocol-native %p: got message %d from %u", client->parent.impl, type, id);
if (!pinos_connection_parse_message (conn, message)) {
pinos_log_error ("protocol-native %p: failed to parse message", client->parent.impl);
continue;
}
resource = find_resource (client->parent.global->object, id);
if (resource == NULL) {
pinos_log_error ("protocol-native %p: unknown resource %u", client->parent.impl, id);
continue;
}
resource->dispatch_func (resource,
type,
message,
resource->dispatch_data);
}
}
@ -190,11 +318,22 @@ client_new (PinosProtocolNative *impl,
close (fd);
return NULL;
}
client->send_func = client_send_func;
client->send_data = this;
this->core_resource = pinos_resource_new (client,
0,
impl->core->uri.core,
impl->core,
NULL);
this->core_resource->dispatch_func = core_dispatch_func;
this->core_resource->dispatch_data = this;
this->fd = fd;
this->source = pinos_loop_add_io (impl->core->main_loop->loop,
this->fd,
SPA_IO_IN,
SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP,
false,
connection_data,
this);
@ -224,7 +363,10 @@ on_global_added (PinosListener *listener,
global,
(PinosDestroy) client_destroy);
} else if (global->type == impl->core->uri.node) {
} else if (global->type == impl->uri.protocol_native) {
object_new (sizeof (PinosProtocolNativeNode),
impl,
global,
NULL);
} else if (global->type == impl->core->uri.link) {
}
}
@ -234,7 +376,7 @@ on_global_removed (PinosListener *listener,
PinosCore *core,
PinosGlobal *global)
{
PinosProtocolNative *impl = SPA_CONTAINER_OF (listener, PinosProtocolNative, global_added);
PinosProtocolNative *impl = SPA_CONTAINER_OF (listener, PinosProtocolNative, global_removed);
PinosProtocolNativeObject *object;
if ((object = find_object (impl, global->object))) {
@ -284,7 +426,7 @@ init_socket_name (Socket *s, const char *name)
s->addr.sun_family = AF_LOCAL;
name_size = snprintf (s->addr.sun_path, sizeof (s->addr.sun_path),
"%s/%s", runtime_dir, name) + 1;
"%s/%s", runtime_dir, name) + 1;
s->core_name = (s->addr.sun_path + name_size - 1) - strlen (name);
@ -434,10 +576,8 @@ pinos_protocol_native_new (PinosCore *core,
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
impl->uri.protocol_native = spa_id_map_get_id (core->uri.map, PINOS_PROTOCOL_NATIVE_URI);
impl->global = pinos_core_add_global (core,
impl->uri.protocol_native,
core->uri.module,
impl);
return impl;
@ -472,5 +612,5 @@ bool
pinos__module_init (PinosModule * module, const char * args)
{
pinos_protocol_native_new (module->core, NULL);
return TRUE;
return true;
}

View file

@ -26,18 +26,11 @@
#include "pinos/server/core.h"
#include "pinos/server/module.h"
#define MODULE_URI "http://pinos.org/ns/module-suspend-on-idle"
#define MODULE_PREFIX MODULE_URI "#"
typedef struct {
PinosCore *core;
PinosProperties *properties;
PinosGlobal *global;
struct {
uint32_t module;
} uri;
PinosListener global_added;
PinosListener global_removed;
PinosListener node_state_request;
@ -196,10 +189,8 @@ module_new (PinosCore *core,
pinos_signal_add (&core->node_state_request, &impl->node_state_request, on_node_state_request);
pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed);
impl->uri.module = spa_id_map_get_id (core->uri.map, MODULE_URI);
impl->global = pinos_core_add_global (core,
impl->uri.module,
core->uri.module,
impl);
return impl;
}
@ -221,5 +212,5 @@ bool
pinos__module_init (PinosModule * module, const char * args)
{
module_new (module->core, NULL);
return TRUE;
return true;
}

View file

@ -89,5 +89,5 @@ pinos__module_init (PinosModule * module, const char * args)
"videotestsrc",
video_props);
return TRUE;
return true;
}