mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
Use refcounting for async shutdown
fix some memory leaks
This commit is contained in:
parent
ee0aa6a2ac
commit
6d4db64767
21 changed files with 216 additions and 260 deletions
|
|
@ -42,8 +42,6 @@ pinos_node_state_as_string (PinosNodeState state)
|
||||||
return "creating";
|
return "creating";
|
||||||
case PINOS_NODE_STATE_SUSPENDED:
|
case PINOS_NODE_STATE_SUSPENDED:
|
||||||
return "suspended";
|
return "suspended";
|
||||||
case PINOS_NODE_STATE_INITIALIZING:
|
|
||||||
return "initializing";
|
|
||||||
case PINOS_NODE_STATE_IDLE:
|
case PINOS_NODE_STATE_IDLE:
|
||||||
return "idle";
|
return "idle";
|
||||||
case PINOS_NODE_STATE_RUNNING:
|
case PINOS_NODE_STATE_RUNNING:
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,8 @@ enum _PinosNodeState {
|
||||||
PINOS_NODE_STATE_ERROR = -1,
|
PINOS_NODE_STATE_ERROR = -1,
|
||||||
PINOS_NODE_STATE_CREATING = 0,
|
PINOS_NODE_STATE_CREATING = 0,
|
||||||
PINOS_NODE_STATE_SUSPENDED = 1,
|
PINOS_NODE_STATE_SUSPENDED = 1,
|
||||||
PINOS_NODE_STATE_INITIALIZING = 2,
|
PINOS_NODE_STATE_IDLE = 2,
|
||||||
PINOS_NODE_STATE_IDLE = 3,
|
PINOS_NODE_STATE_RUNNING = 3,
|
||||||
PINOS_NODE_STATE_RUNNING = 4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * pinos_node_state_as_string (PinosNodeState state);
|
const char * pinos_node_state_as_string (PinosNodeState state);
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,11 @@ id_map_get_uri (SpaIDMap *map, uint32_t id)
|
||||||
IDMap *this = SPA_CONTAINER_OF (map, IDMap, map);
|
IDMap *this = SPA_CONTAINER_OF (map, IDMap, map);
|
||||||
if (id == SPA_ID_INVALID)
|
if (id == SPA_ID_INVALID)
|
||||||
return NULL;
|
return NULL;
|
||||||
return pinos_map_lookup (&this->uris, id);
|
|
||||||
|
if (SPA_LIKELY (pinos_map_check_id (&this->uris, id)))
|
||||||
|
return pinos_map_lookup_unchecked (&this->uris, id);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IDMap default_id_map = {
|
static IDMap default_id_map = {
|
||||||
|
|
|
||||||
|
|
@ -844,8 +844,6 @@ pinos_stream_connect (PinosStream *stream,
|
||||||
{
|
{
|
||||||
PinosStreamImpl *impl = SPA_CONTAINER_OF (stream, PinosStreamImpl, this);
|
PinosStreamImpl *impl = SPA_CONTAINER_OF (stream, PinosStreamImpl, this);
|
||||||
PinosMessageCreateClientNode ccn;
|
PinosMessageCreateClientNode ccn;
|
||||||
SpaDict dict;
|
|
||||||
SpaDictItem items[1];
|
|
||||||
|
|
||||||
impl->direction = direction == PINOS_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
impl->direction = direction == PINOS_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
||||||
impl->port_id = 0;
|
impl->port_id = 0;
|
||||||
|
|
@ -866,7 +864,7 @@ pinos_stream_connect (PinosStream *stream,
|
||||||
|
|
||||||
impl->node_proxy = pinos_proxy_new (stream->context,
|
impl->node_proxy = pinos_proxy_new (stream->context,
|
||||||
SPA_ID_INVALID,
|
SPA_ID_INVALID,
|
||||||
0);
|
stream->context->uri.client_node);
|
||||||
|
|
||||||
pinos_proxy_set_dispatch (impl->node_proxy,
|
pinos_proxy_set_dispatch (impl->node_proxy,
|
||||||
stream_dispatch_func,
|
stream_dispatch_func,
|
||||||
|
|
@ -874,11 +872,7 @@ pinos_stream_connect (PinosStream *stream,
|
||||||
|
|
||||||
ccn.seq = ++impl->seq;
|
ccn.seq = ++impl->seq;
|
||||||
ccn.name = "client-node";
|
ccn.name = "client-node";
|
||||||
dict.n_items = 1;
|
ccn.props = &stream->properties->dict;
|
||||||
dict.items = items;
|
|
||||||
items[0].key = "pinos.target.node";
|
|
||||||
items[0].value = port_path;
|
|
||||||
ccn.props = &dict;
|
|
||||||
ccn.new_id = impl->node_proxy->id;
|
ccn.new_id = impl->node_proxy->id;
|
||||||
|
|
||||||
pinos_proxy_send_message (stream->context->core_proxy,
|
pinos_proxy_send_message (stream->context->core_proxy,
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,16 @@ check_global_owner (PinosCore *core,
|
||||||
PinosGlobal *global;
|
PinosGlobal *global;
|
||||||
|
|
||||||
global = pinos_map_lookup (&core->objects, id);
|
global = pinos_map_lookup (&core->objects, id);
|
||||||
|
if (global == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
return (global && global->owner == client);
|
if (global->owner == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (global->owner->ucred.uid == client->ucred.uid)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,8 @@ try_link_port (PinosNode *node, PinosPort *port, ModuleImpl *impl)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
{
|
{
|
||||||
pinos_node_update_state (node, PINOS_NODE_STATE_ERROR, error);
|
pinos_log_error ("module %p: can't link node '%s'", impl, error);
|
||||||
|
free (error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -271,6 +272,6 @@ module_destroy (ModuleImpl *impl)
|
||||||
bool
|
bool
|
||||||
pinos__module_init (PinosModule * module, const char * args)
|
pinos__module_init (PinosModule * module, const char * args)
|
||||||
{
|
{
|
||||||
module_new (module->core, NULL);
|
module->user_data = module_new (module->core, NULL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ client_new (PinosProtocolDBus *impl,
|
||||||
PinosProtocolDBusClient *this;
|
PinosProtocolDBusClient *this;
|
||||||
PinosClient *client;
|
PinosClient *client;
|
||||||
|
|
||||||
client = pinos_client_new (impl->core, NULL);
|
client = pinos_client_new (impl->core, NULL, NULL);
|
||||||
|
|
||||||
if ((this = (PinosProtocolDBusClient *) find_object (impl, client))) {
|
if ((this = (PinosProtocolDBusClient *) find_object (impl, client))) {
|
||||||
pinos_client1_set_sender (this->parent.iface, sender);
|
pinos_client1_set_sender (this->parent.iface, sender);
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,7 @@ client_new (PinosProtocolNative *impl,
|
||||||
PinosProtocolNativeClient *this;
|
PinosProtocolNativeClient *this;
|
||||||
PinosClient *client;
|
PinosClient *client;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
|
struct ucred ucred, *ucredp;
|
||||||
|
|
||||||
this = calloc (1, sizeof (PinosProtocolNativeClient));
|
this = calloc (1, sizeof (PinosProtocolNativeClient));
|
||||||
if (this == NULL)
|
if (this == NULL)
|
||||||
|
|
@ -200,7 +201,15 @@ client_new (PinosProtocolNative *impl,
|
||||||
if (this->connection == NULL)
|
if (this->connection == NULL)
|
||||||
goto no_connection;
|
goto no_connection;
|
||||||
|
|
||||||
client = pinos_client_new (impl->core, NULL);
|
len = sizeof (ucred);
|
||||||
|
if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
|
||||||
|
pinos_log_error ("no peercred: %m");
|
||||||
|
ucredp = NULL;
|
||||||
|
} else {
|
||||||
|
ucredp = &ucred;
|
||||||
|
}
|
||||||
|
|
||||||
|
client = pinos_client_new (impl->core, ucredp, NULL);
|
||||||
if (client == NULL)
|
if (client == NULL)
|
||||||
goto no_client;
|
goto no_client;
|
||||||
|
|
||||||
|
|
@ -210,14 +219,6 @@ client_new (PinosProtocolNative *impl,
|
||||||
client_send_func,
|
client_send_func,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
len = sizeof (client->ucred);
|
|
||||||
if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &client->ucred, &len) < 0) {
|
|
||||||
client->ucred_valid = false;
|
|
||||||
pinos_log_error ("no peercred: %m");
|
|
||||||
} else {
|
|
||||||
client->ucred_valid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
spa_list_insert (impl->client_list.prev, &this->link);
|
spa_list_insert (impl->client_list.prev, &this->link);
|
||||||
|
|
||||||
pinos_global_bind (impl->core->global,
|
pinos_global_bind (impl->core->global,
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ pinos__module_init (PinosModule * module, const char * args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (argv);
|
free (argv);
|
||||||
|
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/alsa/libspa-alsa.so", "alsa-monitor");
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ typedef struct
|
||||||
|
|
||||||
SpaProxy proxy;
|
SpaProxy proxy;
|
||||||
|
|
||||||
|
PinosListener node_free;
|
||||||
PinosListener transport_changed;
|
PinosListener transport_changed;
|
||||||
PinosListener loop_changed;
|
PinosListener loop_changed;
|
||||||
PinosListener global_added;
|
PinosListener global_added;
|
||||||
|
|
@ -177,6 +178,9 @@ spa_proxy_node_send_command (SpaNode *node,
|
||||||
|
|
||||||
this = SPA_CONTAINER_OF (node, SpaProxy, node);
|
this = SPA_CONTAINER_OF (node, SpaProxy, node);
|
||||||
|
|
||||||
|
if (this->resource == NULL)
|
||||||
|
return SPA_RESULT_OK;
|
||||||
|
|
||||||
switch (command->type) {
|
switch (command->type) {
|
||||||
case SPA_NODE_COMMAND_INVALID:
|
case SPA_NODE_COMMAND_INVALID:
|
||||||
return SPA_RESULT_INVALID_COMMAND;
|
return SPA_RESULT_INVALID_COMMAND;
|
||||||
|
|
@ -200,7 +204,6 @@ spa_proxy_node_send_command (SpaNode *node,
|
||||||
uint8_t cmd = PINOS_TRANSPORT_CMD_NEED_DATA;
|
uint8_t cmd = PINOS_TRANSPORT_CMD_NEED_DATA;
|
||||||
write (this->data_source.fd, &cmd, 1);
|
write (this->data_source.fd, &cmd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = SPA_RESULT_RETURN_ASYNC (cnc.seq);
|
res = SPA_RESULT_RETURN_ASYNC (cnc.seq);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -295,7 +298,7 @@ spa_proxy_node_get_port_ids (SpaNode *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_update_port (SpaProxy *this,
|
do_update_port (SpaProxy *this,
|
||||||
PinosMessagePortUpdate *pu)
|
PinosMessagePortUpdate *pu)
|
||||||
{
|
{
|
||||||
SpaProxyPort *port;
|
SpaProxyPort *port;
|
||||||
|
|
@ -312,17 +315,22 @@ do_update_port (SpaProxy *this,
|
||||||
for (i = 0; i < port->n_formats; i++)
|
for (i = 0; i < port->n_formats; i++)
|
||||||
free (port->formats[i]);
|
free (port->formats[i]);
|
||||||
port->n_formats = pu->n_possible_formats;
|
port->n_formats = pu->n_possible_formats;
|
||||||
port->formats = realloc (port->formats, port->n_formats * sizeof (SpaFormat *));
|
if (port->n_formats)
|
||||||
|
port->formats = realloc (port->formats, port->n_formats * sizeof (SpaFormat *));
|
||||||
|
else {
|
||||||
|
free (port->formats);
|
||||||
|
port->formats = NULL;
|
||||||
|
}
|
||||||
for (i = 0; i < port->n_formats; i++) {
|
for (i = 0; i < port->n_formats; i++) {
|
||||||
size = pinos_serialize_format_get_size (pu->possible_formats[i]);
|
size = pinos_serialize_format_get_size (pu->possible_formats[i]);
|
||||||
port->formats[i] = pinos_serialize_format_copy_into (malloc (size), pu->possible_formats[i]);
|
port->formats[i] = size ? pinos_serialize_format_copy_into (malloc (size), pu->possible_formats[i]) : NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_FORMAT) {
|
if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_FORMAT) {
|
||||||
if (port->format)
|
if (port->format)
|
||||||
free (port->format);
|
free (port->format);
|
||||||
size = pinos_serialize_format_get_size (pu->format);
|
size = pinos_serialize_format_get_size (pu->format);
|
||||||
port->format = pinos_serialize_format_copy_into (malloc (size), pu->format);
|
port->format = size ? pinos_serialize_format_copy_into (malloc (size), pu->format) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_PROPS) {
|
if (pu->change_mask & PINOS_MESSAGE_PORT_UPDATE_PROPS) {
|
||||||
|
|
@ -332,7 +340,7 @@ do_update_port (SpaProxy *this,
|
||||||
if (port->info)
|
if (port->info)
|
||||||
free (port->info);
|
free (port->info);
|
||||||
size = pinos_serialize_port_info_get_size (pu->info);
|
size = pinos_serialize_port_info_get_size (pu->info);
|
||||||
port->info = pinos_serialize_port_info_copy_into (malloc (size), pu->info);
|
port->info = size ? pinos_serialize_port_info_copy_into (malloc (size), pu->info) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!port->valid) {
|
if (!port->valid) {
|
||||||
|
|
@ -482,6 +490,9 @@ spa_proxy_node_port_set_format (SpaNode *node,
|
||||||
if (!CHECK_PORT (this, direction, port_id))
|
if (!CHECK_PORT (this, direction, port_id))
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
|
if (this->resource == NULL)
|
||||||
|
return SPA_RESULT_OK;
|
||||||
|
|
||||||
sf.seq = this->seq++;
|
sf.seq = this->seq++;
|
||||||
sf.direction = direction;
|
sf.direction = direction;
|
||||||
sf.port_id = port_id;
|
sf.port_id = port_id;
|
||||||
|
|
@ -641,6 +652,11 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
||||||
mb = NULL;
|
mb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
port->n_buffers = n_buffers;
|
||||||
|
|
||||||
|
if (this->resource == NULL)
|
||||||
|
return SPA_RESULT_OK;
|
||||||
|
|
||||||
n_mem = 0;
|
n_mem = 0;
|
||||||
for (i = 0; i < n_buffers; i++) {
|
for (i = 0; i < n_buffers; i++) {
|
||||||
ProxyBuffer *b = &port->buffers[i];
|
ProxyBuffer *b = &port->buffers[i];
|
||||||
|
|
@ -715,8 +731,6 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
port->n_buffers = n_buffers;
|
|
||||||
|
|
||||||
ub.seq = this->seq++;
|
ub.seq = this->seq++;
|
||||||
ub.direction = direction;
|
ub.direction = direction;
|
||||||
ub.port_id = port_id;
|
ub.port_id = port_id;
|
||||||
|
|
@ -1169,6 +1183,9 @@ on_transport_changed (PinosListener *listener,
|
||||||
PinosTransportInfo info;
|
PinosTransportInfo info;
|
||||||
PinosMessageTransportUpdate tu;
|
PinosMessageTransportUpdate tu;
|
||||||
|
|
||||||
|
if (this->resource == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
pinos_transport_get_info (node->transport, &info);
|
pinos_transport_get_info (node->transport, &info);
|
||||||
|
|
||||||
tu.memfd = info.memfd;
|
tu.memfd = info.memfd;
|
||||||
|
|
@ -1194,6 +1211,7 @@ on_global_added (PinosListener *listener,
|
||||||
PinosGlobal *global)
|
PinosGlobal *global)
|
||||||
{
|
{
|
||||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, global_added);
|
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, global_added);
|
||||||
|
|
||||||
if (global->object == impl->this.node)
|
if (global->object == impl->this.node)
|
||||||
global->owner = impl->this.client;
|
global->owner = impl->this.client;
|
||||||
}
|
}
|
||||||
|
|
@ -1222,7 +1240,25 @@ proxy_clear (SpaProxy *this)
|
||||||
static void
|
static void
|
||||||
client_node_resource_destroy (PinosResource *resource)
|
client_node_resource_destroy (PinosResource *resource)
|
||||||
{
|
{
|
||||||
pinos_client_node_destroy (resource->object);
|
PinosClientNode *this = resource->object;
|
||||||
|
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||||
|
|
||||||
|
impl->proxy.resource = this->resource = NULL;
|
||||||
|
pinos_client_node_destroy (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_node_free (PinosListener *listener,
|
||||||
|
PinosNode *node)
|
||||||
|
{
|
||||||
|
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (listener, PinosClientNodeImpl, node_free);
|
||||||
|
|
||||||
|
pinos_log_debug ("client-node %p: free", &impl->this);
|
||||||
|
proxy_clear (&impl->proxy);
|
||||||
|
|
||||||
|
if (impl->data_fd != -1)
|
||||||
|
close (impl->data_fd);
|
||||||
|
free (impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1249,6 +1285,8 @@ pinos_client_node_new (PinosClient *client,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
this = &impl->this;
|
this = &impl->this;
|
||||||
|
this->client = client;
|
||||||
|
|
||||||
impl->core = client->core;
|
impl->core = client->core;
|
||||||
impl->data_fd = -1;
|
impl->data_fd = -1;
|
||||||
pinos_log_debug ("client-node %p: new", impl);
|
pinos_log_debug ("client-node %p: new", impl);
|
||||||
|
|
@ -1277,6 +1315,10 @@ pinos_client_node_new (PinosClient *client,
|
||||||
|
|
||||||
impl->proxy.resource = this->resource;
|
impl->proxy.resource = this->resource;
|
||||||
|
|
||||||
|
pinos_signal_add (&this->node->free_signal,
|
||||||
|
&impl->node_free,
|
||||||
|
on_node_free);
|
||||||
|
|
||||||
pinos_signal_add (&this->node->transport_changed,
|
pinos_signal_add (&this->node->transport_changed,
|
||||||
&impl->transport_changed,
|
&impl->transport_changed,
|
||||||
on_transport_changed);
|
on_transport_changed);
|
||||||
|
|
@ -1303,24 +1345,6 @@ error_no_node:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_node_remove (void *object,
|
|
||||||
void *data,
|
|
||||||
SpaResult res,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
PinosClientNode *this = object;
|
|
||||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
|
||||||
|
|
||||||
pinos_log_debug ("client-node %p: finalize", this);
|
|
||||||
proxy_clear (&impl->proxy);
|
|
||||||
|
|
||||||
if (impl->data_fd != -1)
|
|
||||||
close (impl->data_fd);
|
|
||||||
free (impl);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pinos_client_node_destroy (PinosClientNode * this)
|
pinos_client_node_destroy (PinosClientNode * this)
|
||||||
{
|
{
|
||||||
|
|
@ -1330,14 +1354,10 @@ pinos_client_node_destroy (PinosClientNode * this)
|
||||||
pinos_signal_emit (&this->destroy_signal, this);
|
pinos_signal_emit (&this->destroy_signal, this);
|
||||||
|
|
||||||
pinos_signal_remove (&impl->global_added);
|
pinos_signal_remove (&impl->global_added);
|
||||||
|
pinos_signal_remove (&impl->loop_changed);
|
||||||
|
pinos_signal_remove (&impl->transport_changed);
|
||||||
|
|
||||||
pinos_node_destroy (this->node);
|
pinos_node_destroy (this->node);
|
||||||
|
|
||||||
pinos_main_loop_defer (this->node->core->main_loop,
|
|
||||||
this,
|
|
||||||
SPA_RESULT_WAIT_SYNC,
|
|
||||||
(PinosDeferFunc) on_node_remove,
|
|
||||||
this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ no_mem:
|
||||||
*/
|
*/
|
||||||
PinosClient *
|
PinosClient *
|
||||||
pinos_client_new (PinosCore *core,
|
pinos_client_new (PinosCore *core,
|
||||||
|
struct ucred *ucred,
|
||||||
PinosProperties *properties)
|
PinosProperties *properties)
|
||||||
{
|
{
|
||||||
PinosClient *this;
|
PinosClient *this;
|
||||||
|
|
@ -123,6 +124,8 @@ pinos_client_new (PinosCore *core,
|
||||||
|
|
||||||
this = &impl->this;
|
this = &impl->this;
|
||||||
this->core = core;
|
this->core = core;
|
||||||
|
if ((this->ucred_valid = (ucred != NULL)))
|
||||||
|
this->ucred = *ucred;
|
||||||
this->properties = properties;
|
this->properties = properties;
|
||||||
|
|
||||||
spa_list_init (&this->resource_list);
|
spa_list_init (&this->resource_list);
|
||||||
|
|
@ -142,23 +145,6 @@ pinos_client_new (PinosCore *core,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sync_destroy (void *object,
|
|
||||||
void *data,
|
|
||||||
SpaResult res,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
PinosClientImpl *impl = SPA_CONTAINER_OF (object, PinosClientImpl, this);
|
|
||||||
PinosClient *client = &impl->this;
|
|
||||||
|
|
||||||
pinos_log_debug ("client %p: sync destroy", impl);
|
|
||||||
|
|
||||||
if (client->properties)
|
|
||||||
pinos_properties_free (client->properties);
|
|
||||||
|
|
||||||
free (impl);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_resource (void *object,
|
destroy_resource (void *object,
|
||||||
void *data)
|
void *data)
|
||||||
|
|
@ -176,23 +162,26 @@ void
|
||||||
pinos_client_destroy (PinosClient * client)
|
pinos_client_destroy (PinosClient * client)
|
||||||
{
|
{
|
||||||
PinosResource *resource, *tmp;
|
PinosResource *resource, *tmp;
|
||||||
|
PinosClientImpl *impl = SPA_CONTAINER_OF (client, PinosClientImpl, this);
|
||||||
|
|
||||||
pinos_log_debug ("client %p: destroy", client);
|
pinos_log_debug ("client %p: destroy", client);
|
||||||
pinos_signal_emit (&client->destroy_signal, client);
|
pinos_signal_emit (&client->destroy_signal, client);
|
||||||
|
|
||||||
pinos_map_for_each (&client->objects, destroy_resource, client);
|
|
||||||
|
|
||||||
pinos_global_destroy (client->global);
|
|
||||||
spa_list_remove (&client->link);
|
spa_list_remove (&client->link);
|
||||||
|
pinos_global_destroy (client->global);
|
||||||
|
|
||||||
spa_list_for_each_safe (resource, tmp, &client->resource_list, link)
|
spa_list_for_each_safe (resource, tmp, &client->resource_list, link)
|
||||||
pinos_resource_destroy (resource);
|
pinos_resource_destroy (resource);
|
||||||
|
|
||||||
pinos_main_loop_defer (client->core->main_loop,
|
pinos_map_for_each (&client->objects, destroy_resource, client);
|
||||||
client,
|
|
||||||
SPA_RESULT_WAIT_SYNC,
|
pinos_log_debug ("client %p: free", impl);
|
||||||
sync_destroy,
|
pinos_map_clear (&client->objects);
|
||||||
client);
|
|
||||||
|
if (client->properties)
|
||||||
|
pinos_properties_free (client->properties);
|
||||||
|
|
||||||
|
free (impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,11 @@ struct _PinosClient {
|
||||||
SpaList resource_list;
|
SpaList resource_list;
|
||||||
|
|
||||||
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
||||||
PinosClient *client));
|
PinosClient *client));
|
||||||
};
|
};
|
||||||
|
|
||||||
PinosClient * pinos_client_new (PinosCore *core,
|
PinosClient * pinos_client_new (PinosCore *core,
|
||||||
|
struct ucred *ucred,
|
||||||
PinosProperties *properties);
|
PinosProperties *properties);
|
||||||
void pinos_client_destroy (PinosClient *client);
|
void pinos_client_destroy (PinosClient *client);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,13 @@ no_mem:
|
||||||
return SPA_RESULT_NO_MEMORY;
|
return SPA_RESULT_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
core_unbind_func (void *data)
|
||||||
|
{
|
||||||
|
PinosResource *resource = data;
|
||||||
|
resource->client->core_resource = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static SpaResult
|
static SpaResult
|
||||||
core_bind_func (PinosGlobal *global,
|
core_bind_func (PinosGlobal *global,
|
||||||
PinosClient *client,
|
PinosClient *client,
|
||||||
|
|
@ -207,7 +214,7 @@ core_bind_func (PinosGlobal *global,
|
||||||
id,
|
id,
|
||||||
global->type,
|
global->type,
|
||||||
global->object,
|
global->object,
|
||||||
NULL);
|
core_unbind_func);
|
||||||
if (resource == NULL)
|
if (resource == NULL)
|
||||||
goto no_mem;
|
goto no_mem;
|
||||||
|
|
||||||
|
|
@ -310,10 +317,14 @@ pinos_core_destroy (PinosCore *core)
|
||||||
{
|
{
|
||||||
PinosCoreImpl *impl = SPA_CONTAINER_OF (core, PinosCoreImpl, this);
|
PinosCoreImpl *impl = SPA_CONTAINER_OF (core, PinosCoreImpl, this);
|
||||||
|
|
||||||
|
pinos_log_debug ("core %p: destroy", core);
|
||||||
pinos_signal_emit (&core->destroy_signal, core);
|
pinos_signal_emit (&core->destroy_signal, core);
|
||||||
|
|
||||||
pinos_data_loop_destroy (core->data_loop);
|
pinos_data_loop_destroy (core->data_loop);
|
||||||
|
|
||||||
|
pinos_map_clear (&core->objects);
|
||||||
|
|
||||||
|
pinos_log_debug ("core %p: free", core);
|
||||||
free (impl);
|
free (impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,10 +361,11 @@ pinos_core_add_global (PinosCore *core,
|
||||||
spa_list_insert (core->global_list.prev, &this->link);
|
spa_list_insert (core->global_list.prev, &this->link);
|
||||||
pinos_signal_emit (&core->global_added, core, this);
|
pinos_signal_emit (&core->global_added, core, this);
|
||||||
|
|
||||||
pinos_log_debug ("global %p: new %u", this, this->id);
|
|
||||||
|
|
||||||
ng.id = this->id;
|
ng.id = this->id;
|
||||||
ng.type = spa_id_map_get_uri (core->uri.map, this->type);
|
ng.type = spa_id_map_get_uri (core->uri.map, this->type);
|
||||||
|
|
||||||
|
pinos_log_debug ("global %p: new %u %s", this, ng.id, ng.type);
|
||||||
|
|
||||||
spa_list_for_each (registry, &core->registry_resource_list, link) {
|
spa_list_for_each (registry, &core->registry_resource_list, link) {
|
||||||
pinos_resource_send_message (registry,
|
pinos_resource_send_message (registry,
|
||||||
PINOS_MESSAGE_NOTIFY_GLOBAL,
|
PINOS_MESSAGE_NOTIFY_GLOBAL,
|
||||||
|
|
@ -384,18 +396,6 @@ pinos_global_bind (PinosGlobal *global,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sync_destroy (void *object,
|
|
||||||
void *data,
|
|
||||||
SpaResult res,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
PinosGlobal *global = object;
|
|
||||||
|
|
||||||
pinos_log_debug ("global %p: sync destroy", global);
|
|
||||||
free (global);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pinos_global_destroy (PinosGlobal *global)
|
pinos_global_destroy (PinosGlobal *global)
|
||||||
{
|
{
|
||||||
|
|
@ -406,11 +406,6 @@ pinos_global_destroy (PinosGlobal *global)
|
||||||
pinos_log_debug ("global %p: destroy %u", global, global->id);
|
pinos_log_debug ("global %p: destroy %u", global, global->id);
|
||||||
pinos_signal_emit (&global->destroy_signal, global);
|
pinos_signal_emit (&global->destroy_signal, global);
|
||||||
|
|
||||||
pinos_map_remove (&core->objects, global->id);
|
|
||||||
|
|
||||||
spa_list_remove (&global->link);
|
|
||||||
pinos_signal_emit (&core->global_removed, core, global);
|
|
||||||
|
|
||||||
ng.id = global->id;
|
ng.id = global->id;
|
||||||
spa_list_for_each (registry, &core->registry_resource_list, link) {
|
spa_list_for_each (registry, &core->registry_resource_list, link) {
|
||||||
pinos_resource_send_message (registry,
|
pinos_resource_send_message (registry,
|
||||||
|
|
@ -419,11 +414,13 @@ pinos_global_destroy (PinosGlobal *global)
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pinos_main_loop_defer (core->main_loop,
|
pinos_map_remove (&core->objects, global->id);
|
||||||
global,
|
|
||||||
SPA_RESULT_WAIT_SYNC,
|
spa_list_remove (&global->link);
|
||||||
sync_destroy,
|
pinos_signal_emit (&core->global_removed, core, global);
|
||||||
global);
|
|
||||||
|
pinos_log_debug ("global %p: free", global);
|
||||||
|
free (global);
|
||||||
}
|
}
|
||||||
|
|
||||||
PinosPort *
|
PinosPort *
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ typedef struct
|
||||||
{
|
{
|
||||||
PinosLink this;
|
PinosLink this;
|
||||||
|
|
||||||
|
int refcount;
|
||||||
|
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
|
|
||||||
SpaFormat **format_filter;
|
SpaFormat **format_filter;
|
||||||
|
|
@ -648,25 +650,12 @@ on_output_async_complete_notify (PinosListener *listener,
|
||||||
pinos_main_loop_defer_complete (this->core->main_loop, impl, seq, res);
|
pinos_main_loop_defer_complete (this->core->main_loop, impl, seq, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_port_unlinked (PinosPort *port, PinosLink *this, SpaResult res, uint32_t id)
|
|
||||||
{
|
|
||||||
pinos_signal_emit (&this->core->port_unlinked, this, port);
|
|
||||||
|
|
||||||
if (this->input == NULL || this->output == NULL) {
|
|
||||||
pinos_link_update_state (this, PINOS_LINK_STATE_UNLINKED, NULL);
|
|
||||||
pinos_link_destroy (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_port_destroy (PinosLink *this,
|
on_port_destroy (PinosLink *this,
|
||||||
PinosPort *port)
|
PinosPort *port)
|
||||||
{
|
{
|
||||||
PinosLinkImpl *impl = (PinosLinkImpl *) this;
|
PinosLinkImpl *impl = (PinosLinkImpl *) this;
|
||||||
PinosPort *other;
|
PinosPort *other;
|
||||||
SpaResult res = SPA_RESULT_OK;
|
|
||||||
|
|
||||||
if (port == this->input) {
|
if (port == this->input) {
|
||||||
pinos_log_debug ("link %p: input port destroyed %p", this, port);
|
pinos_log_debug ("link %p: input port destroyed %p", this, port);
|
||||||
|
|
@ -691,11 +680,10 @@ on_port_destroy (PinosLink *this,
|
||||||
pinos_port_clear_buffers (other);
|
pinos_port_clear_buffers (other);
|
||||||
}
|
}
|
||||||
|
|
||||||
pinos_main_loop_defer (this->core->main_loop,
|
pinos_signal_emit (&this->core->port_unlinked, this, port);
|
||||||
port,
|
|
||||||
res,
|
pinos_link_update_state (this, PINOS_LINK_STATE_UNLINKED, NULL);
|
||||||
(PinosDeferFunc) on_port_unlinked,
|
pinos_link_destroy (this);
|
||||||
this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -749,11 +737,31 @@ link_dispatch_func (void *object,
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pinos_link_free (PinosLink *link)
|
||||||
|
{
|
||||||
|
PinosLinkImpl *impl = SPA_CONTAINER_OF (link, PinosLinkImpl, this);
|
||||||
|
|
||||||
|
pinos_log_debug ("link %p: free", link);
|
||||||
|
pinos_signal_emit (&link->free_signal, link);
|
||||||
|
|
||||||
|
if (impl->allocated)
|
||||||
|
pinos_memblock_free (&impl->buffer_mem);
|
||||||
|
|
||||||
|
free (impl);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
link_unbind_func (void *data)
|
link_unbind_func (void *data)
|
||||||
{
|
{
|
||||||
PinosResource *resource = data;
|
PinosResource *resource = data;
|
||||||
|
PinosLink *this = resource->object;
|
||||||
|
PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
|
||||||
|
|
||||||
spa_list_remove (&resource->link);
|
spa_list_remove (&resource->link);
|
||||||
|
|
||||||
|
if (--impl->refcount == 0)
|
||||||
|
pinos_link_free (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaResult
|
static SpaResult
|
||||||
|
|
@ -763,6 +771,7 @@ link_bind_func (PinosGlobal *global,
|
||||||
uint32_t id)
|
uint32_t id)
|
||||||
{
|
{
|
||||||
PinosLink *this = global->object;
|
PinosLink *this = global->object;
|
||||||
|
PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
|
||||||
PinosResource *resource;
|
PinosResource *resource;
|
||||||
PinosMessageLinkInfo m;
|
PinosMessageLinkInfo m;
|
||||||
PinosLinkInfo info;
|
PinosLinkInfo info;
|
||||||
|
|
@ -775,6 +784,8 @@ link_bind_func (PinosGlobal *global,
|
||||||
if (resource == NULL)
|
if (resource == NULL)
|
||||||
goto no_mem;
|
goto no_mem;
|
||||||
|
|
||||||
|
impl->refcount++;
|
||||||
|
|
||||||
pinos_resource_set_dispatch (resource,
|
pinos_resource_set_dispatch (resource,
|
||||||
link_dispatch_func,
|
link_dispatch_func,
|
||||||
global);
|
global);
|
||||||
|
|
@ -790,6 +801,7 @@ link_bind_func (PinosGlobal *global,
|
||||||
info.output_port_id = this->output ? this->output->port_id : -1;
|
info.output_port_id = this->output ? this->output->port_id : -1;
|
||||||
info.input_node_id = this->input ? this->input->node->global->id : -1;
|
info.input_node_id = this->input ? this->input->node->global->id : -1;
|
||||||
info.input_port_id = this->input ? this->input->port_id : -1;
|
info.input_port_id = this->input ? this->input->port_id : -1;
|
||||||
|
|
||||||
return pinos_resource_send_message (resource,
|
return pinos_resource_send_message (resource,
|
||||||
PINOS_MESSAGE_LINK_INFO,
|
PINOS_MESSAGE_LINK_INFO,
|
||||||
&m,
|
&m,
|
||||||
|
|
@ -821,12 +833,14 @@ pinos_link_new (PinosCore *core,
|
||||||
this->core = core;
|
this->core = core;
|
||||||
this->properties = properties;
|
this->properties = properties;
|
||||||
this->state = PINOS_LINK_STATE_INIT;
|
this->state = PINOS_LINK_STATE_INIT;
|
||||||
|
impl->refcount = 1;
|
||||||
|
|
||||||
this->input = input;
|
this->input = input;
|
||||||
this->output = output;
|
this->output = output;
|
||||||
|
|
||||||
spa_list_init (&this->resource_list);
|
spa_list_init (&this->resource_list);
|
||||||
pinos_signal_init (&this->destroy_signal);
|
pinos_signal_init (&this->destroy_signal);
|
||||||
|
pinos_signal_init (&this->free_signal);
|
||||||
|
|
||||||
impl->format_filter = format_filter;
|
impl->format_filter = format_filter;
|
||||||
|
|
||||||
|
|
@ -884,6 +898,7 @@ do_link_remove_done (SpaLoop *loop,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
PinosLink *this = user_data;
|
PinosLink *this = user_data;
|
||||||
|
PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
|
||||||
|
|
||||||
if (this->input) {
|
if (this->input) {
|
||||||
spa_list_remove (&this->input_link);
|
spa_list_remove (&this->input_link);
|
||||||
|
|
@ -907,11 +922,8 @@ do_link_remove_done (SpaLoop *loop,
|
||||||
clear_port_buffers (this, this->output);
|
clear_port_buffers (this, this->output);
|
||||||
this->output = NULL;
|
this->output = NULL;
|
||||||
}
|
}
|
||||||
|
if (--impl->refcount == 0)
|
||||||
pinos_main_loop_defer_complete (this->core->main_loop,
|
pinos_link_free (this);
|
||||||
this,
|
|
||||||
seq,
|
|
||||||
SPA_RESULT_OK);
|
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -945,22 +957,6 @@ do_link_remove (SpaLoop *loop,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sync_destroy (void *object,
|
|
||||||
void *data,
|
|
||||||
SpaResult res,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
PinosLinkImpl *impl = SPA_CONTAINER_OF (object, PinosLinkImpl, this);
|
|
||||||
|
|
||||||
pinos_log_debug ("link %p: sync destroy", impl);
|
|
||||||
|
|
||||||
if (impl->allocated)
|
|
||||||
pinos_memblock_free (&impl->buffer_mem);
|
|
||||||
|
|
||||||
free (impl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pinos_link_destroy:
|
* pinos_link_destroy:
|
||||||
* @link: a #PinosLink
|
* @link: a #PinosLink
|
||||||
|
|
@ -970,7 +966,6 @@ sync_destroy (void *object,
|
||||||
void
|
void
|
||||||
pinos_link_destroy (PinosLink * this)
|
pinos_link_destroy (PinosLink * this)
|
||||||
{
|
{
|
||||||
SpaResult res = SPA_RESULT_OK;
|
|
||||||
PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
|
PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
|
||||||
PinosResource *resource, *tmp;
|
PinosResource *resource, *tmp;
|
||||||
|
|
||||||
|
|
@ -987,31 +982,26 @@ pinos_link_destroy (PinosLink * this)
|
||||||
pinos_signal_remove (&impl->input_port_destroy);
|
pinos_signal_remove (&impl->input_port_destroy);
|
||||||
pinos_signal_remove (&impl->input_async_complete);
|
pinos_signal_remove (&impl->input_async_complete);
|
||||||
|
|
||||||
res = pinos_loop_invoke (this->input->node->data_loop->loop,
|
impl->refcount++;
|
||||||
do_link_remove,
|
pinos_loop_invoke (this->input->node->data_loop->loop,
|
||||||
impl->seq++,
|
do_link_remove,
|
||||||
0,
|
impl->seq++,
|
||||||
NULL,
|
0,
|
||||||
this);
|
NULL,
|
||||||
|
this);
|
||||||
pinos_main_loop_defer (this->core->main_loop, this, res, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
if (this->output) {
|
if (this->output) {
|
||||||
pinos_signal_remove (&impl->output_port_destroy);
|
pinos_signal_remove (&impl->output_port_destroy);
|
||||||
pinos_signal_remove (&impl->output_async_complete);
|
pinos_signal_remove (&impl->output_async_complete);
|
||||||
|
|
||||||
res = pinos_loop_invoke (this->output->node->data_loop->loop,
|
impl->refcount++;
|
||||||
do_link_remove,
|
pinos_loop_invoke (this->output->node->data_loop->loop,
|
||||||
impl->seq++,
|
do_link_remove,
|
||||||
0,
|
impl->seq++,
|
||||||
NULL,
|
0,
|
||||||
this);
|
NULL,
|
||||||
pinos_main_loop_defer (this->core->main_loop, this, res, NULL, NULL);
|
this);
|
||||||
}
|
}
|
||||||
|
if (--impl->refcount == 0)
|
||||||
pinos_main_loop_defer (this->core->main_loop,
|
pinos_link_free (this);
|
||||||
this,
|
|
||||||
SPA_RESULT_WAIT_SYNC,
|
|
||||||
sync_destroy,
|
|
||||||
this);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ struct _PinosLink {
|
||||||
|
|
||||||
PINOS_SIGNAL (destroy_signal, (PinosListener *,
|
PINOS_SIGNAL (destroy_signal, (PinosListener *,
|
||||||
PinosLink *));
|
PinosLink *));
|
||||||
|
PINOS_SIGNAL (free_signal, (PinosListener *,
|
||||||
|
PinosLink *));
|
||||||
|
|
||||||
SpaList resource_list;
|
SpaList resource_list;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,16 @@ extern "C" {
|
||||||
typedef struct _PinosModule PinosModule;
|
typedef struct _PinosModule PinosModule;
|
||||||
|
|
||||||
struct _PinosModule {
|
struct _PinosModule {
|
||||||
PinosCore *core;
|
PinosCore *core;
|
||||||
SpaList link;
|
SpaList link;
|
||||||
PinosGlobal *global;
|
PinosGlobal *global;
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
char *filename;
|
char *filename;
|
||||||
char *args;
|
char *args;
|
||||||
|
|
||||||
|
void *user_data;
|
||||||
|
|
||||||
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
||||||
PinosModule *module));
|
PinosModule *module));
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -461,10 +461,9 @@ init_complete (PinosNode *this)
|
||||||
pinos_log_debug ("node %p: init completed", this);
|
pinos_log_debug ("node %p: init completed", this);
|
||||||
impl->async_init = false;
|
impl->async_init = false;
|
||||||
|
|
||||||
spa_list_insert (this->core->node_list.prev, &this->link);
|
|
||||||
|
|
||||||
pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED, NULL);
|
pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED, NULL);
|
||||||
|
|
||||||
|
spa_list_insert (this->core->node_list.prev, &this->link);
|
||||||
this->global = pinos_core_add_global (this->core,
|
this->global = pinos_core_add_global (this->core,
|
||||||
NULL,
|
NULL,
|
||||||
this->core->uri.node,
|
this->core->uri.node,
|
||||||
|
|
@ -512,6 +511,7 @@ pinos_node_new (PinosCore *core,
|
||||||
pinos_log_warn ("node %p: error setting callback", this);
|
pinos_log_warn ("node %p: error setting callback", this);
|
||||||
|
|
||||||
pinos_signal_init (&this->destroy_signal);
|
pinos_signal_init (&this->destroy_signal);
|
||||||
|
pinos_signal_init (&this->free_signal);
|
||||||
pinos_signal_init (&this->async_complete);
|
pinos_signal_init (&this->async_complete);
|
||||||
pinos_signal_init (&this->transport_changed);
|
pinos_signal_init (&this->transport_changed);
|
||||||
pinos_signal_init (&this->loop_changed);
|
pinos_signal_init (&this->loop_changed);
|
||||||
|
|
@ -564,6 +564,7 @@ do_node_remove_done (SpaLoop *loop,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
PinosNode *this = user_data;
|
PinosNode *this = user_data;
|
||||||
|
PinosNodeImpl *impl = SPA_CONTAINER_OF (this, PinosNodeImpl, this);
|
||||||
PinosPort *port, *tmp;
|
PinosPort *port, *tmp;
|
||||||
|
|
||||||
pinos_log_debug ("node %p: remove done, destroy ports", this);
|
pinos_log_debug ("node %p: remove done, destroy ports", this);
|
||||||
|
|
@ -573,10 +574,21 @@ do_node_remove_done (SpaLoop *loop,
|
||||||
spa_list_for_each_safe (port, tmp, &this->output_ports, link)
|
spa_list_for_each_safe (port, tmp, &this->output_ports, link)
|
||||||
pinos_port_destroy (port);
|
pinos_port_destroy (port);
|
||||||
|
|
||||||
pinos_main_loop_defer_complete (this->core->main_loop,
|
pinos_log_debug ("node %p: free", this);
|
||||||
this,
|
pinos_signal_emit (&this->free_signal, this);
|
||||||
seq,
|
|
||||||
SPA_RESULT_OK);
|
if (this->transport)
|
||||||
|
pinos_transport_destroy (this->transport);
|
||||||
|
if (this->input_port_map)
|
||||||
|
free (this->input_port_map);
|
||||||
|
if (this->output_port_map)
|
||||||
|
free (this->output_port_map);
|
||||||
|
|
||||||
|
free (this->name);
|
||||||
|
free (this->error);
|
||||||
|
if (this->properties)
|
||||||
|
pinos_properties_free (this->properties);
|
||||||
|
free (impl);
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -620,24 +632,6 @@ do_node_remove (SpaLoop *loop,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sync_destroy (void *object,
|
|
||||||
void *data,
|
|
||||||
SpaResult res,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
PinosNode *this = object;
|
|
||||||
PinosNodeImpl *impl = SPA_CONTAINER_OF (this, PinosNodeImpl, this);
|
|
||||||
|
|
||||||
pinos_log_debug ("node %p: sync destroy", this);
|
|
||||||
|
|
||||||
free (this->name);
|
|
||||||
free (this->error);
|
|
||||||
if (this->properties)
|
|
||||||
pinos_properties_free (this->properties);
|
|
||||||
free (impl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pinos_node_destroy:
|
* pinos_node_destroy:
|
||||||
* @node: a #PinosNode
|
* @node: a #PinosNode
|
||||||
|
|
@ -648,7 +642,6 @@ sync_destroy (void *object,
|
||||||
void
|
void
|
||||||
pinos_node_destroy (PinosNode * this)
|
pinos_node_destroy (PinosNode * this)
|
||||||
{
|
{
|
||||||
SpaResult res;
|
|
||||||
PinosNodeImpl *impl = SPA_CONTAINER_OF (this, PinosNodeImpl, this);
|
PinosNodeImpl *impl = SPA_CONTAINER_OF (this, PinosNodeImpl, this);
|
||||||
PinosResource *resource, *tmp;
|
PinosResource *resource, *tmp;
|
||||||
|
|
||||||
|
|
@ -661,24 +654,12 @@ pinos_node_destroy (PinosNode * this)
|
||||||
spa_list_for_each_safe (resource, tmp, &this->resource_list, link)
|
spa_list_for_each_safe (resource, tmp, &this->resource_list, link)
|
||||||
pinos_resource_destroy (resource);
|
pinos_resource_destroy (resource);
|
||||||
|
|
||||||
res = pinos_loop_invoke (this->data_loop->loop,
|
pinos_loop_invoke (this->data_loop->loop,
|
||||||
do_node_remove,
|
do_node_remove,
|
||||||
impl->seq++,
|
impl->seq++,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
pinos_main_loop_defer (this->core->main_loop,
|
|
||||||
this,
|
|
||||||
res,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
pinos_main_loop_defer (this->core->main_loop,
|
|
||||||
this,
|
|
||||||
SPA_RESULT_WAIT_SYNC,
|
|
||||||
sync_destroy,
|
|
||||||
this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -771,9 +752,6 @@ pinos_node_set_state (PinosNode *node,
|
||||||
res = suspend_node (node);
|
res = suspend_node (node);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PINOS_NODE_STATE_INITIALIZING:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PINOS_NODE_STATE_IDLE:
|
case PINOS_NODE_STATE_IDLE:
|
||||||
res = pause_node (node);
|
res = pause_node (node);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@ struct _PinosNode {
|
||||||
|
|
||||||
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
||||||
PinosNode *object));
|
PinosNode *object));
|
||||||
|
PINOS_SIGNAL (free_signal, (PinosListener *listener,
|
||||||
|
PinosNode *object));
|
||||||
|
|
||||||
PINOS_SIGNAL (async_complete, (PinosListener *listener,
|
PINOS_SIGNAL (async_complete, (PinosListener *listener,
|
||||||
PinosNode *node,
|
PinosNode *node,
|
||||||
|
|
|
||||||
|
|
@ -56,17 +56,6 @@ pinos_port_new (PinosNode *node,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sync_destroy (void *object,
|
|
||||||
void *data,
|
|
||||||
SpaResult res,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
PinosPort *port = object;
|
|
||||||
|
|
||||||
free (port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pinos_port_destroy (PinosPort *port)
|
pinos_port_destroy (PinosPort *port)
|
||||||
{
|
{
|
||||||
|
|
@ -83,11 +72,7 @@ pinos_port_destroy (PinosPort *port)
|
||||||
port->buffers = NULL;
|
port->buffers = NULL;
|
||||||
port->n_buffers = 0;
|
port->n_buffers = 0;
|
||||||
|
|
||||||
pinos_main_loop_defer (port->node->core->main_loop,
|
free (port);
|
||||||
port,
|
|
||||||
SPA_RESULT_WAIT_SYNC,
|
|
||||||
sync_destroy,
|
|
||||||
port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaResult
|
static SpaResult
|
||||||
|
|
|
||||||
|
|
@ -59,28 +59,12 @@ pinos_resource_new (PinosClient *client,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
sync_destroy (void *object,
|
|
||||||
void *data,
|
|
||||||
SpaResult res,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
PinosResource *resource = object;
|
|
||||||
pinos_log_debug ("resource %p: sync destroy", resource);
|
|
||||||
free (resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
SpaResult
|
|
||||||
pinos_resource_destroy (PinosResource *resource)
|
pinos_resource_destroy (PinosResource *resource)
|
||||||
{
|
{
|
||||||
pinos_log_debug ("resource %p: destroy", resource);
|
pinos_log_debug ("resource %p: destroy", resource);
|
||||||
pinos_signal_emit (&resource->destroy_signal, resource);
|
pinos_signal_emit (&resource->destroy_signal, resource);
|
||||||
|
|
||||||
pinos_map_remove (&resource->client->objects, resource->id);
|
|
||||||
|
|
||||||
if (resource->destroy)
|
|
||||||
resource->destroy (resource);
|
|
||||||
|
|
||||||
if (resource->client->core_resource) {
|
if (resource->client->core_resource) {
|
||||||
PinosMessageRemoveId m;
|
PinosMessageRemoveId m;
|
||||||
m.id = resource->id;
|
m.id = resource->id;
|
||||||
|
|
@ -90,13 +74,13 @@ pinos_resource_destroy (PinosResource *resource)
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pinos_main_loop_defer (resource->core->main_loop,
|
pinos_map_remove (&resource->client->objects, resource->id);
|
||||||
resource,
|
|
||||||
SPA_RESULT_WAIT_SYNC,
|
|
||||||
sync_destroy,
|
|
||||||
resource);
|
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
if (resource->destroy)
|
||||||
|
resource->destroy (resource);
|
||||||
|
|
||||||
|
pinos_log_debug ("resource %p: free", resource);
|
||||||
|
free (resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ PinosResource * pinos_resource_new (PinosClient *client,
|
||||||
uint32_t type,
|
uint32_t type,
|
||||||
void *object,
|
void *object,
|
||||||
PinosDestroy destroy);
|
PinosDestroy destroy);
|
||||||
SpaResult pinos_resource_destroy (PinosResource *resource);
|
void pinos_resource_destroy (PinosResource *resource);
|
||||||
|
|
||||||
void pinos_resource_set_dispatch (PinosResource *resource,
|
void pinos_resource_set_dispatch (PinosResource *resource,
|
||||||
PinosDispatchFunc func,
|
PinosDispatchFunc func,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue