clock: expose lock

This is a first step to allow the caller to compute an arbitrary
deadline based on vlc_clock_ConvertToSystemLocked() then wait using
vlc_clock_Wait() without race condition.
This commit is contained in:
Romain Vimont 2021-07-08 16:17:45 +02:00 committed by Jean-Baptiste Kempf
parent 6208d519af
commit a2e2c056d9
3 changed files with 56 additions and 12 deletions

View File

@ -346,11 +346,30 @@ static vlc_tick_t vlc_clock_slave_set_delay(vlc_clock_t *clock, vlc_tick_t delay
return 0;
}
void vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t system_now, vlc_tick_t ts,
double rate, vlc_tick_t max_duration)
void vlc_clock_Lock(vlc_clock_t *clock)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_lock(&main_clock->lock);
}
void vlc_clock_Unlock(vlc_clock_t *clock)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_unlock(&main_clock->lock);
}
static inline void AssertLocked(vlc_clock_t *clock)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_assert(&main_clock->lock);
}
void vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t system_now, vlc_tick_t ts,
double rate, vlc_tick_t max_duration)
{
AssertLocked(clock);
vlc_clock_main_t *main_clock = clock->owner;
const vlc_tick_t max_deadline =
max_duration > 0 ? system_now + max_duration : VLC_TICK_MAX;
while (!main_clock->abort)
@ -365,7 +384,6 @@ void vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t system_now, vlc_tick_t ts,
if (vlc_cond_timedwait(&main_clock->cond, &main_clock->lock, deadline))
break;
}
vlc_mutex_unlock(&main_clock->lock);
}
vlc_clock_main_t *vlc_clock_main_New(struct vlc_logger *parent_logger)
@ -516,14 +534,11 @@ vlc_tick_t vlc_clock_SetDelay(vlc_clock_t *clock, vlc_tick_t delay)
return clock->set_delay(clock, delay);
}
vlc_tick_t vlc_clock_ConvertToSystem(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate)
vlc_tick_t vlc_clock_ConvertToSystemLocked(vlc_clock_t *clock,
vlc_tick_t system_now, vlc_tick_t ts,
double rate)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_lock(&main_clock->lock);
vlc_tick_t system = clock->to_system_locked(clock, system_now, ts, rate);
vlc_mutex_unlock(&main_clock->lock);
return system;
return clock->to_system_locked(clock, system_now, ts, rate);
}
void vlc_clock_ConvertArrayToSystem(vlc_clock_t *clock, vlc_tick_t system_now,

View File

@ -173,18 +173,45 @@ void vlc_clock_Reset(vlc_clock_t *clock);
*/
vlc_tick_t vlc_clock_SetDelay(vlc_clock_t *clock, vlc_tick_t ts_delay);
/**
* Lock the clock mutex
*/
void vlc_clock_Lock(vlc_clock_t *clock);
/**
* Unlock the clock mutex
*/
void vlc_clock_Unlock(vlc_clock_t *clock);
/**
* Wait for a timestamp expressed in stream time
*
* The clock mutex must be locked.
*/
void vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t system_now, vlc_tick_t ts,
double rate, vlc_tick_t max_duration);
/**
* This function converts a timestamp from stream to system
*
* The clock mutex must be locked.
*
* @return the valid system time or VLC_TICK_MAX when the clock is paused
*/
vlc_tick_t vlc_clock_ConvertToSystem(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate);
vlc_tick_t vlc_clock_ConvertToSystemLocked(vlc_clock_t *clock,
vlc_tick_t system_now, vlc_tick_t ts,
double rate);
static inline vlc_tick_t
vlc_clock_ConvertToSystem(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate)
{
vlc_clock_Lock(clock);
vlc_tick_t system =
vlc_clock_ConvertToSystemLocked(clock, system_now, ts, rate);
vlc_clock_Unlock(clock);
return system;
}
/**
* This functon converts an array of timestamp from stream to system

View File

@ -1330,8 +1330,10 @@ static int RenderPicture(vout_thread_sys_t *vout, bool render_now)
{
/* Wait to reach system_pts if the plugin doesn't handle
* asynchronous display */
vlc_clock_Lock(sys->clock);
vlc_clock_Wait(sys->clock, system_now, pts, sys->rate,
VOUT_REDISPLAY_DELAY);
vlc_clock_Unlock(sys->clock);
/* Don't touch system_pts. Tell the clock that the pts was rendered
* at the expected date */