From 4e36cbabc0025dc27133ab833c15adffe729b7aa Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sat, 6 Jan 2024 23:24:12 +0800 Subject: [PATCH] Fix crash on get 509 and mDownloadReference > 1 --- .../ehviewer/download/DownloadManager.kt | 86 ++++++++++--------- .../com/hippo/ehviewer/spider/SpiderQueen.kt | 10 ++- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt b/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt index 588f32415..4a048ee3e 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt @@ -54,6 +54,8 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.transform import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import splitties.preferences.edit object DownloadManager : OnSpiderListener { @@ -83,6 +85,8 @@ object DownloadManager : OnSpiderListener { private val mutableNotifyFlow = MutableSharedFlow(extraBufferCapacity = 1) val notifyFlow = mutableNotifyFlow.asSharedFlow() + private val mutex = Mutex() + init { assertNotMainThread() map = runAssertingNotMainThread { @@ -134,35 +138,37 @@ object DownloadManager : OnSpiderListener { } private suspend fun ensureDownload() { - if (mCurrentTask != null) { - // Only one download - return - } + mutex.withLock { + if (mCurrentTask != null) { + // Only one download + return + } - // Get download from wait list - if (!mWaitList.isEmpty()) { - val info = mWaitList.removeFirst() - val spider = SpiderQueen.obtainSpiderQueen(info, SpiderQueen.MODE_DOWNLOAD) - mCurrentTask = info - mCurrentSpider = spider - spider.addOnSpiderListener(this) - info.state = DownloadInfo.STATE_DOWNLOAD - info.speed = -1 - info.remaining = -1 - info.total = -1 - info.finished = 0 - info.downloaded = 0 - info.legacy = -1 - // Update in DB - EhDB.putDownloadInfo(info) - // Start speed count - mSpeedReminder.start() - // Notify start downloading - if (mDownloadListener != null) { - mDownloadListener!!.onStart(info) + // Get download from wait list + if (!mWaitList.isEmpty()) { + val info = mWaitList.removeFirst() + val spider = SpiderQueen.obtainSpiderQueen(info, SpiderQueen.MODE_DOWNLOAD) + mCurrentTask = info + mCurrentSpider = spider + spider.addOnSpiderListener(this) + info.state = DownloadInfo.STATE_DOWNLOAD + info.speed = -1 + info.remaining = -1 + info.total = -1 + info.finished = 0 + info.downloaded = 0 + info.legacy = -1 + // Update in DB + EhDB.putDownloadInfo(info) + // Start speed count + mSpeedReminder.start() + // Notify start downloading + if (mDownloadListener != null) { + mDownloadListener!!.onStart(info) + } + // Notify state update + mutableNotifyFlow.emit(info) } - // Notify state update - mutableNotifyFlow.emit(info) } } @@ -365,20 +371,22 @@ object DownloadManager : OnSpiderListener { } suspend fun stopAllDownload() { - // Stop all in wait list - for (info in mWaitList) { - info.state = DownloadInfo.STATE_NONE - // Update in DB - EhDB.putDownloadInfo(info) + mutex.withLock { + // Stop all in wait list + for (info in mWaitList) { + info.state = DownloadInfo.STATE_NONE + // Update in DB + EhDB.putDownloadInfo(info) - // Notify - mutableNotifyFlow.emit(info) + // Notify + mutableNotifyFlow.emit(info) + } + mWaitList.clear() + + // Stop current + val info = stopCurrentDownloadInternal() + info?.let { mutableNotifyFlow.emit(it) } } - mWaitList.clear() - - // Stop current - val info = stopCurrentDownloadInternal() - info?.let { mutableNotifyFlow.emit(it) } } suspend fun deleteDownload(gid: Long, deleteFiles: Boolean = false) { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt index 200fd3ce3..fee96fd8a 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt @@ -212,7 +212,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS MODE_READ -> mReadReference++ MODE_DOWNLOAD -> mDownloadReference++ } - check(mDownloadReference <= 1) { "mDownloadReference can't more than 0" } + check(mDownloadReference <= 1) { "mDownloadReference can't more than 1" } } private fun clearMode(@Mode mode: Int) { @@ -562,9 +562,11 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS } }.onFailure { if (it is CancellationException) { - Log.d(WORKER_DEBUG_TAG, "Download image $index cancelled") - if (it.message != FORCE_RETRY) { - updatePageState(index, STATE_FAILED, "Cancelled") + if (mReadReference > 0) { + Log.d(WORKER_DEBUG_TAG, "Download image $index cancelled") + if (it.message != FORCE_RETRY) { + updatePageState(index, STATE_FAILED, "Cancelled") + } } throw it }