diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-07-31 17:13:09 -0700 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-07-31 17:21:19 -0700 |
commit | c1bd857318b01b223b3f5dbd99aa2e71b1b232d4 (patch) | |
tree | 71d7eacfe41dbeb3211fe182d9241eebacacc3c9 | |
parent | 25b29ea4036b0bc910a5eb07d64c93d294be4e55 (diff) | |
download | scala-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.scala | 16 |
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)) |