diff --git a/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java b/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java index cbdefdd2..63013c49 100644 --- a/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java +++ b/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java @@ -53,8 +53,8 @@ import org.slf4j.LoggerFactory; import java.io.InputStream; import java.io.OutputStream; +import java.util.LinkedList; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; @@ -76,7 +76,7 @@ public abstract class AbstractChannel /** Remote recipient ID */ private int recipient; - private final Queue> chanReqResponseEvents = new ConcurrentLinkedQueue>(); + private final Queue> chanReqResponseEvents = new LinkedList>(); /* The lock used by to create the open & close events */ private final ReentrantLock lock = new ReentrantLock(); @@ -368,33 +368,37 @@ public abstract class AbstractChannel Buffer.PlainBuffer reqSpecific) throws TransportException { log.info("Sending channel request for `{}`", reqType); - trans.write( - newBuffer(Message.CHANNEL_REQUEST) - .putString(reqType) - .putBoolean(wantReply) - .putBuffer(reqSpecific) - ); + synchronized (chanReqResponseEvents) { + trans.write( + newBuffer(Message.CHANNEL_REQUEST) + .putString(reqType) + .putBoolean(wantReply) + .putBuffer(reqSpecific) + ); - Event responseEvent = null; - if (wantReply) { - responseEvent = new Event("chan#" + id + " / " + "chanreq for " + reqType, - ConnectionException.chainer); - chanReqResponseEvents.add(responseEvent); + Event responseEvent = null; + if (wantReply) { + responseEvent = new Event("chan#" + id + " / " + "chanreq for " + reqType, + ConnectionException.chainer); + chanReqResponseEvents.add(responseEvent); + } + return responseEvent; } - return responseEvent; } private void gotResponse(boolean success) throws ConnectionException { - final Event responseEvent = chanReqResponseEvents.poll(); - if (responseEvent != null) { - if (success) - responseEvent.set(); - else - responseEvent.deliverError(new ConnectionException("Request failed")); - } else - throw new ConnectionException(DisconnectReason.PROTOCOL_ERROR, - "Received response to channel request when none was requested"); + synchronized (chanReqResponseEvents) { + final Event responseEvent = chanReqResponseEvents.poll(); + if (responseEvent != null) { + if (success) + responseEvent.set(); + else + responseEvent.deliverError(new ConnectionException("Request failed")); + } else + throw new ConnectionException(DisconnectReason.PROTOCOL_ERROR, + "Received response to channel request when none was requested"); + } } private synchronized void gotEOF()