|
38 | 38 | import java.util.concurrent.ConcurrentHashMap; |
39 | 39 | import java.util.concurrent.atomic.AtomicBoolean; |
40 | 40 | import java.util.concurrent.atomic.AtomicInteger; |
| 41 | +import java.util.concurrent.atomic.AtomicReference; |
| 42 | +import java.util.concurrent.locks.ReentrantLock; |
41 | 43 |
|
42 | 44 | import org.apache.sshd.client.channel.ChannelSubsystem; |
43 | 45 | import org.apache.sshd.client.channel.ClientChannel; |
@@ -80,8 +82,9 @@ public class DefaultSftpClient extends AbstractSftpClient { |
80 | 82 | private final AtomicBoolean closing = new AtomicBoolean(false); |
81 | 83 | private final NavigableMap<String, byte[]> extensions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); |
82 | 84 | private final NavigableMap<String, byte[]> exposedExtensions = Collections.unmodifiableNavigableMap(extensions); |
83 | | - private Charset nameDecodingCharset; |
84 | | - private SftpMessage lastMessage; |
| 85 | + private final ReentrantLock writeLock = new ReentrantLock(); |
| 86 | + private final AtomicReference<SftpMessage> lastMessage = new AtomicReference<>(); |
| 87 | + private volatile Charset nameDecodingCharset; |
85 | 88 |
|
86 | 89 | /** |
87 | 90 | * @param clientSession The {@link ClientSession} |
@@ -167,7 +170,7 @@ public void close() throws IOException { |
167 | 170 | if (isOpen()) { |
168 | 171 | this.channel.close(false); |
169 | 172 | } |
170 | | - lastMessage = null; |
| 173 | + lastMessage.set(null); |
171 | 174 | } |
172 | 175 |
|
173 | 176 | /** |
@@ -276,7 +279,7 @@ public int send(int cmd, Buffer buffer) throws IOException { |
276 | 279 | msg.waitUntilSent(); |
277 | 280 | return msg.getId(); |
278 | 281 | } finally { |
279 | | - lastMessage = null; |
| 282 | + lastMessage.compareAndSet(msg, null); |
280 | 283 | } |
281 | 284 | } |
282 | 285 |
|
@@ -311,13 +314,20 @@ public SftpMessage write(int cmd, Buffer buffer) throws IOException { |
311 | 314 |
|
312 | 315 | ClientChannel clientChannel = getClientChannel(); |
313 | 316 | IoOutputStream asyncIn = clientChannel.getAsyncIn(); |
314 | | - if (lastMessage != null) { |
315 | | - lastMessage.waitUntilSent(); |
| 317 | + writeLock.lock(); |
| 318 | + try { |
| 319 | + SftpMessage msg = lastMessage.getAndSet(null); |
| 320 | + if (msg != null) { |
| 321 | + msg.waitUntilSent(); |
| 322 | + } |
| 323 | + IoWriteFuture writeFuture = asyncIn.writeBuffer(buf); |
| 324 | + Duration sendTimeout = SFTP_CLIENT_CMD_TIMEOUT.getRequired(clientChannel); |
| 325 | + msg = new SftpMessage(id, writeFuture, sendTimeout); |
| 326 | + lastMessage.set(msg); |
| 327 | + return msg; |
| 328 | + } finally { |
| 329 | + writeLock.unlock(); |
316 | 330 | } |
317 | | - IoWriteFuture writeFuture = asyncIn.writeBuffer(buf); |
318 | | - Duration sendTimeout = SFTP_CLIENT_CMD_TIMEOUT.getRequired(clientChannel); |
319 | | - lastMessage = new SftpMessage(id, writeFuture, sendTimeout); |
320 | | - return lastMessage; |
321 | 331 | } |
322 | 332 |
|
323 | 333 | @Override |
|
0 commit comments