From b15ea8ba2facabc27606c78a3c6df43fc7990e49 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Wed, 4 Nov 2015 14:57:07 +0000
Subject: [PATCH] Timers: Improve OutboundMessageRegistry locking SimpleTimer2
 cleanups possible fix for ticket #1694

---
 core/java/src/net/i2p/util/SimpleTimer2.java   | 18 +++++++++++-------
 .../transport/OutboundMessageRegistry.java     | 10 ++++++----
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/core/java/src/net/i2p/util/SimpleTimer2.java b/core/java/src/net/i2p/util/SimpleTimer2.java
index 4cfab3a0a9..e8dcc2fcbe 100644
--- a/core/java/src/net/i2p/util/SimpleTimer2.java
+++ b/core/java/src/net/i2p/util/SimpleTimer2.java
@@ -416,13 +416,15 @@ public class SimpleTimer2 {
                   case IDLE:  // fall through
                   case RUNNING:
                     throw new IllegalStateException(this + " not possible to be in " + _state);
-                  case SCHEDULED: // proceed, switch to IDLE in case I need to reschedule
-                    _state = TimedEventState.IDLE;
+                  case SCHEDULED:
+                    // proceed, will switch to IDLE to reschedule
                 }
                                                
                 // if I was rescheduled by the user, re-submit myself to the executor.
-                int difference = (int)(_nextRun - before); // careful with long uptimes
+                long difference = _nextRun - before; // careful with long uptimes
                 if (difference > _fuzz) {
+                    // proceed, switch to IDLE to reschedule
+                    _state = TimedEventState.IDLE;
                     schedule(difference); 
                     return;
                 }
@@ -437,10 +439,12 @@ public class SimpleTimer2 {
             else if (_log.shouldLog(Log.WARN))
                 _log.warn(_pool + " no _future " + this);
             // This can be an incorrect warning especially after a schedule(0)
-            if (_log.shouldLog(Log.WARN) && delay > 100)
-                _log.warn(_pool + " early execution " + delay + ": " + this);
-            else if (_log.shouldLog(Log.WARN) && delay < -1000)
-                _log.warn(" late execution " + (0 - delay) + ": " + this + _pool.debug());
+            if (_log.shouldWarn()) {
+                if (delay > 100)
+                    _log.warn(_pool + " early execution " + delay + ": " + this);
+                else if (delay < -1000)
+                    _log.warn(" late execution " + (0 - delay) + ": " + this + _pool.debug());
+            }
             try {
                 timeReached();
             } catch (Throwable t) {
diff --git a/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java b/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java
index 7c8e1b37dd..9c04f52b63 100644
--- a/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java
+++ b/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java
@@ -330,12 +330,14 @@ public class OutboundMessageRegistry {
                 if (r > 0 || e > 0 || a > 0)
                     _log.debug("Expired: " + e + " remaining: " + r + " active: " + a);
             }
-            if (_nextExpire <= now)
-                _nextExpire = now + 10*1000;
-            schedule(_nextExpire - now);
+            synchronized(this) {
+                if (_nextExpire <= now)
+                    _nextExpire = now + 10*1000;
+                schedule(_nextExpire - now);
+            }
         }
 
-        public void scheduleExpiration(MessageSelector sel) {
+        public synchronized void scheduleExpiration(MessageSelector sel) {
             long now = _context.clock().now();
             if ( (_nextExpire <= now) || (sel.getExpiration() < _nextExpire) ) {
                 _nextExpire = sel.getExpiration();
-- 
GitLab