mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
Fix proxy ids
The proxy/resource ids are generated by the client and so we need to used them as index in the client resource map instead of making our own number. Fix stream disconnect and client-node destroy Fix gstreamer device provider Make all sockets non-blocking to avoid errors with bad clients Advertise the subsystems we monitor and disable the gstreamer monitors. Implement core properties updates Make sure we send REMOVE_ID after we are done with the resource.
This commit is contained in:
parent
e579efea10
commit
4b55d7c4da
18 changed files with 222 additions and 69 deletions
|
|
@ -195,7 +195,6 @@ typedef struct {
|
|||
/* PINOS_MESSAGE_DESTROY */
|
||||
typedef struct {
|
||||
uint32_t seq;
|
||||
uint32_t id;
|
||||
} PinosMessageDestroy;
|
||||
|
||||
/* PINOS_MESSAGE_NODE_UPDATE */
|
||||
|
|
|
|||
|
|
@ -443,6 +443,7 @@ on_context_data (SpaSource *source,
|
|||
pinos_log_error ("context %p: could not find proxy %u", this, id);
|
||||
continue;
|
||||
}
|
||||
pinos_log_debug ("context %p: object dispatch %u", this, id);
|
||||
|
||||
pinos_proxy_dispatch (proxy, type, p);
|
||||
}
|
||||
|
|
@ -588,7 +589,7 @@ pinos_context_connect (PinosContext *context)
|
|||
if (name == NULL)
|
||||
name = "pinos-0";
|
||||
|
||||
if ((fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
|
||||
if ((fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0)
|
||||
return false;
|
||||
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
|
|
|
|||
|
|
@ -118,6 +118,13 @@ const char * pinos_link_state_as_string (PinosLinkState state);
|
|||
struct _PinosCoreInfo {
|
||||
uint32_t id;
|
||||
uint64_t change_mask;
|
||||
#define PINOS_CORE_CHANGE_MASK_USER_NAME (1 << 0)
|
||||
#define PINOS_CORE_CHANGE_MASK_HOST_NAME (1 << 1)
|
||||
#define PINOS_CORE_CHANGE_MASK_VERSION (1 << 2)
|
||||
#define PINOS_CORE_CHANGE_MASK_NAME (1 << 3)
|
||||
#define PINOS_CORE_CHANGE_MASK_COOKIE (1 << 4)
|
||||
#define PINOS_CORE_CHANGE_MASK_PROPS (1 << 5)
|
||||
#define PINOS_CORE_CHANGE_MASK_ALL (~0)
|
||||
const char *user_name;
|
||||
const char *host_name;
|
||||
const char *version;
|
||||
|
|
|
|||
|
|
@ -302,7 +302,6 @@ loop_iterate (SpaLoopControl *ctrl,
|
|||
SpaSource *source = ep[i].data.ptr;
|
||||
if (source->rmask) {
|
||||
source->func (source);
|
||||
source->rmask = 0;
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -311,8 +310,8 @@ loop_iterate (SpaLoopControl *ctrl,
|
|||
static void
|
||||
source_io_func (SpaSource *source)
|
||||
{
|
||||
SpaSourceImpl *s = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
s->func.io (source, source->fd, source->rmask, source->data);
|
||||
SpaSourceImpl *impl = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
impl->func.io (source, source->fd, source->rmask, source->data);
|
||||
}
|
||||
|
||||
static SpaSource *
|
||||
|
|
@ -357,8 +356,8 @@ loop_update_io (SpaSource *source,
|
|||
static void
|
||||
source_idle_func (SpaSource *source)
|
||||
{
|
||||
SpaSourceImpl *s = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
s->func.idle (source, source->data);
|
||||
SpaSourceImpl *impl = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
impl->func.idle (source, source->data);
|
||||
}
|
||||
|
||||
static SpaSource *
|
||||
|
|
@ -409,13 +408,13 @@ loop_enable_idle (SpaSource *source,
|
|||
static void
|
||||
source_event_func (SpaSource *source)
|
||||
{
|
||||
SpaSourceImpl *s = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
SpaSourceImpl *impl = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
uint64_t count;
|
||||
|
||||
if (read (source->fd, &count, sizeof (uint64_t)) != sizeof (uint64_t))
|
||||
pinos_log_warn ("loop %p: failed to read event fd: %s", source, strerror (errno));
|
||||
|
||||
s->func.event (source, source->data);
|
||||
impl->func.event (source, source->data);
|
||||
}
|
||||
|
||||
static SpaSource *
|
||||
|
|
@ -457,13 +456,13 @@ loop_signal_event (SpaSource *source)
|
|||
static void
|
||||
source_timer_func (SpaSource *source)
|
||||
{
|
||||
SpaSourceImpl *s = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
SpaSourceImpl *impl = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
uint64_t expires;
|
||||
|
||||
if (read (source->fd, &expires, sizeof (uint64_t)) != sizeof (uint64_t))
|
||||
pinos_log_warn ("loop %p: failed to read timer fd: %s", source, strerror (errno));
|
||||
|
||||
s->func.timer (source, source->data);
|
||||
impl->func.timer (source, source->data);
|
||||
}
|
||||
|
||||
static SpaSource *
|
||||
|
|
@ -519,13 +518,13 @@ loop_update_timer (SpaSource *source,
|
|||
static void
|
||||
source_signal_func (SpaSource *source)
|
||||
{
|
||||
SpaSourceImpl *s = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
SpaSourceImpl *impl = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
struct signalfd_siginfo signal_info;
|
||||
|
||||
if (read (source->fd, &signal_info, sizeof (signal_info)) != sizeof (signal_info))
|
||||
pinos_log_warn ("loop %p: failed to read signal fd: %s", source, strerror (errno));
|
||||
|
||||
s->func.signal (source, s->signal_number, source->data);
|
||||
impl->func.signal (source, impl->signal_number, source->data);
|
||||
}
|
||||
|
||||
static SpaSource *
|
||||
|
|
@ -564,15 +563,15 @@ loop_add_signal (SpaLoopUtils *utils,
|
|||
static void
|
||||
loop_destroy_source (SpaSource *source)
|
||||
{
|
||||
SpaSourceImpl *s = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
SpaSourceImpl *impl = SPA_CONTAINER_OF (source, SpaSourceImpl, source);
|
||||
|
||||
spa_list_remove (&s->link);
|
||||
spa_list_remove (&impl->link);
|
||||
|
||||
spa_loop_remove_source (source->loop, source);
|
||||
|
||||
if (source->fd != -1 && s->close)
|
||||
if (source->fd != -1 && impl->close)
|
||||
close (source->fd);
|
||||
free (s);
|
||||
free (impl);
|
||||
}
|
||||
|
||||
PinosLoop *
|
||||
|
|
|
|||
|
|
@ -88,6 +88,25 @@ pinos_map_insert_new (PinosMap *map,
|
|||
return id;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pinos_map_insert_at (PinosMap *map,
|
||||
uint32_t id,
|
||||
void *data)
|
||||
{
|
||||
size_t size = pinos_map_get_size (map);
|
||||
PinosMapItem *item;
|
||||
|
||||
if (id > size)
|
||||
return false;
|
||||
else if (id == size)
|
||||
item = pinos_array_add (&map->items, sizeof (PinosMapItem));
|
||||
else
|
||||
item = pinos_map_get_item (map, id);
|
||||
|
||||
item->data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
pinos_map_remove (PinosMap *map,
|
||||
uint32_t id)
|
||||
|
|
|
|||
|
|
@ -40,16 +40,16 @@ pinos_proxy_new (PinosContext *context,
|
|||
return NULL;
|
||||
|
||||
this = &impl->this;
|
||||
|
||||
this->context = context;
|
||||
this->type = type;
|
||||
|
||||
pinos_signal_init (&this->destroy_signal);
|
||||
|
||||
this->id = pinos_map_insert_new (&context->objects, this);
|
||||
|
||||
spa_list_insert (&this->context->proxy_list, &this->link);
|
||||
|
||||
pinos_log_debug ("proxy %p: new %u", this, this->id);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -58,10 +58,13 @@ pinos_proxy_destroy (PinosProxy *proxy)
|
|||
{
|
||||
PinosProxyImpl *impl = SPA_CONTAINER_OF (proxy, PinosProxyImpl, this);
|
||||
|
||||
pinos_log_debug ("proxy %p: destroy %u", proxy, proxy->id);
|
||||
pinos_signal_emit (&proxy->destroy_signal, proxy);
|
||||
|
||||
pinos_map_remove (&proxy->context->objects, proxy->id);
|
||||
spa_list_remove (&proxy->link);
|
||||
|
||||
pinos_log_debug ("proxy %p: free", proxy);
|
||||
free (impl);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,14 +74,15 @@ typedef struct
|
|||
|
||||
PinosStreamFlags flags;
|
||||
|
||||
bool disconnecting;
|
||||
|
||||
PinosStreamMode mode;
|
||||
|
||||
int rtfd;
|
||||
SpaSource *rtsocket_source;
|
||||
|
||||
PinosProxy *node_proxy;
|
||||
bool disconnecting;
|
||||
PinosListener node_proxy_destroy;
|
||||
|
||||
PinosTransport *trans;
|
||||
|
||||
SpaSource *timeout_source;
|
||||
|
|
@ -845,6 +846,18 @@ stream_dispatch_func (void *object,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
on_node_proxy_destroy (PinosListener *listener,
|
||||
PinosProxy *proxy)
|
||||
{
|
||||
PinosStreamImpl *impl = SPA_CONTAINER_OF (listener, PinosStreamImpl, node_proxy_destroy);
|
||||
PinosStream *this = &impl->this;
|
||||
|
||||
impl->disconnecting = false;
|
||||
impl->node_proxy = NULL;
|
||||
stream_set_state (this, PINOS_STREAM_STATE_UNCONNECTED, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_stream_connect:
|
||||
* @stream: a #PinosStream
|
||||
|
|
@ -897,6 +910,10 @@ pinos_stream_connect (PinosStream *stream,
|
|||
if (impl->node_proxy == NULL)
|
||||
return false;
|
||||
|
||||
pinos_signal_add (&impl->node_proxy->destroy_signal,
|
||||
&impl->node_proxy_destroy,
|
||||
on_node_proxy_destroy);
|
||||
|
||||
pinos_proxy_set_dispatch (impl->node_proxy,
|
||||
stream_dispatch_func,
|
||||
impl);
|
||||
|
|
@ -1002,9 +1019,18 @@ bool
|
|||
pinos_stream_disconnect (PinosStream *stream)
|
||||
{
|
||||
PinosStreamImpl *impl = SPA_CONTAINER_OF (stream, PinosStreamImpl, this);
|
||||
PinosMessageDestroy msg;
|
||||
|
||||
impl->disconnecting = true;
|
||||
|
||||
unhandle_socket (stream);
|
||||
|
||||
msg.seq = ++impl->seq;
|
||||
pinos_proxy_send_message (impl->node_proxy,
|
||||
PINOS_MESSAGE_DESTROY,
|
||||
&msg,
|
||||
true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
loop = pinos_main_loop_new ();
|
||||
core = pinos_core_new (loop);
|
||||
core = pinos_core_new (loop, NULL);
|
||||
|
||||
pinos_daemon_config_run_commands (config, core);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,9 +81,12 @@ gst_pinos_device_create_element (GstDevice * device, const gchar * name)
|
|||
{
|
||||
GstPinosDevice *pinos_dev = GST_PINOS_DEVICE (device);
|
||||
GstElement *elem;
|
||||
gchar *str;
|
||||
|
||||
elem = gst_element_factory_make (pinos_dev->element, name);
|
||||
g_object_set (elem, "path", pinos_dev->id, NULL);
|
||||
str = g_strdup_printf ("%u", pinos_dev->id);
|
||||
g_object_set (elem, "path", str, NULL);
|
||||
g_free (str);
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
|
@ -92,6 +95,7 @@ static gboolean
|
|||
gst_pinos_device_reconfigure_element (GstDevice * device, GstElement * element)
|
||||
{
|
||||
GstPinosDevice *pinos_dev = GST_PINOS_DEVICE (device);
|
||||
gchar *str;
|
||||
|
||||
if (!strcmp (pinos_dev->element, "pinossrc")) {
|
||||
if (!GST_IS_PINOS_SRC (element))
|
||||
|
|
@ -103,7 +107,9 @@ gst_pinos_device_reconfigure_element (GstDevice * device, GstElement * element)
|
|||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_object_set (element, "path", pinos_dev->id, NULL);
|
||||
str = g_strdup_printf ("%u", pinos_dev->id);
|
||||
g_object_set (element, "path", str, NULL);
|
||||
g_free (str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -198,15 +204,16 @@ new_node (const PinosNodeInfo *info)
|
|||
if (info->possible_formats)
|
||||
caps = gst_caps_from_string (g_bytes_get_data (info->possible_formats, NULL));
|
||||
else
|
||||
#endif
|
||||
caps = gst_caps_new_any();
|
||||
#endif
|
||||
caps = gst_caps_from_string ("video/x-raw,width=320,height=240,framerate=15/1");
|
||||
|
||||
props = gst_structure_new_empty ("pinos-proplist");
|
||||
if (info->props) {
|
||||
spa_dict_for_each (item, info->props)
|
||||
gst_structure_set (props, item->key, G_TYPE_STRING, item->value, NULL);
|
||||
|
||||
klass = spa_dict_lookup (info->props, "gstreamer.device.class");
|
||||
klass = spa_dict_lookup (info->props, "media.class");
|
||||
}
|
||||
if (klass == NULL)
|
||||
klass = "unknown/unknown";
|
||||
|
|
@ -318,17 +325,20 @@ get_core_info_cb (PinosContext *c,
|
|||
if (info == NULL || info->props == NULL)
|
||||
return;
|
||||
|
||||
value = spa_dict_lookup (info->props, "gstreamer.deviceproviders");
|
||||
value = spa_dict_lookup (info->props, "monitors");
|
||||
if (value) {
|
||||
gchar **providers = g_strsplit (value, ",", -1);
|
||||
gchar **monitors = g_strsplit (value, ",", -1);
|
||||
gint i;
|
||||
|
||||
GST_DEBUG_OBJECT (provider, "have hidden providers: %s", value);
|
||||
|
||||
for (i = 0; providers[i]; i++) {
|
||||
gst_device_provider_hide_provider (provider, providers[i]);
|
||||
for (i = 0; monitors[i]; i++) {
|
||||
if (strcmp (monitors[i], "v4l2") == 0)
|
||||
gst_device_provider_hide_provider (provider, "v4l2deviceprovider");
|
||||
else if (strcmp (monitors[i], "alsa") == 0)
|
||||
gst_device_provider_hide_provider (provider, "pulsedeviceprovider");
|
||||
}
|
||||
g_strfreev (providers);
|
||||
g_strfreev (monitors);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ add_socket (PinosProtocolNative *impl, Socket *s)
|
|||
{
|
||||
socklen_t size;
|
||||
|
||||
if ((s->fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
|
||||
if ((s->fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0)
|
||||
return false;
|
||||
|
||||
size = offsetof (struct sockaddr_un, sun_path) + strlen (s->addr.sun_path);
|
||||
|
|
|
|||
|
|
@ -116,8 +116,14 @@ pinos__module_init (PinosModule * module, const char * args)
|
|||
pinos_free_strv (tmp_argv);
|
||||
}
|
||||
|
||||
pinos_spa_monitor_load (module->core, "build/spa/plugins/alsa/libspa-alsa.so", "alsa-monitor");
|
||||
pinos_spa_monitor_load (module->core, "build/spa/plugins/v4l2/libspa-v4l2.so", "v4l2-monitor");
|
||||
pinos_spa_monitor_load (module->core,
|
||||
"build/spa/plugins/alsa/libspa-alsa.so",
|
||||
"alsa-monitor",
|
||||
"alsa");
|
||||
pinos_spa_monitor_load (module->core,
|
||||
"build/spa/plugins/v4l2/libspa-v4l2.so",
|
||||
"v4l2-monitor",
|
||||
"v4l2");
|
||||
pinos_spa_node_load (module->core,
|
||||
"build/spa/plugins/audiotestsrc/libspa-audiotestsrc.so",
|
||||
"audiotestsrc",
|
||||
|
|
|
|||
|
|
@ -81,17 +81,19 @@ add_item (PinosSpaMonitor *this, SpaMonitorItem *item)
|
|||
pinos_log_info ("no CLOCK interface: %d", res);
|
||||
}
|
||||
|
||||
props = pinos_properties_new (NULL, NULL);
|
||||
|
||||
if (item->info) {
|
||||
unsigned int i;
|
||||
|
||||
props = pinos_properties_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < item->info->n_items; i++)
|
||||
pinos_properties_set (props,
|
||||
item->info->items[i].key,
|
||||
item->info->items[i].value);
|
||||
}
|
||||
|
||||
pinos_properties_set (props, "media.class", item->klass);
|
||||
|
||||
mitem = calloc (1, sizeof (PinosSpaMonitorItem));
|
||||
mitem->id = strdup (item->id);
|
||||
mitem->node = pinos_node_new (impl->core,
|
||||
|
|
@ -168,10 +170,31 @@ on_monitor_event (SpaMonitor *monitor,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_monitor (PinosCore *core,
|
||||
const char *name)
|
||||
{
|
||||
PinosProperties *props;
|
||||
const char *monitors;
|
||||
|
||||
if (!(props = core->properties))
|
||||
props = pinos_properties_new (NULL, NULL);
|
||||
|
||||
monitors = pinos_properties_get (props, "monitors");
|
||||
|
||||
if (monitors == NULL)
|
||||
pinos_properties_setf (props, "monitors", "%s", name);
|
||||
else
|
||||
pinos_properties_setf (props, "monitors", "%s,%s", monitors, name);
|
||||
|
||||
pinos_core_update_properties (core, &props->dict);
|
||||
}
|
||||
|
||||
PinosSpaMonitor *
|
||||
pinos_spa_monitor_load (PinosCore *core,
|
||||
const char *lib,
|
||||
const char *factory_name)
|
||||
const char *factory_name,
|
||||
const char *system_name)
|
||||
{
|
||||
PinosSpaMonitorImpl *impl;
|
||||
PinosSpaMonitor *this;
|
||||
|
|
@ -226,8 +249,11 @@ pinos_spa_monitor_load (PinosCore *core,
|
|||
this->monitor = iface;
|
||||
this->lib = strdup (lib);
|
||||
this->factory_name = strdup (factory_name);
|
||||
this->system_name = strdup (system_name);
|
||||
this->handle = handle;
|
||||
|
||||
update_monitor (core, this->system_name);
|
||||
|
||||
spa_list_init (&impl->item_list);
|
||||
|
||||
state = NULL;
|
||||
|
|
@ -273,6 +299,7 @@ pinos_spa_monitor_destroy (PinosSpaMonitor * monitor)
|
|||
free (monitor->handle);
|
||||
free (monitor->lib);
|
||||
free (monitor->factory_name);
|
||||
free (monitor->system_name);
|
||||
|
||||
dlclose (impl->hnd);
|
||||
free (impl);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ struct _PinosSpaMonitor {
|
|||
|
||||
char *lib;
|
||||
char *factory_name;
|
||||
char *system_name;
|
||||
SpaHandle *handle;
|
||||
|
||||
PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PinosSpaMonitor *monitor));
|
||||
|
|
@ -41,7 +42,8 @@ struct _PinosSpaMonitor {
|
|||
|
||||
PinosSpaMonitor * pinos_spa_monitor_load (PinosCore *core,
|
||||
const char *lib,
|
||||
const char *factory_name);
|
||||
const char *factory_name,
|
||||
const char *system_name);
|
||||
void pinos_spa_monitor_destroy (PinosSpaMonitor *monitor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -1041,6 +1041,9 @@ client_node_dispatch_func (void *object,
|
|||
handle_node_event (this, cne->event);
|
||||
break;
|
||||
}
|
||||
case PINOS_MESSAGE_DESTROY:
|
||||
pinos_client_node_destroy (node);
|
||||
break;
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -1202,8 +1205,16 @@ client_node_resource_destroy (PinosResource *resource)
|
|||
PinosClientNode *this = resource->object;
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||
|
||||
pinos_log_debug ("client-node %p: destroy", impl);
|
||||
pinos_signal_emit (&this->destroy_signal, this);
|
||||
|
||||
impl->proxy.resource = this->resource = NULL;
|
||||
pinos_client_node_destroy (this);
|
||||
|
||||
pinos_signal_remove (&impl->global_added);
|
||||
pinos_signal_remove (&impl->loop_changed);
|
||||
pinos_signal_remove (&impl->transport_changed);
|
||||
|
||||
pinos_node_destroy (this->node);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1307,16 +1318,7 @@ error_no_node:
|
|||
void
|
||||
pinos_client_node_destroy (PinosClientNode * this)
|
||||
{
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||
|
||||
pinos_log_debug ("client-node %p: destroy", impl);
|
||||
pinos_signal_emit (&this->destroy_signal, this);
|
||||
|
||||
pinos_signal_remove (&impl->global_added);
|
||||
pinos_signal_remove (&impl->loop_changed);
|
||||
pinos_signal_remove (&impl->transport_changed);
|
||||
|
||||
pinos_node_destroy (this->node);
|
||||
pinos_resource_destroy (this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1339,7 +1341,7 @@ pinos_client_node_get_data_socket (PinosClientNode *this,
|
|||
#if 1
|
||||
int fd[2];
|
||||
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fd) != 0)
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, fd) != 0)
|
||||
return SPA_RESULT_ERRNO;
|
||||
|
||||
impl->proxy.data_source.fd = fd[0];
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ registry_dispatch_func (void *object,
|
|||
"unknown object id %u", m->id);
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
pinos_log_debug ("global %p: bind object id %d", global, m->id);
|
||||
res = pinos_global_bind (global, client, 0, m->id);
|
||||
pinos_log_debug ("global %p: bind object id %d to %d", global, m->id, m->new_id);
|
||||
res = pinos_global_bind (global, client, 0, m->new_id);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -110,7 +110,7 @@ core_dispatch_func (void *object,
|
|||
PinosResource *registry_resource;
|
||||
|
||||
registry_resource = pinos_resource_new (resource->client,
|
||||
SPA_ID_INVALID,
|
||||
m->new_id,
|
||||
this->uri.registry,
|
||||
this,
|
||||
destroy_registry_resource);
|
||||
|
|
@ -203,6 +203,7 @@ core_unbind_func (void *data)
|
|||
{
|
||||
PinosResource *resource = data;
|
||||
resource->client->core_resource = NULL;
|
||||
spa_list_remove (&resource->link);
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
|
|
@ -228,20 +229,21 @@ core_bind_func (PinosGlobal *global,
|
|||
core_dispatch_func,
|
||||
this);
|
||||
|
||||
spa_list_insert (this->resource_list.prev, &resource->link);
|
||||
client->core_resource = resource;
|
||||
|
||||
pinos_log_debug ("core %p: bound to %d", global->object, resource->id);
|
||||
|
||||
m.info = &info;
|
||||
info.id = global->id;
|
||||
info.change_mask = ~0;
|
||||
info.change_mask = PINOS_CORE_CHANGE_MASK_ALL;
|
||||
info.user_name = pinos_get_user_name ();
|
||||
info.host_name = pinos_get_host_name ();
|
||||
info.version = "0";
|
||||
info.name = "pinos-0";
|
||||
srandom (time (NULL));
|
||||
info.cookie = random ();
|
||||
info.props = NULL;
|
||||
info.props = this->properties ? &this->properties->dict : NULL;
|
||||
|
||||
return pinos_client_send_message (resource->client,
|
||||
resource,
|
||||
|
|
@ -254,7 +256,8 @@ no_mem:
|
|||
}
|
||||
|
||||
PinosCore *
|
||||
pinos_core_new (PinosMainLoop *main_loop)
|
||||
pinos_core_new (PinosMainLoop *main_loop,
|
||||
PinosProperties *properties)
|
||||
{
|
||||
PinosCoreImpl *impl;
|
||||
PinosCore *this;
|
||||
|
|
@ -269,6 +272,7 @@ pinos_core_new (PinosMainLoop *main_loop)
|
|||
goto no_data_loop;
|
||||
|
||||
this->main_loop = main_loop;
|
||||
this->properties = properties;
|
||||
|
||||
pinos_uri_init (&this->uri);
|
||||
pinos_access_init (&this->access);
|
||||
|
|
@ -287,6 +291,7 @@ pinos_core_new (PinosMainLoop *main_loop)
|
|||
|
||||
pinos_data_loop_start (this->data_loop);
|
||||
|
||||
spa_list_init (&this->resource_list);
|
||||
spa_list_init (&this->registry_resource_list);
|
||||
spa_list_init (&this->global_list);
|
||||
spa_list_init (&this->client_list);
|
||||
|
|
@ -425,6 +430,40 @@ pinos_global_destroy (PinosGlobal *global)
|
|||
free (global);
|
||||
}
|
||||
|
||||
void
|
||||
pinos_core_update_properties (PinosCore *core,
|
||||
const SpaDict *dict)
|
||||
{
|
||||
PinosMessageCoreInfo m;
|
||||
PinosCoreInfo info;
|
||||
PinosResource *resource;
|
||||
|
||||
if (core->properties == NULL) {
|
||||
if (dict)
|
||||
core->properties = pinos_properties_new_dict (dict);
|
||||
} else if (dict != &core->properties->dict) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < dict->n_items; i++)
|
||||
pinos_properties_set (core->properties,
|
||||
dict->items[i].key,
|
||||
dict->items[i].value);
|
||||
}
|
||||
|
||||
m.info = &info;
|
||||
info.id = core->global->id;
|
||||
info.change_mask = PINOS_CORE_CHANGE_MASK_PROPS;
|
||||
info.props = core->properties ? &core->properties->dict : NULL;
|
||||
|
||||
spa_list_for_each (resource, &core->resource_list, link) {
|
||||
pinos_client_send_message (resource->client,
|
||||
resource,
|
||||
PINOS_MESSAGE_CORE_INFO,
|
||||
&m,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
PinosPort *
|
||||
pinos_core_find_port (PinosCore *core,
|
||||
PinosPort *other_port,
|
||||
|
|
|
|||
|
|
@ -64,11 +64,14 @@ struct _PinosGlobal {
|
|||
struct _PinosCore {
|
||||
PinosGlobal *global;
|
||||
|
||||
PinosProperties *properties;
|
||||
|
||||
PinosURI uri;
|
||||
PinosAccess access;
|
||||
|
||||
PinosMap objects;
|
||||
|
||||
SpaList resource_list;
|
||||
SpaList registry_resource_list;
|
||||
SpaList global_list;
|
||||
SpaList client_list;
|
||||
|
|
@ -93,8 +96,12 @@ struct _PinosCore {
|
|||
PinosGlobal *global));
|
||||
};
|
||||
|
||||
PinosCore * pinos_core_new (PinosMainLoop *main_loop);
|
||||
void pinos_core_destroy (PinosCore *core);
|
||||
PinosCore * pinos_core_new (PinosMainLoop *main_loop,
|
||||
PinosProperties *props);
|
||||
void pinos_core_destroy (PinosCore *core);
|
||||
|
||||
void pinos_core_update_properties (PinosCore *core,
|
||||
const SpaDict *dict);
|
||||
|
||||
PinosGlobal * pinos_core_add_global (PinosCore *core,
|
||||
PinosClient *owner,
|
||||
|
|
|
|||
|
|
@ -657,8 +657,10 @@ pinos_node_destroy (PinosNode * this)
|
|||
pinos_log_debug ("node %p: destroy", impl);
|
||||
pinos_signal_emit (&this->destroy_signal, this);
|
||||
|
||||
spa_list_remove (&this->link);
|
||||
pinos_global_destroy (this->global);
|
||||
if (!impl->async_init) {
|
||||
spa_list_remove (&this->link);
|
||||
pinos_global_destroy (this->global);
|
||||
}
|
||||
|
||||
spa_list_for_each_safe (resource, tmp, &this->resource_list, link)
|
||||
pinos_resource_destroy (resource);
|
||||
|
|
|
|||
|
|
@ -43,16 +43,20 @@ pinos_resource_new (PinosClient *client,
|
|||
return NULL;
|
||||
|
||||
this = &impl->this;
|
||||
|
||||
this->core = client->core;
|
||||
this->client = client;
|
||||
this->type = type;
|
||||
this->object = object;
|
||||
this->destroy = destroy;
|
||||
this->id = id;
|
||||
|
||||
pinos_signal_init (&this->destroy_signal);
|
||||
|
||||
this->id = pinos_map_insert_new (&client->objects, this);
|
||||
if (!pinos_map_insert_at (&client->objects, this->id, this)) {
|
||||
free (impl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pinos_log_debug ("resource %p: new for client %p id %u", this, client, this->id);
|
||||
pinos_signal_emit (&client->resource_added, client, this);
|
||||
|
||||
|
|
@ -64,9 +68,15 @@ pinos_resource_destroy (PinosResource *resource)
|
|||
{
|
||||
PinosClient *client = resource->client;
|
||||
|
||||
pinos_log_debug ("resource %p: destroy", resource);
|
||||
pinos_log_debug ("resource %p: destroy %u", resource, resource->id);
|
||||
pinos_signal_emit (&resource->destroy_signal, resource);
|
||||
|
||||
pinos_map_remove (&client->objects, resource->id);
|
||||
pinos_signal_emit (&client->resource_removed, client, resource);
|
||||
|
||||
if (resource->destroy)
|
||||
resource->destroy (resource);
|
||||
|
||||
if (client->core_resource) {
|
||||
PinosMessageRemoveId m;
|
||||
m.id = resource->id;
|
||||
|
|
@ -77,12 +87,6 @@ pinos_resource_destroy (PinosResource *resource)
|
|||
true);
|
||||
}
|
||||
|
||||
pinos_map_remove (&client->objects, resource->id);
|
||||
pinos_signal_emit (&client->resource_removed, client, resource);
|
||||
|
||||
if (resource->destroy)
|
||||
resource->destroy (resource);
|
||||
|
||||
pinos_log_debug ("resource %p: free", resource);
|
||||
free (resource);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue