diff --git a/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt b/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt index c15fd9c68d3..e382fcb982d 100644 --- a/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt +++ b/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt @@ -3,6 +3,7 @@ package com.mapbox.navigation.base.internal.route import android.util.LruCache import com.mapbox.api.directions.v5.models.DirectionsRoute import com.mapbox.navigation.base.route.NavigationRoute +import java.util.concurrent.Semaphore /** * **Internal** cache object that aims to improve the performance performance of compatibility functions @@ -17,16 +18,17 @@ import com.mapbox.navigation.base.route.NavigationRoute object RouteCompatibilityCache { private val directionsSessionCache = mutableListOf() private val creationCache = LruCache(3) - private val lock = Any() + private val semaphore = Semaphore(1) /** * Use to put a result of a random route creation to cache. */ fun cacheCreationResult(routes: List) { - synchronized(lock) { + if (safelyAcquire()) { routes.forEach { creationCache.put(it.directionsRoute, it) } + semaphore.release() } } @@ -34,10 +36,11 @@ object RouteCompatibilityCache { * Use to put all routes tracked by `MapboxDirectionsSession` to cache (and clear everything else). */ fun setDirectionsSessionResult(routes: List) { - synchronized(lock) { + if (safelyAcquire()) { creationCache.evictAll() directionsSessionCache.clear() directionsSessionCache.addAll(routes) + semaphore.release() } } @@ -45,9 +48,21 @@ object RouteCompatibilityCache { * Get a cached [NavigationRoute] if there is one that wraps the provided [DirectionsRoute] (based on equality) or `null`. */ fun getFor(directionsRoute: DirectionsRoute): NavigationRoute? { - synchronized(lock) { - return directionsSessionCache.find { it.directionsRoute == directionsRoute } + var toReturn: NavigationRoute? = null + if (safelyAcquire()) { + toReturn = directionsSessionCache.find { it.directionsRoute == directionsRoute } ?: creationCache.get(directionsRoute) + semaphore.release() + } + return toReturn + } + + private fun safelyAcquire(): Boolean { + return try { + semaphore.acquire() + true + } catch (ex: Exception) { + false } } }