aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2016-10-07 16:02:18 +0200
committerPierre Ossman <ossman@cendio.se>2017-02-24 13:13:53 +0100
commit79621345b91316cc127154f28e2f2934fc1f64b4 (patch)
tree6be08a04f9a8407cfdd034d2a0ef3ade399d713d /common
parent7e8b8b10cd290d80954f6e2c57112f2eb3e2a251 (diff)
downloadtigervnc-79621345b91316cc127154f28e2f2934fc1f64b4.tar.gz
tigervnc-79621345b91316cc127154f28e2f2934fc1f64b4.zip
Better handling of slow timers
Make sure the code deals more gracefully with timers that take a long time to execute, and therefore might miss their deadlines.
Diffstat (limited to 'common')
-rw-r--r--common/rfb/Timer.cxx30
1 files changed, 23 insertions, 7 deletions
diff --git a/common/rfb/Timer.cxx b/common/rfb/Timer.cxx
index 676f24e1..efae36e2 100644
--- a/common/rfb/Timer.cxx
+++ b/common/rfb/Timer.cxx
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2016 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
@@ -58,20 +59,35 @@ inline static int diffTimeMillis(timeval later, timeval earlier) {
std::list<Timer*> Timer::pending;
int Timer::checkTimeouts() {
+ timeval start;
+
if (pending.empty())
return 0;
- timeval now;
- gettimeofday(&now, 0);
- while (pending.front()->isBefore(now)) {
- Timer* timer = pending.front();
+
+ gettimeofday(&start, 0);
+ while (pending.front()->isBefore(start)) {
+ Timer* timer;
+ timeval before;
+
+ timer = pending.front();
pending.pop_front();
+
+ gettimeofday(&before, 0);
if (timer->cb->handleTimeout(timer)) {
+ timeval now;
+
+ gettimeofday(&now, 0);
+
timer->dueTime = addMillis(timer->dueTime, timer->timeoutMs);
if (timer->isBefore(now)) {
- // Time has jumped forwards!
- vlog.info("time has moved forwards!");
- timer->dueTime = addMillis(now, timer->timeoutMs);
+ // Time has jumped forwards, or we're not getting enough
+ // CPU time for the timers
+
+ timer->dueTime = addMillis(before, timer->timeoutMs);
+ if (timer->isBefore(now))
+ timer->dueTime = now;
}
+
insertTimer(timer);
} else if (pending.empty()) {
return 0;