Komplettes G-Earth Paket inkl. JRE, Extensions und Tools. Extensions: - G-BuildTools, G-Click Ultimate, G-Loader, G-Manipulate - G-Presets, G-Translator, G-Trigger, G-itemViewer - Market Utils, Packet Info Explorer, Plants - RandomRoomVisitor, RoomLogger, Sanbovir Photo Inspector - SpyFriends, WallAligner, XabboScripter, xabbo
266 lines
7.7 KiB
Java
266 lines
7.7 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*/
|
|
package okio;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InterruptedIOException;
|
|
import okio.Buffer;
|
|
import okio.Sink;
|
|
import okio.Source;
|
|
import okio.Timeout;
|
|
|
|
public class AsyncTimeout
|
|
extends Timeout {
|
|
private static AsyncTimeout head;
|
|
private boolean inQueue;
|
|
private AsyncTimeout next;
|
|
private long timeoutAt;
|
|
|
|
public final void enter() {
|
|
if (this.inQueue) {
|
|
throw new IllegalStateException("Unbalanced enter/exit");
|
|
}
|
|
long timeoutNanos = this.timeoutNanos();
|
|
boolean hasDeadline = this.hasDeadline();
|
|
if (timeoutNanos == 0L && !hasDeadline) {
|
|
return;
|
|
}
|
|
this.inQueue = true;
|
|
AsyncTimeout.scheduleTimeout(this, timeoutNanos, hasDeadline);
|
|
}
|
|
|
|
private static synchronized void scheduleTimeout(AsyncTimeout node, long timeoutNanos, boolean hasDeadline) {
|
|
if (head == null) {
|
|
head = new AsyncTimeout();
|
|
new Watchdog().start();
|
|
}
|
|
long now = System.nanoTime();
|
|
if (timeoutNanos != 0L && hasDeadline) {
|
|
node.timeoutAt = now + Math.min(timeoutNanos, node.deadlineNanoTime() - now);
|
|
} else if (timeoutNanos != 0L) {
|
|
node.timeoutAt = now + timeoutNanos;
|
|
} else if (hasDeadline) {
|
|
node.timeoutAt = node.deadlineNanoTime();
|
|
} else {
|
|
throw new AssertionError();
|
|
}
|
|
long remainingNanos = node.remainingNanos(now);
|
|
AsyncTimeout prev = head;
|
|
while (true) {
|
|
if (prev.next == null || remainingNanos < prev.next.remainingNanos(now)) {
|
|
node.next = prev.next;
|
|
prev.next = node;
|
|
if (prev != head) break;
|
|
AsyncTimeout.class.notify();
|
|
break;
|
|
}
|
|
prev = prev.next;
|
|
}
|
|
}
|
|
|
|
public final boolean exit() {
|
|
if (!this.inQueue) {
|
|
return false;
|
|
}
|
|
this.inQueue = false;
|
|
return AsyncTimeout.cancelScheduledTimeout(this);
|
|
}
|
|
|
|
private static synchronized boolean cancelScheduledTimeout(AsyncTimeout node) {
|
|
AsyncTimeout prev = head;
|
|
while (prev != null) {
|
|
if (prev.next == node) {
|
|
prev.next = node.next;
|
|
node.next = null;
|
|
return false;
|
|
}
|
|
prev = prev.next;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private long remainingNanos(long now) {
|
|
return this.timeoutAt - now;
|
|
}
|
|
|
|
protected void timedOut() {
|
|
}
|
|
|
|
public final Sink sink(final Sink sink) {
|
|
return new Sink(){
|
|
|
|
@Override
|
|
public void write(Buffer source, long byteCount) throws IOException {
|
|
boolean throwOnTimeout = false;
|
|
AsyncTimeout.this.enter();
|
|
try {
|
|
sink.write(source, byteCount);
|
|
throwOnTimeout = true;
|
|
}
|
|
catch (IOException e) {
|
|
throw AsyncTimeout.this.exit(e);
|
|
}
|
|
finally {
|
|
AsyncTimeout.this.exit(throwOnTimeout);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void flush() throws IOException {
|
|
boolean throwOnTimeout = false;
|
|
AsyncTimeout.this.enter();
|
|
try {
|
|
sink.flush();
|
|
throwOnTimeout = true;
|
|
}
|
|
catch (IOException e) {
|
|
throw AsyncTimeout.this.exit(e);
|
|
}
|
|
finally {
|
|
AsyncTimeout.this.exit(throwOnTimeout);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
boolean throwOnTimeout = false;
|
|
AsyncTimeout.this.enter();
|
|
try {
|
|
sink.close();
|
|
throwOnTimeout = true;
|
|
}
|
|
catch (IOException e) {
|
|
throw AsyncTimeout.this.exit(e);
|
|
}
|
|
finally {
|
|
AsyncTimeout.this.exit(throwOnTimeout);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Timeout timeout() {
|
|
return AsyncTimeout.this;
|
|
}
|
|
|
|
public String toString() {
|
|
return "AsyncTimeout.sink(" + sink + ")";
|
|
}
|
|
};
|
|
}
|
|
|
|
public final Source source(final Source source) {
|
|
return new Source(){
|
|
|
|
@Override
|
|
public long read(Buffer sink, long byteCount) throws IOException {
|
|
boolean throwOnTimeout = false;
|
|
AsyncTimeout.this.enter();
|
|
try {
|
|
long result = source.read(sink, byteCount);
|
|
throwOnTimeout = true;
|
|
long l = result;
|
|
return l;
|
|
}
|
|
catch (IOException e) {
|
|
throw AsyncTimeout.this.exit(e);
|
|
}
|
|
finally {
|
|
AsyncTimeout.this.exit(throwOnTimeout);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
boolean throwOnTimeout = false;
|
|
try {
|
|
source.close();
|
|
throwOnTimeout = true;
|
|
}
|
|
catch (IOException e) {
|
|
throw AsyncTimeout.this.exit(e);
|
|
}
|
|
finally {
|
|
AsyncTimeout.this.exit(throwOnTimeout);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Timeout timeout() {
|
|
return AsyncTimeout.this;
|
|
}
|
|
|
|
public String toString() {
|
|
return "AsyncTimeout.source(" + source + ")";
|
|
}
|
|
};
|
|
}
|
|
|
|
final void exit(boolean throwOnTimeout) throws IOException {
|
|
boolean timedOut = this.exit();
|
|
if (timedOut && throwOnTimeout) {
|
|
throw this.newTimeoutException(null);
|
|
}
|
|
}
|
|
|
|
final IOException exit(IOException cause) throws IOException {
|
|
if (!this.exit()) {
|
|
return cause;
|
|
}
|
|
return this.newTimeoutException(cause);
|
|
}
|
|
|
|
protected IOException newTimeoutException(IOException cause) {
|
|
InterruptedIOException e = new InterruptedIOException("timeout");
|
|
if (cause != null) {
|
|
e.initCause(cause);
|
|
}
|
|
return e;
|
|
}
|
|
|
|
private static synchronized AsyncTimeout awaitTimeout() throws InterruptedException {
|
|
AsyncTimeout node = AsyncTimeout.head.next;
|
|
if (node == null) {
|
|
AsyncTimeout.class.wait();
|
|
return null;
|
|
}
|
|
long waitNanos = node.remainingNanos(System.nanoTime());
|
|
if (waitNanos > 0L) {
|
|
long waitMillis = waitNanos / 1000000L;
|
|
AsyncTimeout.class.wait(waitMillis, (int)(waitNanos -= waitMillis * 1000000L));
|
|
return null;
|
|
}
|
|
AsyncTimeout.head.next = node.next;
|
|
node.next = null;
|
|
return node;
|
|
}
|
|
|
|
private static final class Watchdog
|
|
extends Thread {
|
|
public Watchdog() {
|
|
super("Okio Watchdog");
|
|
this.setDaemon(true);
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
while (true) {
|
|
try {
|
|
while (true) {
|
|
AsyncTimeout timedOut;
|
|
if ((timedOut = AsyncTimeout.awaitTimeout()) == null) {
|
|
continue;
|
|
}
|
|
timedOut.timedOut();
|
|
}
|
|
}
|
|
catch (InterruptedException interruptedException) {
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|