1 package ch.qos.logback.classic;
2
3 import java.util.concurrent.CyclicBarrier;
4
5 import org.junit.Ignore;
6 import org.junit.Test;
7
8 import ch.qos.logback.core.contention.AbstractMultiThreadedHarness;
9 import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
10 import ch.qos.logback.core.testUtil.StatusChecker;
11
12 @Ignore
13 public class LoggerContextConcurrentResetTest {
14 static int CONCURRENT_RESET_THREAD_COUNT = 10;
15
16
17 @Test(timeout = 1000)
18 public void concurrentReset() throws InterruptedException {
19 LoggerContext loggerContext = new LoggerContext();
20 CyclicBarrier cyclicBarrier = new CyclicBarrier(CONCURRENT_RESET_THREAD_COUNT);
21 StatusChecker statusChecker = new StatusChecker(loggerContext);
22 int desiredResetCount = 100;
23 RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(loggerContext, cyclicBarrier);
24 Harness harness = new Harness((Resetter) runnableArray[0], desiredResetCount);
25 harness.execute(runnableArray);
26 statusChecker.assertIsErrorFree();
27 }
28
29 class Harness extends AbstractMultiThreadedHarness {
30 int desiredResetCount;
31 Resetter resetter;
32
33 Harness(Resetter resetter, int desiredResetCount) {
34 this.resetter = resetter;
35 this.desiredResetCount = desiredResetCount;
36 }
37
38 public void waitUntilEndCondition() throws InterruptedException {
39 while (resetter.getCounter() < desiredResetCount) {
40 Thread.yield();
41 }
42 }
43 }
44
45 static class GetLoggerRunnable extends RunnableWithCounterAndDone {
46
47 final int burstLength = 30;
48 LoggerContext loggerContext;
49 CyclicBarrier cyclicBarrier;
50 String nameSuffix;
51
52 GetLoggerRunnable(LoggerContext loggerContext, CyclicBarrier cyclicBarrier, String nameSuffix) {
53 this.loggerContext = loggerContext;
54 this.cyclicBarrier = cyclicBarrier;
55 this.nameSuffix = nameSuffix;
56 }
57
58 public void run() {
59 try {
60 cyclicBarrier.await();
61 } catch (Exception e) {
62 }
63
64 while (!isDone()) {
65 long i = counter % burstLength;
66 loggerContext.getLogger("org.bla." + nameSuffix + ".x" + i);
67 counter++;
68 if (i == 0) {
69 Thread.yield();
70 }
71 }
72 }
73 }
74
75 static class Resetter extends RunnableWithCounterAndDone {
76 LoggerContext loggerContext;
77 CyclicBarrier cyclicBarrier;
78 public int resetCount = 0;
79
80 Resetter(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) {
81 this.loggerContext = loggerContext;
82 this.cyclicBarrier = cyclicBarrier;
83 }
84
85 public void run() {
86 try {
87 cyclicBarrier.await();
88 } catch (Exception e) {
89 }
90 while (!isDone()) {
91 loggerContext.reset();
92 counter++;
93 Thread.yield();
94 }
95 }
96 }
97
98 private RunnableWithCounterAndDone[] buildRunnableArray(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) {
99 RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[CONCURRENT_RESET_THREAD_COUNT];
100 rArray[0] = new Resetter(loggerContext, cyclicBarrier);
101 for (int i = 1; i < CONCURRENT_RESET_THREAD_COUNT; i++) {
102 rArray[i] = new GetLoggerRunnable(loggerContext, cyclicBarrier, "mouse-" + i);
103 }
104 return rArray;
105 }
106 }