/* Wait for an interval of time. * parameter: delay how long to wait (in microseconds) */ void msleep (mtime_t delay) { struct timespec ts = mtime_to_ts (delay); while (nanosleep (&ts, &ts) == -1) assert (errno == EINTR); }
/** * Waits for a condition variable up to a certain date. * This works like vlc_cond_wait(), except for the additional time-out. * * 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(), the timeout is expressed from the Unix epoch. * * @param p_condvar condition variable to wait on * @param p_mutex mutex which is unlocked while waiting, * then locked again when waking up. * @param deadline <b>absolute</b> timeout * * @return 0 if the condition was signaled, an error code in case of timeout. */ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex, mtime_t deadline) { struct timespec ts = mtime_to_ts (deadline); int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts); if (val != ETIMEDOUT) VLC_THREAD_ASSERT ("timed-waiting on condition"); return val; }
int vlc_cond_timedwait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex, mtime_t deadline) { struct timespec ts = mtime_to_ts (deadline); vlc_thread_t th = thread; int (*cb)(pthread_cond_t *, pthread_mutex_t *, const struct timespec *); if (th != NULL) { vlc_testcancel (); if (vlc_mutex_trylock (&th->lock) == 0) { th->cond = &condvar->cond; vlc_mutex_unlock (&th->lock); } else { /* The lock is already held by another thread. * => That other thread has just cancelled this one. */ vlc_testcancel (); /* Cancellation did not occur even though this thread is cancelled. * => Cancellation is disabled. */ th = NULL; } } switch (condvar->clock) { case CLOCK_REALTIME: cb = pthread_cond_timedwait; break; case CLOCK_MONOTONIC: cb = pthread_cond_timedwait_monotonic_np; break; default: assert (0); } int val = cb (&condvar->cond, p_mutex, &ts); if (val != ETIMEDOUT) VLC_THREAD_ASSERT ("timed-waiting on condition"); if (th != NULL) { if (vlc_mutex_trylock (&th->lock) == 0) { thread->cond = NULL; vlc_mutex_unlock (&th->lock); } /* Else: This thread was cancelled and is cancellable. vlc_testcancel() will take of it right there: */ vlc_testcancel(); } return val; }
/** * Waits for an interval of time. * @param delay how long to wait (in microseconds) */ void msleep (mtime_t delay) { struct timespec ts = mtime_to_ts (delay); #if (_POSIX_CLOCK_SELECTION > 0) vlc_clock_setup (); while (clock_nanosleep (vlc_clock_id, 0, &ts, &ts) == EINTR); #else while (nanosleep (&ts, &ts) == -1) assert (errno == EINTR); #endif }
/** * Waits until a deadline (possibly later due to OS scheduling). * @param deadline timestamp to wait for (see mdate()) */ void mwait (mtime_t deadline) { #if (_POSIX_CLOCK_SELECTION > 0) vlc_clock_setup (); /* If the deadline is already elapsed, or within the clock precision, * do not even bother the system timer. */ deadline -= vlc_clock_prec; struct timespec ts = mtime_to_ts (deadline); while (clock_nanosleep (vlc_clock_id, TIMER_ABSTIME, &ts, NULL) == EINTR); #else deadline -= mdate (); if (deadline > 0) msleep (deadline); #endif }