fix: make ApiVersionsRegistry thread-safe

This commit is contained in:
Akash Yadav
2024-06-28 07:20:09 +05:30
parent 52a6117451
commit 11858d7dce
2 changed files with 52 additions and 52 deletions
@@ -19,14 +19,15 @@ package com.itsaky.androidide.xml.internal.versions
import com.itsaky.androidide.xml.versions.ApiVersion
import com.itsaky.androidide.xml.versions.ApiVersions
import org.eclipse.jdt.core.Signature
import java.util.concurrent.ConcurrentHashMap
/** @author Akash Yadav */
/**
* This implementation is not thread safe. Do not modify concurrently.
*
* @author Akash Yadav
*/
internal class DefaultApiVersions : ApiVersions {
val classes =
ConcurrentHashMap<String, Pair<ApiVersion?, ConcurrentHashMap<String, ApiVersion>>>()
val classes = HashMap<String, Pair<ApiVersion?, HashMap<String, ApiVersion>>>()
private fun String.flatten() = replace('.', '/')
@@ -57,9 +58,9 @@ internal class DefaultApiVersions : ApiVersions {
private fun computeClass(
name: String,
version: ApiVersion? = null
): Pair<ApiVersion?, ConcurrentHashMap<String, ApiVersion>> {
): Pair<ApiVersion?, HashMap<String, ApiVersion>> {
return classes.computeIfAbsent(name.flatten()) {
version to ConcurrentHashMap()
version to hashMapOf()
}
}
}
@@ -33,7 +33,7 @@ import java.util.concurrent.ConcurrentHashMap
*/
@AutoService(ApiVersionsRegistry::class)
@VisibleForTesting
class DefaultApiVersionsRegistry : ApiVersionsParser(), ApiVersionsRegistry {
class DefaultApiVersionsRegistry : ApiVersionsRegistry {
private val versions = ConcurrentHashMap<String, ApiVersions>()
@@ -43,10 +43,6 @@ class DefaultApiVersionsRegistry : ApiVersionsParser(), ApiVersionsRegistry {
override var isLoggingEnabled: Boolean = true
private var _currentApiVersions: DefaultApiVersions? = null
private val currentApiVersions: DefaultApiVersions
get() = checkNotNull(_currentApiVersions)
override fun forPlatformDir(platform: File): ApiVersions? {
var version = versions[platform.path]
if (version != null) {
@@ -69,15 +65,21 @@ class DefaultApiVersionsRegistry : ApiVersionsParser(), ApiVersionsRegistry {
}
return versionsFile.inputStream().buffered().use { inputStream ->
check(_currentApiVersions == null)
_currentApiVersions = DefaultApiVersions()
parse(inputStream)
currentApiVersions.also {
_currentApiVersions = null
}
// we do not implement the parsing logic in the registry itself for thread safety
val versions = DefaultApiVersions()
val parser = ApiVersionsParserInternal(versions)
parser.parse(inputStream)
versions
}
}
override fun clear() {
versions.clear()
}
private class ApiVersionsParserInternal(
private val currentApiVersions: DefaultApiVersions
) : ApiVersionsParser() {
override fun isDuplicateClass(name: String): Boolean {
return currentApiVersions.containsClass(name)
}
@@ -111,8 +113,5 @@ class DefaultApiVersionsRegistry : ApiVersionsParser(), ApiVersionsRegistry {
currentApiVersions.putMember(className, identifier, apiVersion)
}
override fun clear() {
versions.clear()
}
}