summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-07-31 17:13:09 -0700
committerJason Zaugg <jzaugg@gmail.com>2016-07-31 17:21:19 -0700
commitc1bd857318b01b223b3f5dbd99aa2e71b1b232d4 (patch)
tree71d7eacfe41dbeb3211fe182d9241eebacacc3c9
parent25b29ea4036b0bc910a5eb07d64c93d294be4e55 (diff)
downloadscala-c1bd857318b01b223b3f5dbd99aa2e71b1b232d4.tar.gz
scala-c1bd857318b01b223b3f5dbd99aa2e71b1b232d4.tar.bz2
scala-c1bd857318b01b223b3f5dbd99aa2e71b1b232d4.zip
Fix race condition in lambda deserialization
Review of the code made me aware that concurrent calls to `$deserializeLambda$` for some lambda hosting class could result in concurrent calls to operations on `j.u.HashMap`. I've added a synchronized block to avoid this problem. I don't think this is likely to be a bottleneck in practical use cases, but if so we could come up with a lock-free scheme in the future.
-rw-r--r--src/library/scala/runtime/LambdaDeserializer.scala16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/library/scala/runtime/LambdaDeserializer.scala b/src/library/scala/runtime/LambdaDeserializer.scala
index ad7d12ba5d..a6e08e6e61 100644
--- a/src/library/scala/runtime/LambdaDeserializer.scala
+++ b/src/library/scala/runtime/LambdaDeserializer.scala
@@ -94,13 +94,15 @@ object LambdaDeserializer {
val key = serialized.getImplMethodName + " : " + serialized.getImplMethodSignature
val factory: MethodHandle = if (cache == null) {
makeCallSite.getTarget
- } else cache.get(key) match {
- case null =>
- val callSite = makeCallSite
- val temp = callSite.getTarget
- cache.put(key, temp)
- temp
- case target => target
+ } else cache.synchronized{
+ cache.get(key) match {
+ case null =>
+ val callSite = makeCallSite
+ val temp = callSite.getTarget
+ cache.put(key, temp)
+ temp
+ case target => target
+ }
}
val captures = Array.tabulate(serialized.getCapturedArgCount)(n => serialized.getCapturedArg(n))