mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-18 07:00:06 -05:00
Move suspend on idle in module
Move suspend-on-idle code from the node to a module Add some more SpaLoop API
This commit is contained in:
parent
d250ed42e6
commit
3dcbf4b228
13 changed files with 363 additions and 110 deletions
|
|
@ -64,6 +64,7 @@ pinos_core_new (PinosMainLoop *main_loop)
|
|||
pinos_signal_init (&this->destroy_signal);
|
||||
pinos_signal_init (&this->global_added);
|
||||
pinos_signal_init (&this->global_removed);
|
||||
pinos_signal_init (&this->node_state_request);
|
||||
pinos_signal_init (&this->node_state_changed);
|
||||
pinos_signal_init (&this->port_added);
|
||||
pinos_signal_init (&this->port_removed);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,9 @@ struct _PinosCore {
|
|||
PinosCore *core,
|
||||
PinosGlobal *global));
|
||||
|
||||
PINOS_SIGNAL (node_state_request, (PinosListener *listener,
|
||||
PinosNode *object,
|
||||
PinosNodeState state));
|
||||
PINOS_SIGNAL (node_state_changed, (PinosListener *listener,
|
||||
PinosNode *object,
|
||||
PinosNodeState old,
|
||||
|
|
|
|||
|
|
@ -96,11 +96,14 @@ do_loop (void *user_data)
|
|||
make_realtime (this);
|
||||
|
||||
pinos_log_debug ("data-loop %p: enter thread", this);
|
||||
pinos_loop_enter_thread (impl->this.loop);
|
||||
|
||||
while (impl->running) {
|
||||
if ((res = pinos_loop_iterate (this->loop, -1)) < 0)
|
||||
pinos_log_warn ("data-loop %p: iterate error %d", this, res);
|
||||
}
|
||||
pinos_log_debug ("data-loop %p: leave thread", this);
|
||||
pinos_loop_leave_thread (impl->this.loop);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -169,7 +172,6 @@ pinos_data_loop_start (PinosDataLoop *loop)
|
|||
impl->running = false;
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
pinos_loop_set_thread (impl->this.loop, &impl->thread);
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -748,7 +748,7 @@ do_link_remove_done (SpaLoop *loop,
|
|||
|
||||
if (this->input->node->n_used_input_links == 0 &&
|
||||
this->input->node->n_used_output_links == 0)
|
||||
pinos_node_report_idle (this->input->node);
|
||||
pinos_node_set_state (this->input->node, PINOS_NODE_STATE_IDLE);
|
||||
|
||||
clear_port_buffers (this, this->input);
|
||||
this->input = NULL;
|
||||
|
|
@ -759,7 +759,7 @@ do_link_remove_done (SpaLoop *loop,
|
|||
|
||||
if (this->output->node->n_used_input_links == 0 &&
|
||||
this->output->node->n_used_output_links == 0)
|
||||
pinos_node_report_idle (this->output->node);
|
||||
pinos_node_set_state (this->output->node, PINOS_NODE_STATE_IDLE);
|
||||
|
||||
clear_port_buffers (this, this->output);
|
||||
this->output = NULL;
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ typedef struct
|
|||
uint32_t seq;
|
||||
|
||||
bool async_init;
|
||||
|
||||
guint idle_timeout;
|
||||
} PinosNodeImpl;
|
||||
|
||||
static void init_complete (PinosNode *this);
|
||||
|
|
@ -396,7 +394,7 @@ init_complete (PinosNode *this)
|
|||
pinos_log_debug ("node %p: init completed", this);
|
||||
impl->async_init = false;
|
||||
|
||||
pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED);
|
||||
pinos_node_update_state (this, PINOS_NODE_STATE_SUSPENDED, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -630,31 +628,20 @@ pinos_node_get_free_port (PinosNode *node,
|
|||
|
||||
}
|
||||
|
||||
static void
|
||||
remove_idle_timeout (PinosNode *node)
|
||||
{
|
||||
PinosNodeImpl *impl = SPA_CONTAINER_OF (node, PinosNodeImpl, this);
|
||||
|
||||
if (impl->idle_timeout) {
|
||||
g_source_remove (impl->idle_timeout);
|
||||
impl->idle_timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_state_complete (PinosNode *node,
|
||||
gpointer data,
|
||||
SpaResult res)
|
||||
{
|
||||
PinosNodeState state = GPOINTER_TO_INT (data);
|
||||
char *error = NULL;
|
||||
|
||||
pinos_log_debug ("node %p: state complete %d", node, res);
|
||||
if (SPA_RESULT_IS_ERROR (res)) {
|
||||
char *error;
|
||||
asprintf (&error, "error changing node state: %d", res);
|
||||
pinos_node_report_error (node, error);
|
||||
} else
|
||||
pinos_node_update_state (node, state);
|
||||
state = PINOS_NODE_STATE_ERROR;
|
||||
}
|
||||
pinos_node_update_state (node, state, error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -672,7 +659,7 @@ pinos_node_set_state (PinosNode *node,
|
|||
{
|
||||
SpaResult res = SPA_RESULT_OK;
|
||||
|
||||
remove_idle_timeout (node);
|
||||
pinos_signal_emit (&node->core->node_state_request, node, state);
|
||||
|
||||
pinos_log_debug ("node %p: set state %s", node, pinos_node_state_as_string (state));
|
||||
|
||||
|
|
@ -715,13 +702,15 @@ pinos_node_set_state (PinosNode *node,
|
|||
* pinos_node_update_state:
|
||||
* @node: a #PinosNode
|
||||
* @state: a #PinosNodeState
|
||||
* @error: error when @state is #PINOS_NODE_STATE_ERROR
|
||||
*
|
||||
* Update the state of a node. This method is used from
|
||||
* inside @node itself.
|
||||
*/
|
||||
void
|
||||
pinos_node_update_state (PinosNode *node,
|
||||
PinosNodeState state)
|
||||
PinosNodeState state,
|
||||
char *error)
|
||||
{
|
||||
PinosNodeState old;
|
||||
|
||||
|
|
@ -731,75 +720,10 @@ pinos_node_update_state (PinosNode *node,
|
|||
pinos_node_state_as_string (old),
|
||||
pinos_node_state_as_string (state));
|
||||
|
||||
if (node->error)
|
||||
free (node->error);
|
||||
node->error = error;
|
||||
node->state = state;
|
||||
pinos_signal_emit (&node->core->node_state_changed, node, old, state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_node_report_error:
|
||||
* @node: a #PinosNode
|
||||
* @error: an error message
|
||||
*
|
||||
* Report an error from within @node.
|
||||
*/
|
||||
void
|
||||
pinos_node_report_error (PinosNode *node,
|
||||
char *error)
|
||||
{
|
||||
PinosNodeState old;
|
||||
|
||||
free (node->error);
|
||||
remove_idle_timeout (node);
|
||||
node->error = error;
|
||||
old = node->state;
|
||||
node->state = PINOS_NODE_STATE_ERROR;
|
||||
pinos_log_debug ("node %p: got error state %s", node, error);
|
||||
pinos_signal_emit (&node->core->node_state_changed, node, old, node->state);
|
||||
}
|
||||
|
||||
static bool
|
||||
idle_timeout (PinosNode *node)
|
||||
{
|
||||
PinosNodeImpl *impl = SPA_CONTAINER_OF (node, PinosNodeImpl, this);
|
||||
|
||||
impl->idle_timeout = 0;
|
||||
pinos_log_debug ("node %p: idle timeout", node);
|
||||
pinos_node_set_state (node, PINOS_NODE_STATE_SUSPENDED);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_node_report_idle:
|
||||
* @node: a #PinosNode
|
||||
*
|
||||
* Mark @node as being idle. This will start a timeout that will
|
||||
* set the node to SUSPENDED.
|
||||
*/
|
||||
void
|
||||
pinos_node_report_idle (PinosNode *node)
|
||||
{
|
||||
PinosNodeImpl *impl = SPA_CONTAINER_OF (node, PinosNodeImpl, this);
|
||||
|
||||
pinos_log_debug ("node %p: report idle", node);
|
||||
pinos_node_set_state (node, PINOS_NODE_STATE_IDLE);
|
||||
|
||||
impl->idle_timeout = g_timeout_add_seconds (3,
|
||||
(GSourceFunc) idle_timeout,
|
||||
node);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_node_report_busy:
|
||||
* @node: a #PinosNode
|
||||
*
|
||||
* Mark @node as being busy. This will set the state of the node
|
||||
* to the RUNNING state.
|
||||
*/
|
||||
void
|
||||
pinos_node_report_busy (PinosNode *node)
|
||||
{
|
||||
pinos_log_debug ("node %p: report busy", node);
|
||||
pinos_node_set_state (node, PINOS_NODE_STATE_RUNNING);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,12 +103,11 @@ void pinos_node_set_data_loop (PinosNode *node,
|
|||
PinosPort * pinos_node_get_free_port (PinosNode *node,
|
||||
PinosDirection direction);
|
||||
|
||||
SpaResult pinos_node_set_state (PinosNode *node, PinosNodeState state);
|
||||
void pinos_node_update_state (PinosNode *node, PinosNodeState state);
|
||||
|
||||
void pinos_node_report_error (PinosNode *node, char *error);
|
||||
void pinos_node_report_idle (PinosNode *node);
|
||||
void pinos_node_report_busy (PinosNode *node);
|
||||
SpaResult pinos_node_set_state (PinosNode *node,
|
||||
PinosNodeState state);
|
||||
void pinos_node_update_state (PinosNode *node,
|
||||
PinosNodeState state,
|
||||
char *error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ do_remove_link_done (SpaLoop *loop,
|
|||
|
||||
if (node->n_used_output_links == 0 &&
|
||||
node->n_used_input_links == 0) {
|
||||
pinos_node_report_idle (node);
|
||||
pinos_node_update_state (node, PINOS_NODE_STATE_IDLE, NULL);
|
||||
}
|
||||
|
||||
if (!port->allocated) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue