@@ -7,8 +7,12 @@ import scoverage.Platform._
77object Invoker {
88
99 private val MeasurementsPrefix = " scoverage.measurements."
10- private val threadFiles = new ThreadLocal [ThreadSafeMap [String , FileWriter ]]
11- private val ids = ThreadSafeMap .empty[(String , Int ), Any ]
10+ private val threadFiles = new ThreadLocal [mutable.HashMap [String , FileWriter ]]
11+
12+ // For each data directory we maintain a thread-safe set tracking the ids that we've already
13+ // seen and recorded. We're using a map as a set, so we only care about its keys and can ignore
14+ // its values.
15+ private val dataDirToIds = ThreadSafeMap .empty[String , ThreadSafeMap [Int , Any ]]
1216
1317 /**
1418 * We record that the given id has been invoked by appending its id to the coverage
@@ -31,18 +35,27 @@ object Invoker {
3135 // times since for coverage we only care about 1 or more, (it just slows things down to
3236 // do it more than once), anything we can do to help is good. This helps especially with code
3337 // that is executed many times quickly, eg tight loops.
34- if (! ids.contains(dataDir, id)) {
38+ if (! dataDirToIds.contains(dataDir)) {
39+ // Guard against SI-7943: "TrieMap method getOrElseUpdate is not thread-safe".
40+ dataDirToIds.synchronized {
41+ if (! dataDirToIds.contains(dataDir)) {
42+ dataDirToIds(dataDir) = ThreadSafeMap .empty[Int , Any ]
43+ }
44+ }
45+ }
46+ val ids = dataDirToIds(dataDir)
47+ if (! ids.contains(id)) {
3548 // Each thread writes to a separate measurement file, to reduce contention
3649 // and because file appends via FileWriter are not atomic on Windows.
3750 var files = threadFiles.get()
3851 if (files == null ) {
39- files = ThreadSafeMap .empty[String , FileWriter ]
52+ files = mutable. HashMap .empty[String , FileWriter ]
4053 threadFiles.set(files)
4154 }
4255 val writer = files.getOrElseUpdate(dataDir, new FileWriter (measurementFile(dataDir), true ))
43- writer.append(id .toString + ' \n ' ).flush()
56+ writer.append(Integer .toString(id)).append( " \n " ).flush()
4457
45- ids.put((dataDir, id) , ())
58+ ids.put(id , ())
4659 }
4760 }
4861
0 commit comments