mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
Work on async cleanup
Track all async changes and only perform free of resources when all previous async operations completed.
This commit is contained in:
parent
7ecfc28d0f
commit
1d61fd3696
19 changed files with 270 additions and 130 deletions
|
|
@ -1021,7 +1021,7 @@ pinos_connection_flush (PinosConnection *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
len = sendmsg (conn->fd, &msg, 0);
|
len = sendmsg (conn->fd, &msg, MSG_NOSIGNAL);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,12 @@ gst_pinos_src_finalize (GObject * object)
|
||||||
|
|
||||||
g_queue_foreach (&pinossrc->queue, (GFunc) gst_mini_object_unref, NULL);
|
g_queue_foreach (&pinossrc->queue, (GFunc) gst_mini_object_unref, NULL);
|
||||||
g_queue_clear (&pinossrc->queue);
|
g_queue_clear (&pinossrc->queue);
|
||||||
|
|
||||||
|
pinos_thread_main_loop_destroy (pinossrc->main_loop);
|
||||||
|
pinossrc->main_loop = NULL;
|
||||||
|
pinos_loop_destroy (pinossrc->loop);
|
||||||
|
pinossrc->loop = NULL;
|
||||||
|
|
||||||
if (pinossrc->properties)
|
if (pinossrc->properties)
|
||||||
gst_structure_free (pinossrc->properties);
|
gst_structure_free (pinossrc->properties);
|
||||||
g_object_unref (pinossrc->fd_allocator);
|
g_object_unref (pinossrc->fd_allocator);
|
||||||
|
|
@ -275,6 +281,10 @@ gst_pinos_src_init (GstPinosSrc * src)
|
||||||
src->fd_allocator = gst_fd_allocator_new ();
|
src->fd_allocator = gst_fd_allocator_new ();
|
||||||
src->client_name = pinos_client_name ();
|
src->client_name = pinos_client_name ();
|
||||||
src->buf_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) gst_buffer_unref);
|
src->buf_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) gst_buffer_unref);
|
||||||
|
|
||||||
|
src->loop = pinos_loop_new ();
|
||||||
|
src->main_loop = pinos_thread_main_loop_new (src->loop, "pinos-main-loop");
|
||||||
|
GST_DEBUG ("loop %p, mainloop %p", src->loop, src->main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
|
|
@ -989,10 +999,6 @@ gst_pinos_src_open (GstPinosSrc * pinossrc)
|
||||||
{
|
{
|
||||||
PinosProperties *props;
|
PinosProperties *props;
|
||||||
|
|
||||||
pinossrc->loop = pinos_loop_new ();
|
|
||||||
GST_DEBUG ("loop %p", pinossrc->loop);
|
|
||||||
|
|
||||||
pinossrc->main_loop = pinos_thread_main_loop_new (pinossrc->loop, "pinos-main-loop");
|
|
||||||
if (pinos_thread_main_loop_start (pinossrc->main_loop) != SPA_RESULT_OK)
|
if (pinos_thread_main_loop_start (pinossrc->main_loop) != SPA_RESULT_OK)
|
||||||
goto mainloop_failed;
|
goto mainloop_failed;
|
||||||
|
|
||||||
|
|
@ -1052,24 +1058,19 @@ connect_error:
|
||||||
static void
|
static void
|
||||||
gst_pinos_src_close (GstPinosSrc * pinossrc)
|
gst_pinos_src_close (GstPinosSrc * pinossrc)
|
||||||
{
|
{
|
||||||
|
clear_queue (pinossrc);
|
||||||
|
|
||||||
pinos_thread_main_loop_stop (pinossrc->main_loop);
|
pinos_thread_main_loop_stop (pinossrc->main_loop);
|
||||||
pinos_thread_main_loop_destroy (pinossrc->main_loop);
|
|
||||||
pinossrc->main_loop = NULL;
|
pinos_stream_destroy (pinossrc->stream);
|
||||||
|
pinossrc->stream = NULL;
|
||||||
|
|
||||||
pinos_context_destroy (pinossrc->ctx);
|
pinos_context_destroy (pinossrc->ctx);
|
||||||
pinossrc->ctx = NULL;
|
pinossrc->ctx = NULL;
|
||||||
|
|
||||||
pinos_loop_destroy (pinossrc->loop);
|
|
||||||
pinossrc->loop = NULL;
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (pinossrc);
|
GST_OBJECT_LOCK (pinossrc);
|
||||||
g_clear_object (&pinossrc->clock);
|
g_clear_object (&pinossrc->clock);
|
||||||
g_clear_object (&pinossrc->stream);
|
|
||||||
GST_OBJECT_UNLOCK (pinossrc);
|
GST_OBJECT_UNLOCK (pinossrc);
|
||||||
clear_queue (pinossrc);
|
|
||||||
if (pinossrc->clock)
|
|
||||||
gst_object_unref (pinossrc->clock);
|
|
||||||
pinossrc->clock = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
|
|
||||||
|
|
@ -124,15 +124,30 @@ object_new (size_t size,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
object_destroy (PinosProtocolNativeObject *this)
|
sync_destroy (void *object,
|
||||||
|
void *data,
|
||||||
|
SpaResult res,
|
||||||
|
uint32_t id)
|
||||||
{
|
{
|
||||||
spa_list_remove (&this->link);
|
PinosProtocolNativeObject *this = object;
|
||||||
|
|
||||||
if (this->destroy)
|
if (this->destroy)
|
||||||
this->destroy (this);
|
this->destroy (this);
|
||||||
free (this);
|
free (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
object_destroy (PinosProtocolNativeObject *this)
|
||||||
|
{
|
||||||
|
spa_list_remove (&this->link);
|
||||||
|
|
||||||
|
pinos_main_loop_defer (this->impl->core->main_loop,
|
||||||
|
this,
|
||||||
|
SPA_RESULT_WAIT_SYNC,
|
||||||
|
sync_destroy,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
static PinosProtocolNativeObject *
|
static PinosProtocolNativeObject *
|
||||||
find_object (PinosProtocolNative *impl,
|
find_object (PinosProtocolNative *impl,
|
||||||
void *object)
|
void *object)
|
||||||
|
|
@ -149,8 +164,9 @@ static void
|
||||||
client_destroy (PinosProtocolNativeClient *this)
|
client_destroy (PinosProtocolNativeClient *this)
|
||||||
{
|
{
|
||||||
spa_list_remove (&this->link);
|
spa_list_remove (&this->link);
|
||||||
pinos_loop_destroy_source (this->parent.impl->core->main_loop->loop,
|
if (this->source)
|
||||||
this->source);
|
pinos_loop_destroy_source (this->parent.impl->core->main_loop->loop,
|
||||||
|
this->source);
|
||||||
pinos_connection_destroy (this->connection);
|
pinos_connection_destroy (this->connection);
|
||||||
close (this->fd);
|
close (this->fd);
|
||||||
}
|
}
|
||||||
|
|
@ -276,6 +292,10 @@ connection_data (SpaSource *source,
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
|
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
|
||||||
|
pinos_log_debug ("protocol-native %p: got connection error", client->parent.impl);
|
||||||
|
pinos_loop_destroy_source (client->parent.impl->core->main_loop->loop,
|
||||||
|
client->source);
|
||||||
|
client->source = NULL;
|
||||||
pinos_client_destroy (client->parent.global->object);
|
pinos_client_destroy (client->parent.global->object);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1274,14 +1274,15 @@ pinos_client_node_new (PinosClient *client,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_node_remove (PinosNode *node,
|
on_node_remove (void *object,
|
||||||
void *data,
|
void *data,
|
||||||
SpaResult res)
|
SpaResult res,
|
||||||
|
uint32_t id)
|
||||||
{
|
{
|
||||||
PinosClientNode *this = data;
|
PinosClientNode *this = object;
|
||||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||||
|
|
||||||
pinos_log_debug ("client-node %p: finalize", node);
|
pinos_log_debug ("client-node %p: finalize", this);
|
||||||
proxy_clear (&impl->proxy);
|
proxy_clear (&impl->proxy);
|
||||||
|
|
||||||
if (impl->data_fd != -1)
|
if (impl->data_fd != -1)
|
||||||
|
|
@ -1290,24 +1291,21 @@ on_node_remove (PinosNode *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SpaResult
|
void
|
||||||
pinos_client_node_destroy (PinosClientNode * this)
|
pinos_client_node_destroy (PinosClientNode * this)
|
||||||
{
|
{
|
||||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||||
SpaResult res;
|
|
||||||
|
|
||||||
pinos_log_debug ("client-node %p: destroy", impl);
|
pinos_log_debug ("client-node %p: destroy", impl);
|
||||||
pinos_signal_emit (&this->destroy_signal, this);
|
pinos_signal_emit (&this->destroy_signal, this);
|
||||||
|
|
||||||
res = pinos_node_destroy (this->node);
|
pinos_node_destroy (this->node);
|
||||||
|
|
||||||
pinos_main_loop_defer (this->node->core->main_loop,
|
pinos_main_loop_defer (this->node->core->main_loop,
|
||||||
this->node,
|
this,
|
||||||
res,
|
SPA_RESULT_WAIT_SYNC,
|
||||||
(PinosDeferFunc) on_node_remove,
|
(PinosDeferFunc) on_node_remove,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ PinosClientNode * pinos_client_node_new (PinosClient *client,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
const char *name,
|
const char *name,
|
||||||
PinosProperties *properties);
|
PinosProperties *properties);
|
||||||
SpaResult pinos_client_node_destroy (PinosClientNode *node);
|
void pinos_client_node_destroy (PinosClientNode *node);
|
||||||
|
|
||||||
SpaResult pinos_client_node_get_data_socket (PinosClientNode *node, int *fd);
|
SpaResult pinos_client_node_get_data_socket (PinosClientNode *node, int *fd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,32 +63,46 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pinos_client_destroy:
|
* pinos_client_destroy:
|
||||||
* @client: a #PinosClient
|
* @client: a #PinosClient
|
||||||
*
|
*
|
||||||
* Trigger removal of @client
|
* Trigger removal of @client
|
||||||
*/
|
*/
|
||||||
SpaResult
|
void
|
||||||
pinos_client_destroy (PinosClient * client)
|
pinos_client_destroy (PinosClient * client)
|
||||||
{
|
{
|
||||||
PinosClientImpl *impl = SPA_CONTAINER_OF (client, PinosClientImpl, this);
|
|
||||||
PinosResource *resource, *tmp;
|
PinosResource *resource, *tmp;
|
||||||
|
|
||||||
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_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_global_destroy (client->global);
|
||||||
spa_list_remove (&client->link);
|
spa_list_remove (&client->link);
|
||||||
|
|
||||||
if (client->properties)
|
pinos_main_loop_defer (client->core->main_loop,
|
||||||
pinos_properties_free (client->properties);
|
client,
|
||||||
|
SPA_RESULT_WAIT_SYNC,
|
||||||
free (impl);
|
sync_destroy,
|
||||||
|
client);
|
||||||
return SPA_RESULT_OK;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ struct _PinosClient {
|
||||||
|
|
||||||
PinosClient * pinos_client_new (PinosCore *core,
|
PinosClient * pinos_client_new (PinosCore *core,
|
||||||
PinosProperties *properties);
|
PinosProperties *properties);
|
||||||
SpaResult pinos_client_destroy (PinosClient *client);
|
void pinos_client_destroy (PinosClient *client);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,24 @@ pinos_core_add_global (PinosCore *core,
|
||||||
return global;
|
return global;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpaResult
|
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
|
||||||
pinos_global_destroy (PinosGlobal *global)
|
pinos_global_destroy (PinosGlobal *global)
|
||||||
{
|
{
|
||||||
PinosCore *core = global->core;
|
PinosCore *core = global->core;
|
||||||
|
|
||||||
|
pinos_log_debug ("global %p: destroy", global);
|
||||||
pinos_signal_emit (&global->destroy_signal, global);
|
pinos_signal_emit (&global->destroy_signal, global);
|
||||||
|
|
||||||
pinos_map_remove (&core->objects, global->id);
|
pinos_map_remove (&core->objects, global->id);
|
||||||
|
|
@ -126,9 +139,11 @@ pinos_global_destroy (PinosGlobal *global)
|
||||||
spa_list_remove (&global->link);
|
spa_list_remove (&global->link);
|
||||||
pinos_signal_emit (&core->global_removed, core, global);
|
pinos_signal_emit (&core->global_removed, core, global);
|
||||||
|
|
||||||
free (global);
|
pinos_main_loop_defer (core->main_loop,
|
||||||
|
global,
|
||||||
return SPA_RESULT_OK;
|
SPA_RESULT_WAIT_SYNC,
|
||||||
|
sync_destroy,
|
||||||
|
global);
|
||||||
}
|
}
|
||||||
|
|
||||||
PinosPort *
|
PinosPort *
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ void pinos_core_destroy (PinosCore *core);
|
||||||
PinosGlobal * pinos_core_add_global (PinosCore *core,
|
PinosGlobal * pinos_core_add_global (PinosCore *core,
|
||||||
uint32_t type,
|
uint32_t type,
|
||||||
void *object);
|
void *object);
|
||||||
SpaResult pinos_global_destroy (PinosGlobal *global);
|
void pinos_global_destroy (PinosGlobal *global);
|
||||||
|
|
||||||
|
|
||||||
PinosPort * pinos_core_find_port (PinosCore *core,
|
PinosPort * pinos_core_find_port (PinosCore *core,
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@ again:
|
||||||
asprintf (&error, "error set output format: %d", res);
|
asprintf (&error, "error set output format: %d", res);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
pinos_main_loop_defer (this->core->main_loop, this->output->node, res, NULL, NULL);
|
||||||
} else if (in_state == SPA_NODE_STATE_CONFIGURE) {
|
} else if (in_state == SPA_NODE_STATE_CONFIGURE) {
|
||||||
pinos_log_debug ("link %p: doing set format on input", this);
|
pinos_log_debug ("link %p: doing set format on input", this);
|
||||||
if ((res = spa_node_port_set_format (this->input->node->node,
|
if ((res = spa_node_port_set_format (this->input->node->node,
|
||||||
|
|
@ -164,6 +165,7 @@ again:
|
||||||
asprintf (&error, "error set input format: %d", res);
|
asprintf (&error, "error set input format: %d", res);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
pinos_main_loop_defer (this->core->main_loop, this->input->node, res, NULL, NULL);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
@ -419,6 +421,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||||
asprintf (&error, "error alloc output buffers: %d", res);
|
asprintf (&error, "error alloc output buffers: %d", res);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
pinos_main_loop_defer (this->core->main_loop, this->output->node, res, NULL, NULL);
|
||||||
this->output->buffers = impl->buffers;
|
this->output->buffers = impl->buffers;
|
||||||
this->output->n_buffers = impl->n_buffers;
|
this->output->n_buffers = impl->n_buffers;
|
||||||
this->output->allocated = TRUE;
|
this->output->allocated = TRUE;
|
||||||
|
|
@ -434,6 +437,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||||
asprintf (&error, "error alloc input buffers: %d", res);
|
asprintf (&error, "error alloc input buffers: %d", res);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
pinos_main_loop_defer (this->core->main_loop, this->input->node, res, NULL, NULL);
|
||||||
this->input->buffers = impl->buffers;
|
this->input->buffers = impl->buffers;
|
||||||
this->input->n_buffers = impl->n_buffers;
|
this->input->n_buffers = impl->n_buffers;
|
||||||
this->input->allocated = TRUE;
|
this->input->allocated = TRUE;
|
||||||
|
|
@ -453,6 +457,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||||
asprintf (&error, "error use input buffers: %d", res);
|
asprintf (&error, "error use input buffers: %d", res);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
pinos_main_loop_defer (this->core->main_loop, this->input->node, res, NULL, NULL);
|
||||||
this->input->buffers = impl->buffers;
|
this->input->buffers = impl->buffers;
|
||||||
this->input->n_buffers = impl->n_buffers;
|
this->input->n_buffers = impl->n_buffers;
|
||||||
this->input->allocated = FALSE;
|
this->input->allocated = FALSE;
|
||||||
|
|
@ -467,6 +472,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||||
asprintf (&error, "error use output buffers: %d", res);
|
asprintf (&error, "error use output buffers: %d", res);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
pinos_main_loop_defer (this->core->main_loop, this->output->node, res, NULL, NULL);
|
||||||
this->output->buffers = impl->buffers;
|
this->output->buffers = impl->buffers;
|
||||||
this->output->n_buffers = impl->n_buffers;
|
this->output->n_buffers = impl->n_buffers;
|
||||||
this->output->allocated = FALSE;
|
this->output->allocated = FALSE;
|
||||||
|
|
@ -519,11 +525,6 @@ check_states (PinosLink *this,
|
||||||
{
|
{
|
||||||
SpaNodeState in_state, out_state;
|
SpaNodeState in_state, out_state;
|
||||||
|
|
||||||
if (res != SPA_RESULT_OK) {
|
|
||||||
pinos_log_warn ("link %p: error: %d", this, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (this->input == NULL || this->output == NULL)
|
if (this->input == NULL || this->output == NULL)
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
|
|
@ -550,7 +551,11 @@ again:
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
pinos_main_loop_defer (this->core->main_loop, this, res, (PinosDeferFunc) check_states, this);
|
pinos_main_loop_defer (this->core->main_loop,
|
||||||
|
this,
|
||||||
|
SPA_RESULT_WAIT_SYNC,
|
||||||
|
(PinosDeferFunc) check_states,
|
||||||
|
this);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -740,7 +745,6 @@ 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);
|
||||||
|
|
@ -765,12 +769,10 @@ do_link_remove_done (SpaLoop *loop,
|
||||||
this->output = NULL;
|
this->output = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pinos_main_loop_defer_cancel (this->core->main_loop, this, 0);
|
pinos_main_loop_defer_complete (this->core->main_loop,
|
||||||
|
this,
|
||||||
if (impl->allocated)
|
seq,
|
||||||
pinos_memblock_free (&impl->buffer_mem);
|
SPA_RESULT_OK);
|
||||||
|
|
||||||
free (impl);
|
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -804,13 +806,29 @@ 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
|
||||||
*
|
*
|
||||||
* Trigger removal of @link
|
* Trigger removal of @link
|
||||||
*/
|
*/
|
||||||
SpaResult
|
void
|
||||||
pinos_link_destroy (PinosLink * this)
|
pinos_link_destroy (PinosLink * this)
|
||||||
{
|
{
|
||||||
SpaResult res = SPA_RESULT_OK;
|
SpaResult res = SPA_RESULT_OK;
|
||||||
|
|
@ -832,6 +850,8 @@ pinos_link_destroy (PinosLink * this)
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
this);
|
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);
|
||||||
|
|
@ -843,6 +863,12 @@ pinos_link_destroy (PinosLink * this)
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
this);
|
this);
|
||||||
|
pinos_main_loop_defer (this->core->main_loop, this, res, NULL, NULL);
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
|
pinos_main_loop_defer (this->core->main_loop,
|
||||||
|
this,
|
||||||
|
SPA_RESULT_WAIT_SYNC,
|
||||||
|
sync_destroy,
|
||||||
|
this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ PinosLink * pinos_link_new (PinosCore *core,
|
||||||
PinosPort *input,
|
PinosPort *input,
|
||||||
SpaFormat **format_filter,
|
SpaFormat **format_filter,
|
||||||
PinosProperties *properties);
|
PinosProperties *properties);
|
||||||
SpaResult pinos_link_destroy (PinosLink *link);
|
void pinos_link_destroy (PinosLink *link);
|
||||||
|
|
||||||
bool pinos_link_activate (PinosLink *link);
|
bool pinos_link_activate (PinosLink *link);
|
||||||
bool pinos_link_deactivate (PinosLink *link);
|
bool pinos_link_deactivate (PinosLink *link);
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,15 @@ process_work_queue (SpaSource *source,
|
||||||
WorkItem *item, *tmp;
|
WorkItem *item, *tmp;
|
||||||
|
|
||||||
spa_list_for_each_safe (item, tmp, &impl->work_list, link) {
|
spa_list_for_each_safe (item, tmp, &impl->work_list, link) {
|
||||||
if (item->seq != SPA_ID_INVALID)
|
if (item->seq != SPA_ID_INVALID) {
|
||||||
|
pinos_log_debug ("main-loop %p: waiting for item %p %d", this, item->obj, item->seq);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->res == SPA_RESULT_WAIT_SYNC && item != spa_list_first (&impl->work_list, WorkItem, link)) {
|
||||||
|
pinos_log_debug ("main-loop %p: sync item %p not head", this, item->obj);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
spa_list_remove (&item->link);
|
spa_list_remove (&item->link);
|
||||||
|
|
||||||
|
|
@ -78,11 +85,11 @@ process_work_queue (SpaSource *source,
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
do_add_work (PinosMainLoop *loop,
|
main_loop_defer (PinosMainLoop *loop,
|
||||||
void *obj,
|
void *obj,
|
||||||
SpaResult res,
|
SpaResult res,
|
||||||
PinosDeferFunc func,
|
PinosDeferFunc func,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
|
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
|
||||||
WorkItem *item;
|
WorkItem *item;
|
||||||
|
|
@ -103,6 +110,11 @@ do_add_work (PinosMainLoop *loop,
|
||||||
item->seq = SPA_RESULT_ASYNC_SEQ (res);
|
item->seq = SPA_RESULT_ASYNC_SEQ (res);
|
||||||
item->res = res;
|
item->res = res;
|
||||||
pinos_log_debug ("main-loop %p: defer async %d for object %p", loop, item->seq, obj);
|
pinos_log_debug ("main-loop %p: defer async %d for object %p", loop, item->seq, obj);
|
||||||
|
} else if (res == SPA_RESULT_WAIT_SYNC) {
|
||||||
|
pinos_log_debug ("main-loop %p: wait sync object %p", loop, obj);
|
||||||
|
item->seq = SPA_ID_INVALID;
|
||||||
|
item->res = res;
|
||||||
|
have_work = TRUE;
|
||||||
} else {
|
} else {
|
||||||
item->seq = SPA_ID_INVALID;
|
item->seq = SPA_ID_INVALID;
|
||||||
item->res = res;
|
item->res = res;
|
||||||
|
|
@ -117,16 +129,6 @@ do_add_work (PinosMainLoop *loop,
|
||||||
return item->id;
|
return item->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
|
||||||
main_loop_defer (PinosMainLoop *loop,
|
|
||||||
void *obj,
|
|
||||||
SpaResult res,
|
|
||||||
PinosDeferFunc func,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
return do_add_work (loop, obj, res, func, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
main_loop_defer_cancel (PinosMainLoop *loop,
|
main_loop_defer_cancel (PinosMainLoop *loop,
|
||||||
void *obj,
|
void *obj,
|
||||||
|
|
@ -175,28 +177,6 @@ main_loop_defer_complete (PinosMainLoop *loop,
|
||||||
return have_work;
|
return have_work;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
main_loop_quit (PinosMainLoop *loop)
|
|
||||||
{
|
|
||||||
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
|
|
||||||
pinos_log_debug ("main-loop %p: quit", impl);
|
|
||||||
impl->running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
main_loop_run (PinosMainLoop *loop)
|
|
||||||
{
|
|
||||||
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
|
|
||||||
|
|
||||||
pinos_log_debug ("main-loop %p: run", impl);
|
|
||||||
|
|
||||||
impl->running = true;
|
|
||||||
pinos_loop_enter (loop->loop);
|
|
||||||
while (impl->running) {
|
|
||||||
pinos_loop_iterate (loop->loop, -1);
|
|
||||||
}
|
|
||||||
pinos_loop_leave (loop->loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pinos_main_loop_new:
|
* pinos_main_loop_new:
|
||||||
|
|
@ -223,8 +203,6 @@ pinos_main_loop_new (void)
|
||||||
process_work_queue,
|
process_work_queue,
|
||||||
impl);
|
impl);
|
||||||
|
|
||||||
this->run = main_loop_run;
|
|
||||||
this->quit = main_loop_quit;
|
|
||||||
this->defer = main_loop_defer;
|
this->defer = main_loop_defer;
|
||||||
this->defer_cancel = main_loop_defer_cancel;
|
this->defer_cancel = main_loop_defer_cancel;
|
||||||
this->defer_complete = main_loop_defer_complete;
|
this->defer_complete = main_loop_defer_complete;
|
||||||
|
|
@ -251,3 +229,26 @@ pinos_main_loop_destroy (PinosMainLoop *loop)
|
||||||
free (item);
|
free (item);
|
||||||
free (impl);
|
free (impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pinos_main_loop_quit (PinosMainLoop *loop)
|
||||||
|
{
|
||||||
|
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
|
||||||
|
pinos_log_debug ("main-loop %p: quit", impl);
|
||||||
|
impl->running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pinos_main_loop_run (PinosMainLoop *loop)
|
||||||
|
{
|
||||||
|
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
|
||||||
|
|
||||||
|
pinos_log_debug ("main-loop %p: run", impl);
|
||||||
|
|
||||||
|
impl->running = true;
|
||||||
|
pinos_loop_enter (loop->loop);
|
||||||
|
while (impl->running) {
|
||||||
|
pinos_loop_iterate (loop->loop, -1);
|
||||||
|
}
|
||||||
|
pinos_loop_leave (loop->loop);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,6 @@ struct _PinosMainLoop {
|
||||||
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
||||||
PinosMainLoop *loop));
|
PinosMainLoop *loop));
|
||||||
|
|
||||||
void (*run) (PinosMainLoop *loop);
|
|
||||||
void (*quit) (PinosMainLoop *loop);
|
|
||||||
|
|
||||||
uint32_t (*defer) (PinosMainLoop *loop,
|
uint32_t (*defer) (PinosMainLoop *loop,
|
||||||
void *obj,
|
void *obj,
|
||||||
SpaResult res,
|
SpaResult res,
|
||||||
|
|
@ -65,13 +62,12 @@ struct _PinosMainLoop {
|
||||||
PinosMainLoop * pinos_main_loop_new (void);
|
PinosMainLoop * pinos_main_loop_new (void);
|
||||||
void pinos_main_loop_destroy (PinosMainLoop *loop);
|
void pinos_main_loop_destroy (PinosMainLoop *loop);
|
||||||
|
|
||||||
#define pinos_main_loop_run(m) (m)->run(m)
|
void pinos_main_loop_run (PinosMainLoop *loop);
|
||||||
#define pinos_main_loop_quit(m) (m)->quit(m)
|
void pinos_main_loop_quit (PinosMainLoop *loop);
|
||||||
|
|
||||||
#define pinos_main_loop_defer(m,...) (m)->defer(m,__VA_ARGS__)
|
#define pinos_main_loop_defer(m,...) (m)->defer(m,__VA_ARGS__)
|
||||||
#define pinos_main_loop_defer_cancel(m,...) (m)->defer_cancel(m,__VA_ARGS__)
|
#define pinos_main_loop_defer_cancel(m,...) (m)->defer_cancel(m,__VA_ARGS__)
|
||||||
#define pinos_main_loop_defer_complete(m,...) (m)->defer_complete(m,__VA_ARGS__)
|
#define pinos_main_loop_defer_complete(m,...) (m)->defer_complete(m,__VA_ARGS__)
|
||||||
#define pinos_main_loop_sync(m,...) (m)->sync(m,__VA_ARGS__)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -477,22 +477,19 @@ 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_main_loop_defer_cancel (this->core->main_loop, this, 0);
|
pinos_log_debug ("node %p: remove done, destroy ports", this);
|
||||||
|
|
||||||
spa_list_for_each_safe (port, tmp, &this->input_ports, link)
|
spa_list_for_each_safe (port, tmp, &this->input_ports, link)
|
||||||
pinos_port_destroy (port);
|
pinos_port_destroy (port);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
free (this->name);
|
pinos_main_loop_defer_complete (this->core->main_loop,
|
||||||
free (this->error);
|
this,
|
||||||
if (this->properties)
|
seq,
|
||||||
pinos_properties_free (this->properties);
|
SPA_RESULT_OK);
|
||||||
free (impl);
|
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -536,6 +533,24 @@ 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
|
||||||
|
|
@ -543,7 +558,7 @@ do_node_remove (SpaLoop *loop,
|
||||||
* Remove @node. This will stop the transfer on the node and
|
* Remove @node. This will stop the transfer on the node and
|
||||||
* free the resources allocated by @node.
|
* free the resources allocated by @node.
|
||||||
*/
|
*/
|
||||||
SpaResult
|
void
|
||||||
pinos_node_destroy (PinosNode * this)
|
pinos_node_destroy (PinosNode * this)
|
||||||
{
|
{
|
||||||
SpaResult res;
|
SpaResult res;
|
||||||
|
|
@ -561,7 +576,18 @@ pinos_node_destroy (PinosNode * this)
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
this);
|
this);
|
||||||
return res;
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ PinosNode * pinos_node_new (PinosCore *core,
|
||||||
SpaNode *node,
|
SpaNode *node,
|
||||||
SpaClock *clock,
|
SpaClock *clock,
|
||||||
PinosProperties *properties);
|
PinosProperties *properties);
|
||||||
SpaResult pinos_node_destroy (PinosNode *node);
|
void pinos_node_destroy (PinosNode *node);
|
||||||
|
|
||||||
|
|
||||||
void pinos_node_set_data_loop (PinosNode *node,
|
void pinos_node_set_data_loop (PinosNode *node,
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,17 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -61,6 +72,8 @@ pinos_port_destroy (PinosPort *port)
|
||||||
|
|
||||||
pinos_signal_emit (&port->destroy_signal, port);
|
pinos_signal_emit (&port->destroy_signal, port);
|
||||||
|
|
||||||
|
spa_list_remove (&port->link);
|
||||||
|
|
||||||
spa_node_port_use_buffers (port->node->node,
|
spa_node_port_use_buffers (port->node->node,
|
||||||
port->direction,
|
port->direction,
|
||||||
port->port_id,
|
port->port_id,
|
||||||
|
|
@ -68,8 +81,11 @@ pinos_port_destroy (PinosPort *port)
|
||||||
port->buffers = NULL;
|
port->buffers = NULL;
|
||||||
port->n_buffers = 0;
|
port->n_buffers = 0;
|
||||||
|
|
||||||
spa_list_remove (&port->link);
|
pinos_main_loop_defer (port->node->core->main_loop,
|
||||||
free (port);
|
port,
|
||||||
|
SPA_RESULT_WAIT_SYNC,
|
||||||
|
sync_destroy,
|
||||||
|
port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaResult
|
static SpaResult
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,17 @@ pinos_resource_new (PinosClient *client,
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static 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
|
SpaResult
|
||||||
pinos_resource_destroy (PinosResource *resource)
|
pinos_resource_destroy (PinosResource *resource)
|
||||||
{
|
{
|
||||||
|
|
@ -61,7 +72,11 @@ pinos_resource_destroy (PinosResource *resource)
|
||||||
if (resource->destroy)
|
if (resource->destroy)
|
||||||
resource->destroy (resource->object);
|
resource->destroy (resource->object);
|
||||||
|
|
||||||
free (resource);
|
pinos_main_loop_defer (resource->core->main_loop,
|
||||||
|
resource,
|
||||||
|
SPA_RESULT_WAIT_SYNC,
|
||||||
|
sync_destroy,
|
||||||
|
resource);
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ extern "C" {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPA_RESULT_ASYNC = (1 << 30),
|
SPA_RESULT_ASYNC = (1 << 30),
|
||||||
|
SPA_RESULT_WAIT_SYNC = 2,
|
||||||
SPA_RESULT_MODIFIED = 1,
|
SPA_RESULT_MODIFIED = 1,
|
||||||
SPA_RESULT_OK = 0,
|
SPA_RESULT_OK = 0,
|
||||||
SPA_RESULT_ERROR = -1,
|
SPA_RESULT_ERROR = -1,
|
||||||
|
|
|
||||||
|
|
@ -40,16 +40,27 @@ struct _SpaDict {
|
||||||
SpaDictItem *items;
|
SpaDictItem *items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define spa_dict_for_each(item, dict) \
|
||||||
|
for ((item) = (dict)->items; \
|
||||||
|
(item) < &(dict)->items[(dict)->n_items]; \
|
||||||
|
(item)++)
|
||||||
|
|
||||||
|
static inline SpaDictItem *
|
||||||
|
spa_dict_lookup_item (const SpaDict *dict, const char *key)
|
||||||
|
{
|
||||||
|
SpaDictItem *item;
|
||||||
|
spa_dict_for_each (item, dict) {
|
||||||
|
if (!strcmp (item->key, key))
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline const char *
|
static inline const char *
|
||||||
spa_dict_lookup (const SpaDict *dict, const char *key)
|
spa_dict_lookup (const SpaDict *dict, const char *key)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
SpaDictItem *item = spa_dict_lookup_item (dict, key);
|
||||||
|
return item ? item->value : NULL;
|
||||||
for (i = 0; i < dict->n_items; i++) {
|
|
||||||
if (!strcmp (dict->items[i].key, key))
|
|
||||||
return dict->items[i].value;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue