mirror of https://code.videolan.org/videolan/vlc
threads: add vlc_cond_timedwait_daytime()
This separates waiting on UTC deadline from waiting on monotonic clock. That way, storing the reference clock in vlc_cond_t is no longer necessary. There was only one single condition variable using the UTC clock (in VLM), so vlc_cond_t.clock was rather wasteful.
This commit is contained in:
parent
a07a959f53
commit
0ef03f60c0
|
@ -72,9 +72,8 @@ typedef struct
|
|||
{
|
||||
HANDLE semaphore;
|
||||
LONG waiters;
|
||||
unsigned clock;
|
||||
} vlc_cond_t;
|
||||
#define VLC_STATIC_COND { NULL, 0, 0 }
|
||||
#define VLC_STATIC_COND { NULL, 0 }
|
||||
typedef HANDLE vlc_sem_t;
|
||||
#define LIBVLC_NEED_RWLOCK
|
||||
typedef struct vlc_threadvar *vlc_threadvar_t;
|
||||
|
@ -124,9 +123,8 @@ typedef struct
|
|||
unsigned waiters;
|
||||
HEV hevAck;
|
||||
unsigned signaled;
|
||||
unsigned clock;
|
||||
} vlc_cond_t;
|
||||
#define VLC_STATIC_COND { NULLHANDLE, 0, NULLHANDLE, 0, 0 }
|
||||
#define VLC_STATIC_COND { NULLHANDLE, 0, NULLHANDLE, 0 }
|
||||
#define LIBVLC_NEED_SEMAPHORE
|
||||
#define LIBVLC_NEED_RWLOCK
|
||||
typedef struct vlc_threadvar *vlc_threadvar_t;
|
||||
|
@ -174,14 +172,9 @@ static inline int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
|
|||
typedef struct vlc_thread *vlc_thread_t;
|
||||
#define VLC_THREAD_CANCELED NULL
|
||||
typedef pthread_mutex_t vlc_mutex_t;
|
||||
|
||||
#define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
|
||||
typedef struct
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
unsigned clock;
|
||||
} vlc_cond_t;
|
||||
#define VLC_STATIC_COND { PTHREAD_COND_INITIALIZER, CLOCK_REALTIME }
|
||||
typedef pthread_cond_t vlc_cond_t;
|
||||
#define VLC_STATIC_COND PTHREAD_COND_INITIALIZER
|
||||
|
||||
typedef pthread_key_t vlc_threadvar_t;
|
||||
typedef struct vlc_timer *vlc_timer_t;
|
||||
|
@ -227,12 +220,8 @@ typedef pthread_t vlc_thread_t;
|
|||
#define VLC_THREAD_CANCELED PTHREAD_CANCELED
|
||||
typedef pthread_mutex_t vlc_mutex_t;
|
||||
#define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
|
||||
typedef struct
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
unsigned clock;
|
||||
} vlc_cond_t;
|
||||
#define VLC_STATIC_COND { PTHREAD_COND_INITIALIZER, 0 }
|
||||
typedef pthread_cond_t vlc_cond_t;
|
||||
#define VLC_STATIC_COND PTHREAD_COND_INITIALIZER
|
||||
typedef semaphore_t vlc_sem_t;
|
||||
typedef pthread_rwlock_t vlc_rwlock_t;
|
||||
#define VLC_STATIC_RWLOCK PTHREAD_RWLOCK_INITIALIZER
|
||||
|
@ -292,6 +281,12 @@ typedef pthread_cond_t vlc_cond_t;
|
|||
|
||||
/**
|
||||
* Static initializer for (static) condition variable.
|
||||
*
|
||||
* \note
|
||||
* The condition variable will use the default clock, which is OS-dependent.
|
||||
* Therefore, where timed waits are necessary the condition variable should
|
||||
* always be initialized dynamically explicit instead of using this
|
||||
* initializer.
|
||||
*/
|
||||
#define VLC_STATIC_COND PTHREAD_COND_INITIALIZER
|
||||
|
||||
|
@ -419,10 +414,13 @@ VLC_API void vlc_cond_init(vlc_cond_t *);
|
|||
/**
|
||||
* Initializes a condition variable (wall clock).
|
||||
*
|
||||
* Contrary to vlc_cond_init(), the wall clock will be used as a reference for
|
||||
* the vlc_cond_timedwait() time-out parameter.
|
||||
* This function initializes a condition variable for timed waiting using the
|
||||
* UTC wall clock time. The time reference is the same as with time() and with
|
||||
* timespec_get() and TIME_UTC.
|
||||
* vlc_cond_timedwait_daytime() must be instead of
|
||||
* vlc_cond_timedwait() for actual waiting.
|
||||
*/
|
||||
VLC_API void vlc_cond_init_daytime(vlc_cond_t *);
|
||||
void vlc_cond_init_daytime(vlc_cond_t *);
|
||||
|
||||
/**
|
||||
* Deinitializes a condition variable.
|
||||
|
@ -485,23 +483,26 @@ VLC_API void vlc_cond_wait(vlc_cond_t *cond, vlc_mutex_t *mutex);
|
|||
* Waits on a condition variable up to a certain date.
|
||||
*
|
||||
* This works like vlc_cond_wait() but with an additional time-out.
|
||||
* The time-out is expressed as an absolute timestamp using the same arbitrary
|
||||
* time reference as the mdate() and mwait() functions.
|
||||
*
|
||||
* If the variable was initialized with vlc_cond_init(), the timeout has the
|
||||
* same arbitrary origin as mdate(). If the variable was initialized with
|
||||
* vlc_cond_init_daytime(), or was statically initialized with
|
||||
* \ref VLC_STATIC_COND, the timeout is expressed from the Unix epoch (i.e.
|
||||
* the wall clock).
|
||||
*
|
||||
* \param p_condvar condition variable to wait on
|
||||
* \param p_mutex mutex which is unlocked while waiting,
|
||||
* then locked again when waking up.
|
||||
* \param cond condition variable to wait on
|
||||
* \param mutex mutex which is unlocked while waiting,
|
||||
* then locked again when waking up
|
||||
* \param deadline <b>absolute</b> timeout
|
||||
*
|
||||
* \warning If the variable was initialized with vlc_cond_init_daytime(), or
|
||||
* was statically initialized with \ref VLC_STATIC_COND, the time reference
|
||||
* used by this function is unspecified (depending on the implementation, it
|
||||
* might be the Unix epoch or the mdate() clock).
|
||||
*
|
||||
* \return 0 if the condition was signaled, an error code in case of timeout.
|
||||
*/
|
||||
VLC_API int vlc_cond_timedwait(vlc_cond_t *cond, vlc_mutex_t *mutex,
|
||||
mtime_t deadline);
|
||||
|
||||
int vlc_cond_timedwait_daytime(vlc_cond_t *, vlc_mutex_t *, time_t);
|
||||
|
||||
/**
|
||||
* Initializes a semaphore.
|
||||
*
|
||||
|
|
|
@ -190,7 +190,7 @@ void vlc_threads_setup (libvlc_int_t *p_libvlc)
|
|||
void vlc_cond_init (vlc_cond_t *condvar)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
|
||||
if (unlikely(pthread_cond_init (&condvar->cond, NULL)))
|
||||
if (unlikely(pthread_cond_init (condvar, NULL)))
|
||||
abort ();
|
||||
#else
|
||||
pthread_condattr_t attr;
|
||||
|
@ -198,34 +198,32 @@ void vlc_cond_init (vlc_cond_t *condvar)
|
|||
pthread_condattr_init (&attr);
|
||||
pthread_condattr_setclock (&attr, CLOCK_MONOTONIC);
|
||||
|
||||
if (unlikely(pthread_cond_init (&condvar->cond, &attr)))
|
||||
if (unlikely(pthread_cond_init (condvar, &attr)))
|
||||
abort ();
|
||||
#endif
|
||||
condvar->clock = CLOCK_MONOTONIC;
|
||||
}
|
||||
|
||||
void vlc_cond_init_daytime (vlc_cond_t *condvar)
|
||||
{
|
||||
if (unlikely(pthread_cond_init (&condvar->cond, NULL)))
|
||||
if (unlikely(pthread_cond_init (condvar, NULL)))
|
||||
abort ();
|
||||
condvar->clock = CLOCK_REALTIME;
|
||||
}
|
||||
|
||||
void vlc_cond_destroy (vlc_cond_t *condvar)
|
||||
{
|
||||
int val = pthread_cond_destroy (&condvar->cond);
|
||||
int val = pthread_cond_destroy (condvar);
|
||||
VLC_THREAD_ASSERT ("destroying condition");
|
||||
}
|
||||
|
||||
void vlc_cond_signal (vlc_cond_t *condvar)
|
||||
{
|
||||
int val = pthread_cond_signal (&condvar->cond);
|
||||
int val = pthread_cond_signal (condvar);
|
||||
VLC_THREAD_ASSERT ("signaling condition variable");
|
||||
}
|
||||
|
||||
void vlc_cond_broadcast (vlc_cond_t *condvar)
|
||||
{
|
||||
pthread_cond_broadcast (&condvar->cond);
|
||||
pthread_cond_broadcast (condvar);
|
||||
}
|
||||
|
||||
void vlc_cond_wait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex)
|
||||
|
@ -237,7 +235,7 @@ void vlc_cond_wait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex)
|
|||
vlc_testcancel ();
|
||||
if (vlc_mutex_trylock (&th->lock) == 0)
|
||||
{
|
||||
th->cond = &condvar->cond;
|
||||
th->cond = condvar;
|
||||
vlc_mutex_unlock (&th->lock);
|
||||
}
|
||||
else
|
||||
|
@ -250,7 +248,7 @@ void vlc_cond_wait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex)
|
|||
}
|
||||
}
|
||||
|
||||
int val = pthread_cond_wait (&condvar->cond, p_mutex);
|
||||
int val = pthread_cond_wait (condvar, p_mutex);
|
||||
VLC_THREAD_ASSERT ("waiting on condition");
|
||||
|
||||
if (th != NULL)
|
||||
|
@ -262,21 +260,21 @@ void vlc_cond_wait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex)
|
|||
}
|
||||
}
|
||||
|
||||
int vlc_cond_timedwait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex,
|
||||
mtime_t deadline)
|
||||
typedef int (*vlc_cond_wait_cb)(pthread_cond_t *, pthread_mutex_t *,
|
||||
const struct timespec *);
|
||||
|
||||
static int vlc_cond_timedwait_common(vlc_cond_t *condvar, vlc_mutex_t *mutex,
|
||||
const struct timespec *ts,
|
||||
vlc_cond_wait_cb cb)
|
||||
{
|
||||
struct timespec ts = mtime_to_ts (deadline);
|
||||
vlc_thread_t th = thread;
|
||||
#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
|
||||
int (*cb)(pthread_cond_t *, pthread_mutex_t *, const struct timespec *);
|
||||
#endif
|
||||
|
||||
if (th != NULL)
|
||||
{
|
||||
vlc_testcancel ();
|
||||
if (vlc_mutex_trylock (&th->lock) == 0)
|
||||
{
|
||||
th->cond = &condvar->cond;
|
||||
th->cond = condvar;
|
||||
vlc_mutex_unlock (&th->lock);
|
||||
}
|
||||
else
|
||||
|
@ -289,24 +287,7 @@ int vlc_cond_timedwait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
|
||||
switch (condvar->clock)
|
||||
{
|
||||
case CLOCK_REALTIME:
|
||||
cb = pthread_cond_timedwait;
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
cb = pthread_cond_timedwait_monotonic_np;
|
||||
break;
|
||||
default:
|
||||
vlc_assert_unreachable ();
|
||||
}
|
||||
|
||||
int val = cb (&condvar->cond, p_mutex, &ts);
|
||||
#else
|
||||
int val = pthread_cond_timedwait(&condvar->cond, p_mutex, &ts);
|
||||
#endif
|
||||
|
||||
int val = cb(condvar, p_mutex, ts);
|
||||
if (val != ETIMEDOUT)
|
||||
VLC_THREAD_ASSERT ("timed-waiting on condition");
|
||||
|
||||
|
@ -320,6 +301,26 @@ int vlc_cond_timedwait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex,
|
|||
return val;
|
||||
}
|
||||
|
||||
int vlc_cond_timedwait(vlc_cond_t *cond, vlc_mutex_t *mutex, mtime_t deadline)
|
||||
{
|
||||
struct timespec ts = mtime_to_ts(deadline);
|
||||
|
||||
#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
|
||||
return vlc_cond_timedwait_common(cond, mutex, &ts,
|
||||
pthread_cond_timedwait_monotonic_np);
|
||||
#else
|
||||
return vlc_cond_timedwait_common(cond, mutex, &ts, pthread_cond_timedwait);
|
||||
#endif
|
||||
}
|
||||
|
||||
int vlc_cond_timedwait_daytime(vlc_cond_t *cond, vlc_mutex_t *mutex,
|
||||
time_t deadline)
|
||||
{
|
||||
struct timespec ts = { deadline, 0 };
|
||||
|
||||
return vlc_cond_timedwait_common(cond, mutex, &ts, pthread_cond_timedwait);
|
||||
}
|
||||
|
||||
/* pthread */
|
||||
static void clean_detached_thread(void *data)
|
||||
{
|
||||
|
|
|
@ -193,30 +193,21 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
|
|||
VLC_THREAD_ASSERT ("unlocking mutex");
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
VLC_CLOCK_MONOTONIC = 0,
|
||||
VLC_CLOCK_REALTIME,
|
||||
};
|
||||
|
||||
void vlc_cond_init (vlc_cond_t *p_condvar)
|
||||
{
|
||||
if (unlikely(pthread_cond_init (&p_condvar->cond, NULL)))
|
||||
if (unlikely(pthread_cond_init (p_condvar, NULL)))
|
||||
abort ();
|
||||
p_condvar->clock = VLC_CLOCK_MONOTONIC;
|
||||
}
|
||||
|
||||
void vlc_cond_init_daytime (vlc_cond_t *p_condvar)
|
||||
{
|
||||
if (unlikely(pthread_cond_init (&p_condvar->cond, NULL)))
|
||||
if (unlikely(pthread_cond_init (p_condvar, NULL)))
|
||||
abort ();
|
||||
p_condvar->clock = VLC_CLOCK_REALTIME;
|
||||
|
||||
}
|
||||
|
||||
void vlc_cond_destroy (vlc_cond_t *p_condvar)
|
||||
{
|
||||
int val = pthread_cond_destroy (&p_condvar->cond);
|
||||
int val = pthread_cond_destroy (p_condvar);
|
||||
|
||||
/* due to a faulty pthread implementation within Darwin 11 and
|
||||
* later condition variables cannot be destroyed without
|
||||
|
@ -244,26 +235,48 @@ void vlc_cond_destroy (vlc_cond_t *p_condvar)
|
|||
|
||||
void vlc_cond_signal (vlc_cond_t *p_condvar)
|
||||
{
|
||||
int val = pthread_cond_signal (&p_condvar->cond);
|
||||
int val = pthread_cond_signal (p_condvar);
|
||||
VLC_THREAD_ASSERT ("signaling condition variable");
|
||||
}
|
||||
|
||||
void vlc_cond_broadcast (vlc_cond_t *p_condvar)
|
||||
{
|
||||
pthread_cond_broadcast (&p_condvar->cond);
|
||||
pthread_cond_broadcast (p_condvar);
|
||||
}
|
||||
|
||||
void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
|
||||
{
|
||||
int val = pthread_cond_wait (&p_condvar->cond, p_mutex);
|
||||
int val = pthread_cond_wait (p_condvar, p_mutex);
|
||||
VLC_THREAD_ASSERT ("waiting on condition");
|
||||
}
|
||||
|
||||
int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
||||
mtime_t deadline)
|
||||
{
|
||||
int val = 0;
|
||||
/* according to POSIX standards, cond_timedwait should be a cancellation point
|
||||
* Of course, Darwin does not care */
|
||||
pthread_testcancel();
|
||||
|
||||
/*
|
||||
* mdate() is the monotonic clock, pthread_cond_timedwait expects
|
||||
* origin of gettimeofday(). Use timedwait_relative_np() instead.
|
||||
*/
|
||||
mtime_t base = mdate();
|
||||
deadline -= base;
|
||||
if (deadline < 0)
|
||||
deadline = 0;
|
||||
|
||||
struct timespec ts = mtime_to_ts(deadline);
|
||||
int val = pthread_cond_timedwait_relative_np(p_condvar, p_mutex, &ts);
|
||||
if (val != ETIMEDOUT)
|
||||
VLC_THREAD_ASSERT ("timed-waiting on condition");
|
||||
return val;
|
||||
}
|
||||
|
||||
/* variant for vlc_cond_init_daytime */
|
||||
int vlc_cond_timedwait_daytime (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
||||
time_t deadline)
|
||||
{
|
||||
/*
|
||||
* Note that both pthread_cond_timedwait_relative_np and pthread_cond_timedwait
|
||||
* convert the given timeout to a mach absolute deadline, with system startup
|
||||
|
@ -272,43 +285,22 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
|||
* For more details, see: https://devforums.apple.com/message/931605
|
||||
*/
|
||||
|
||||
/* according to POSIX standards, cond_timedwait should be a cancellation point
|
||||
* Of course, Darwin does not care */
|
||||
pthread_testcancel();
|
||||
|
||||
if (p_condvar->clock == VLC_CLOCK_MONOTONIC) {
|
||||
/*
|
||||
* FIXME: It is assumed, that in this case the system waits until the real
|
||||
* time deadline is passed, even if the real time is adjusted in between.
|
||||
* This is not fulfilled, as described above.
|
||||
*/
|
||||
struct timespec ts = mtime_to_ts(deadline);
|
||||
int val = pthread_cond_timedwait(p_condvar, p_mutex, &ts);
|
||||
|
||||
/*
|
||||
* mdate() is the monotonic clock, pthread_cond_timedwait expects
|
||||
* origin of gettimeofday(). Use timedwait_relative_np() instead.
|
||||
*/
|
||||
mtime_t base = mdate();
|
||||
deadline -= base;
|
||||
if (deadline < 0)
|
||||
deadline = 0;
|
||||
struct timespec ts = mtime_to_ts(deadline);
|
||||
|
||||
val = pthread_cond_timedwait_relative_np(&p_condvar->cond, p_mutex, &ts);
|
||||
|
||||
} else {
|
||||
/* variant for vlc_cond_init_daytime */
|
||||
assert (p_condvar->clock == VLC_CLOCK_REALTIME);
|
||||
|
||||
/*
|
||||
* FIXME: It is assumed, that in this case the system waits until the real
|
||||
* time deadline is passed, even if the real time is adjusted in between.
|
||||
* This is not fulfilled, as described above.
|
||||
*/
|
||||
struct timespec ts = mtime_to_ts(deadline);
|
||||
|
||||
val = pthread_cond_timedwait(&p_condvar->cond, p_mutex, &ts);
|
||||
}
|
||||
|
||||
if (val != ETIMEDOUT)
|
||||
VLC_THREAD_ASSERT ("timed-waiting on condition");
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize a semaphore. */
|
||||
void vlc_sem_init (vlc_sem_t *sem, unsigned value)
|
||||
{
|
||||
|
|
|
@ -395,7 +395,7 @@ static void* Manage( void* p_object )
|
|||
while( !vlm->input_state_changed && !scheduled_command )
|
||||
{
|
||||
if( nextschedule != 0 )
|
||||
scheduled_command = vlc_cond_timedwait( &vlm->wait_manage, &vlm->lock_manage, nextschedule * CLOCK_FREQ ) != 0;
|
||||
scheduled_command = vlc_cond_timedwait_daytime( &vlm->wait_manage, &vlm->lock_manage, nextschedule ) != 0;
|
||||
else
|
||||
vlc_cond_wait( &vlm->wait_manage, &vlm->lock_manage );
|
||||
}
|
||||
|
|
|
@ -517,7 +517,6 @@ VLC_Compiler
|
|||
vlc_cond_broadcast
|
||||
vlc_cond_destroy
|
||||
vlc_cond_init
|
||||
vlc_cond_init_daytime
|
||||
vlc_cond_signal
|
||||
vlc_cond_timedwait
|
||||
vlc_cond_wait
|
||||
|
|
|
@ -256,25 +256,6 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
|
|||
}
|
||||
|
||||
/*** Condition variables ***/
|
||||
#undef CLOCK_REALTIME
|
||||
#undef CLOCK_MONOTONIC
|
||||
enum
|
||||
{
|
||||
CLOCK_REALTIME=0, /* must be zero for VLC_STATIC_COND */
|
||||
CLOCK_MONOTONIC,
|
||||
};
|
||||
|
||||
static void vlc_cond_init_common (vlc_cond_t *p_condvar, unsigned clock)
|
||||
{
|
||||
if (DosCreateEventSem (NULL, &p_condvar->hev, 0, FALSE) ||
|
||||
DosCreateEventSem (NULL, &p_condvar->hevAck, 0, FALSE))
|
||||
abort();
|
||||
|
||||
p_condvar->waiters = 0;
|
||||
p_condvar->signaled = 0;
|
||||
p_condvar->clock = clock;
|
||||
}
|
||||
|
||||
typedef struct vlc_static_cond_t vlc_static_cond_t;
|
||||
|
||||
struct vlc_static_cond_t
|
||||
|
@ -291,7 +272,7 @@ static void vlc_static_cond_init (vlc_cond_t *p_condvar)
|
|||
|
||||
if (p_condvar->hev == NULLHANDLE)
|
||||
{
|
||||
vlc_cond_init_common (p_condvar, p_condvar->clock);
|
||||
vlc_cond_init (p_condvar);
|
||||
|
||||
vlc_static_cond_t *new_static_condvar;
|
||||
|
||||
|
@ -325,12 +306,17 @@ static void vlc_static_cond_destroy_all (void)
|
|||
|
||||
void vlc_cond_init (vlc_cond_t *p_condvar)
|
||||
{
|
||||
vlc_cond_init_common (p_condvar, CLOCK_MONOTONIC);
|
||||
if (DosCreateEventSem (NULL, &p_condvar->hev, 0, FALSE) ||
|
||||
DosCreateEventSem (NULL, &p_condvar->hevAck, 0, FALSE))
|
||||
abort();
|
||||
|
||||
p_condvar->waiters = 0;
|
||||
p_condvar->signaled = 0;
|
||||
}
|
||||
|
||||
void vlc_cond_init_daytime (vlc_cond_t *p_condvar)
|
||||
{
|
||||
vlc_cond_init_common (p_condvar, CLOCK_REALTIME);
|
||||
vlc_cond_init (p_condvar);
|
||||
}
|
||||
|
||||
void vlc_cond_destroy (vlc_cond_t *p_condvar)
|
||||
|
@ -371,6 +357,8 @@ static int vlc_cond_wait_common (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
|||
ULONG ulPost;
|
||||
ULONG rc;
|
||||
|
||||
assert(p_condvar->hev != NULLHANDLE);
|
||||
|
||||
do
|
||||
{
|
||||
vlc_testcancel();
|
||||
|
@ -408,28 +396,29 @@ void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
|
|||
int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
||||
mtime_t deadline)
|
||||
{
|
||||
ULONG ulTimeout;
|
||||
ULONG ulTimeout;
|
||||
|
||||
if (p_condvar->hev == NULLHANDLE)
|
||||
vlc_static_cond_init (p_condvar);
|
||||
mtime_t total = mdate();
|
||||
total = (deadline - total) / 1000;
|
||||
if( total < 0 )
|
||||
total = 0;
|
||||
|
||||
ulTimeout = ( total > 0x7fffffff ) ? 0x7fffffff : total;
|
||||
|
||||
return vlc_cond_wait_common (p_condvar, p_mutex, ulTimeout);
|
||||
}
|
||||
|
||||
int vlc_cond_timedwait_daytime (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
||||
time_t deadline)
|
||||
{
|
||||
ULONG ulTimeout;
|
||||
mtime_t total;
|
||||
switch (p_condvar->clock)
|
||||
{
|
||||
case CLOCK_REALTIME:
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday (&tv, NULL);
|
||||
struct timeval tv;
|
||||
|
||||
total = CLOCK_FREQ * tv.tv_sec +
|
||||
CLOCK_FREQ * tv.tv_usec / 1000000L;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert (p_condvar->clock == CLOCK_MONOTONIC);
|
||||
total = mdate();
|
||||
break;
|
||||
}
|
||||
gettimeofday (&tv, NULL);
|
||||
|
||||
total = CLOCK_FREQ * tv.tv_sec +
|
||||
CLOCK_FREQ * tv.tv_usec / 1000000L;
|
||||
total = (deadline - total) / 1000;
|
||||
if( total < 0 )
|
||||
total = 0;
|
||||
|
|
|
@ -303,6 +303,16 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
|||
return val;
|
||||
}
|
||||
|
||||
int vlc_cond_timedwait_daytime (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
|
||||
time_t deadline)
|
||||
{
|
||||
struct timespec ts = { deadline, 0 };
|
||||
int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts);
|
||||
if (val != ETIMEDOUT)
|
||||
VLC_THREAD_ASSERT ("timed-waiting on condition");
|
||||
return val;
|
||||
}
|
||||
|
||||
void vlc_sem_init (vlc_sem_t *sem, unsigned value)
|
||||
{
|
||||
if (unlikely(sem_init (sem, 0, value)))
|
||||
|
|
|
@ -195,29 +195,17 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
|
|||
}
|
||||
|
||||
/*** Condition variables ***/
|
||||
enum
|
||||
{
|
||||
VLC_CLOCK_REALTIME=0, /* must be zero for VLC_STATIC_COND */
|
||||
VLC_CLOCK_MONOTONIC,
|
||||
};
|
||||
|
||||
static void vlc_cond_init_common(vlc_cond_t *wait, unsigned clock)
|
||||
void vlc_cond_init(vlc_cond_t *wait)
|
||||
{
|
||||
wait->semaphore = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
|
||||
if (unlikely(wait->semaphore == NULL))
|
||||
abort();
|
||||
wait->waiters = 0;
|
||||
wait->clock = clock;
|
||||
}
|
||||
|
||||
void vlc_cond_init (vlc_cond_t *p_condvar)
|
||||
{
|
||||
vlc_cond_init_common (p_condvar, VLC_CLOCK_MONOTONIC);
|
||||
}
|
||||
|
||||
void vlc_cond_init_daytime (vlc_cond_t *p_condvar)
|
||||
{
|
||||
vlc_cond_init_common (p_condvar, VLC_CLOCK_REALTIME);
|
||||
vlc_cond_init (p_condvar);
|
||||
}
|
||||
|
||||
void vlc_cond_destroy(vlc_cond_t *wait)
|
||||
|
@ -260,9 +248,15 @@ void vlc_cond_broadcast(vlc_cond_t *wait)
|
|||
ReleaseSemaphore(wait->semaphore, waiters, NULL);
|
||||
}
|
||||
|
||||
static DWORD vlc_cond_wait_delay(vlc_cond_t *wait, vlc_mutex_t *lock,
|
||||
DWORD delay)
|
||||
static int vlc_cond_wait_delay(vlc_cond_t *wait, vlc_mutex_t *lock,
|
||||
mtime_t us)
|
||||
{
|
||||
if (us < 0)
|
||||
us = 0;
|
||||
if (us > 0x7fffffff)
|
||||
us = 0x7fffffff;
|
||||
|
||||
DWORD delay = us;
|
||||
DWORD result;
|
||||
|
||||
vlc_testcancel();
|
||||
|
@ -282,7 +276,7 @@ static DWORD vlc_cond_wait_delay(vlc_cond_t *wait, vlc_mutex_t *lock,
|
|||
|
||||
if (result == WAIT_IO_COMPLETION)
|
||||
vlc_testcancel();
|
||||
return result;
|
||||
return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
|
||||
}
|
||||
|
||||
void vlc_cond_wait(vlc_cond_t *wait, vlc_mutex_t *lock)
|
||||
|
@ -292,29 +286,19 @@ void vlc_cond_wait(vlc_cond_t *wait, vlc_mutex_t *lock)
|
|||
|
||||
int vlc_cond_timedwait(vlc_cond_t *wait, vlc_mutex_t *lock, mtime_t deadline)
|
||||
{
|
||||
mtime_t total;
|
||||
return vlc_cond_wait_delay(wait, lock, deadline - mdate());
|
||||
}
|
||||
|
||||
switch (wait->clock)
|
||||
{
|
||||
case VLC_CLOCK_REALTIME: /* FIXME? sub-second precision */
|
||||
total = CLOCK_FREQ * time(NULL);
|
||||
break;
|
||||
case VLC_CLOCK_MONOTONIC:
|
||||
total = mdate();
|
||||
break;
|
||||
default:
|
||||
vlc_assert_unreachable();
|
||||
}
|
||||
int vlc_cond_timedwait_daytime(vlc_cond_t *wait, vlc_mutex_t *lock,
|
||||
time_t deadline)
|
||||
{
|
||||
time_t now;
|
||||
mtime_t delay;
|
||||
|
||||
total = (deadline - total) / 1000;
|
||||
if (total < 0)
|
||||
total = 0;
|
||||
time(&now);
|
||||
delay = ((mtime_t)deadline - (mtime_t)now) * CLOCK_FREQ;
|
||||
|
||||
DWORD delay = (total > 0x7fffffff) ? 0x7fffffff : total;
|
||||
|
||||
if (vlc_cond_wait_delay(wait, lock, delay) == WAIT_TIMEOUT)
|
||||
return ETIMEDOUT;
|
||||
return 0;
|
||||
return vlc_cond_wait_delay(wait, lock, delay);
|
||||
}
|
||||
|
||||
/*** Semaphore ***/
|
||||
|
|
Loading…
Reference in New Issue