mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -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) {
|
||||
len = sendmsg (conn->fd, &msg, 0);
|
||||
len = sendmsg (conn->fd, &msg, MSG_NOSIGNAL);
|
||||
if (len < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -180,6 +180,12 @@ gst_pinos_src_finalize (GObject * object)
|
|||
|
||||
g_queue_foreach (&pinossrc->queue, (GFunc) gst_mini_object_unref, NULL);
|
||||
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)
|
||||
gst_structure_free (pinossrc->properties);
|
||||
g_object_unref (pinossrc->fd_allocator);
|
||||
|
|
@ -275,6 +281,10 @@ gst_pinos_src_init (GstPinosSrc * src)
|
|||
src->fd_allocator = gst_fd_allocator_new ();
|
||||
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->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 *
|
||||
|
|
@ -989,10 +999,6 @@ gst_pinos_src_open (GstPinosSrc * pinossrc)
|
|||
{
|
||||
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)
|
||||
goto mainloop_failed;
|
||||
|
||||
|
|
@ -1052,24 +1058,19 @@ connect_error:
|
|||
static void
|
||||
gst_pinos_src_close (GstPinosSrc * pinossrc)
|
||||
{
|
||||
clear_queue (pinossrc);
|
||||
|
||||
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);
|
||||
pinossrc->ctx = NULL;
|
||||
|
||||
pinos_loop_destroy (pinossrc->loop);
|
||||
pinossrc->loop = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (pinossrc);
|
||||
g_clear_object (&pinossrc->clock);
|
||||
g_clear_object (&pinossrc->stream);
|
||||
GST_OBJECT_UNLOCK (pinossrc);
|
||||
clear_queue (pinossrc);
|
||||
if (pinossrc->clock)
|
||||
gst_object_unref (pinossrc->clock);
|
||||
pinossrc->clock = NULL;
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
|
|
|
|||
|
|
@ -124,15 +124,30 @@ object_new (size_t size,
|
|||
}
|
||||
|
||||
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)
|
||||
this->destroy (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 *
|
||||
find_object (PinosProtocolNative *impl,
|
||||
void *object)
|
||||
|
|
@ -149,8 +164,9 @@ static void
|
|||
client_destroy (PinosProtocolNativeClient *this)
|
||||
{
|
||||
spa_list_remove (&this->link);
|
||||
pinos_loop_destroy_source (this->parent.impl->core->main_loop->loop,
|
||||
this->source);
|
||||
if (this->source)
|
||||
pinos_loop_destroy_source (this->parent.impl->core->main_loop->loop,
|
||||
this->source);
|
||||
pinos_connection_destroy (this->connection);
|
||||
close (this->fd);
|
||||
}
|
||||
|
|
@ -276,6 +292,10 @@ connection_data (SpaSource *source,
|
|||
size_t size;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1274,14 +1274,15 @@ pinos_client_node_new (PinosClient *client,
|
|||
}
|
||||
|
||||
static void
|
||||
on_node_remove (PinosNode *node,
|
||||
on_node_remove (void *object,
|
||||
void *data,
|
||||
SpaResult res)
|
||||
SpaResult res,
|
||||
uint32_t id)
|
||||
{
|
||||
PinosClientNode *this = data;
|
||||
PinosClientNode *this = object;
|
||||
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);
|
||||
|
||||
if (impl->data_fd != -1)
|
||||
|
|
@ -1290,24 +1291,21 @@ on_node_remove (PinosNode *node,
|
|||
}
|
||||
|
||||
|
||||
SpaResult
|
||||
void
|
||||
pinos_client_node_destroy (PinosClientNode * this)
|
||||
{
|
||||
PinosClientNodeImpl *impl = SPA_CONTAINER_OF (this, PinosClientNodeImpl, this);
|
||||
SpaResult res;
|
||||
|
||||
pinos_log_debug ("client-node %p: destroy", impl);
|
||||
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,
|
||||
this->node,
|
||||
res,
|
||||
this,
|
||||
SPA_RESULT_WAIT_SYNC,
|
||||
(PinosDeferFunc) on_node_remove,
|
||||
this);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ PinosClientNode * pinos_client_node_new (PinosClient *client,
|
|||
uint32_t id,
|
||||
const char *name,
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,32 +63,46 @@ pinos_client_new (PinosCore *core,
|
|||
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:
|
||||
* @client: a #PinosClient
|
||||
*
|
||||
* Trigger removal of @client
|
||||
*/
|
||||
SpaResult
|
||||
void
|
||||
pinos_client_destroy (PinosClient * client)
|
||||
{
|
||||
PinosClientImpl *impl = SPA_CONTAINER_OF (client, PinosClientImpl, this);
|
||||
PinosResource *resource, *tmp;
|
||||
|
||||
pinos_log_debug ("client %p: destroy", client);
|
||||
pinos_signal_emit (&client->destroy_signal, client);
|
||||
|
||||
pinos_global_destroy (client->global);
|
||||
|
||||
spa_list_for_each_safe (resource, tmp, &client->resource_list, link)
|
||||
pinos_resource_destroy (resource);
|
||||
|
||||
pinos_global_destroy (client->global);
|
||||
spa_list_remove (&client->link);
|
||||
|
||||
if (client->properties)
|
||||
pinos_properties_free (client->properties);
|
||||
|
||||
free (impl);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
pinos_main_loop_defer (client->core->main_loop,
|
||||
client,
|
||||
SPA_RESULT_WAIT_SYNC,
|
||||
sync_destroy,
|
||||
client);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ struct _PinosClient {
|
|||
|
||||
PinosClient * pinos_client_new (PinosCore *core,
|
||||
PinosProperties *properties);
|
||||
SpaResult pinos_client_destroy (PinosClient *client);
|
||||
void pinos_client_destroy (PinosClient *client);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,11 +114,24 @@ pinos_core_add_global (PinosCore *core,
|
|||
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)
|
||||
{
|
||||
PinosCore *core = global->core;
|
||||
|
||||
pinos_log_debug ("global %p: destroy", global);
|
||||
pinos_signal_emit (&global->destroy_signal, global);
|
||||
|
||||
pinos_map_remove (&core->objects, global->id);
|
||||
|
|
@ -126,9 +139,11 @@ pinos_global_destroy (PinosGlobal *global)
|
|||
spa_list_remove (&global->link);
|
||||
pinos_signal_emit (&core->global_removed, core, global);
|
||||
|
||||
free (global);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
pinos_main_loop_defer (core->main_loop,
|
||||
global,
|
||||
SPA_RESULT_WAIT_SYNC,
|
||||
sync_destroy,
|
||||
global);
|
||||
}
|
||||
|
||||
PinosPort *
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ void pinos_core_destroy (PinosCore *core);
|
|||
PinosGlobal * pinos_core_add_global (PinosCore *core,
|
||||
uint32_t type,
|
||||
void *object);
|
||||
SpaResult pinos_global_destroy (PinosGlobal *global);
|
||||
void pinos_global_destroy (PinosGlobal *global);
|
||||
|
||||
|
||||
PinosPort * pinos_core_find_port (PinosCore *core,
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ again:
|
|||
asprintf (&error, "error set output format: %d", res);
|
||||
goto error;
|
||||
}
|
||||
pinos_main_loop_defer (this->core->main_loop, this->output->node, res, NULL, NULL);
|
||||
} else if (in_state == SPA_NODE_STATE_CONFIGURE) {
|
||||
pinos_log_debug ("link %p: doing set format on input", this);
|
||||
if ((res = spa_node_port_set_format (this->input->node->node,
|
||||
|
|
@ -164,6 +165,7 @@ again:
|
|||
asprintf (&error, "error set input format: %d", res);
|
||||
goto error;
|
||||
}
|
||||
pinos_main_loop_defer (this->core->main_loop, this->input->node, res, NULL, NULL);
|
||||
}
|
||||
return res;
|
||||
|
||||
|
|
@ -419,6 +421,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
|||
asprintf (&error, "error alloc output buffers: %d", res);
|
||||
goto error;
|
||||
}
|
||||
pinos_main_loop_defer (this->core->main_loop, this->output->node, res, NULL, NULL);
|
||||
this->output->buffers = impl->buffers;
|
||||
this->output->n_buffers = impl->n_buffers;
|
||||
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);
|
||||
goto error;
|
||||
}
|
||||
pinos_main_loop_defer (this->core->main_loop, this->input->node, res, NULL, NULL);
|
||||
this->input->buffers = impl->buffers;
|
||||
this->input->n_buffers = impl->n_buffers;
|
||||
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);
|
||||
goto error;
|
||||
}
|
||||
pinos_main_loop_defer (this->core->main_loop, this->input->node, res, NULL, NULL);
|
||||
this->input->buffers = impl->buffers;
|
||||
this->input->n_buffers = impl->n_buffers;
|
||||
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);
|
||||
goto error;
|
||||
}
|
||||
pinos_main_loop_defer (this->core->main_loop, this->output->node, res, NULL, NULL);
|
||||
this->output->buffers = impl->buffers;
|
||||
this->output->n_buffers = impl->n_buffers;
|
||||
this->output->allocated = FALSE;
|
||||
|
|
@ -519,11 +525,6 @@ check_states (PinosLink *this,
|
|||
{
|
||||
SpaNodeState in_state, out_state;
|
||||
|
||||
if (res != SPA_RESULT_OK) {
|
||||
pinos_log_warn ("link %p: error: %d", this, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
again:
|
||||
if (this->input == NULL || this->output == NULL)
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -550,7 +551,11 @@ again:
|
|||
return SPA_RESULT_OK;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -740,7 +745,6 @@ do_link_remove_done (SpaLoop *loop,
|
|||
void *user_data)
|
||||
{
|
||||
PinosLink *this = user_data;
|
||||
PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
|
||||
|
||||
if (this->input) {
|
||||
spa_list_remove (&this->input_link);
|
||||
|
|
@ -765,12 +769,10 @@ do_link_remove_done (SpaLoop *loop,
|
|||
this->output = NULL;
|
||||
}
|
||||
|
||||
pinos_main_loop_defer_cancel (this->core->main_loop, this, 0);
|
||||
|
||||
if (impl->allocated)
|
||||
pinos_memblock_free (&impl->buffer_mem);
|
||||
|
||||
free (impl);
|
||||
pinos_main_loop_defer_complete (this->core->main_loop,
|
||||
this,
|
||||
seq,
|
||||
SPA_RESULT_OK);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -804,13 +806,29 @@ do_link_remove (SpaLoop *loop,
|
|||
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:
|
||||
* @link: a #PinosLink
|
||||
*
|
||||
* Trigger removal of @link
|
||||
*/
|
||||
SpaResult
|
||||
void
|
||||
pinos_link_destroy (PinosLink * this)
|
||||
{
|
||||
SpaResult res = SPA_RESULT_OK;
|
||||
|
|
@ -832,6 +850,8 @@ pinos_link_destroy (PinosLink * this)
|
|||
0,
|
||||
NULL,
|
||||
this);
|
||||
|
||||
pinos_main_loop_defer (this->core->main_loop, this, res, NULL, NULL);
|
||||
}
|
||||
if (this->output) {
|
||||
pinos_signal_remove (&impl->output_port_destroy);
|
||||
|
|
@ -843,6 +863,12 @@ pinos_link_destroy (PinosLink * this)
|
|||
0,
|
||||
NULL,
|
||||
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,
|
||||
SpaFormat **format_filter,
|
||||
PinosProperties *properties);
|
||||
SpaResult pinos_link_destroy (PinosLink *link);
|
||||
void pinos_link_destroy (PinosLink *link);
|
||||
|
||||
bool pinos_link_activate (PinosLink *link);
|
||||
bool pinos_link_deactivate (PinosLink *link);
|
||||
|
|
|
|||
|
|
@ -64,8 +64,15 @@ process_work_queue (SpaSource *source,
|
|||
WorkItem *item, *tmp;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -78,11 +85,11 @@ process_work_queue (SpaSource *source,
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
do_add_work (PinosMainLoop *loop,
|
||||
void *obj,
|
||||
SpaResult res,
|
||||
PinosDeferFunc func,
|
||||
void *data)
|
||||
main_loop_defer (PinosMainLoop *loop,
|
||||
void *obj,
|
||||
SpaResult res,
|
||||
PinosDeferFunc func,
|
||||
void *data)
|
||||
{
|
||||
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
|
||||
WorkItem *item;
|
||||
|
|
@ -103,6 +110,11 @@ do_add_work (PinosMainLoop *loop,
|
|||
item->seq = SPA_RESULT_ASYNC_SEQ (res);
|
||||
item->res = res;
|
||||
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 {
|
||||
item->seq = SPA_ID_INVALID;
|
||||
item->res = res;
|
||||
|
|
@ -117,16 +129,6 @@ do_add_work (PinosMainLoop *loop,
|
|||
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
|
||||
main_loop_defer_cancel (PinosMainLoop *loop,
|
||||
void *obj,
|
||||
|
|
@ -175,28 +177,6 @@ main_loop_defer_complete (PinosMainLoop *loop,
|
|||
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:
|
||||
|
|
@ -223,8 +203,6 @@ pinos_main_loop_new (void)
|
|||
process_work_queue,
|
||||
impl);
|
||||
|
||||
this->run = main_loop_run;
|
||||
this->quit = main_loop_quit;
|
||||
this->defer = main_loop_defer;
|
||||
this->defer_cancel = main_loop_defer_cancel;
|
||||
this->defer_complete = main_loop_defer_complete;
|
||||
|
|
@ -251,3 +229,26 @@ pinos_main_loop_destroy (PinosMainLoop *loop)
|
|||
free (item);
|
||||
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,
|
||||
PinosMainLoop *loop));
|
||||
|
||||
void (*run) (PinosMainLoop *loop);
|
||||
void (*quit) (PinosMainLoop *loop);
|
||||
|
||||
uint32_t (*defer) (PinosMainLoop *loop,
|
||||
void *obj,
|
||||
SpaResult res,
|
||||
|
|
@ -65,13 +62,12 @@ struct _PinosMainLoop {
|
|||
PinosMainLoop * pinos_main_loop_new (void);
|
||||
void pinos_main_loop_destroy (PinosMainLoop *loop);
|
||||
|
||||
#define pinos_main_loop_run(m) (m)->run(m)
|
||||
#define pinos_main_loop_quit(m) (m)->quit(m)
|
||||
void pinos_main_loop_run (PinosMainLoop *loop);
|
||||
void pinos_main_loop_quit (PinosMainLoop *loop);
|
||||
|
||||
#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_complete(m,...) (m)->defer_complete(m,__VA_ARGS__)
|
||||
#define pinos_main_loop_sync(m,...) (m)->sync(m,__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -477,22 +477,19 @@ do_node_remove_done (SpaLoop *loop,
|
|||
void *user_data)
|
||||
{
|
||||
PinosNode *this = user_data;
|
||||
PinosNodeImpl *impl = SPA_CONTAINER_OF (this, PinosNodeImpl, this);
|
||||
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)
|
||||
pinos_port_destroy (port);
|
||||
|
||||
spa_list_for_each_safe (port, tmp, &this->output_ports, link)
|
||||
pinos_port_destroy (port);
|
||||
|
||||
free (this->name);
|
||||
free (this->error);
|
||||
if (this->properties)
|
||||
pinos_properties_free (this->properties);
|
||||
free (impl);
|
||||
pinos_main_loop_defer_complete (this->core->main_loop,
|
||||
this,
|
||||
seq,
|
||||
SPA_RESULT_OK);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -536,6 +533,24 @@ do_node_remove (SpaLoop *loop,
|
|||
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:
|
||||
* @node: a #PinosNode
|
||||
|
|
@ -543,7 +558,7 @@ do_node_remove (SpaLoop *loop,
|
|||
* Remove @node. This will stop the transfer on the node and
|
||||
* free the resources allocated by @node.
|
||||
*/
|
||||
SpaResult
|
||||
void
|
||||
pinos_node_destroy (PinosNode * this)
|
||||
{
|
||||
SpaResult res;
|
||||
|
|
@ -561,7 +576,18 @@ pinos_node_destroy (PinosNode * this)
|
|||
0,
|
||||
NULL,
|
||||
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,
|
||||
SpaClock *clock,
|
||||
PinosProperties *properties);
|
||||
SpaResult pinos_node_destroy (PinosNode *node);
|
||||
void pinos_node_destroy (PinosNode *node);
|
||||
|
||||
|
||||
void pinos_node_set_data_loop (PinosNode *node,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,17 @@ pinos_port_new (PinosNode *node,
|
|||
return this;
|
||||
}
|
||||
|
||||
static void
|
||||
sync_destroy (void *object,
|
||||
void *data,
|
||||
SpaResult res,
|
||||
uint32_t id)
|
||||
{
|
||||
PinosPort *port = object;
|
||||
|
||||
free (port);
|
||||
}
|
||||
|
||||
void
|
||||
pinos_port_destroy (PinosPort *port)
|
||||
{
|
||||
|
|
@ -61,6 +72,8 @@ pinos_port_destroy (PinosPort *port)
|
|||
|
||||
pinos_signal_emit (&port->destroy_signal, port);
|
||||
|
||||
spa_list_remove (&port->link);
|
||||
|
||||
spa_node_port_use_buffers (port->node->node,
|
||||
port->direction,
|
||||
port->port_id,
|
||||
|
|
@ -68,8 +81,11 @@ pinos_port_destroy (PinosPort *port)
|
|||
port->buffers = NULL;
|
||||
port->n_buffers = 0;
|
||||
|
||||
spa_list_remove (&port->link);
|
||||
free (port);
|
||||
pinos_main_loop_defer (port->node->core->main_loop,
|
||||
port,
|
||||
SPA_RESULT_WAIT_SYNC,
|
||||
sync_destroy,
|
||||
port);
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
|
|
|
|||
|
|
@ -50,6 +50,17 @@ pinos_resource_new (PinosClient *client,
|
|||
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
|
||||
pinos_resource_destroy (PinosResource *resource)
|
||||
{
|
||||
|
|
@ -61,7 +72,11 @@ pinos_resource_destroy (PinosResource *resource)
|
|||
if (resource->destroy)
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
|
||||
typedef enum {
|
||||
SPA_RESULT_ASYNC = (1 << 30),
|
||||
SPA_RESULT_WAIT_SYNC = 2,
|
||||
SPA_RESULT_MODIFIED = 1,
|
||||
SPA_RESULT_OK = 0,
|
||||
SPA_RESULT_ERROR = -1,
|
||||
|
|
|
|||
|
|
@ -40,16 +40,27 @@ struct _SpaDict {
|
|||
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 *
|
||||
spa_dict_lookup (const SpaDict *dict, const char *key)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < dict->n_items; i++) {
|
||||
if (!strcmp (dict->items[i].key, key))
|
||||
return dict->items[i].value;
|
||||
}
|
||||
return NULL;
|
||||
SpaDictItem *item = spa_dict_lookup_item (dict, key);
|
||||
return item ? item->value : NULL;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue