summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ballard <peter.ballard@isode.com>2015-07-07 12:33:47 (GMT)
committerPeter Ballard <peter.ballard@isode.com>2015-07-08 08:57:05 (GMT)
commit1afab8c1f2c417b08371bc12569e03171851d785 (patch)
tree81b137f46f782a211f867b60db6f18535fdee26e
parentcc8fc8685df570e5ab7cb0620f9f5836bd44ef7a (diff)
downloadstroke-1afab8c1f2c417b08371bc12569e03171851d785.zip
stroke-1afab8c1f2c417b08371bc12569e03171851d785.tar.bz2
Add option to only read from TCP socket when previous read has been processed
By default this option is disabled, existing usages will function as normal. This option stops the JavaConnection from reading data if the previous read has not been processed by the event loop. Previously constrained devices were seeing OutOfMemoryErrors, if they were not able to process the incoming data quick enough. This change does not affect the write behavour. Change-Id: I47bc0eafba32336f5bf250ccb1fea530f51d328e
-rw-r--r--src/com/isode/stroke/network/JavaConnection.java33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/com/isode/stroke/network/JavaConnection.java b/src/com/isode/stroke/network/JavaConnection.java
index 3560e83..4e7503b 100644
--- a/src/com/isode/stroke/network/JavaConnection.java
+++ b/src/com/isode/stroke/network/JavaConnection.java
@@ -79,7 +79,8 @@ public class JavaConnection extends Connection implements EventOwner {
while (!disconnecting_ || isWriteNeeded()) {
/* Something(s) happened. See what needs doing */
boolean writeNeeded = isWriteNeeded();
- boolean readNeeded = selectionKey_.isReadable();
+ boolean readNeeded = (selectionKey_.interestOps() & SelectionKey.OP_READ) != 0
+ && selectionKey_.isReadable();
{ /* Handle any writing */
if (writeNeeded) {
@@ -299,21 +300,46 @@ public class JavaConnection extends Connection implements EventOwner {
}
private void handleDataRead(final ByteArray data) {
+ if (synchroniseReads_) {
+ selectionKey_.interestOps(0);
+ }
eventLoop_.postEvent(new Callback() {
public void run() {
onDataRead.emit(data);
+ // Check "isOpen" to Avoid Android crash see
+ // https://code.google.com/p/android/issues/detail?id=80785
+ if (synchroniseReads_ && selector_ != null) {
+ synchronized (selectorLock_) {
+ selectionKey_.interestOps(SelectionKey.OP_READ);
+ if (selector_.isOpen()) {
+ selector_.wakeup();
+ }
+ }
+ }
}
});
}
}
- private JavaConnection(EventLoop eventLoop) {
+ private JavaConnection(EventLoop eventLoop, boolean synchroniseReads) {
eventLoop_ = eventLoop;
+ synchroniseReads_ = synchroniseReads;
}
public static JavaConnection create(EventLoop eventLoop) {
- return new JavaConnection(eventLoop);
+ return new JavaConnection(eventLoop, false);
+ }
+
+ /**
+ * Creates a new JavaConnection
+ * @param eventLoop the EventLoop for read and write events to be posted to
+ * @param synchroniseReads if true then data will not be read from the connection
+ * until the previous read has been processed by the EventLoop
+ * @return a new JavaConnection
+ */
+ public static JavaConnection create(EventLoop eventLoop, boolean synchroniseReads) {
+ return new JavaConnection(eventLoop, synchroniseReads);
}
@Override
@@ -386,5 +412,6 @@ public class JavaConnection extends Connection implements EventOwner {
private Selector selector_;
private final Object selectorLock_ = new Object(); // use private lock object that is not visible elsewhere
private Worker worker_;
+ private final boolean synchroniseReads_;
}