[vlc-commits] commit: vlc_timer_schedule: fix resetting the timer from itself ( =?UTF-8?Q?R=C3=A9mi=20Denis=2DCourmont=20?=)
git at videolan.org
git at videolan.org
Wed Nov 24 18:02:58 CET 2010
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Nov 24 19:01:28 2010 +0200| [66c47c31f0f81448e55100170822fae29e4834ac] | committer: Rémi Denis-Courmont
vlc_timer_schedule: fix resetting the timer from itself
This also fixes error handling: if the thread cannot be created, we do
fail cleanly.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=66c47c31f0f81448e55100170822fae29e4834ac
---
src/misc/pthread.c | 68 +++++++++++++++++++++++++++++-----------------------
1 files changed, 38 insertions(+), 30 deletions(-)
diff --git a/src/misc/pthread.c b/src/misc/pthread.c
index 7603b24..88691c6 100644
--- a/src/misc/pthread.c
+++ b/src/misc/pthread.c
@@ -800,6 +800,7 @@ void vlc_control_cancel (int cmd, ...)
struct vlc_timer
{
vlc_thread_t thread;
+ vlc_cond_t reschedule;
vlc_mutex_t lock;
void (*func) (void *);
void *data;
@@ -810,37 +811,43 @@ struct vlc_timer
static void *vlc_timer_thread (void *data)
{
struct vlc_timer *timer = data;
- mtime_t value, interval;
vlc_mutex_lock (&timer->lock);
- value = timer->value;
- interval = timer->interval;
- vlc_mutex_unlock (&timer->lock);
+ mutex_cleanup_push (&timer->lock);
for (;;)
{
- mwait (value);
+ while (timer->value == 0)
+ vlc_cond_wait (&timer->reschedule, &timer->lock);
+
+ if (vlc_cond_timedwait (&timer->reschedule, &timer->lock,
+ timer->value) == 0)
+ continue;
+ vlc_mutex_unlock (&timer->lock);
int canc = vlc_savecancel ();
timer->func (timer->data);
vlc_restorecancel (canc);
- if (interval == 0)
- return NULL;
-
mtime_t now = mdate ();
- unsigned misses = (now - value) / interval;
+ unsigned misses;
+
+ vlc_mutex_lock (&timer->lock);
+ misses = (now - timer->value) / timer->interval;
+ timer->value += timer->interval;
/* Try to compensate for one miss (mwait() will return immediately)
* but no more. Otherwise, we might busy loop, after extended periods
* without scheduling (suspend, SIGSTOP, RT preemption, ...). */
if (misses > 1)
{
misses--;
+ timer->value += misses * timer->interval;
vlc_atomic_add (&timer->overruns, misses);
- value += misses * interval;
}
- value += interval;
}
+
+ vlc_cleanup_pop ();
+ assert (0);
}
/**
@@ -861,12 +868,23 @@ int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data)
if (unlikely(timer == NULL))
return ENOMEM;
vlc_mutex_init (&timer->lock);
+ vlc_cond_init (&timer->reschedule);
assert (func);
timer->func = func;
timer->data = data;
timer->value = 0;
timer->interval = 0;
vlc_atomic_set(&timer->overruns, 0);
+
+ if (vlc_clone (&timer->thread, vlc_timer_thread, timer,
+ VLC_THREAD_PRIORITY_INPUT))
+ {
+ vlc_cond_destroy (&timer->reschedule);
+ vlc_mutex_destroy (&timer->lock);
+ free (timer);
+ return ENOMEM;
+ }
+
*id = timer;
return 0;
}
@@ -882,7 +900,9 @@ int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data)
*/
void vlc_timer_destroy (vlc_timer_t timer)
{
- vlc_timer_schedule (timer, false, 0, 0);
+ vlc_cancel (timer->thread);
+ vlc_join (timer->thread, NULL);
+ vlc_cond_destroy (&timer->reschedule);
vlc_mutex_destroy (&timer->lock);
free (timer);
}
@@ -907,25 +927,13 @@ void vlc_timer_destroy (vlc_timer_t timer)
void vlc_timer_schedule (vlc_timer_t timer, bool absolute,
mtime_t value, mtime_t interval)
{
- vlc_mutex_lock (&timer->lock);
- while (timer->value)
- {
- vlc_thread_t thread = timer->thread;
+ if (!absolute && value != 0)
+ value += mdate();
- timer->value = 0;
- vlc_mutex_unlock (&timer->lock);
- vlc_cancel (thread);
- /* cannot keep the lock during vlc_join X( */
- vlc_join (thread, NULL);
- vlc_mutex_lock (&timer->lock);
- }
- if ((value != 0)
- && (vlc_clone (&timer->thread, vlc_timer_thread, timer,
- VLC_THREAD_PRIORITY_INPUT) == 0))
- {
- timer->value = (absolute ? 0 : mdate ()) + value;
- timer->interval = interval;
- }
+ vlc_mutex_lock (&timer->lock);
+ timer->value = value;
+ timer->interval = interval;
+ vlc_cond_signal (&timer->reschedule);
vlc_mutex_unlock (&timer->lock);
}
More information about the vlc-commits
mailing list