From dfbfb4c9ee7a14a0a86a1836dcf1fbebb311148b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 16 Nov 2016 16:57:47 +0100 Subject: [PATCH] Rework dbus handling Remove the Daemon object and remove all dbus code from the main objects. We can use the signals in a separate module to create and destroy the DBus interfaces. Move the dbus protocol in a module Move the autolink policy to a module --- pinos/client/stream.c | 3 +- pinos/daemon/daemon-config.c | 6 +- pinos/daemon/daemon-config.h | 4 +- pinos/daemon/main.c | 21 +- pinos/daemon/pinos.conf.in | 2 + pinos/modules/meson.build | 23 + pinos/modules/module-autolink.c | 311 ++++++++++++ pinos/modules/module-protocol-dbus.c | 681 +++++++++++++++++++++++++++ pinos/modules/spa/meson.build | 1 - pinos/modules/spa/module.c | 2 +- pinos/server/client-node.c | 2 +- pinos/server/client.c | 91 +--- pinos/server/client.h | 13 +- pinos/server/command.h | 2 +- pinos/server/core.c | 57 ++- pinos/server/core.h | 23 +- pinos/server/daemon.c | 660 -------------------------- pinos/server/daemon.h | 75 --- pinos/server/link.c | 51 +- pinos/server/link.h | 4 +- pinos/server/main-loop.c | 5 +- pinos/server/main-loop.h | 3 +- pinos/server/meson.build | 2 - pinos/server/node.c | 51 +- pinos/server/node.h | 2 - pinos/server/registry.c | 20 - pinos/server/registry.h | 11 - spa/plugins/alsa/alsa-source.c | 3 + 28 files changed, 1122 insertions(+), 1007 deletions(-) create mode 100644 pinos/modules/module-autolink.c create mode 100644 pinos/modules/module-protocol-dbus.c delete mode 100644 pinos/server/daemon.c delete mode 100644 pinos/server/daemon.h diff --git a/pinos/client/stream.c b/pinos/client/stream.c index a8443556f..adb139fd7 100644 --- a/pinos/client/stream.c +++ b/pinos/client/stream.c @@ -29,8 +29,9 @@ #include #include "pinos/dbus/org-pinos.h" -#include "pinos/server/daemon.h" + #include "pinos/client/pinos.h" +#include "pinos/client/array.h" #include "pinos/client/connection.h" #include "pinos/client/context.h" #include "pinos/client/stream.h" diff --git a/pinos/daemon/daemon-config.c b/pinos/daemon/daemon-config.c index d9b3fa7b6..b13234a10 100644 --- a/pinos/daemon/daemon-config.c +++ b/pinos/daemon/daemon-config.c @@ -179,7 +179,7 @@ pinos_daemon_config_load (PinosDaemonConfig *config, /** * pinos_daemon_config_run_commands: * @config: A #PinosDaemonConfig - * @daemon: A #PinosDaemon + * @core: A #PinosCore * * Run all commands that have been parsed. The list of commands will be cleared * when this function has been called. @@ -188,14 +188,14 @@ pinos_daemon_config_load (PinosDaemonConfig *config, */ bool pinos_daemon_config_run_commands (PinosDaemonConfig *config, - PinosDaemon *daemon) + PinosCore *core) { char *err = NULL; bool ret = true; PinosCommand *command, *tmp; spa_list_for_each (command, &config->commands, link) { - if (!pinos_command_run (command, daemon->core, &err)) { + if (!pinos_command_run (command, core, &err)) { pinos_log_warn ("could not run command %s: %s", command->name, err); free (err); ret = false; diff --git a/pinos/daemon/daemon-config.h b/pinos/daemon/daemon-config.h index 15ff004b6..78ccd6b15 100644 --- a/pinos/daemon/daemon-config.h +++ b/pinos/daemon/daemon-config.h @@ -25,7 +25,7 @@ extern "C" { #endif -#include +#include typedef struct _PinosDaemonConfig PinosDaemonConfig; @@ -41,7 +41,7 @@ bool pinos_daemon_config_load_file (PinosDaemonConfig *confi bool pinos_daemon_config_load (PinosDaemonConfig *config, char **err); bool pinos_daemon_config_run_commands (PinosDaemonConfig *config, - PinosDaemon *daemon); + PinosCore *core); #ifdef __cplusplus } #endif diff --git a/pinos/daemon/main.c b/pinos/daemon/main.c index 2ba9809b6..088f72faf 100644 --- a/pinos/daemon/main.c +++ b/pinos/daemon/main.c @@ -18,7 +18,7 @@ */ #include -#include +#include #include #include "daemon-config.h" @@ -27,37 +27,30 @@ int main (int argc, char *argv[]) { PinosCore *core; - PinosDaemon *daemon; PinosMainLoop *loop; PinosDaemonConfig *config; - PinosProperties *props; char *err = NULL; pinos_init (&argc, &argv); - loop = pinos_main_loop_new (NULL); - core = pinos_core_new (loop); - /* parse configuration */ config = pinos_daemon_config_new (); if (!pinos_daemon_config_load (config, &err)) { g_error ("failed to parse config: %s", err); free (err); + return -1; } - props = pinos_properties_new ("test", "test", NULL); - daemon = pinos_daemon_new (core, - props); + loop = pinos_main_loop_new (); + core = pinos_core_new (loop); - pinos_daemon_config_run_commands (config, daemon); - - pinos_daemon_start (daemon); + pinos_daemon_config_run_commands (config, core); pinos_main_loop_run (loop); - pinos_properties_free (props); pinos_main_loop_destroy (loop); - pinos_daemon_destroy (daemon); + + pinos_core_destroy (core); return 0; } diff --git a/pinos/daemon/pinos.conf.in b/pinos/daemon/pinos.conf.in index a96734c72..814c94b1b 100644 --- a/pinos/daemon/pinos.conf.in +++ b/pinos/daemon/pinos.conf.in @@ -1 +1,3 @@ +load-module libpinos-module-protocol-dbus load-module libpinos-module-spa +load-module libpinos-module-autolink diff --git a/pinos/modules/meson.build b/pinos/modules/meson.build index a5b87326e..4dbd56fc7 100644 --- a/pinos/modules/meson.build +++ b/pinos/modules/meson.build @@ -1,2 +1,25 @@ #subdir('gst') subdir('spa') + +pinos_module_c_args = [ + '-DHAVE_CONFIG_H', + '-D_GNU_SOURCE', +] + +pinos_module_autolink = shared_library('pinos-module-autolink', [ 'module-autolink.c' ], + c_args : pinos_module_c_args, + include_directories : [configinc, pinosinc, spa_inc], + link_with : spalib, + install : true, + install_dir : '@0@/pinos-0.1'.format(get_option('libdir')), + dependencies : [mathlib, dl_lib, pinos_dep, pinoscore_dep], +) + +pinos_module_protocol_dbus = shared_library('pinos-module-protocol-dbus', [ 'module-protocol-dbus.c' ], + c_args : pinos_module_c_args, + include_directories : [configinc, pinosinc, spa_inc], + link_with : spalib, + install : true, + install_dir : '@0@/pinos-0.1'.format(get_option('libdir')), + dependencies : [gobject_dep, gmodule_dep, glib_dep, gio_dep, mathlib, dl_lib, pinos_dep, pinoscore_dep], +) diff --git a/pinos/modules/module-autolink.c b/pinos/modules/module-autolink.c new file mode 100644 index 000000000..234f4c919 --- /dev/null +++ b/pinos/modules/module-autolink.c @@ -0,0 +1,311 @@ +/* Pinos + * Copyright (C) 2015 Wim Taymans + * + * 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 +#include +#include + +#include "config.h" + +#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; + PinosListener port_removed; + PinosListener port_unlinked; + PinosListener node_state_changed; + PinosListener link_state_changed; +} ModuleImpl; + +static void try_link_port (PinosNode *node, PinosPort *port, ModuleImpl *impl); + +static void +on_link_port_unlinked (PinosListener *listener, + PinosLink *link, + PinosPort *port) +{ + ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, port_unlinked); + + pinos_log_debug ("module %p: link %p: port %p unlinked", impl, link, port); + if (port->direction == PINOS_DIRECTION_OUTPUT && link->input) + try_link_port (link->input->node, link->input, impl); +} + +static void +on_link_state_changed (PinosListener *listener, + PinosLink *link) +{ + ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, link_state_changed); + PinosLinkState state; + + state = link->state; + switch (state) { + case PINOS_LINK_STATE_ERROR: + { + pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error); + + if (link->input && link->input->node) + pinos_node_report_error (link->input->node, strdup (link->error)); + if (link->output && link->output->node) + pinos_node_report_error (link->output->node, strdup (link->error)); + break; + } + + case PINOS_LINK_STATE_UNLINKED: + pinos_log_debug ("module %p: link %p: unlinked", impl, link); + +#if 0 + g_set_error (&error, + PINOS_ERROR, + PINOS_ERROR_NODE_LINK, + "error node unlinked"); + + if (link->input && link->input->node) + pinos_node_report_error (link->input->node, g_error_copy (error)); + if (link->output && link->output->node) + pinos_node_report_error (link->output->node, g_error_copy (error)); +#endif + break; + + case PINOS_LINK_STATE_INIT: + case PINOS_LINK_STATE_NEGOTIATING: + case PINOS_LINK_STATE_ALLOCATING: + case PINOS_LINK_STATE_PAUSED: + case PINOS_LINK_STATE_RUNNING: + break; + } +} + +static void +try_link_port (PinosNode *node, PinosPort *port, ModuleImpl *impl) +{ + //PinosClient *client; + PinosProperties *props; + const char *path; + char *error = NULL; + PinosLink *link; + + props = node->properties; + if (props == NULL) + return; + + path = pinos_properties_get (props, "pinos.target.node"); + + pinos_log_debug ("module %p: try to find and link to node %s", impl, path); + + if (path) { + PinosPort *target; + + target = pinos_core_find_port (impl->core, + port, + atoi (path), + NULL, + NULL, + &error); + if (target == NULL) + goto error; + + if (port->direction == PINOS_DIRECTION_OUTPUT) + link = pinos_port_link (port, target, NULL, NULL, &error); + else + link = pinos_port_link (target, port, NULL, NULL, &error); + + if (link == NULL) + goto error; + +#if 0 + client = pinos_node_get_client (node); + if (client) + pinos_client_add_object (client, &link->object); +#endif + + pinos_link_activate (link); + } + return; + +error: + { + pinos_node_report_error (node, error); + return; + } +} + +static void +on_port_added (PinosListener *listener, + PinosNode *node, + PinosPort *port) +{ + ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, port_added); + + try_link_port (node, port, impl); +} + +static void +on_port_removed (PinosListener *listener, + PinosNode *node, + PinosPort *port) +{ +} + +static void +on_node_created (PinosNode *node, + ModuleImpl *impl) +{ + PinosPort *port; + + spa_list_for_each (port, &node->input_ports, link) + on_port_added (&impl->port_added, node, port); + + spa_list_for_each (port, &node->output_ports, link) + on_port_added (&impl->port_added, node, port); +} + +static void +on_node_state_changed (PinosListener *listener, + PinosNode *node, + PinosNodeState old, + PinosNodeState state) +{ + ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, node_state_changed); + + pinos_log_debug ("module %p: node %p state change %s -> %s", impl, node, + pinos_node_state_as_string (old), + pinos_node_state_as_string (state)); + + if (old == PINOS_NODE_STATE_CREATING && state == PINOS_NODE_STATE_SUSPENDED) + on_node_created (node, impl); +} + +static void +on_node_added (ModuleImpl *impl, PinosNode *node) +{ + pinos_log_debug ("module %p: node %p added", impl, node); + + if (node->state > PINOS_NODE_STATE_CREATING) + on_node_created (node, impl); +} + +static void +on_node_removed (ModuleImpl *impl, PinosNode *node) +{ + pinos_log_debug ("module %p: node %p removed", impl, node); +} + +static void +on_global_added (PinosListener *listener, + PinosCore *core, + PinosGlobal *global) +{ + ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_added); + + if (global->type == impl->core->registry.uri.node) { + PinosNode *node = global->object; + on_node_added (impl, node); + } +} + +static void +on_global_removed (PinosListener *listener, + PinosCore *core, + PinosGlobal *global) +{ + ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_removed); + + if (global->type == impl->core->registry.uri.node) { + PinosNode *node = global->object; + on_node_removed (impl, node); + } +} + +/** + * module_new: + * @core: #PinosCore + * @properties: #PinosProperties + * + * Make a new #ModuleImpl object with given @properties + * + * Returns: a new #ModuleImpl + */ +ModuleImpl * +module_new (PinosCore *core, + PinosProperties *properties) +{ + ModuleImpl *impl; + + impl = calloc (1, sizeof (ModuleImpl)); + pinos_log_debug ("module %p: new", impl); + + impl->core = core; + impl->properties = properties; + + pinos_signal_add (&core->global_added, &impl->global_added, on_global_added); + pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed); + pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed); + pinos_signal_add (&core->port_added, &impl->port_added, on_port_added); + pinos_signal_add (&core->port_removed, &impl->port_removed, on_port_removed); + 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->registry.map, MODULE_URI); + + impl->global = pinos_core_add_global (core, + impl->uri.module, + impl); + return impl; +} + +void +module_destroy (ModuleImpl *impl) +{ + pinos_log_debug ("module %p: destroy", impl); + + pinos_global_destroy (impl->global); + + pinos_signal_remove (&impl->global_added); + pinos_signal_remove (&impl->global_removed); + pinos_signal_remove (&impl->node_state_changed); + pinos_signal_remove (&impl->port_added); + pinos_signal_remove (&impl->port_removed); + pinos_signal_remove (&impl->port_unlinked); + pinos_signal_remove (&impl->link_state_changed); + free (impl); +} + +bool pinos__module_init (PinosModule *module, const char * args); + +G_MODULE_EXPORT bool +pinos__module_init (PinosModule * module, const char * args) +{ + module_new (module->core, NULL); + return TRUE; +} diff --git a/pinos/modules/module-protocol-dbus.c b/pinos/modules/module-protocol-dbus.c new file mode 100644 index 000000000..3a525b152 --- /dev/null +++ b/pinos/modules/module-protocol-dbus.c @@ -0,0 +1,681 @@ +/* Pinos + * Copyright (C) 2015 Wim Taymans + * + * 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 +#include +#include + +#include +#include + +#include "config.h" + +#include "pinos/client/pinos.h" +#include "pinos/client/log.h" + +#include "pinos/server/core.h" +#include "pinos/server/node.h" +#include "pinos/server/module.h" +#include "pinos/server/client-node.h" +#include "pinos/server/client.h" +#include "pinos/server/link.h" +#include "pinos/server/node-factory.h" +#include "pinos/server/data-loop.h" +#include "pinos/server/main-loop.h" + +#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 _PinosProtocolDBus PinosProtocolDBus; + +struct _PinosProtocolDBus { + PinosCore *core; + SpaList link; + PinosGlobal *global; + + PinosProperties *properties; + + PINOS_SIGNAL (destroy_signal, (PinosListener *listener, + PinosProtocolDBus *proto)); +}; + +typedef struct { + PinosProtocolDBus this; + + struct { + uint32_t protocol_dbus; + } uri; + + GDBusConnection *connection; + GDBusObjectManagerServer *server_manager; + + SpaList client_list; + SpaList object_list; + + PinosListener global_added; + PinosListener global_removed; + PinosListener node_state_changed; +} PinosProtocolDBusImpl; + +typedef struct { + PinosProtocolDBusImpl *impl; + SpaList link; + void *object; + void *iface; + PinosObjectSkeleton *skel; + const gchar *object_path; + PinosDestroy destroy; +} PinosProtocolDBusObject; + +typedef struct { + PinosProtocolDBusObject parent; + SpaList link; + guint id; +} PinosProtocolDBusServer; + +typedef struct { + PinosProtocolDBusObject parent; + SpaList link; + gchar *sender; + guint id; +} PinosProtocolDBusClient; + +typedef struct { + PinosProtocolDBusObject parent; + PinosListener state_changed; +} PinosProtocolDBusNode; + +static void +object_export (PinosProtocolDBusObject *this) +{ + g_dbus_object_manager_server_export_uniquely (this->impl->server_manager, + G_DBUS_OBJECT_SKELETON (this->skel)); + this->object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (this->skel)); + pinos_log_debug ("protocol-dbus %p: export object %s", this->impl, this->object_path); +} + +static void +object_unexport (PinosProtocolDBusObject *this) +{ + if (this->object_path) + g_dbus_object_manager_server_unexport (this->impl->server_manager, this->object_path); +} + +static void * +object_new (size_t size, + PinosProtocolDBusImpl *impl, + void *object, + void *iface, + PinosObjectSkeleton *skel, + bool export, + PinosDestroy destroy) +{ + PinosProtocolDBusObject *this; + + this = calloc (1, size); + this->impl = impl; + this->object = object; + this->iface = iface; + this->skel = skel; + this->destroy = destroy; + + spa_list_insert (impl->object_list.prev, &this->link); + + if (export) + object_export (this); + + return this; +} + +static void +object_destroy (PinosProtocolDBusObject *this) +{ + spa_list_remove (&this->link); + + if (this->destroy) + this->destroy (this); + + object_unexport (this); + g_clear_object (&this->iface); + g_clear_object (&this->skel); + free (this); +} + +static PinosProtocolDBusObject * +find_object (PinosProtocolDBusImpl *impl, + void *object) +{ + PinosProtocolDBusObject *obj; + spa_list_for_each (obj, &impl->object_list, link) { + if (obj->object == object) + return obj; + } + return NULL; +} + +static void +client_name_appeared_handler (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + PinosProtocolDBusClient *this = user_data; + pinos_log_debug ("client %p: appeared %s %s", this, name, name_owner); + object_export (&this->parent); +} + +static void +client_destroy (PinosProtocolDBusClient *this) +{ + spa_list_remove (&this->link); + free (this->sender); +} + +static void +client_name_vanished_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + PinosProtocolDBusClient *this = user_data; + pinos_log_debug ("client %p: vanished %s", this, name); + g_bus_unwatch_name (this->id); + /* destroying the client here will trigger the global_removed, which + * will then destroy our wrapper */ + pinos_client_destroy (this->parent.object); +} + + +static PinosProtocolDBusClient * +client_new (PinosProtocolDBusImpl *impl, + const char *sender) +{ + PinosProtocolDBus *proto = &impl->this; + PinosProtocolDBusClient *this; + PinosClient *client; + PinosObjectSkeleton *skel; + PinosClient1 *iface; + + client = pinos_client_new (proto->core, NULL); + iface = pinos_client1_skeleton_new (); + skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_CLIENT); + pinos_object_skeleton_set_client1 (skel, iface); + + this = object_new (sizeof (PinosProtocolDBusClient), + impl, + client, + iface, + skel, + false, + (PinosDestroy) client_destroy); + this->sender = strdup (sender); + this->id = g_bus_watch_name_on_connection (impl->connection, + this->sender, + G_BUS_NAME_WATCHER_FLAGS_NONE, + client_name_appeared_handler, + client_name_vanished_handler, + this, + NULL); + + spa_list_insert (impl->client_list.prev, &this->link); + + return this; +} + +static PinosClient * +sender_get_client (PinosProtocolDBus *proto, + const char *sender, + bool create) +{ + PinosProtocolDBusImpl *impl = SPA_CONTAINER_OF (proto, PinosProtocolDBusImpl, this); + PinosProtocolDBusClient *client; + + spa_list_for_each (client, &impl->client_list, link) { + if (strcmp (client->sender, sender) == 0) + return client->parent.object; + } + if (!create) + return NULL; + + client = client_new (impl, sender); + + return client->parent.object; +} + +static PinosNodeFactory * +find_factory_by_name (PinosProtocolDBus *proto, + const char *name) +{ + PinosNodeFactory *factory; + + spa_list_for_each (factory, &proto->core->node_factory_list, link) { + if (strcmp (factory->name, name) == 0) + return factory; + } + return NULL; +} + +static bool +handle_create_node (PinosDaemon1 *interface, + GDBusMethodInvocation *invocation, + const char *arg_factory_name, + const char *arg_name, + GVariant *arg_properties, + gpointer user_data) +{ + PinosProtocolDBusImpl *impl = user_data; + PinosProtocolDBus *this = &impl->this; + PinosNodeFactory *factory; + PinosNode *node; + PinosClient *client; + const char *sender, *object_path; + PinosProperties *props; + PinosProtocolDBusObject *object; + + sender = g_dbus_method_invocation_get_sender (invocation); + client = sender_get_client (this, sender, TRUE); + + pinos_log_debug ("protocol-dbus %p: create node: %s", impl, sender); + + props = pinos_properties_from_variant (arg_properties); + + factory = find_factory_by_name (this, arg_factory_name); + if (factory == NULL) + goto no_factory; + + node = pinos_node_factory_create_node (factory, + client, + arg_name, + props); + pinos_properties_free (props); + + if (node == NULL) + goto no_node; + + object = find_object (impl, node); + if (object == NULL) + goto object_failed; + + pinos_client_add_resource (client, + this->core->registry.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); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(o)", object_path)); + return TRUE; + + /* ERRORS */ +no_factory: + { + pinos_log_debug ("protocol-dbus %p: could not find factory named %s", impl, arg_factory_name); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.pinos.Error", "can't find factory"); + return TRUE; + } +no_node: + { + pinos_log_debug ("protocol-dbus %p: could not create node named %s from factory %s", impl, arg_name, arg_factory_name); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.pinos.Error", "can't create node"); + return TRUE; + } +object_failed: + { + pinos_log_debug ("protocol-dbus %p: could not create dbus object", impl); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.pinos.Error", "can't create object"); + return TRUE; + } +} + +static void +on_node_state_changed (PinosListener *listener, + PinosNode *node, + PinosNodeState old, + PinosNodeState state) +{ + PinosProtocolDBusImpl *impl = SPA_CONTAINER_OF (listener, PinosProtocolDBusImpl, node_state_changed); + PinosProtocolDBusObject *object; + + pinos_log_debug ("protocol-dbus %p: node %p state change %s -> %s", impl, node, + pinos_node_state_as_string (old), + pinos_node_state_as_string (state)); + + if ((object = find_object (impl, node))) { + pinos_node1_set_state (object->iface, node->state); + } +} + +static bool +handle_create_client_node (PinosDaemon1 *interface, + GDBusMethodInvocation *invocation, + const char *arg_name, + GVariant *arg_properties, + gpointer user_data) +{ + PinosProtocolDBusImpl *impl = user_data; + PinosProtocolDBus *this = &impl->this; + PinosClientNode *node; + PinosClient *client; + SpaResult res; + const char *sender, *object_path; + PinosProperties *props; + GError *error = NULL; + GUnixFDList *fdlist; + int ctrl_fd, data_fd; + int ctrl_idx, data_idx; + PinosProtocolDBusObject *object; + + sender = g_dbus_method_invocation_get_sender (invocation); + client = sender_get_client (this, sender, TRUE); + + pinos_log_debug ("protocol-dbus %p: create client-node: %s", impl, sender); + props = pinos_properties_from_variant (arg_properties); + + node = pinos_client_node_new (this->core, + arg_name, + props); + + object = find_object (impl, node->node); + 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, + this->core->registry.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); + + fdlist = g_unix_fd_list_new (); + ctrl_idx = g_unix_fd_list_append (fdlist, ctrl_fd, &error); + data_idx = g_unix_fd_list_append (fdlist, data_fd, &error); + + g_dbus_method_invocation_return_value_with_unix_fd_list (invocation, + g_variant_new ("(ohh)", object_path, ctrl_idx, data_idx), fdlist); + g_object_unref (fdlist); + + return TRUE; + +object_failed: + { + pinos_log_debug ("protocol-dbus %p: could not create object", impl); + goto exit_error; + } +no_socket: + { + pinos_log_debug ("protocol-dbus %p: could not create socket: %s", impl, strerror (errno)); + pinos_client_node_destroy (node); + goto exit_error; + } +exit_error: + { + g_dbus_method_invocation_return_gerror (invocation, error); + g_clear_error (&error); + return TRUE; + } +} + +static void +bus_acquired_handler (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + PinosProtocolDBusImpl *impl = user_data; + GDBusObjectManagerServer *manager = impl->server_manager; + + impl->connection = connection; + g_dbus_object_manager_server_set_connection (manager, connection); +} + +static void +name_acquired_handler (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ +} + +static void +name_lost_handler (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + PinosProtocolDBusImpl *impl = user_data; + GDBusObjectManagerServer *manager = impl->server_manager; + + g_dbus_object_manager_server_set_connection (manager, connection); + impl->connection = connection; +} + +static bool +handle_node_remove (PinosNode1 *interface, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + PinosNode *this = user_data; + + pinos_log_debug ("node %p: remove", this); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("()")); + return true; +} + +static void +on_global_added (PinosListener *listener, + PinosCore *core, + PinosGlobal *global) +{ + PinosProtocolDBusImpl *impl = SPA_CONTAINER_OF (listener, PinosProtocolDBusImpl, global_added); + PinosProtocolDBus *this = &impl->this; + PinosObjectSkeleton *skel; + + if (global->type == this->core->registry.uri.node) { + PinosNode1 *iface; + PinosNode *node = global->object; + PinosProperties *props = node->properties; + + skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_NODE); + + iface = pinos_node1_skeleton_new (); + g_signal_connect (iface, "handle-remove", + (GCallback) handle_node_remove, + node); + pinos_node1_set_state (iface, node->state); + pinos_node1_set_owner (iface, "/"); + pinos_node1_set_name (iface, node->name); + pinos_node1_set_properties (iface, props ? pinos_properties_to_variant (props) : NULL); + pinos_object_skeleton_set_node1 (skel, iface); + + object_new (sizeof (PinosProtocolDBusNode), + impl, + node, + iface, + skel, + true, + NULL); + } + else if (global->type == impl->uri.protocol_dbus) { + PinosProtocolDBus *proto = global->object; + PinosProtocolDBusServer *server; + PinosDaemon1 *iface; + + iface = pinos_daemon1_skeleton_new (); + g_signal_connect (iface, "handle-create-node", (GCallback) handle_create_node, proto); + g_signal_connect (iface, "handle-create-client-node", (GCallback) handle_create_client_node, proto); + + skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_SERVER); + + pinos_daemon1_set_user_name (iface, g_get_user_name ()); + pinos_daemon1_set_host_name (iface, g_get_host_name ()); + pinos_daemon1_set_version (iface, PACKAGE_VERSION); + pinos_daemon1_set_name (iface, PACKAGE_NAME); + pinos_daemon1_set_cookie (iface, g_random_int()); + pinos_daemon1_set_properties (iface, proto->properties ? + pinos_properties_to_variant (proto->properties): + NULL); + pinos_object_skeleton_set_daemon1 (skel, iface); + + server = object_new (sizeof (PinosProtocolDBusServer), + impl, + proto, + iface, + skel, + true, + NULL); + server->id = g_bus_own_name (G_BUS_TYPE_SESSION, + PINOS_DBUS_SERVICE, + G_BUS_NAME_OWNER_FLAGS_REPLACE, + bus_acquired_handler, + name_acquired_handler, + name_lost_handler, + proto, + NULL); + } else if (global->type == this->core->registry.uri.link) { + PinosLink1 *iface; + PinosLink *link = global->object; + PinosProtocolDBusObject *obj; + + skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_LINK); + + iface = pinos_link1_skeleton_new (); + + obj = link->output ? find_object (impl, link->output->node) : NULL; + if (obj) { + pinos_link1_set_output_node (iface, obj->object_path); + pinos_link1_set_output_port (iface, link->output->port_id); + } else { + pinos_link1_set_output_node (iface, "/"); + pinos_link1_set_output_port (iface, SPA_ID_INVALID); + } + obj = link->input ? find_object (impl, link->input->node) : NULL; + if (obj) { + pinos_link1_set_input_node (iface, obj->object_path); + pinos_link1_set_input_port (iface, link->input->port_id); + } else { + pinos_link1_set_output_node (iface, "/"); + pinos_link1_set_output_port (iface, SPA_ID_INVALID); + } + pinos_object_skeleton_set_link1 (skel, iface); + + object_new (sizeof (PinosProtocolDBusObject), + impl, + link, + iface, + skel, + true, + NULL); + } +} + +static void +on_global_removed (PinosListener *listener, + PinosCore *core, + PinosGlobal *global) +{ + PinosProtocolDBusImpl *impl = SPA_CONTAINER_OF (listener, PinosProtocolDBusImpl, global_removed); + PinosProtocolDBusObject *object; + + if ((object = find_object (impl, global->object))) + object_destroy (object); +} + +static PinosProtocolDBus * +pinos_protocol_dbus_new (PinosCore *core, + PinosProperties *properties) +{ + PinosProtocolDBusImpl *impl; + PinosProtocolDBus *this; + + impl = calloc (1, sizeof (PinosProtocolDBusImpl)); + this = &impl->this; + pinos_log_debug ("protocol-dbus %p: new", impl); + + this->core = core; + this->properties = properties; + + spa_list_init (&impl->client_list); + spa_list_init (&impl->object_list); + + pinos_signal_init (&this->destroy_signal); + + pinos_signal_add (&core->global_added, &impl->global_added, on_global_added); + pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed); + pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed); + + impl->server_manager = g_dbus_object_manager_server_new (PINOS_DBUS_OBJECT_PREFIX); + + impl->uri.protocol_dbus = spa_id_map_get_id (core->registry.map, PINOS_PROTOCOL_DBUS_URI); + + this->global = pinos_core_add_global (core, + impl->uri.protocol_dbus, + this); + return this; +} + +#if 0 +static void +pinos_protocol_dbus_destroy (PinosProtocolDBus *proto) +{ + PinosProtocolDBusImpl *impl = SPA_CONTAINER_OF (proto, PinosProtocolDBusImpl, this); + PinosProtocolDBusObject *object, *tmp; + + pinos_log_debug ("protocol-dbus %p: destroy", impl); + + pinos_signal_emit (&proto->destroy_signal, proto); + + pinos_global_destroy (proto->global); + + spa_list_for_each_safe (object, tmp, &impl->object_list, link) + object_destroy (object); + +#if 0 + if (impl->id != 0) + g_bus_unown_name (impl->id); +#endif + + pinos_signal_remove (&impl->global_added); + pinos_signal_remove (&impl->global_removed); + pinos_signal_remove (&impl->node_state_changed); + + g_clear_object (&impl->server_manager); + + free (impl); +} +#endif + +G_MODULE_EXPORT bool +pinos__module_init (PinosModule * module, const char * args) +{ + pinos_protocol_dbus_new (module->core, NULL); + return TRUE; +} diff --git a/pinos/modules/spa/meson.build b/pinos/modules/spa/meson.build index 8521dd702..009242bdf 100644 --- a/pinos/modules/spa/meson.build +++ b/pinos/modules/spa/meson.build @@ -14,7 +14,6 @@ pinos_module_spa_c_args = [ '-D_GNU_SOURCE', ] - pinos_module_spa = shared_library('pinos-module-spa', pinos_module_spa_sources, c_args : pinos_module_spa_c_args, include_directories : [configinc, pinosinc, spa_inc], diff --git a/pinos/modules/spa/module.c b/pinos/modules/spa/module.c index 37717be6a..fd7dc344c 100644 --- a/pinos/modules/spa/module.c +++ b/pinos/modules/spa/module.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301, USA. */ -#include +#include #include #include "spa-monitor.h" diff --git a/pinos/server/client-node.c b/pinos/server/client-node.c index d24698842..828d7e577 100644 --- a/pinos/server/client-node.c +++ b/pinos/server/client-node.c @@ -35,7 +35,7 @@ #include "pinos/client/serialize.h" #include "pinos/client/transport.h" -#include "pinos/server/daemon.h" +#include "pinos/server/core.h" #include "pinos/server/client-node.h" #include "spa/include/spa/node.h" diff --git a/pinos/server/client.c b/pinos/server/client.c index 3ac2d2a57..d4c70d266 100644 --- a/pinos/server/client.c +++ b/pinos/server/client.c @@ -27,64 +27,8 @@ typedef struct { PinosClient this; - - guint id; - PinosClient1 *iface; - } PinosClientImpl; -static void -client_name_appeared_handler (GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data) -{ - PinosClientImpl *impl = user_data; - PinosClient *this = &impl->this; - PinosObjectSkeleton *skel; - - pinos_log_debug ("client %p: appeared %s %s", this, name, name_owner); - - skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_CLIENT); - pinos_object_skeleton_set_client1 (skel, impl->iface); - - this->global = pinos_core_add_global (this->core, - this->core->registry.uri.client, - this, - skel); -} - -static void -client_name_vanished_handler (GDBusConnection *connection, - const gchar *name, - gpointer user_data) -{ - PinosClientImpl *impl = user_data; - PinosClient *this = &impl->this; - - pinos_log_debug ("client %p: vanished %s", this, name); - - pinos_core_remove_global (this->core, - this->global); - this->global = NULL; - - g_bus_unwatch_name (impl->id); -} - -static void -client_watch_name (PinosClient *this) -{ - PinosClientImpl *impl = SPA_CONTAINER_OF (this, PinosClientImpl, this); - - impl->id = g_bus_watch_name_on_connection (this->core->connection, - this->sender, - G_BUS_NAME_WATCHER_FLAGS_NONE, - client_name_appeared_handler, - client_name_vanished_handler, - impl, - (GDestroyNotify) pinos_client_destroy); -} - PinosResource * pinos_client_add_resource (PinosClient *client, uint32_t type, @@ -95,6 +39,7 @@ pinos_client_add_resource (PinosClient *client, resource = calloc (1, sizeof (PinosResource)); resource->core = client->core; + resource->client = client; resource->id = 0; resource->type = type; resource->object = object; @@ -109,11 +54,10 @@ pinos_client_add_resource (PinosClient *client, return resource; } -void -pinos_client_remove_resource (PinosClient *client, - PinosResource *resource) +SpaResult +pinos_resource_destroy (PinosResource *resource) { - pinos_log_debug ("client %p: resource %p destroy", client, resource); + pinos_log_debug ("resource %p: destroy", resource); pinos_signal_emit (&resource->destroy_signal, resource); spa_list_remove (&resource->link); @@ -122,29 +66,21 @@ pinos_client_remove_resource (PinosClient *client, resource->destroy (resource->object); free (resource); -} -bool -pinos_client_has_resource (PinosClient *client, - PinosResource *resource) -{ - return false; + return SPA_RESULT_OK; } /** * pinos_client_new: * @daemon: a #PinosDaemon - * @sender: the sender id - * @prefix: a prefix * @properties: extra client properties * - * Make a new #PinosClient object and register it to @daemon under the @prefix. + * Make a new #PinosClient object and register it to @core * * Returns: a new #PinosClient */ PinosClient * pinos_client_new (PinosCore *core, - const gchar *sender, PinosProperties *properties) { PinosClient *this; @@ -155,18 +91,17 @@ pinos_client_new (PinosCore *core, this = &impl->this; this->core = core; - this->sender = strdup (sender); this->properties = properties; spa_list_init (&this->resource_list); pinos_signal_init (&this->destroy_signal); - impl->iface = pinos_client1_skeleton_new (); - - client_watch_name (this); - spa_list_insert (core->client_list.prev, &this->link); + this->global = pinos_core_add_global (core, + core->registry.uri.client, + this); + return this; } @@ -185,16 +120,16 @@ pinos_client_destroy (PinosClient * client) pinos_log_debug ("client %p: destroy", client); pinos_signal_emit (&client->destroy_signal, client); + pinos_global_destroy (client->global); + spa_list_for_each_safe (resource, tmp, &client->resource_list, link) - pinos_client_remove_resource (client, resource); + pinos_resource_destroy (resource); spa_list_remove (&client->link); - free (client->sender); if (client->properties) pinos_properties_free (client->properties); - g_clear_object (&impl->iface); free (impl); return SPA_RESULT_OK; diff --git a/pinos/server/client.h b/pinos/server/client.h index d45965d79..de0e78b99 100644 --- a/pinos/server/client.h +++ b/pinos/server/client.h @@ -32,12 +32,14 @@ typedef struct _PinosResource PinosResource; typedef void (*PinosDestroy) (void *object); -#include -#include +#include struct _PinosResource { PinosCore *core; SpaList link; + + PinosClient *client; + uint32_t id; uint32_t type; void *object; @@ -57,7 +59,6 @@ struct _PinosClient { SpaList link; PinosGlobal *global; - char *sender; PinosProperties *properties; SpaList resource_list; @@ -67,7 +68,6 @@ struct _PinosClient { }; PinosClient * pinos_client_new (PinosCore *core, - const gchar *sender, PinosProperties *properties); SpaResult pinos_client_destroy (PinosClient *client); @@ -77,10 +77,7 @@ PinosResource * pinos_client_add_resource (PinosClient *client, void *object, PinosDestroy destroy); -void pinos_client_remove_resource (PinosClient *client, - PinosResource *resource); -bool pinos_client_has_resource (PinosClient *client, - PinosResource *resource); +SpaResult pinos_resource_destroy (PinosResource *resource); #ifdef __cplusplus } diff --git a/pinos/server/command.h b/pinos/server/command.h index 2be80b359..ac502b04d 100644 --- a/pinos/server/command.h +++ b/pinos/server/command.h @@ -25,7 +25,7 @@ extern "C" { #endif -#include +#include typedef struct _PinosCommand PinosCommand; diff --git a/pinos/server/core.c b/pinos/server/core.c index 39c3f9dbe..d66f389d0 100644 --- a/pinos/server/core.c +++ b/pinos/server/core.c @@ -17,13 +17,14 @@ * Boston, MA 02110-1301, USA. */ +#include #include #include typedef struct { PinosCore this; - GDBusObjectManagerServer *server_manager; + uint32_t counter; SpaSupport support[4]; @@ -87,17 +88,16 @@ pinos_core_destroy (PinosCore *core) PinosGlobal * pinos_core_add_global (PinosCore *core, uint32_t type, - void *object, - PinosObjectSkeleton *skel) + void *object) { + PinosCoreImpl *impl = SPA_CONTAINER_OF (core, PinosCoreImpl, this); PinosGlobal *global; global = calloc (1, sizeof (PinosGlobal)); global->core = core; - global->id = 0; + global->id = ++impl->counter; global->type = type; global->object = object; - global->skel = skel; pinos_signal_init (&global->destroy_signal); @@ -107,16 +107,53 @@ pinos_core_add_global (PinosCore *core, return global; } -void -pinos_core_remove_global (PinosCore *core, - PinosGlobal *global) +SpaResult +pinos_global_destroy (PinosGlobal *global) { + PinosCore *core = global->core; + pinos_signal_emit (&global->destroy_signal, global); spa_list_remove (&global->link); pinos_signal_emit (&core->global_removed, core, global); - g_clear_object (&global->skel); - free (global); + + return SPA_RESULT_OK; +} + +PinosPort * +pinos_core_find_port (PinosCore *core, + PinosPort *other_port, + uint32_t id, + PinosProperties *props, + SpaFormat **format_filters, + char **error) +{ + PinosPort *best = NULL; + bool have_id; + PinosNode *n; + + have_id = id != SPA_ID_INVALID; + + pinos_log_debug ("id \"%u\", %d", id, have_id); + + spa_list_for_each (n, &core->node_list, link) { + pinos_log_debug ("node id \"%d\"", n->global->id); + + if (have_id) { + if (n->global->id == id) { + pinos_log_debug ("id \"%u\" matches node %p", id, n); + + best = pinos_node_get_free_port (n, pinos_direction_reverse (other_port->direction)); + if (best) + break; + } + } else { + } + } + if (best == NULL) { + asprintf (error, "No matching Node found"); + } + return best; } diff --git a/pinos/server/core.h b/pinos/server/core.h index 507253b14..5b3d5ed0a 100644 --- a/pinos/server/core.h +++ b/pinos/server/core.h @@ -27,8 +27,6 @@ extern "C" { typedef struct _PinosCore PinosCore; typedef struct _PinosGlobal PinosGlobal; -#include - #include #include #include @@ -36,8 +34,6 @@ typedef struct _PinosGlobal PinosGlobal; #include #include -#include "pinos/dbus/org-pinos.h" - struct _PinosGlobal { PinosCore *core; SpaList link; @@ -47,9 +43,6 @@ struct _PinosGlobal { PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PinosGlobal *global)); - - PinosObjectSkeleton *skel; - const char *object_path; }; /** @@ -60,8 +53,6 @@ struct _PinosGlobal { struct _PinosCore { PinosRegistry registry; - GDBusConnection *connection; - SpaList global_list; SpaList client_list; SpaList node_list; @@ -111,10 +102,16 @@ void pinos_core_destroy (PinosCore *core); PinosGlobal * pinos_core_add_global (PinosCore *core, uint32_t type, - void *object, - PinosObjectSkeleton *skel); -void pinos_core_remove_global (PinosCore *core, - PinosGlobal *global); + void *object); +SpaResult pinos_global_destroy (PinosGlobal *global); + + +PinosPort * pinos_core_find_port (PinosCore *core, + PinosPort *other_port, + uint32_t id, + PinosProperties *props, + SpaFormat **format_filter, + char **error); #ifdef __cplusplus } diff --git a/pinos/server/daemon.c b/pinos/server/daemon.c deleted file mode 100644 index fa0293c6c..000000000 --- a/pinos/server/daemon.c +++ /dev/null @@ -1,660 +0,0 @@ -/* Pinos - * Copyright (C) 2015 Wim Taymans - * - * 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 -#include -#include - -#include -#include - -#include "config.h" - -#include "pinos/client/pinos.h" -#include "pinos/client/log.h" - -#include "pinos/server/daemon.h" -#include "pinos/server/node.h" -#include "pinos/server/client-node.h" -#include "pinos/server/client.h" -#include "pinos/server/link.h" -#include "pinos/server/node-factory.h" -#include "pinos/server/data-loop.h" -#include "pinos/server/main-loop.h" - -#include "pinos/dbus/org-pinos.h" - -typedef struct { - PinosDaemon this; - - GDBusObjectManagerServer *server_manager; - - PinosDaemon1 *iface; - guint id; - - PinosListener global_added; - PinosListener global_removed; - PinosListener port_added; - PinosListener port_removed; - PinosListener port_unlinked; - PinosListener node_state_changed; - PinosListener link_state_changed; -} PinosDaemonImpl; - -static void try_link_port (PinosNode *node, PinosPort *port, PinosDaemon *daemon); - -static PinosClient * -sender_get_client (PinosDaemon *daemon, - const char *sender, - bool create) -{ - PinosClient *client; - - spa_list_for_each (client, &daemon->core->client_list, link) { - if (strcmp (client->sender, sender) == 0) - return client; - } - client = pinos_client_new (daemon->core, sender, NULL); - return client; -} - -static PinosNodeFactory * -find_factory_by_name (PinosDaemon *daemon, - const char *name) -{ - PinosNodeFactory *factory; - - spa_list_for_each (factory, &daemon->core->node_factory_list, link) { - if (strcmp (factory->name, name) == 0) - return factory; - } - return NULL; -} - -static bool -handle_create_node (PinosDaemon1 *interface, - GDBusMethodInvocation *invocation, - const char *arg_factory_name, - const char *arg_name, - GVariant *arg_properties, - gpointer user_data) -{ - PinosDaemonImpl *impl = user_data; - PinosDaemon *this = &impl->this; - PinosNodeFactory *factory; - PinosNode *node; - PinosClient *client; - const char *sender, *object_path; - PinosProperties *props; - - sender = g_dbus_method_invocation_get_sender (invocation); - client = sender_get_client (this, sender, TRUE); - - pinos_log_debug ("daemon %p: create node: %s", impl, sender); - - props = pinos_properties_from_variant (arg_properties); - - factory = find_factory_by_name (this, arg_factory_name); - if (factory == NULL) - goto no_factory; - - node = pinos_node_factory_create_node (factory, - client, - arg_name, - props); - pinos_properties_free (props); - - if (node == NULL) - goto no_node; - - //pinos_client_add_object (client, &node->object); - - object_path = node->global->object_path; - pinos_log_debug ("daemon %p: added node %p with path %s", impl, node, object_path); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(o)", object_path)); - return TRUE; - - /* ERRORS */ -no_factory: - { - pinos_log_debug ("daemon %p: could find factory named %s", impl, arg_factory_name); - g_dbus_method_invocation_return_dbus_error (invocation, - "org.pinos.Error", "can't find factory"); - return TRUE; - } -no_node: - { - pinos_log_debug ("daemon %p: could create node named %s from factory %s", impl, arg_name, arg_factory_name); - g_dbus_method_invocation_return_dbus_error (invocation, - "org.pinos.Error", "can't create node"); - return TRUE; - } -} - - -static void -on_link_port_unlinked (PinosListener *listener, - PinosLink *link, - PinosPort *port) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (listener, PinosDaemonImpl, port_unlinked); - - pinos_log_debug ("daemon %p: link %p: port %p unlinked", impl, link, port); - - if (port->direction == PINOS_DIRECTION_OUTPUT && link->input) - try_link_port (link->input->node, link->input, &impl->this); -} - -static void -on_link_state_changed (PinosListener *listener, - PinosLink *link) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (listener, PinosDaemonImpl, link_state_changed); - PinosLinkState state; - - state = link->state; - switch (state) { - case PINOS_LINK_STATE_ERROR: - { - pinos_log_debug ("daemon %p: link %p: state error: %s", impl, link, link->error); - - if (link->input && link->input->node) - pinos_node_report_error (link->input->node, strdup (link->error)); - if (link->output && link->output->node) - pinos_node_report_error (link->output->node, strdup (link->error)); - break; - } - - case PINOS_LINK_STATE_UNLINKED: - pinos_log_debug ("daemon %p: link %p: unlinked", impl, link); - -#if 0 - g_set_error (&error, - PINOS_ERROR, - PINOS_ERROR_NODE_LINK, - "error node unlinked"); - - if (link->input && link->input->node) - pinos_node_report_error (link->input->node, g_error_copy (error)); - if (link->output && link->output->node) - pinos_node_report_error (link->output->node, g_error_copy (error)); -#endif - break; - - case PINOS_LINK_STATE_INIT: - case PINOS_LINK_STATE_NEGOTIATING: - case PINOS_LINK_STATE_ALLOCATING: - case PINOS_LINK_STATE_PAUSED: - case PINOS_LINK_STATE_RUNNING: - break; - } -} - -static void -try_link_port (PinosNode *node, PinosPort *port, PinosDaemon *this) -{ - //PinosDaemonImpl *impl = SPA_CONTAINER_OF (this, PinosDaemonImpl, this); - //PinosClient *client; - PinosProperties *props; - const char *path; - char *error = NULL; - PinosLink *link; - - props = node->properties; - if (props == NULL) - return; - - path = pinos_properties_get (props, "pinos.target.node"); - - if (path) { - PinosPort *target; - - target = pinos_daemon_find_port (this, - port, - path, - NULL, - NULL, - &error); - if (target == NULL) - goto error; - - if (port->direction == PINOS_DIRECTION_OUTPUT) - link = pinos_port_link (port, target, NULL, NULL, &error); - else - link = pinos_port_link (target, port, NULL, NULL, &error); - - if (link == NULL) - goto error; - -#if 0 - client = pinos_node_get_client (node); - if (client) - pinos_client_add_object (client, &link->object); -#endif - - - pinos_link_activate (link); - } - return; - -error: - { - pinos_node_report_error (node, error); - return; - } -} - -static void -on_port_added (PinosListener *listener, - PinosNode *node, - PinosPort *port) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (listener, PinosDaemonImpl, port_added); - - try_link_port (node, port, &impl->this); -} - -static void -on_port_removed (PinosListener *listener, - PinosNode *node, - PinosPort *port) -{ -} - -static void -on_node_created (PinosNode *node, - PinosDaemonImpl *impl) -{ - PinosPort *port; - - spa_list_for_each (port, &node->input_ports, link) - on_port_added (&impl->port_added, node, port); - - spa_list_for_each (port, &node->output_ports, link) - on_port_added (&impl->port_added, node, port); -} - -static void -on_node_state_changed (PinosListener *listener, - PinosNode *node, - PinosNodeState old, - PinosNodeState state) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (listener, PinosDaemonImpl, node_state_changed); - - pinos_log_debug ("daemon %p: node %p state change %s -> %s", impl, node, - pinos_node_state_as_string (old), - pinos_node_state_as_string (state)); - - if (old == PINOS_NODE_STATE_CREATING && state == PINOS_NODE_STATE_SUSPENDED) - on_node_created (node, impl); -} - -static void -on_node_added (PinosDaemon *daemon, PinosNode *node) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (daemon, PinosDaemonImpl, this); - - pinos_log_debug ("daemon %p: node %p added", impl, node); - - pinos_node_set_data_loop (node, daemon->core->data_loop); - - if (node->state > PINOS_NODE_STATE_CREATING) { - on_node_created (node, impl); - } -} - -static void -on_node_removed (PinosDaemon *daemon, PinosNode *node) -{ - pinos_log_debug ("daemon %p: node %p removed", daemon, node); -} - -static bool -handle_create_client_node (PinosDaemon1 *interface, - GDBusMethodInvocation *invocation, - const char *arg_name, - GVariant *arg_properties, - gpointer user_data) -{ - PinosDaemonImpl *impl = user_data; - PinosDaemon *this = &impl->this; - PinosClientNode *node; - PinosClient *client; - SpaResult res; - const char *sender, *object_path; - PinosProperties *props; - GError *error = NULL; - GUnixFDList *fdlist; - int ctrl_fd, data_fd; - int ctrl_idx, data_idx; - - sender = g_dbus_method_invocation_get_sender (invocation); - client = sender_get_client (this, sender, TRUE); - - pinos_log_debug ("daemon %p: create client-node: %s", impl, sender); - props = pinos_properties_from_variant (arg_properties); - - node = pinos_client_node_new (this->core, - arg_name, - props); - - 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, - this->core->registry.uri.client_node, - node, - (PinosDestroy) pinos_client_node_destroy); - - object_path = node->node->global->object_path; - pinos_log_debug ("daemon %p: add client-node %p, %s", impl, node, object_path); - - fdlist = g_unix_fd_list_new (); - ctrl_idx = g_unix_fd_list_append (fdlist, ctrl_fd, &error); - data_idx = g_unix_fd_list_append (fdlist, data_fd, &error); - - g_dbus_method_invocation_return_value_with_unix_fd_list (invocation, - g_variant_new ("(ohh)", object_path, ctrl_idx, data_idx), fdlist); - g_object_unref (fdlist); - - return TRUE; - -no_socket: - { - pinos_log_debug ("daemon %p: could not create socket: %s", impl, strerror (errno)); - pinos_client_node_destroy (node); - goto exit_error; - } -exit_error: - { - g_dbus_method_invocation_return_gerror (invocation, error); - g_clear_error (&error); - return TRUE; - } -} - -#if 0 -static void -export_server_object (PinosDaemon *daemon, - GDBusObjectManagerServer *manager) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (daemon, PinosDaemonImpl, this); - - skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_SERVER); - pinos_object_skeleton_set_daemon1 (skel, impl->iface); - - g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (skel)); - g_free (impl->object_path); - impl->object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (skel))); - g_object_unref (skel); -} -#endif - -static void -bus_acquired_handler (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - PinosDaemonImpl *impl = user_data; - PinosDaemon *this = &impl->this; - GDBusObjectManagerServer *manager = impl->server_manager; - - this->core->connection = connection; - g_dbus_object_manager_server_set_connection (manager, connection); -} - -static void -name_acquired_handler (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ -} - -static void -name_lost_handler (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - PinosDaemonImpl *impl = user_data; - PinosDaemon *this = &impl->this; - GDBusObjectManagerServer *manager = impl->server_manager; - - g_dbus_object_manager_server_set_connection (manager, connection); - this->core->connection = connection; -} - -static SpaResult -daemon_start (PinosDaemon *daemon) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (daemon, PinosDaemonImpl, this); - - g_return_val_if_fail (impl, SPA_RESULT_INVALID_ARGUMENTS); - g_return_val_if_fail (impl->id == 0, SPA_RESULT_INVALID_ARGUMENTS); - - pinos_log_debug ("daemon %p: start", daemon); - - impl->id = g_bus_own_name (G_BUS_TYPE_SESSION, - PINOS_DBUS_SERVICE, - G_BUS_NAME_OWNER_FLAGS_REPLACE, - bus_acquired_handler, - name_acquired_handler, - name_lost_handler, - daemon, - NULL); - - return SPA_RESULT_OK; -} - -static SpaResult -daemon_stop (PinosDaemon *daemon) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (daemon, PinosDaemonImpl, this); - - g_return_val_if_fail (impl, SPA_RESULT_INVALID_ARGUMENTS); - - pinos_log_debug ("daemon %p: stop", daemon); - - if (impl->id != 0) { - g_bus_unown_name (impl->id); - impl->id = 0; - } - return SPA_RESULT_OK; -} - -static void -on_global_added (PinosListener *listener, - PinosCore *core, - PinosGlobal *global) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (listener, PinosDaemonImpl, global_added); - PinosDaemon *this = &impl->this; - - if (global->skel) { - g_dbus_object_manager_server_export_uniquely (impl->server_manager, - G_DBUS_OBJECT_SKELETON (global->skel)); - global->object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (global->skel)); - } - - if (global->type == this->core->registry.uri.node) { - PinosNode *node = global->object; - - on_node_added (this, node); - } -} - -static void -on_global_removed (PinosListener *listener, - PinosCore *core, - PinosGlobal *global) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (listener, PinosDaemonImpl, global_removed); - PinosDaemon *this = &impl->this; - - if (global->object_path) { - g_dbus_object_manager_server_unexport (impl->server_manager, global->object_path); - } - - if (global->type == this->core->registry.uri.node) { - PinosNode *node = global->object; - - on_node_removed (this, node); - } -} - -/** - * pinos_daemon_find_port: - * @daemon: a #PinosDaemon - * @other_port: a port to be compatible with - * @name: a port name - * @props: port properties - * @format_filter: a format filter - * @error: location for an error - * - * Find the best port in @daemon that matches the given parameters. - * - * Returns: a #PinosPort or %NULL when no port could be found. - */ -PinosPort * -pinos_daemon_find_port (PinosDaemon *daemon, - PinosPort *other_port, - const char *name, - PinosProperties *props, - SpaFormat **format_filters, - char **error) -{ - PinosPort *best = NULL; - bool have_name; - PinosNode *n; - - g_return_val_if_fail (daemon, NULL); - - have_name = name ? strlen (name) > 0 : FALSE; - - pinos_log_debug ("name \"%s\", %d", name, have_name); - - spa_list_for_each (n, &daemon->core->node_list, link) { - pinos_log_debug ("node path \"%s\"", n->global->object_path); - - if (have_name) { - if (g_str_has_suffix (n->global->object_path, name)) { - pinos_log_debug ("name \"%s\" matches node %p", name, n); - - best = pinos_node_get_free_port (n, pinos_direction_reverse (other_port->direction)); - if (best) - break; - } - } else { - } - } - if (best == NULL) { - asprintf (error, "No matching Node found"); - } - return best; -} - -/** - * pinos_daemon_new: - * @core: #PinosCore - * @properties: #PinosProperties - * - * Make a new #PinosDaemon object with given @properties - * - * Returns: a new #PinosDaemon - */ -PinosDaemon * -pinos_daemon_new (PinosCore *core, - PinosProperties *properties) -{ - PinosDaemonImpl *impl; - PinosDaemon *this; - PinosObjectSkeleton *skel; - - impl = calloc (1, sizeof (PinosDaemonImpl)); - this = &impl->this; - pinos_log_debug ("daemon %p: new", impl); - - this->core = core; - this->properties = properties; - - this->start = daemon_start; - this->stop = daemon_stop; - - pinos_signal_init (&this->destroy_signal); - - pinos_signal_add (&core->global_added, &impl->global_added, on_global_added); - pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed); - pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed); - pinos_signal_add (&core->port_added, &impl->port_added, on_port_added); - pinos_signal_add (&core->port_removed, &impl->port_removed, on_port_removed); - 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->server_manager = g_dbus_object_manager_server_new (PINOS_DBUS_OBJECT_PREFIX); - - impl->iface = pinos_daemon1_skeleton_new (); - g_signal_connect (impl->iface, "handle-create-node", (GCallback) handle_create_node, impl); - g_signal_connect (impl->iface, "handle-create-client-node", (GCallback) handle_create_client_node, impl); - - skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_SERVER); - pinos_object_skeleton_set_daemon1 (skel, impl->iface); - - pinos_daemon1_set_user_name (impl->iface, g_get_user_name ()); - pinos_daemon1_set_host_name (impl->iface, g_get_host_name ()); - pinos_daemon1_set_version (impl->iface, PACKAGE_VERSION); - pinos_daemon1_set_name (impl->iface, PACKAGE_NAME); - pinos_daemon1_set_cookie (impl->iface, g_random_int()); - pinos_daemon1_set_properties (impl->iface, pinos_properties_to_variant (this->properties)); - - this->global = pinos_core_add_global (core, - core->registry.uri.daemon, - this, - skel); - - return this; -} - -void -pinos_daemon_destroy (PinosDaemon *daemon) -{ - PinosDaemonImpl *impl = SPA_CONTAINER_OF (daemon, PinosDaemonImpl, this); - - pinos_log_debug ("daemon %p: destroy", impl); - - pinos_signal_emit (&daemon->destroy_signal, daemon); - - pinos_daemon_stop (daemon); - - pinos_signal_remove (&impl->global_added); - pinos_signal_remove (&impl->global_removed); - pinos_signal_remove (&impl->node_state_changed); - pinos_signal_remove (&impl->port_added); - pinos_signal_remove (&impl->port_removed); - pinos_signal_remove (&impl->port_unlinked); - pinos_signal_remove (&impl->link_state_changed); - - g_clear_object (&impl->server_manager); - g_clear_object (&impl->iface); - - free (impl); -} diff --git a/pinos/server/daemon.h b/pinos/server/daemon.h deleted file mode 100644 index 193ef1b64..000000000 --- a/pinos/server/daemon.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Pinos - * Copyright (C) 2015 Wim Taymans - * - * 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_DAEMON_H__ -#define __PINOS_DAEMON_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define PINOS_DAEMON_URI "http://pinos.org/ns/daemon" -#define PINOS_DAEMON_PREFIX PINOS_DAEMON_URI "#" - -typedef struct _PinosDaemon PinosDaemon; - -#include -#include -#include -#include - -/** - * PinosDaemon: - * - * Pinos daemon object class. - */ -struct _PinosDaemon { - PinosCore *core; - SpaList link; - PinosGlobal *global; - - PinosProperties *properties; - - PINOS_SIGNAL (destroy_signal, (PinosListener *listener, - PinosDaemon *daemon)); - - SpaResult (*start) (PinosDaemon *daemon); - SpaResult (*stop) (PinosDaemon *daemon); -}; - -PinosDaemon * pinos_daemon_new (PinosCore *core, - PinosProperties *properties); -void pinos_daemon_destroy (PinosDaemon *daemon); - - -#define pinos_daemon_start(d) (d)->start(d) -#define pinos_daemon_stop(d) (d)->stop(d) - -PinosPort * pinos_daemon_find_port (PinosDaemon *daemon, - PinosPort *other_port, - const char *name, - PinosProperties *props, - SpaFormat **format_filter, - char **error); - -#ifdef __cplusplus -} -#endif - -#endif /* __PINOS_DAEMON_H__ */ diff --git a/pinos/server/link.c b/pinos/server/link.c index ee861ec7d..20ee3f229 100644 --- a/pinos/server/link.c +++ b/pinos/server/link.c @@ -19,8 +19,6 @@ #include -#include - #include #include @@ -29,19 +27,12 @@ #include "pinos/server/link.h" -#include "pinos/dbus/org-pinos.h" - -#define PINOS_LINK_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_LINK, PinosLinkPrivate)) - #define MAX_BUFFERS 16 typedef struct { PinosLink this; - PinosLink1 *iface; - uint32_t seq; SpaFormat **format_filter; @@ -589,36 +580,6 @@ on_output_async_complete_notify (PinosListener *listener, pinos_main_loop_defer_complete (this->core->main_loop, impl, seq, res); } -#if 0 -static void -on_property_notify (GObject *obj, - GParamSpec *pspec, - gpointer user_data) -{ - PinosLink *this = user_data; - PinosLinkImpl *impl = (PinosLinkImpl *) this; - - if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "output-port") == 0) { - if (this->output) { - pinos_link1_set_output_node (impl->iface, pinos_node_get_object_path (this->output->node)); - pinos_link1_set_output_port (impl->iface, this->output->port); - } else { - pinos_link1_set_output_node (impl->iface, "/"); - pinos_link1_set_output_port (impl->iface, -1); - } - } - if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "input-port") == 0) { - if (this->input) { - pinos_link1_set_input_node (impl->iface, pinos_node_get_object_path (this->input->node)); - pinos_link1_set_input_port (impl->iface, this->input->port); - } else { - pinos_link1_set_input_node (impl->iface, "/"); - pinos_link1_set_input_port (impl->iface, -1); - } - } -} -#endif - static void on_port_unlinked (PinosPort *port, PinosLink *this, SpaResult res, gulong id) { @@ -712,7 +673,6 @@ pinos_link_new (PinosCore *core, { PinosLinkImpl *impl; PinosLink *this; - PinosObjectSkeleton *skel; impl = calloc (1, sizeof (PinosLinkImpl)); this = &impl->this; @@ -751,14 +711,9 @@ pinos_link_new (PinosCore *core, spa_list_insert (core->link_list.prev, &this->link); - impl->iface = pinos_link1_skeleton_new (); - skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_LINK); - pinos_object_skeleton_set_link1 (skel, impl->iface); - this->global = pinos_core_add_global (core, core->registry.uri.link, - this, - skel); + this); return this; } @@ -812,8 +767,6 @@ do_link_remove_done (SpaPoll *poll, pinos_main_loop_defer_cancel (this->core->main_loop, this, 0); - g_clear_object (&impl->iface); - if (impl->allocated) pinos_memblock_free (&impl->buffer_mem); @@ -866,7 +819,7 @@ pinos_link_destroy (PinosLink * this) pinos_log_debug ("link %p: destroy", impl); pinos_signal_emit (&this->destroy_signal, this); - pinos_core_remove_global (this->core, this->global); + pinos_global_destroy (this->global); spa_list_remove (&this->link); if (this->input) { diff --git a/pinos/server/link.h b/pinos/server/link.h index 2687b613d..2b2c39eaa 100644 --- a/pinos/server/link.h +++ b/pinos/server/link.h @@ -32,9 +32,9 @@ typedef struct _PinosLink PinosLink; #include #include -#include -#include +#include +#include #include /** diff --git a/pinos/server/main-loop.c b/pinos/server/main-loop.c index 8fce203c9..a4b6e04ea 100644 --- a/pinos/server/main-loop.c +++ b/pinos/server/main-loop.c @@ -373,14 +373,13 @@ main_loop_run (PinosMainLoop *loop) /** * pinos_main_loop_new: - * @context: a #GMainContext or %NULL to use the default context * * Create a new #PinosMainLoop. * * Returns: a new #PinosMainLoop */ PinosMainLoop * -pinos_main_loop_new (GMainContext *context) +pinos_main_loop_new (void) { PinosMainLoopImpl *impl; PinosMainLoop *this; @@ -388,7 +387,7 @@ pinos_main_loop_new (GMainContext *context) impl = calloc (1, sizeof (PinosMainLoopImpl)); pinos_log_debug ("main-loop %p: new", impl); - impl->context = context; + impl->context = g_main_context_default (); this = &impl->this; this->run = main_loop_run; this->quit = main_loop_quit; diff --git a/pinos/server/main-loop.h b/pinos/server/main-loop.h index 23210909b..dea6295be 100644 --- a/pinos/server/main-loop.h +++ b/pinos/server/main-loop.h @@ -25,7 +25,6 @@ extern "C" { #endif #include -#include typedef struct _PinosMainLoop PinosMainLoop; @@ -63,7 +62,7 @@ struct _PinosMainLoop { void *data); }; -PinosMainLoop * pinos_main_loop_new (GMainContext *context); +PinosMainLoop * pinos_main_loop_new (void); void pinos_main_loop_destroy (PinosMainLoop *loop); #define pinos_main_loop_run(m) (m)->run(m) diff --git a/pinos/server/meson.build b/pinos/server/meson.build index 73c57fe27..26646bbeb 100644 --- a/pinos/server/meson.build +++ b/pinos/server/meson.build @@ -3,7 +3,6 @@ pinoscore_headers = [ 'client-node.h', 'command.h', 'core.h', - 'daemon.h', 'data-loop.h', 'link.h', 'main-loop.h', @@ -19,7 +18,6 @@ pinoscore_sources = [ 'client-node.c', 'command.c', 'core.c', - 'daemon.c', 'data-loop.c', 'link.c', 'main-loop.c', diff --git a/pinos/server/node.c b/pinos/server/node.c index 80d123ee0..8928b10fd 100644 --- a/pinos/server/node.c +++ b/pinos/server/node.c @@ -27,16 +27,12 @@ #include "pinos/server/node.h" #include "pinos/server/data-loop.h" #include "pinos/server/main-loop.h" -#include "pinos/server/daemon.h" - -#include "pinos/dbus/org-pinos.h" typedef struct { PinosNode this; PinosClient *client; - PinosNode1 *iface; uint32_t seq; @@ -391,37 +387,15 @@ on_node_event (SpaNode *node, SpaNodeEvent *event, void *user_data) } } -static bool -handle_remove (PinosNode1 *interface, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - PinosNode *this = user_data; - - pinos_log_debug ("node %p: remove", this); - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("()")); - return true; -} - static void init_complete (PinosNode *this) { PinosNodeImpl *impl = SPA_CONTAINER_OF (this, PinosNodeImpl, this); - PinosProperties *props = this->properties; update_port_ids (this, false); pinos_log_debug ("node %p: init completed", this); impl->async_init = false; - if (impl->client) - pinos_node1_set_owner (impl->iface, this->global->object_path); - else - pinos_node1_set_owner (impl->iface, "/"); - pinos_node1_set_name (impl->iface, this->name); - pinos_node1_set_properties (impl->iface, props ? pinos_properties_to_variant (props) : NULL); - pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED); } @@ -442,7 +416,6 @@ pinos_node_new (PinosCore *core, { PinosNodeImpl *impl; PinosNode *this; - PinosObjectSkeleton *skel; impl = calloc (1, sizeof (PinosNodeImpl)); this = &impl->this; @@ -454,6 +427,7 @@ pinos_node_new (PinosCore *core, this->node = node; this->clock = clock; + this->data_loop = core->data_loop; if (spa_node_set_event_callback (this->node, on_node_event, this) < 0) pinos_log_warn ("node %p: error setting callback", this); @@ -463,13 +437,7 @@ pinos_node_new (PinosCore *core, pinos_signal_init (&this->transport_changed); pinos_signal_init (&this->loop_changed); - impl->iface = pinos_node1_skeleton_new (); - g_signal_connect (impl->iface, "handle-remove", - (GCallback) handle_remove, - this); - this->state = PINOS_NODE_STATE_CREATING; - pinos_node1_set_state (impl->iface, this->state); spa_list_init (&this->input_ports); spa_list_init (&this->output_ports); @@ -498,13 +466,9 @@ pinos_node_new (PinosCore *core, } spa_list_insert (core->node_list.prev, &this->link); - skel = pinos_object_skeleton_new (PINOS_DBUS_OBJECT_NODE); - pinos_object_skeleton_set_node1 (skel, impl->iface); - this->global = pinos_core_add_global (core, core->registry.uri.node, - this, - skel); + this); return this; } @@ -528,7 +492,6 @@ do_node_remove_done (SpaPoll *poll, spa_list_for_each_safe (port, tmp, &this->output_ports, link) pinos_port_destroy (port); - g_clear_object (&impl->iface); free (this->name); free (this->error); if (this->properties) @@ -594,7 +557,7 @@ pinos_node_destroy (PinosNode * this) pinos_signal_emit (&this->destroy_signal, this); spa_list_remove (&this->link); - pinos_core_remove_global (this->core, this->global); + pinos_global_destroy (this->global); res = spa_poll_invoke (&this->data_loop->poll, do_node_remove, @@ -764,11 +727,8 @@ void pinos_node_update_state (PinosNode *node, PinosNodeState state) { - PinosNodeImpl *impl = SPA_CONTAINER_OF (node, PinosNodeImpl, this); PinosNodeState old; - g_return_if_fail (node); - old = node->state; if (old != state) { pinos_log_debug ("node %p: update state from %s -> %s", node, @@ -776,7 +736,6 @@ pinos_node_update_state (PinosNode *node, pinos_node_state_as_string (state)); node->state = state; - pinos_node1_set_state (impl->iface, state); pinos_signal_emit (&node->core->node_state_changed, node, old, state); } } @@ -792,18 +751,14 @@ void pinos_node_report_error (PinosNode *node, char *error) { - PinosNodeImpl *impl = SPA_CONTAINER_OF (node, PinosNodeImpl, this); PinosNodeState old; - g_return_if_fail (node); - free (node->error); remove_idle_timeout (node); node->error = error; old = node->state; node->state = PINOS_NODE_STATE_ERROR; pinos_log_debug ("node %p: got error state %s", node, error); - pinos_node1_set_state (impl->iface, PINOS_NODE_STATE_ERROR); pinos_signal_emit (&node->core->node_state_changed, node, old, node->state); } diff --git a/pinos/server/node.h b/pinos/server/node.h index 62923540c..4f8672d09 100644 --- a/pinos/server/node.h +++ b/pinos/server/node.h @@ -101,8 +101,6 @@ SpaResult pinos_node_destroy (PinosNode *node); void pinos_node_set_data_loop (PinosNode *node, PinosDataLoop *loop); -PinosClient * pinos_node_get_client (PinosNode *node); - PinosPort * pinos_node_get_free_port (PinosNode *node, PinosDirection direction); diff --git a/pinos/server/registry.c b/pinos/server/registry.c index 76c801284..9699cfaf1 100644 --- a/pinos/server/registry.c +++ b/pinos/server/registry.c @@ -21,7 +21,6 @@ #include "pinos/client/pinos.h" #include "pinos/server/core.h" -#include "pinos/server/daemon.h" #include "pinos/server/registry.h" #include "pinos/server/node.h" #include "pinos/server/node-factory.h" @@ -35,7 +34,6 @@ pinos_registry_init (PinosRegistry *reg) { reg->map = pinos_id_map_get_default(); - reg->uri.daemon = spa_id_map_get_id (reg->map, PINOS_DAEMON_URI); reg->uri.registry = spa_id_map_get_id (reg->map, PINOS_REGISTRY_URI); reg->uri.node = spa_id_map_get_id (reg->map, PINOS_NODE_URI); reg->uri.node_factory = spa_id_map_get_id (reg->map, PINOS_NODE_FACTORY_URI); @@ -49,21 +47,3 @@ pinos_registry_init (PinosRegistry *reg) pinos_map_init (®->objects, 512); } - -PinosObject * -pinos_registry_iterate_objects (PinosRegistry *reg, - uint32_t type, - void **state) -{ - unsigned int idx; - PinosObject *o; - - while (true) { - idx = SPA_PTR_TO_INT (*state); - *state = SPA_INT_TO_PTR (idx+1); - o = pinos_map_lookup (®->objects, idx); - if (o != NULL) - break; - } - return o; -} diff --git a/pinos/server/registry.h b/pinos/server/registry.h index 7efd657e9..14de6f935 100644 --- a/pinos/server/registry.h +++ b/pinos/server/registry.h @@ -29,13 +29,11 @@ extern "C" { #include #include -#include #include typedef struct _PinosRegistry PinosRegistry; typedef struct { - uint32_t daemon; uint32_t registry; uint32_t node; uint32_t node_factory; @@ -61,15 +59,6 @@ struct _PinosRegistry { void pinos_registry_init (PinosRegistry *reg); -PinosObject * pinos_registry_iterate_objects (PinosRegistry *reg, - uint32_t type, - void **state); - -#define pinos_registry_iterate_nodes(reg,state) \ - pinos_registry_iterate_objects(reg, (reg)->uri.node,state) -#define pinos_registry_iterate_node_factoriess(reg,state) \ - pinos_registry_iterate_objects(reg, (reg)->uri.node_factory,state) - #ifdef __cplusplus } #endif diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index 3886058e4..359de198e 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -907,6 +907,9 @@ alsa_source_init (const SpaHandleFactory *factory, this->stream = SND_PCM_STREAM_CAPTURE; reset_alsa_props (&this->props[1]); + spa_list_init (&this->free); + spa_list_init (&this->ready); + for (i = 0; info && i < info->n_items; i++) { if (!strcmp (info->items[i].key, "alsa.card")) { snprintf (this->props[1].device, 63, "hw:%s", info->items[i].value);