diff --git a/apps/i2psnark/java/src/org/klomp/snark/BitField.java b/apps/i2psnark/java/src/org/klomp/snark/BitField.java index 3534a8d7eebc870530a2f0985157c00c3bad7889..b67ab862237b2f3902e2f2a942bc7914e076446f 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 8cca67e8e776fcb52542ac931d57689cb483c715..b12bf5d883698552d3f3fe418bcaa43d9289deaa 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 6d612e2bb75b7d4c4855a9dd6261037a5eb509f9..69ca276c426f53e97610a719d9ce22ba86e9e11a 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));