diff --git a/app/src/main/java/org/thoughtcrime/securesms/AppContext.kt b/app/src/main/java/org/thoughtcrime/securesms/AppContext.kt index 2588618b72..b9183939cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/AppContext.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/AppContext.kt @@ -1,5 +1,7 @@ package org.thoughtcrime.securesms +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.asExecutor import nl.komponents.kovenant.Kovenant import nl.komponents.kovenant.jvm.asDispatcher import org.session.libsignal.utilities.Log @@ -11,7 +13,7 @@ object AppContext { fun configureKovenant() { Kovenant.context { callbackContext.dispatcher = Executors.newSingleThreadExecutor().asDispatcher() - workerContext.dispatcher = ThreadUtils.executorPool.asDispatcher() + workerContext.dispatcher = Dispatchers.IO.asExecutor().asDispatcher() multipleCompletion = { v1, v2 -> Log.d("Loki", "Promise resolved more than once (first with $v1, then with $v2); ignoring $v2.") } diff --git a/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt b/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt index e920d85b47..6485babe80 100644 --- a/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt +++ b/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt @@ -1,11 +1,13 @@ package org.session.libsignal.utilities import android.os.Process +import kotlinx.coroutines.Dispatchers import java.util.concurrent.ExecutorService import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.SynchronousQueue import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.TimeUnit +import kotlin.coroutines.EmptyCoroutineContext object ThreadUtils { @@ -13,39 +15,16 @@ object ThreadUtils { const val PRIORITY_IMPORTANT_BACKGROUND_THREAD = Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE - // Paraphrased from: https://www.baeldung.com/kotlin/create-thread-pool - // "A cached thread pool such as one created via: - // `val executorPool: ExecutorService = Executors.newCachedThreadPool()` - // will utilize resources according to the requirements of submitted tasks. It will try to reuse - // existing threads for submitted tasks but will create as many threads as it needs if new tasks - // keep pouring in (with a memory usage of at least 1MB per created thread). These threads will - // live for up to 60 seconds of idle time before terminating by default. As such, it presents a - // very sharp tool that doesn't include any backpressure mechanism - and a sudden peak in load - // can bring the system down with an OutOfMemory error. We can achieve a similar effect but with - // better control by creating a ThreadPoolExecutor manually." - - private val corePoolSize = Runtime.getRuntime().availableProcessors() // Default thread pool size is our CPU core count - private val maxPoolSize = corePoolSize * 4 // Allow a maximum pool size of up to 4 threads per core - private val keepAliveTimeSecs = 100L // How long to keep idle threads in the pool before they are terminated - private val workQueue = SynchronousQueue() - val executorPool: ExecutorService = ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTimeSecs, TimeUnit.SECONDS, workQueue) - // Note: To see how many threads are running in our app at any given time we can use: // val threadCount = getAllStackTraces().size @JvmStatic fun queue(target: Runnable) { - executorPool.execute { - try { - target.run() - } catch (e: Exception) { - Log.e(TAG, e) - } - } + queue(target::run) } fun queue(target: () -> Unit) { - executorPool.execute { + Dispatchers.IO.dispatch(EmptyCoroutineContext) { try { target() } catch (e: Exception) {