data-loop: add _wait function

Add function to wait for one iteration of the loop. This can be used
by specialized implementations of the data loop, like jack.
This commit is contained in:
Wim Taymans 2019-09-09 17:17:03 +02:00
parent 3340f3cacc
commit 9c9bff8fe9
5 changed files with 49 additions and 9 deletions

@ -1 +1 @@
Subproject commit 2abcc287627568a88424782c05ff527b5817ba56
Subproject commit 2736c227a19b1db48dd849af6f7f3e929bb53c00

View file

@ -162,11 +162,11 @@ struct spa_loop_control_methods {
/** Perform one iteration of the loop.
* \param ctrl the control
* \param timeout an optional timeout. 0 for no timeout, -1 for infinte
* timeout.
* \param timeout an optional timeout in milliseconds.
* 0 for no timeout, -1 for infinte timeout.
*
* This function will block
* up to \a timeout and then dispatch the fds with activity.
* up to \a timeout milliseconds and then dispatch the fds with activity.
* The number of dispatched fds is returned.
*/
int (*iterate) (void *object, int timeout);

View file

@ -1254,8 +1254,8 @@ static void node_initialized(void *data)
struct spa_system *data_system = impl->node.data_system;
size_t size;
impl->fds[0] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC);
impl->fds[1] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC);
impl->fds[0] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
impl->fds[1] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
impl->other_fds[0] = impl->fds[1];
impl->other_fds[1] = impl->fds[0];
node->data_source.fd = impl->fds[0];
@ -1537,7 +1537,7 @@ static void node_peer_added(void *data, struct pw_node *peer)
pw_log_debug(NAME " %p: can't ensure mem: %m", this);
return;
}
pw_log_debug(NAME " %p: peer %p %u added %u", &impl->this, peer,
pw_log_debug(NAME " %p: peer %p id:%u added mem_id:%u", &impl->this, peer,
peer->info.id, m->id);
if (this->resource == NULL)

View file

@ -32,6 +32,29 @@
#define NAME "data-loop"
SPA_EXPORT
int pw_data_loop_wait(struct pw_data_loop *this, int timeout)
{
int res;
while (true) {
if (!this->running)
return -ECANCELED;
if ((res = pw_loop_iterate(this->loop, timeout)) < 0) {
if (errno == EINTR)
continue;
}
break;
}
return res;
}
SPA_EXPORT
void pw_data_loop_exit(struct pw_data_loop *this)
{
this->running = false;
}
static void *do_loop(void *user_data)
{
struct pw_data_loop *this = user_data;
@ -41,10 +64,14 @@ static void *do_loop(void *user_data)
pw_loop_enter(this->loop);
while (this->running) {
if ((res = pw_loop_iterate(this->loop, -1)) < 0)
pw_log_warn(NAME" %p: iterate error %d (%s)",
if ((res = pw_loop_iterate(this->loop, -1)) < 0) {
if (errno == EINTR)
continue;
pw_log_error(NAME" %p: iterate error %d (%s)",
this, res, spa_strerror(res));
}
}
pw_log_debug(NAME" %p: leave thread", this);
pw_loop_leave(this->loop);
@ -64,6 +91,7 @@ static void do_stop(void *data, uint64_t count)
*
* \memberof pw_data_loop
*/
SPA_EXPORT
struct pw_data_loop *pw_data_loop_new(struct pw_properties *properties)
{
struct pw_data_loop *this;
@ -111,6 +139,7 @@ error_cleanup:
* \param loop the data loop to destroy
* \memberof pw_data_loop
*/
SPA_EXPORT
void pw_data_loop_destroy(struct pw_data_loop *loop)
{
pw_log_debug(NAME" %p: destroy", loop);
@ -124,6 +153,7 @@ void pw_data_loop_destroy(struct pw_data_loop *loop)
free(loop);
}
SPA_EXPORT
void pw_data_loop_add_listener(struct pw_data_loop *loop,
struct spa_hook *listener,
const struct pw_data_loop_events *events,
@ -146,6 +176,7 @@ pw_data_loop_get_loop(struct pw_data_loop *loop)
*
* \memberof pw_data_loop
*/
SPA_EXPORT
int pw_data_loop_start(struct pw_data_loop *loop)
{
if (!loop->running) {
@ -169,6 +200,7 @@ int pw_data_loop_start(struct pw_data_loop *loop)
*
* \memberof pw_data_loop
*/
SPA_EXPORT
int pw_data_loop_stop(struct pw_data_loop *loop)
{
if (loop->running) {
@ -185,6 +217,7 @@ int pw_data_loop_stop(struct pw_data_loop *loop)
*
* \memberof pw_data_loop
*/
SPA_EXPORT
bool pw_data_loop_in_thread(struct pw_data_loop * loop)
{
return pthread_equal(loop->thread, pthread_self());

View file

@ -59,6 +59,13 @@ void pw_data_loop_add_listener(struct pw_data_loop *loop,
const struct pw_data_loop_events *events,
void *data);
/** wait for activity on the loop up to \a timeout milliseconds.
* Should be called from the loop function */
int pw_data_loop_wait(struct pw_data_loop *loop, int timeout);
/** make sure the thread will exit. Can be called from a loop callback */
void pw_data_loop_exit(struct pw_data_loop *loop);
/** Get the loop implementation of this data loop */
struct pw_loop *
pw_data_loop_get_loop(struct pw_data_loop *loop);