]> source.dussan.org Git - tigervnc.git/commitdiff
Detect conflicting timer rescheduling
authorPierre Ossman <ossman@cendio.se>
Thu, 29 Feb 2024 08:23:01 +0000 (09:23 +0100)
committerPierre Ossman <ossman@cendio.se>
Wed, 19 Jun 2024 14:39:07 +0000 (16:39 +0200)
Repeating a timer can be done in two ways:

 * Returning true from the handler
 * Calling start() again in the handler

The latter is useful if you want to change the timer interval.

If both are used, then it becomes ambiguous when the timer should fire
again.

Detect this case and warn about it. Current implementation will respect
the new interval given to start(), rather than the interval set before
running the handler.

common/rfb/Timer.cxx

index 4ff15bc595bc61768fc4e0e7a7af5d67833b666f..b43490d78e6e024a895c4e7318fff41be3570b2a 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright 2016-2018 Pierre Ossman for Cendio AB
+ * Copyright 2016-2024 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -66,15 +66,21 @@ int Timer::checkTimeouts() {
   gettimeofday(&start, 0);
   while (pending.front()->isBefore(start)) {
     Timer* timer;
-    timeval before;
+    timeval before, dueTime;
 
     timer = pending.front();
     pending.pop_front();
 
+    dueTime = timer->dueTime;
     gettimeofday(&before, 0);
     if (timer->cb->handleTimeout(timer)) {
       timeval now;
 
+      if (msBetween(&dueTime, &timer->dueTime) != 0) {
+        vlog.error("Timer incorrectly modified whilst repeating");
+        timer->dueTime = dueTime;
+      }
+
       gettimeofday(&now, 0);
 
       timer->dueTime = addMillis(timer->dueTime, timer->timeoutMs);