MCPcopy Index your code
hub / github.com/OpenTSDB/async / doJoin

Method doJoin

src/Deferred.java:1112–1201  ·  view source on GitHub ↗

Synchronously waits until this Deferred is called back. @param interruptible Whether or not to let InterruptedException interrupt us. If false then this method will never throw InterruptedException, it will handle it and keep waiting. In this case though, the interrupted st

(final boolean interruptible, final long timeout)

Source from the content-addressed store, hash-verified

1110 * @throws TimeoutException if there's a timeout.
1111 */
1112 @SuppressWarnings("unchecked")
1113 private T doJoin(final boolean interruptible, final long timeout)
1114 throws InterruptedException, Exception {
1115 if (state == DONE) { // Nothing to join, we're already DONE.
1116 if (result instanceof Exception) {
1117 throw (Exception) result;
1118 }
1119 return (T) result;
1120 }
1121
1122 final Signal signal_cb = new Signal();
1123
1124 // Dealing with InterruptedException properly is a PITA. I highly
1125 // recommend reading http://goo.gl/aeOOXT to understand how this works.
1126 boolean interrupted = false;
1127 try {
1128 while (true) {
1129 try {
1130 boolean timedout = false;
1131 synchronized (signal_cb) {
1132 addBoth((Callback<T, T>) ((Object) signal_cb));
1133 if (timeout == 0) { // No timeout, we can use a simple loop.
1134 // If we get called back immediately, we won't enter the loop.
1135 while (signal_cb.result == signal_cb) {
1136 signal_cb.wait();
1137 }
1138 } else if (timeout < 0) {
1139 throw new IllegalArgumentException("negative timeout: " + timeout);
1140 } else { // We have a timeout, the loop is a bit more complicated.
1141 long timeleft = timeout * 1000000L; // Convert to nanoseconds.
1142 if (timeout > 31556926000L) { // One year in milliseconds.
1143 // Most likely a programming bug.
1144 LOG.warn("Timeout (" + timeout + ") is long than 1 year."
1145 + " this=" + this);
1146 if (timeleft <= 0) { // Very unlikely.
1147 throw new IllegalArgumentException("timeout overflow after"
1148 + " conversion to nanoseconds: " + timeout);
1149 }
1150 }
1151 // If we get called back immediately, we won't enter the loop.
1152 while (signal_cb.result == signal_cb) {
1153 // We can't distinguish between a timeout and a spurious wakeup.
1154 // So we have to time how long we slept to figure out whether we
1155 // timed out or how long we need to sleep again. There's no
1156 // better way to do this, that's how it's implemented in the JDK
1157 // in `AbstractQueuedSynchronizer.ConditionObject.awaitNanos()'.
1158 long duration = System.nanoTime();
1159 final long millis = timeleft / 1000000L;
1160 final int nanos = (int) (timeleft % 1000000);
1161 // This API is annoying because it won't let us specify just
1162 // nanoseconds. The second argument must be less than 1000000.
1163 signal_cb.wait(millis, nanos);
1164 duration = System.nanoTime() - duration;
1165 timeleft -= duration;
1166 // If we have 0ns or less left, the timeout has expired
1167 // already. If we have less than 100ns left, there's no
1168 // point in looping again, as just going through the loop
1169 // above easily takes 100ns on a modern x86-64 CPU, after

Callers 2

joinMethod · 0.95
joinUninterruptiblyMethod · 0.95

Calls 1

addBothMethod · 0.95

Tested by

no test coverage detected