MCPcopy Create free account
hub / github.com/antlr/codebuff / InterruptibleTask

Class InterruptibleTask

output/java_guava/1.4.16/InterruptibleTask.java:24–117  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

22
23
24@GwtCompatible(emulated = true)
25abstract class InterruptibleTask implements Runnable {
26 // These two fields are used to interrupt running tasks. The thread executing the task publishes
27 // itself to the 'runner' field and the thread interrupting sets 'doneInterrupting' when it has
28 // finished interrupting.
29 private volatile Thread runner;
30 private volatile boolean doneInterrupting;
31 private static final AtomicHelper ATOMIC_HELPER;
32 private static final Logger log = Logger.getLogger(InterruptibleTask.class.getName());
33
34 static {
35 AtomicHelper helper;
36 try {
37 helper = new SafeAtomicHelper(newUpdater(InterruptibleTask.class, (Class) Thread.class, "runner"));
38 } catch (Throwable reflectionFailure) {
39 // Some Android 5.0.x Samsung devices have bugs in JDK reflection APIs that cause
40 // getDeclaredField to throw a NoSuchFieldException when the field is definitely there.
41 // For these users fallback to a suboptimal implementation, based on synchronized. This will
42 // be a definite performance hit to those users.
43 log.log(Level.SEVERE, "SafeAtomicHelper is broken!", reflectionFailure);
44 helper = new SynchronizedAtomicHelper();
45 }
46 ATOMIC_HELPER = helper;
47 }
48
49 @Override
50 public final void run() {
51 if (!ATOMIC_HELPER.compareAndSetRunner(this, null, Thread.currentThread())) {
52 return; // someone else has run or is running.
53 }
54 try {
55 runInterruptibly();
56 } finally {
57 if (wasInterrupted()) {
58 // We were interrupted, it is possible that the interrupted bit hasn't been set yet. Wait
59 // for the interrupting thread to set 'doneInterrupting' to true. See interruptTask().
60 // We want to wait so that we don't interrupt the _next_ thing run on the thread.
61 // Note: We don't reset the interrupted bit, just wait for it to be set.
62 // If this is a thread pool thread, the thread pool will reset it for us. Otherwise, the
63 // interrupted bit may have been intended for something else, so don't clear it.
64 while (!doneInterrupting) {
65 Thread.yield();
66 }
67 }
68 }
69 }
70
71 abstract void runInterruptibly();
72
73 abstract boolean wasInterrupted();
74 final void interruptTask() {
75 // interruptTask is guaranteed to be called at most once, and if runner is non-null when that
76 // happens, then it must have been the first thread that entered run(). So there is no risk that
77 // we are interrupting the wrong thread.
78 Thread currentRunner = runner;
79 if (currentRunner != null) {
80 currentRunner.interrupt();
81 }

Callers

nothing calls this directly

Calls 2

logMethod · 0.80
getNameMethod · 0.45

Tested by

no test coverage detected