X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2FSharedBlockingCallback.java;h=5b4e5a312ebaaf17fce2691cbfa1326885cf1d53;hp=3085a68735d150e20280888357eb3d1a8389fa82;hb=ba4f228fa9f72d50991a2218cfd83987ef5d385e;hpb=875b5e9651498a0cd8e0001c0742ba843e47cad0 diff --git a/lib/jetty/org/eclipse/jetty/util/SharedBlockingCallback.java b/lib/jetty/org/eclipse/jetty/util/SharedBlockingCallback.java index 3085a687..5b4e5a31 100644 --- a/lib/jetty/org/eclipse/jetty/util/SharedBlockingCallback.java +++ b/lib/jetty/org/eclipse/jetty/util/SharedBlockingCallback.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -48,7 +48,11 @@ import org.eclipse.jetty.util.thread.NonBlockingThread; */ public class SharedBlockingCallback { - private static final Logger LOG = Log.getLogger(SharedBlockingCallback.class); + static final Logger LOG = Log.getLogger(SharedBlockingCallback.class); + + final ReentrantLock _lock = new ReentrantLock(); + final Condition _idle = _lock.newCondition(); + final Condition _complete = _lock.newCondition(); private static Throwable IDLE = new Throwable() @@ -78,56 +82,64 @@ public class SharedBlockingCallback } }; - final Blocker _blocker; + Blocker _blocker; public SharedBlockingCallback() { - this(new Blocker()); + _blocker=new Blocker(); } - protected SharedBlockingCallback(Blocker blocker) + protected long getIdleTimeout() { - _blocker=blocker; + return -1; } public Blocker acquire() throws IOException { - _blocker._lock.lock(); + _lock.lock(); + long idle = getIdleTimeout(); try { while (_blocker._state != IDLE) - _blocker._idle.await(); + { + if (idle>0 && (idle < Long.MAX_VALUE/2)) + { + // Wait a little bit longer than the blocker might block + if (!_idle.await(idle*2,TimeUnit.MILLISECONDS)) + throw new IOException(new TimeoutException()); + } + else + _idle.await(); + } _blocker._state = null; } catch (final InterruptedException e) { - throw new InterruptedIOException() - { - { - initCause(e); - } - }; + throw new InterruptedIOException(); } finally { - _blocker._lock.unlock(); + _lock.unlock(); } return _blocker; } + protected void notComplete(Blocker blocker) + { + LOG.warn("Blocker not complete {}",blocker); + if (LOG.isDebugEnabled()) + LOG.debug(new Throwable()); + } /* ------------------------------------------------------------ */ /** A Closeable Callback. * Uses the auto close mechanism to check block has been called OK. */ - public static class Blocker implements Callback, Closeable + public class Blocker implements Callback, Closeable { - final ReentrantLock _lock = new ReentrantLock(); - final Condition _idle = _lock.newCondition(); - final Condition _complete = _lock.newCondition(); Throwable _state = IDLE; - - public Blocker() + + protected Blocker() { } @@ -142,8 +154,8 @@ public class SharedBlockingCallback _state = SUCCEEDED; _complete.signalAll(); } - else if (_state == IDLE) - throw new IllegalStateException("IDLE"); + else + throw new IllegalStateException(_state); } finally { @@ -159,14 +171,17 @@ public class SharedBlockingCallback { if (_state == null) { - // TODO remove when feedback received on 435322 if (cause==null) - LOG.warn("null failed cause (please report stack trace) ",new Throwable()); - _state = cause==null?FAILED:cause; + _state=FAILED; + else if (cause instanceof BlockerTimeoutException) + // Not this blockers timeout + _state=new IOException(cause); + else + _state=cause; _complete.signalAll(); } - else if (_state == IDLE) - throw new IllegalStateException("IDLE"); + else + throw new IllegalStateException(_state); } finally { @@ -187,18 +202,21 @@ public class SharedBlockingCallback LOG.warn("Blocking a NonBlockingThread: ",new Throwable()); _lock.lock(); + long idle = getIdleTimeout(); try { while (_state == null) { - // TODO remove this debug timout! - // This is here to help debug 435322, - if (!_complete.await(10,TimeUnit.MINUTES)) + if (idle>0 && (idle < Long.MAX_VALUE/2)) { - IOException x = new IOException("DEBUG timeout"); - LOG.warn("Blocked too long (please report!!!) "+this, x); - _state=x; + // Wait a little bit longer than expected callback idle timeout + if (!_complete.await(idle+idle/2,TimeUnit.MILLISECONDS)) + // The callback has not arrived in sufficient time. + // We will synthesize a TimeoutException + _state=new BlockerTimeoutException(); } + else + _complete.await(); } if (_state == SUCCEEDED) @@ -217,12 +235,7 @@ public class SharedBlockingCallback } catch (final InterruptedException e) { - throw new InterruptedIOException() - { - { - initCause(e); - } - }; + throw new InterruptedIOException(); } finally { @@ -245,13 +258,26 @@ public class SharedBlockingCallback if (_state == IDLE) throw new IllegalStateException("IDLE"); if (_state == null) - LOG.debug("Blocker not complete",new Throwable()); + notComplete(this); } finally { - _state = IDLE; - _idle.signalAll(); - _lock.unlock(); + try + { + // If the blocker timed itself out, remember the state + if (_state instanceof BlockerTimeoutException) + // and create a new Blocker + _blocker=new Blocker(); + else + // else reuse Blocker + _state = IDLE; + _idle.signalAll(); + _complete.signalAll(); + } + finally + { + _lock.unlock(); + } } } @@ -261,7 +287,7 @@ public class SharedBlockingCallback _lock.lock(); try { - return String.format("%s@%x{%s}",SharedBlockingCallback.class.getSimpleName(),hashCode(),_state); + return String.format("%s@%x{%s}",Blocker.class.getSimpleName(),hashCode(),_state); } finally { @@ -269,4 +295,8 @@ public class SharedBlockingCallback } } } + + private static class BlockerTimeoutException extends TimeoutException + { + } }