From 027f179a4bf796dc56da4bcb6602891a75d269c8 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 31 Mar 2025 06:05:38 +0200 Subject: [PATCH] Update kotlin monorepo to v2.1.20 (#1883) Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> (cherry picked from commit 556290f2d35f739bb4bddc012739acf10b92708d) --- .../data/library/LibraryUpdateJob.kt | 21 +++++++++++-------- .../data/library/MetadataUpdateJob.kt | 15 +++++++------ .../extension/installer/Installer.kt | 16 +++++++------- .../ui/reader/loader/HttpPageLoader.kt | 9 +++++--- .../tachiyomi/network/OkHttpExtensions.kt | 9 +++++--- .../java/tachiyomi/data/TransactionContext.kt | 12 +++++++---- gradle/kotlinx.versions.toml | 2 +- 7 files changed, 51 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt index 7c7011d7e..cf6666e0f 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt @@ -101,9 +101,12 @@ import java.time.Instant import java.time.ZonedDateTime import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicInteger +import kotlin.concurrent.atomics.AtomicBoolean +import kotlin.concurrent.atomics.AtomicInt +import kotlin.concurrent.atomics.ExperimentalAtomicApi +import kotlin.concurrent.atomics.incrementAndFetch +@OptIn(ExperimentalAtomicApi::class) class LibraryUpdateJob(private val context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) { @@ -343,7 +346,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet */ private suspend fun updateChapterList() { val semaphore = Semaphore(5) - val progressCount = AtomicInteger(0) + val progressCount = AtomicInt(0) val currentlyUpdatingManga = CopyOnWriteArrayList() val newUpdates = CopyOnWriteArrayList>>() val failedUpdates = CopyOnWriteArrayList>() @@ -408,7 +411,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet if (chaptersToDownload.isNotEmpty()) { downloadChapters(manga, chaptersToDownload) - hasDownloads.set(true) + hasDownloads.store(true) } libraryPreferences.newUpdatesCount().getAndSet { it + newChapters.size } @@ -441,7 +444,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet if (newUpdates.isNotEmpty()) { notifier.showUpdateNotifications(newUpdates) - if (hasDownloads.get()) { + if (hasDownloads.load()) { downloadManager.startDownloads() } } @@ -641,7 +644,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet private suspend fun withUpdateNotification( updatingManga: CopyOnWriteArrayList, - completed: AtomicInteger, + completed: AtomicInt, manga: Manga, block: suspend () -> Unit, ) = coroutineScope { @@ -650,7 +653,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet updatingManga.add(manga) notifier.showProgressNotification( updatingManga, - completed.get(), + completed.load(), mangaToUpdate.size, ) @@ -659,10 +662,10 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet ensureActive() updatingManga.remove(manga) - completed.getAndIncrement() + completed.incrementAndFetch() notifier.showProgressNotification( updatingManga, - completed.get(), + completed.load(), mangaToUpdate.size, ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt index c6401ef72..b519bb483 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt @@ -37,8 +37,11 @@ import tachiyomi.domain.source.service.SourceManager import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.util.concurrent.CopyOnWriteArrayList -import java.util.concurrent.atomic.AtomicInteger +import kotlin.concurrent.atomics.AtomicInt +import kotlin.concurrent.atomics.ExperimentalAtomicApi +import kotlin.concurrent.atomics.fetchAndIncrement +@OptIn(ExperimentalAtomicApi::class) class MetadataUpdateJob(private val context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) { @@ -97,7 +100,7 @@ class MetadataUpdateJob(private val context: Context, workerParams: WorkerParame private suspend fun updateMetadata() { val semaphore = Semaphore(5) - val progressCount = AtomicInteger(0) + val progressCount = AtomicInt(0) val currentlyUpdatingManga = CopyOnWriteArrayList() coroutineScope { @@ -142,7 +145,7 @@ class MetadataUpdateJob(private val context: Context, workerParams: WorkerParame private suspend fun withUpdateNotification( updatingManga: CopyOnWriteArrayList, - completed: AtomicInteger, + completed: AtomicInt, manga: Manga, block: suspend () -> Unit, ) = coroutineScope { @@ -151,7 +154,7 @@ class MetadataUpdateJob(private val context: Context, workerParams: WorkerParame updatingManga.add(manga) notifier.showProgressNotification( updatingManga, - completed.get(), + completed.load(), mangaToUpdate.size, ) @@ -160,10 +163,10 @@ class MetadataUpdateJob(private val context: Context, workerParams: WorkerParame ensureActive() updatingManga.remove(manga) - completed.getAndIncrement() + completed.fetchAndIncrement() notifier.showProgressNotification( updatingManga, - completed.get(), + completed.load(), mangaToUpdate.size, ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/installer/Installer.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/installer/Installer.kt index 495e82e91..3a2200632 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/installer/Installer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/installer/Installer.kt @@ -12,16 +12,18 @@ import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.model.InstallStep import uy.kohesive.injekt.injectLazy import java.util.Collections -import java.util.concurrent.atomic.AtomicReference +import kotlin.concurrent.atomics.AtomicReference +import kotlin.concurrent.atomics.ExperimentalAtomicApi /** * Base implementation class for extension installer. To be used inside a foreground [Service]. */ +@OptIn(ExperimentalAtomicApi::class) abstract class Installer(private val service: Service) { private val extensionManager: ExtensionManager by injectLazy() - private var waitingInstall = AtomicReference(null) + private var waitingInstall = AtomicReference(null) private val queue = Collections.synchronizedList(mutableListOf()) private val cancelReceiver = object : BroadcastReceiver() { @@ -79,7 +81,7 @@ abstract class Installer(private val service: Service) { * @see waitingInstall */ fun continueQueue(resultStep: InstallStep) { - val completedEntry = waitingInstall.getAndSet(null) + val completedEntry = waitingInstall.exchange(null) if (completedEntry != null) { extensionManager.updateInstallStep(completedEntry.downloadId, resultStep) checkQueue() @@ -115,10 +117,10 @@ abstract class Installer(private val service: Service) { LocalBroadcastManager.getInstance(service).unregisterReceiver(cancelReceiver) queue.forEach { extensionManager.updateInstallStep(it.downloadId, InstallStep.Error) } queue.clear() - waitingInstall.set(null) + waitingInstall.store(null) } - protected fun getActiveEntry(): Entry? = waitingInstall.get() + protected fun getActiveEntry(): Entry? = waitingInstall.load() /** * Cancels queue for the provided download ID if exists. @@ -126,13 +128,13 @@ abstract class Installer(private val service: Service) { * @param downloadId Download ID as known by [ExtensionManager] */ private fun cancelQueue(downloadId: Long) { - val waitingInstall = this.waitingInstall.get() + val waitingInstall = this.waitingInstall.load() val toCancel = queue.find { it.downloadId == downloadId } ?: waitingInstall ?: return if (cancelEntry(toCancel)) { queue.remove(toCancel) if (waitingInstall == toCancel) { // Currently processing removed entry, continue queue - this.waitingInstall.set(null) + this.waitingInstall.store(null) checkQueue() } extensionManager.updateInstallStep(downloadId, InstallStep.Idle) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index e810151a0..b8b2a51b3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -26,7 +26,9 @@ import tachiyomi.core.common.util.lang.withIOContext import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.util.concurrent.PriorityBlockingQueue -import java.util.concurrent.atomic.AtomicInteger +import kotlin.concurrent.atomics.AtomicInt +import kotlin.concurrent.atomics.ExperimentalAtomicApi +import kotlin.concurrent.atomics.incrementAndFetch import kotlin.math.min /** @@ -246,15 +248,16 @@ internal class HttpPageLoader( /** * Data class used to keep ordering of pages in order to maintain priority. */ +@OptIn(ExperimentalAtomicApi::class) private class PriorityPage( val page: ReaderPage, val priority: Int, ) : Comparable { companion object { - private val idGenerator = AtomicInteger() + private val idGenerator = AtomicInt(0) } - private val identifier = idGenerator.incrementAndGet() + private val identifier = idGenerator.incrementAndFetch() override fun compareTo(other: PriorityPage): Int { val p = other.priority.compareTo(priority) diff --git a/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/OkHttpExtensions.kt b/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/OkHttpExtensions.kt index e6eec02f4..2417f6b90 100755 --- a/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/OkHttpExtensions.kt +++ b/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/OkHttpExtensions.kt @@ -16,20 +16,23 @@ import rx.Observable import rx.Producer import rx.Subscription import java.io.IOException -import java.util.concurrent.atomic.AtomicBoolean +import kotlin.concurrent.atomics.AtomicBoolean +import kotlin.concurrent.atomics.ExperimentalAtomicApi import kotlin.coroutines.resumeWithException val jsonMime = "application/json; charset=utf-8".toMediaType() +@OptIn(ExperimentalAtomicApi::class) fun Call.asObservable(): Observable { return Observable.unsafeCreate { subscriber -> // Since Call is a one-shot type, clone it for each new subscriber. val call = clone() // Wrap the call in a helper which handles both unsubscription and backpressure. - val requestArbiter = object : AtomicBoolean(), Producer, Subscription { + val requestArbiter = object : Producer, Subscription { + val boolean = AtomicBoolean(false) override fun request(n: Long) { - if (n == 0L || !compareAndSet(false, true)) return + if (n == 0L || !boolean.compareAndSet(expectedValue = false, newValue = true)) return try { val response = call.execute() diff --git a/data/src/main/java/tachiyomi/data/TransactionContext.kt b/data/src/main/java/tachiyomi/data/TransactionContext.kt index 63a2b7519..f804a0b8e 100644 --- a/data/src/main/java/tachiyomi/data/TransactionContext.kt +++ b/data/src/main/java/tachiyomi/data/TransactionContext.kt @@ -7,7 +7,10 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import java.util.concurrent.RejectedExecutionException -import java.util.concurrent.atomic.AtomicInteger +import kotlin.concurrent.atomics.AtomicInt +import kotlin.concurrent.atomics.ExperimentalAtomicApi +import kotlin.concurrent.atomics.decrementAndFetch +import kotlin.concurrent.atomics.incrementAndFetch import kotlin.coroutines.ContinuationInterceptor import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext @@ -127,6 +130,7 @@ private suspend fun CoroutineDispatcher.acquireTransactionThread( /** * A [CoroutineContext.Element] that indicates there is an on-going database transaction. */ +@OptIn(ExperimentalAtomicApi::class) private class TransactionElement( private val transactionThreadControlJob: Job, val transactionDispatcher: ContinuationInterceptor, @@ -143,14 +147,14 @@ private class TransactionElement( * when [release] is invoked then the transaction job is cancelled and the transaction thread * is released. */ - private val referenceCount = AtomicInteger(0) + private val referenceCount = AtomicInt(0) fun acquire() { - referenceCount.incrementAndGet() + referenceCount.incrementAndFetch() } fun release() { - val count = referenceCount.decrementAndGet() + val count = referenceCount.decrementAndFetch() if (count < 0) { throw IllegalStateException("Transaction was never started or was already released") } else if (count == 0) { diff --git a/gradle/kotlinx.versions.toml b/gradle/kotlinx.versions.toml index 8ec6f7471..538ec03c0 100644 --- a/gradle/kotlinx.versions.toml +++ b/gradle/kotlinx.versions.toml @@ -1,5 +1,5 @@ [versions] -kotlin_version = "2.1.10" +kotlin_version = "2.1.20" serialization_version = "1.8.0" xml_serialization_version = "0.90.3"