1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
import scala.concurrent._, duration._
import ExecutionContext.Implicits.global
import scala.tools.reflect.WrappedProperties.AccessControl._
import java.util.concurrent.CyclicBarrier
object Test extends App {
@volatile var done = false
val barrier = new CyclicBarrier(2)
val probe = Future {
val attempts = 1024 // previously, failed after a few
def fail(i: Int) = s"Failed at $i"
barrier.await()
for (i <- 1 to attempts ; p <- systemProperties)
p match { case (k, v) => assert (k != null && v != null, fail(i)) }
}
probe onComplete {
case _ => done = true
}
System.setProperty("foo", "fooz")
System.setProperty("bar", "barz")
barrier.await() // just for fun, wait to start mucking with properties
// continually modify properties trying to break live iteration over sys props
// hint: don't iterate lively over sys props
var alt = true
while (!done) {
if (alt) {
System.getProperties.remove("foo")
System.setProperty("bar", "barz")
alt = false
} else {
System.getProperties.remove("bar")
System.setProperty("foo", "fooz")
alt = true
}
}
Await.result(probe, Duration.Inf)
}
/*
import scala.concurrent.{duration, Future, Await, ExecutionContext}
import scala.tools.nsc.Settings
import ExecutionContext.Implicits.global
// Was failing pretty regularly with a ConcurrentModificationException as
// WrappedProperties#systemProperties iterated directly over the mutable
// global system properties map.
object Test {
def main(args: Array[String]) {
val tries = 1000 // YMMV
val compiler = Future {
for(_ <- 1 to tries) new Settings(_ => {})
}
for(i <- 1 to tries * 10) System.setProperty(s"foo$i", i.toString)
Await.result(compiler, duration.Duration.Inf)
}
}
*/
|