mirror of
https://github.com/mpv-player/mpv
synced 2024-08-04 14:59:58 +02:00
player: remove in_dispatch field
(Not sure if worth the trouble, but it does seem less awkward.)
This commit is contained in:
parent
435bc003c0
commit
020730da0b
@ -30,6 +30,8 @@ struct mp_dispatch_queue {
|
|||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
void (*wakeup_fn)(void *wakeup_ctx);
|
void (*wakeup_fn)(void *wakeup_ctx);
|
||||||
void *wakeup_ctx;
|
void *wakeup_ctx;
|
||||||
|
// Time at which mp_dispatch_queue_process() should return.
|
||||||
|
int64_t wait;
|
||||||
// Make mp_dispatch_queue_process() exit if it's idle.
|
// Make mp_dispatch_queue_process() exit if it's idle.
|
||||||
bool interrupted;
|
bool interrupted;
|
||||||
// The target thread is in mp_dispatch_queue_process() (and either idling,
|
// The target thread is in mp_dispatch_queue_process() (and either idling,
|
||||||
@ -250,9 +252,8 @@ void mp_dispatch_run(struct mp_dispatch_queue *queue,
|
|||||||
// no enqueued callback can call the lock/unlock functions).
|
// no enqueued callback can call the lock/unlock functions).
|
||||||
void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout)
|
void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout)
|
||||||
{
|
{
|
||||||
int64_t wait = timeout > 0 ? mp_add_timeout(mp_time_us(), timeout) : 0;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&queue->lock);
|
pthread_mutex_lock(&queue->lock);
|
||||||
|
queue->wait = timeout > 0 ? mp_add_timeout(mp_time_us(), timeout) : 0;
|
||||||
assert(!queue->in_process); // recursion not allowed
|
assert(!queue->in_process); // recursion not allowed
|
||||||
queue->in_process = true;
|
queue->in_process = true;
|
||||||
queue->in_process_thread = pthread_self();
|
queue->in_process_thread = pthread_self();
|
||||||
@ -288,10 +289,10 @@ void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout)
|
|||||||
} else {
|
} else {
|
||||||
item->completed = true;
|
item->completed = true;
|
||||||
}
|
}
|
||||||
} else if (wait > 0 && !queue->interrupted) {
|
} else if (queue->wait > 0 && !queue->interrupted) {
|
||||||
struct timespec ts = mp_time_us_to_timespec(wait);
|
struct timespec ts = mp_time_us_to_timespec(queue->wait);
|
||||||
if (pthread_cond_timedwait(&queue->cond, &queue->lock, &ts))
|
if (pthread_cond_timedwait(&queue->cond, &queue->lock, &ts))
|
||||||
wait = 0;
|
queue->wait = 0;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -305,9 +306,9 @@ void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout)
|
|||||||
// If the queue is inside of mp_dispatch_queue_process(), make it return as
|
// If the queue is inside of mp_dispatch_queue_process(), make it return as
|
||||||
// soon as all work items have been run, without waiting for the timeout. This
|
// soon as all work items have been run, without waiting for the timeout. This
|
||||||
// does not make it return early if it's blocked by a mp_dispatch_lock().
|
// does not make it return early if it's blocked by a mp_dispatch_lock().
|
||||||
// If mp_dispatch_queue_process() is called in a reentrant way (including the
|
// If the queue is _not_ inside of mp_dispatch_queue_process(), make the next
|
||||||
// case where another thread calls mp_dispatch_lock() and then
|
// call of it use a timeout of 0 (this is useful behavior if you need to
|
||||||
// mp_dispatch_queue_process()), this affects only the "topmost" invocation.
|
// wakeup the main thread from another thread in a race free way).
|
||||||
void mp_dispatch_interrupt(struct mp_dispatch_queue *queue)
|
void mp_dispatch_interrupt(struct mp_dispatch_queue *queue)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&queue->lock);
|
pthread_mutex_lock(&queue->lock);
|
||||||
@ -316,6 +317,24 @@ void mp_dispatch_interrupt(struct mp_dispatch_queue *queue)
|
|||||||
pthread_mutex_unlock(&queue->lock);
|
pthread_mutex_unlock(&queue->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a mp_dispatch_queue_process() call is in progress, then adjust the maximum
|
||||||
|
// time it blocks due to its timeout argument. Otherwise does nothing. (It
|
||||||
|
// makes sense to call this in code that uses both mp_dispatch_[un]lock() and
|
||||||
|
// a normal event loop.)
|
||||||
|
// Does not work correctly with queues that have mp_dispatch_set_wakeup_fn()
|
||||||
|
// called on them, because this implies you actually do waiting via
|
||||||
|
// mp_dispatch_queue_process(), while wakeup callbacks are used when you need
|
||||||
|
// to wait in external APIs.
|
||||||
|
void mp_dispatch_adjust_timeout(struct mp_dispatch_queue *queue, int64_t until)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&queue->lock);
|
||||||
|
if (queue->in_process && queue->wait > until) {
|
||||||
|
queue->wait = until;
|
||||||
|
pthread_cond_broadcast(&queue->cond);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&queue->lock);
|
||||||
|
}
|
||||||
|
|
||||||
// Grant exclusive access to the target thread's state. While this is active,
|
// Grant exclusive access to the target thread's state. While this is active,
|
||||||
// no other thread can return from mp_dispatch_lock() (i.e. it behaves like
|
// no other thread can return from mp_dispatch_lock() (i.e. it behaves like
|
||||||
// a pthread mutex), and no other thread can get dispatch items completed.
|
// a pthread mutex), and no other thread can get dispatch items completed.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef MP_DISPATCH_H_
|
#ifndef MP_DISPATCH_H_
|
||||||
#define MP_DISPATCH_H_
|
#define MP_DISPATCH_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef void (*mp_dispatch_fn)(void *data);
|
typedef void (*mp_dispatch_fn)(void *data);
|
||||||
struct mp_dispatch_queue;
|
struct mp_dispatch_queue;
|
||||||
|
|
||||||
@ -20,6 +22,7 @@ void mp_dispatch_run(struct mp_dispatch_queue *queue,
|
|||||||
mp_dispatch_fn fn, void *fn_data);
|
mp_dispatch_fn fn, void *fn_data);
|
||||||
void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout);
|
void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout);
|
||||||
void mp_dispatch_interrupt(struct mp_dispatch_queue *queue);
|
void mp_dispatch_interrupt(struct mp_dispatch_queue *queue);
|
||||||
|
void mp_dispatch_adjust_timeout(struct mp_dispatch_queue *queue, int64_t until);
|
||||||
void mp_dispatch_lock(struct mp_dispatch_queue *queue);
|
void mp_dispatch_lock(struct mp_dispatch_queue *queue);
|
||||||
void mp_dispatch_unlock(struct mp_dispatch_queue *queue);
|
void mp_dispatch_unlock(struct mp_dispatch_queue *queue);
|
||||||
|
|
||||||
|
@ -234,7 +234,6 @@ typedef struct MPContext {
|
|||||||
struct mp_client_api *clients;
|
struct mp_client_api *clients;
|
||||||
struct mp_dispatch_queue *dispatch;
|
struct mp_dispatch_queue *dispatch;
|
||||||
struct mp_cancel *playback_abort;
|
struct mp_cancel *playback_abort;
|
||||||
bool in_dispatch;
|
|
||||||
// Number of asynchronous tasks that still need to finish until MPContext
|
// Number of asynchronous tasks that still need to finish until MPContext
|
||||||
// destruction is ok. It's implied that the async tasks call
|
// destruction is ok. It's implied that the async tasks call
|
||||||
// mp_wakeup_core() each time this is decremented.
|
// mp_wakeup_core() each time this is decremented.
|
||||||
|
@ -57,11 +57,8 @@ void mp_wait_events(struct MPContext *mpctx)
|
|||||||
if (sleeping)
|
if (sleeping)
|
||||||
MP_STATS(mpctx, "start sleep");
|
MP_STATS(mpctx, "start sleep");
|
||||||
|
|
||||||
mpctx->in_dispatch = true;
|
|
||||||
|
|
||||||
mp_dispatch_queue_process(mpctx->dispatch, mpctx->sleeptime);
|
mp_dispatch_queue_process(mpctx->dispatch, mpctx->sleeptime);
|
||||||
|
|
||||||
mpctx->in_dispatch = false;
|
|
||||||
mpctx->sleeptime = INFINITY;
|
mpctx->sleeptime = INFINITY;
|
||||||
|
|
||||||
if (sleeping)
|
if (sleeping)
|
||||||
@ -73,11 +70,11 @@ void mp_wait_events(struct MPContext *mpctx)
|
|||||||
// mp_set_timeout(c, 0) is essentially equivalent to mp_wakeup_core(c).
|
// mp_set_timeout(c, 0) is essentially equivalent to mp_wakeup_core(c).
|
||||||
void mp_set_timeout(struct MPContext *mpctx, double sleeptime)
|
void mp_set_timeout(struct MPContext *mpctx, double sleeptime)
|
||||||
{
|
{
|
||||||
mpctx->sleeptime = MPMIN(mpctx->sleeptime, sleeptime);
|
if (mpctx->sleeptime > sleeptime) {
|
||||||
|
mpctx->sleeptime = sleeptime;
|
||||||
// Can't adjust timeout if called from mp_dispatch_queue_process().
|
int64_t abstime = mp_add_timeout(mp_time_us(), sleeptime);
|
||||||
if (mpctx->in_dispatch && isfinite(sleeptime))
|
mp_dispatch_adjust_timeout(mpctx->dispatch, abstime);
|
||||||
mp_wakeup_core(mpctx);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cause the playloop to run. This can be called from any thread. If called
|
// Cause the playloop to run. This can be called from any thread. If called
|
||||||
|
Loading…
Reference in New Issue
Block a user