Skip to content

Commit

Permalink
Cache Lock
Browse files Browse the repository at this point in the history
  • Loading branch information
yschimke committed Jan 20, 2024
1 parent 357ded4 commit 8674a8b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
44 changes: 44 additions & 0 deletions okhttp/src/main/kotlin/okhttp3/internal/cache/CacheLock.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package okhttp3.internal.cache

import android.annotation.SuppressLint
import java.io.Closeable
import java.nio.channels.FileChannel
import java.nio.file.StandardOpenOption
import java.util.Collections
import okhttp3.internal.platform.Platform
import okio.FileSystem
import okio.Path

internal object CacheLock {
private val openCaches = Collections.synchronizedMap(mutableMapOf<Path, Exception>())

fun openLock(fileSystem: FileSystem, directory: Path): Closeable {
return if (fileSystem == FileSystem.SYSTEM && !Platform.isAndroid) {
fileSystemLock(directory)
} else {
inMemoryLock(directory)
}
}

@SuppressLint("NewApi")
fun inMemoryLock(directory: Path): Closeable {
// TODO solution for Android N?
val existing = openCaches.putIfAbsent(directory, Exception("CacheLock($directory)"))
if (existing != null) {
throw IllegalStateException("Cache already open at '$directory'", existing)
}
return okio.Closeable {
openCaches.remove(directory)
}
}

@SuppressLint("NewApi")
fun fileSystemLock(directory: Path): Closeable {
val lockFile = directory / "lock"
val channel = FileChannel.open(lockFile.toNioPath(), StandardOpenOption.APPEND)

return okio.Closeable {
channel.close()
}
}
}
7 changes: 7 additions & 0 deletions okhttp/src/main/kotlin/okhttp3/internal/cache/DiskLruCache.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import java.io.EOFException
import java.io.Flushable
import java.io.IOException
import okhttp3.internal.assertThreadHoldsLock
import okhttp3.internal.cache.CacheLock.openLock
import okhttp3.internal.cache.DiskLruCache.Editor
import okhttp3.internal.closeQuietly
import okhttp3.internal.concurrent.Task
Expand Down Expand Up @@ -95,6 +96,8 @@ class DiskLruCache(
/** Used for asynchronous journal rebuilds. */
taskRunner: TaskRunner,
) : Closeable, Flushable {
lateinit var cacheLock: Closeable

internal val fileSystem: FileSystem =
object : ForwardingFileSystem(fileSystem) {
override fun sink(
Expand Down Expand Up @@ -242,6 +245,8 @@ class DiskLruCache(

civilizedFileSystem = fileSystem.isCivilized(journalFileBackup)

cacheLock = openLock(fileSystem, directory)

// Prefer to pick up where we left off.
if (fileSystem.exists(journalFile)) {
try {
Expand Down Expand Up @@ -705,6 +710,8 @@ class DiskLruCache(
return
}

cacheLock.close()

// Copying for concurrent iteration.
for (entry in lruEntries.values.toTypedArray()) {
if (entry.currentEditor != null) {
Expand Down

0 comments on commit 8674a8b

Please sign in to comment.