diff --git a/history.txt b/history.txt index 7d8eaafac..9d49954f3 100644 --- a/history.txt +++ b/history.txt @@ -1,5 +1,6 @@ 2015-12-03 zzz * Console: Add experimental Sybil analysis tool + * NetDb: Fix deadlock (ticket #1722) 2015-12-01 zzz * i2psnark: diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 99073c366..a6e37ae44 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -488,6 +488,9 @@ public class Router implements RouterClock.ClockShiftListener { /** * Our current router info. * Warning, may be null if called very early. + * + * Warning - risk of deadlock - do not call while holding locks + * */ public RouterInfo getRouterInfo() { synchronized (_routerInfoLock) { @@ -498,6 +501,9 @@ public class Router implements RouterClock.ClockShiftListener { /** * Caller must ensure info is valid - no validation done here. * Not for external use. + * + * Warning - risk of deadlock - do not call while holding locks + * */ public void setRouterInfo(RouterInfo info) { synchronized (_routerInfoLock) { @@ -806,6 +812,9 @@ public class Router implements RouterClock.ClockShiftListener { * Rebuild and republish our routerInfo since something significant * has changed. * Not for external use. + * + * Warning - risk of deadlock - do not call while holding locks + * */ public void rebuildRouterInfo(boolean blockingRebuild) { if (_log.shouldLog(Log.INFO)) @@ -959,6 +968,11 @@ public class Router implements RouterClock.ClockShiftListener { } } + /* + * + * Warning - risk of deadlock - do not call while holding locks + * + */ public boolean isHidden() { RouterInfo ri; synchronized (_routerInfoLock) { diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java index 87bc22b0b..2698faa0c 100644 --- a/router/java/src/net/i2p/router/RouterContext.java +++ b/router/java/src/net/i2p/router/RouterContext.java @@ -261,6 +261,9 @@ public class RouterContext extends I2PAppContext { /** * Convenience method for getting the router hash. * Equivalent to context.router().getRouterInfo().getIdentity().getHash() + * + * Warning - risk of deadlock - do not call while holding locks + * * @return may be null if called very early */ public Hash routerHash() { diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index fecba78d6..a6204817e 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 7; + public final static long BUILD = 8; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java index 251bd7363..68c2c23fc 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java @@ -199,10 +199,12 @@ class IterativeSearchJob extends FloodSearchJob { } } final boolean empty; + // outside sync to avoid deadlock + final Hash us = getContext().routerHash(); synchronized(this) { _toTry.addAll(floodfillPeers); // don't ask ourselves or the target - _toTry.remove(getContext().routerHash()); + _toTry.remove(us); _toTry.remove(_key); empty = _toTry.isEmpty(); }