From 1f569b7359ee31f54659bf695c70ce56362088c4 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Thu, 7 Dec 2017 19:44:56 +0000 Subject: [PATCH] i2psnark: Synch operations on BitField byte array --- .../java/src/org/klomp/snark/BitField.java | 2 ++ .../org/klomp/snark/PeerConnectionOut.java | 20 +++++++++++++++--- .../src/org/klomp/snark/SnarkManager.java | 21 +++++++++++-------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/BitField.java b/apps/i2psnark/java/src/org/klomp/snark/BitField.java index 3534a8d7ee..b67ab86223 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/BitField.java +++ b/apps/i2psnark/java/src/org/klomp/snark/BitField.java @@ -71,6 +71,8 @@ public class BitField * affect this BitField. Note that some bits at the end of the byte * array are supposed to be always unset if they represent bits * bigger then the size of the bitfield. + * + * Caller should synch on this and copy! */ public byte[] getFieldBytes() { diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java index 8cca67e8e7..b12bf5d883 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java @@ -22,6 +22,7 @@ package org.klomp.snark; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.concurrent.BlockingQueue; @@ -355,12 +356,25 @@ class PeerConnectionOut implements Runnable void sendBitfield(BitField bitfield) { boolean fast = peer.supportsFast(); - if (fast && bitfield.complete()) { + boolean all = false; + boolean none = false; + byte[] data = null; + synchronized(bitfield) { + if (fast && bitfield.complete()) { + all = true; + } else if (fast && bitfield.count() <= 0) { + none = true; + } else { + byte[] d = bitfield.getFieldBytes(); + data = Arrays.copyOf(d, d.length); + } + } + if (all) { sendHaveAll(); - } else if (fast && bitfield.count() <= 0) { + } else if (none) { sendHaveNone(); } else { - Message m = new Message(bitfield.getFieldBytes()); + Message m = new Message(data); addMessage(m); } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 6d612e2bb7..69ca276c42 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -1671,7 +1671,8 @@ public class SnarkManager implements CompleteListener, ClientApp { } if (autoStart) { startTorrent(ih); - addMessage(_t("Fetching {0}", name)); + if (false) + addMessage(_t("Fetching {0}", name)); DHT dht = _util.getDHT(); boolean shouldWarn = _util.connected() && _util.getOpenTrackers().isEmpty() && @@ -2053,14 +2054,16 @@ public class SnarkManager implements CompleteListener, ClientApp { if (config.getProperty(PROP_META_ADDED) == null) config.setProperty(PROP_META_ADDED, now); String bfs; - if (bitfield.complete()) { - bfs = "."; - if (config.getProperty(PROP_META_COMPLETED) == null) - config.setProperty(PROP_META_COMPLETED, now); - } else { - byte[] bf = bitfield.getFieldBytes(); - bfs = Base64.encode(bf); - config.remove(PROP_META_COMPLETED); + synchronized(bitfield) { + if (bitfield.complete()) { + bfs = "."; + if (config.getProperty(PROP_META_COMPLETED) == null) + config.setProperty(PROP_META_COMPLETED, now); + } else { + byte[] bf = bitfield.getFieldBytes(); + bfs = Base64.encode(bf); + config.remove(PROP_META_COMPLETED); + } } config.setProperty(PROP_META_BITFIELD, bfs); config.setProperty(PROP_META_PRESERVE_NAMES, Boolean.toString(preserveNames)); -- GitLab