mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
thread_loop: add more accurate timed_wait
Add get_time() to calculate a timespec timeout value. Add timed_wait_full() to wait for a timespec
This commit is contained in:
parent
36511a5d8e
commit
a6d221f18a
2 changed files with 54 additions and 5 deletions
|
|
@ -366,7 +366,7 @@ void pw_thread_loop_wait(struct pw_thread_loop *loop)
|
||||||
*
|
*
|
||||||
* \param loop a \ref pw_thread_loop to signal
|
* \param loop a \ref pw_thread_loop to signal
|
||||||
* \param wait_max_sec the maximum number of seconds to wait for a \ref pw_thread_loop_signal()
|
* \param wait_max_sec the maximum number of seconds to wait for a \ref pw_thread_loop_signal()
|
||||||
* \return 0 on success or ETIMEDOUT on timeout
|
* \return 0 on success or ETIMEDOUT on timeout or a negative errno value.
|
||||||
*
|
*
|
||||||
* \memberof pw_thread_loop
|
* \memberof pw_thread_loop
|
||||||
*/
|
*/
|
||||||
|
|
@ -375,15 +375,55 @@ int pw_thread_loop_timed_wait(struct pw_thread_loop *loop, int wait_max_sec)
|
||||||
{
|
{
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
if ((ret = pw_thread_loop_get_time(loop,
|
||||||
|
&timeout, wait_max_sec * SPA_NSEC_PER_SEC)) < 0)
|
||||||
|
return ret;
|
||||||
|
ret = pw_thread_loop_timed_wait_full(loop, &timeout);
|
||||||
|
return ret == -ETIMEDOUT ? ETIMEDOUT : ret;
|
||||||
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
/** Get the current time of the loop + timeout. This can be used in
|
||||||
|
* pw_thread_loop_timed_wait_full().
|
||||||
|
*
|
||||||
|
* \param loop a \ref pw_thread_loop
|
||||||
|
* \param abstime the result struct timesspec
|
||||||
|
* \param timeout the time in nanoseconds to add to \a tp
|
||||||
|
* \return 0 on success or a negative errno value on error.
|
||||||
|
*
|
||||||
|
* \memberof pw_thread_loop
|
||||||
|
*/
|
||||||
|
SPA_EXPORT
|
||||||
|
int pw_thread_loop_get_time(struct pw_thread_loop *loop, struct timespec *abstime, int64_t timeout)
|
||||||
|
{
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, abstime) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
timeout.tv_sec += wait_max_sec;
|
abstime->tv_sec += timeout / SPA_NSEC_PER_SEC;
|
||||||
|
abstime->tv_nsec += timeout % SPA_NSEC_PER_SEC;
|
||||||
|
if (abstime->tv_nsec >= SPA_NSEC_PER_SEC) {
|
||||||
|
abstime->tv_sec++;
|
||||||
|
abstime->tv_nsec -= SPA_NSEC_PER_SEC;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wait for the loop thread to call \ref pw_thread_loop_signal()
|
||||||
|
* or time out.
|
||||||
|
*
|
||||||
|
* \param loop a \ref pw_thread_loop to signal
|
||||||
|
* \param abstime the absolute time to wait for a \ref pw_thread_loop_signal()
|
||||||
|
* \return 0 on success or -ETIMEDOUT on timeout or a negative error value
|
||||||
|
*
|
||||||
|
* \memberof pw_thread_loop
|
||||||
|
*/
|
||||||
|
SPA_EXPORT
|
||||||
|
int pw_thread_loop_timed_wait_full(struct pw_thread_loop *loop, struct timespec *abstime)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
loop->n_waiting++;
|
loop->n_waiting++;
|
||||||
ret = pthread_cond_timedwait(&loop->cond, &loop->lock, &timeout);
|
ret = pthread_cond_timedwait(&loop->cond, &loop->lock, abstime);
|
||||||
loop->n_waiting--;
|
loop->n_waiting--;
|
||||||
return ret;
|
return -ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Signal the loop thread waiting for accept with \ref pw_thread_loop_signal()
|
/** Signal the loop thread waiting for accept with \ref pw_thread_loop_signal()
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,15 @@ void pw_thread_loop_wait(struct pw_thread_loop *loop);
|
||||||
* until some thread calls \ref pw_thread_loop_signal or time out */
|
* until some thread calls \ref pw_thread_loop_signal or time out */
|
||||||
int pw_thread_loop_timed_wait(struct pw_thread_loop *loop, int wait_max_sec);
|
int pw_thread_loop_timed_wait(struct pw_thread_loop *loop, int wait_max_sec);
|
||||||
|
|
||||||
|
/** Get a struct timespec suitable for \ref pw_thread_loop_timed_wait_full.
|
||||||
|
* Since: 0.3.7 */
|
||||||
|
int pw_thread_loop_get_time(struct pw_thread_loop *loop, struct timespec *abstime, int64_t timeout);
|
||||||
|
|
||||||
|
/** Release the lock and wait until \a timeout until some thread calls
|
||||||
|
* \ref pw_thread_loop_signal. Use \ref pw_thread_loop_get_time to make a timeout.
|
||||||
|
* Since: 0.3.7 */
|
||||||
|
int pw_thread_loop_timed_wait_full(struct pw_thread_loop *loop, struct timespec *abstime);
|
||||||
|
|
||||||
/** Signal all threads waiting with \ref pw_thread_loop_wait */
|
/** Signal all threads waiting with \ref pw_thread_loop_wait */
|
||||||
void pw_thread_loop_signal(struct pw_thread_loop *loop, bool wait_for_accept);
|
void pw_thread_loop_signal(struct pw_thread_loop *loop, bool wait_for_accept);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue