Piotr Caban : server: Use monotonic clock for SetTimer timeouts.

Alexandre Julliard julliard at winehq.org
Thu Apr 9 16:04:47 CDT 2020


Module: wine
Branch: master
Commit: af89b53cef4c0b8cff1ea39fd612c8d1116b020a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=af89b53cef4c0b8cff1ea39fd612c8d1116b020a

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Apr  6 17:21:07 2020 +0200

server: Use monotonic clock for SetTimer timeouts.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 server/file.h  |  6 ++++++
 server/queue.c | 10 +++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/server/file.h b/server/file.h
index 4f130e2cf7..7395814dad 100644
--- a/server/file.h
+++ b/server/file.h
@@ -140,6 +140,12 @@ static inline abstime_t timeout_to_abstime( timeout_t timeout )
     return timeout > 0 ? timeout : timeout - monotonic_time;
 }
 
+static inline timeout_t abstime_to_timeout( abstime_t abstime )
+{
+    if (abstime > 0) return abstime;
+    return -abstime < monotonic_time ? 0 : abstime + monotonic_time;
+}
+
 extern void set_current_time( void );
 extern struct timeout_user *add_timeout_user( timeout_t when, timeout_callback func, void *private );
 extern void remove_timeout_user( struct timeout_user *user );
diff --git a/server/queue.c b/server/queue.c
index b5e17be18f..84ee0f9a4e 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -89,7 +89,7 @@ struct message
 struct timer
 {
     struct list     entry;     /* entry in timer list */
-    timeout_t       when;      /* next expiration */
+    abstime_t       when;      /* next expiration */
     unsigned int    rate;      /* timer rate in ms */
     user_handle_t   win;       /* window handle */
     unsigned int    msg;       /* message to post */
@@ -1154,7 +1154,7 @@ static void set_next_timer( struct msg_queue *queue )
     if ((ptr = list_head( &queue->pending_timers )))
     {
         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
-        queue->timeout = add_timeout_user( timer->when, timer_callback, queue );
+        queue->timeout = add_timeout_user( abstime_to_timeout(timer->when), timer_callback, queue );
     }
     /* set/clear QS_TIMER bit */
     if (list_empty( &queue->expired_timers ))
@@ -1206,7 +1206,7 @@ static void link_timer( struct msg_queue *queue, struct timer *timer )
     for (ptr = queue->pending_timers.next; ptr != &queue->pending_timers; ptr = ptr->next)
     {
         struct timer *t = LIST_ENTRY( ptr, struct timer, entry );
-        if (t->when >= timer->when) break;
+        if (t->when <= timer->when) break;
     }
     list_add_before( ptr, &timer->entry );
 }
@@ -1223,7 +1223,7 @@ static void free_timer( struct msg_queue *queue, struct timer *timer )
 static void restart_timer( struct msg_queue *queue, struct timer *timer )
 {
     list_remove( &timer->entry );
-    while (timer->when <= current_time) timer->when += (timeout_t)timer->rate * 10000;
+    while (-timer->when <= monotonic_time) timer->when -= (timeout_t)timer->rate * 10000;
     link_timer( queue, timer );
     set_next_timer( queue );
 }
@@ -1255,7 +1255,7 @@ static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
     if (timer)
     {
         timer->rate = max( rate, 1 );
-        timer->when = current_time + (timeout_t)timer->rate * 10000;
+        timer->when = -monotonic_time - (timeout_t)timer->rate * 10000;
         link_timer( queue, timer );
         /* check if we replaced the next timer */
         if (list_head( &queue->pending_timers ) == &timer->entry) set_next_timer( queue );




More information about the wine-cvs mailing list