From 095c76c10deb9414fbf3e84caadbe00b0e20dd91 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Sun, 24 Sep 2017 23:11:27 +0200 Subject: [PATCH] =?UTF-8?q?Fixed=20a=20bug=20where=20Android=E2=80=99s=20i?= =?UTF-8?q?mplementation=20of=20Thread::interrupt=20and=20Channel::close?= =?UTF-8?q?=20was=20broken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quasseldroid_ng/service/QuasselService.kt | 30 +++++++++++++++++-- .../libquassel/session/CoreConnection.kt | 30 +++++++++---------- .../de/kuschku/libquassel/session/Session.kt | 7 +++-- .../libquassel/util/nio/WrappedChannel.kt | 14 --------- 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt index 093e6fa00..adb777f4f 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt @@ -3,6 +3,8 @@ package de.kuschku.quasseldroid_ng.service import android.arch.lifecycle.LifecycleService import android.content.Intent import android.os.Binder +import android.os.Handler +import android.os.HandlerThread import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.session.Session @@ -18,7 +20,7 @@ import javax.net.ssl.X509TrustManager class QuasselService : LifecycleService() { private lateinit var session: Session - private val backend = object : Backend { + private val backendImplementation = object : Backend { override fun session() = session override fun connect(address: SocketAddress, user: String, pass: String) { @@ -33,6 +35,30 @@ class QuasselService : LifecycleService() { } } + private val asyncBackend = object : Backend { + private val thread = HandlerThread("BackendHandler") + private val handler: Handler + + init { + thread.start() + handler = Handler(thread.looper) + } + + override fun connect(address: SocketAddress, user: String, pass: String) { + handler.post { + backendImplementation.connect(address, user, pass) + } + } + + override fun disconnect() { + handler.post { + backendImplementation.disconnect() + } + } + + override fun session() = backendImplementation.session() + } + private lateinit var database: QuasselDatabase override fun onCreate() { @@ -63,7 +89,7 @@ class QuasselService : LifecycleService() { override fun onBind(intent: Intent?): QuasselBinder { super.onBind(intent) - return QuasselBinder(backend) + return QuasselBinder(asyncBackend) } class QuasselBinder(val backend: Backend) : Binder() diff --git a/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt index 81f4b8e69..af42d2d4c 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt @@ -112,17 +112,13 @@ class CoreConnection( } override fun close() { - interrupt() - handlerService.quit() - val thread = Thread { - try { - channel?.close() - } catch (e: Throwable) { - log(WARN, TAG, "Error encountered while closing connection", e) - } + try { + channel?.close() + interrupt() + handlerService.quit() + } catch (e: Throwable) { + log(WARN, TAG, "Error encountered while closing connection", e) } - thread.start() - thread.join() } override fun dispatch(message: HandshakeMessage) { @@ -166,15 +162,17 @@ class CoreConnection( if (size > 64 * 1024 * 1024) throw SocketException("Too large frame received: $size") val dataBuffer = ByteBuffer.allocateDirect(size) - while (dataBuffer.position() < dataBuffer.limit() && channel?.read(dataBuffer) ?: -1 > 0) { + while (!isInterrupted && dataBuffer.position() < dataBuffer.limit() && channel?.read( + dataBuffer) ?: -1 > 0) { } dataBuffer.flip() - handlerService.parse { - when (internalState.value) { - ConnectionState.HANDSHAKE -> processHandshake(dataBuffer) - else -> processSigProxy(dataBuffer) + if (!isInterrupted) + handlerService.parse { + when (internalState.value) { + ConnectionState.HANDSHAKE -> processHandshake(dataBuffer) + else -> processSigProxy(dataBuffer) + } } - } } } catch (e: Throwable) { log(WARN, TAG, "Error encountered in connection", e) diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt index 389e90769..56dc9efdd 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt @@ -149,15 +149,16 @@ class Session( backlogManager = null bufferSyncer = null bufferViewManager = null - certManagers.clear() coreInfo = null dccConfig = null - identities.clear() ignoreListManager = null ircListHelper = null - networks.clear() networkConfig = null + certManagers.clear() + identities.clear() + networks.clear() + super.cleanUp() } } diff --git a/lib/src/main/java/de/kuschku/libquassel/util/nio/WrappedChannel.kt b/lib/src/main/java/de/kuschku/libquassel/util/nio/WrappedChannel.kt index 4c98f3db2..1896f5f90 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/nio/WrappedChannel.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/nio/WrappedChannel.kt @@ -176,17 +176,3 @@ class WrappedChannel( flusher?.invoke() } } - -fun ByteArray.toHexDump(): String { - val buf = StringBuffer() - var i = 0 - buf.append("HexDump ========================================================================\n") - while (i < this.size) { - buf.append(String.format("%02x ", this[i])) - if (i > 0 && (i + 1) % 32 == 0) { - buf.append("\n") - } - i++ - } - return buf.toString() -} -- GitLab