You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by en...@apache.org on 2015/09/25 20:04:58 UTC
hbase git commit: HBASE-14474 DeadLock in
RpcClientImpl.Connection.close()
Repository: hbase
Updated Branches:
refs/heads/master bdea8b891 -> 32f49fa7f
HBASE-14474 DeadLock in RpcClientImpl.Connection.close()
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/32f49fa7
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/32f49fa7
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/32f49fa7
Branch: refs/heads/master
Commit: 32f49fa7fc2bcad0004e249887cc1973becc98db
Parents: bdea8b8
Author: Enis Soztutar <en...@apache.org>
Authored: Fri Sep 25 11:04:53 2015 -0700
Committer: Enis Soztutar <en...@apache.org>
Committed: Fri Sep 25 11:04:53 2015 -0700
----------------------------------------------------------------------
.../apache/hadoop/hbase/ipc/RpcClientImpl.java | 25 +++++++++++++-------
1 file changed, 17 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/32f49fa7/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
index b09674c..cb18952 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
@@ -914,14 +914,20 @@ public class RpcClientImpl extends AbstractRpcClient {
IPCUtil.write(this.out, header, call.param, cellBlock);
} catch (IOException e) {
// We set the value inside the synchronized block, this way the next in line
- // won't even try to write
- markClosed(e);
- close();
+ // won't even try to write. Otherwise we might miss a call in the calls map?
+ shouldCloseConnection.set(true);
writeException = e;
interrupt();
}
}
+ // call close outside of the synchronized (outLock) to prevent deadlock - HBASE-14474
+ if (writeException != null) {
+ if (markClosed(writeException)) {
+ close();
+ }
+ }
+
// We added a call, and may be started the connection close. In both cases, we
// need to notify the reader.
synchronized (this) {
@@ -1022,10 +1028,11 @@ public class RpcClientImpl extends AbstractRpcClient {
e.getStackTrace(), doNotRetry);
}
- protected synchronized void markClosed(IOException e) {
+ protected synchronized boolean markClosed(IOException e) {
if (e == null) throw new NullPointerException();
- if (shouldCloseConnection.compareAndSet(false, true)) {
+ boolean ret = shouldCloseConnection.compareAndSet(false, true);
+ if (ret) {
if (LOG.isTraceEnabled()) {
LOG.trace(getName() + ": marking at should close, reason: " + e.getMessage());
}
@@ -1034,6 +1041,7 @@ public class RpcClientImpl extends AbstractRpcClient {
}
notifyAll();
}
+ return ret;
}
@@ -1142,14 +1150,15 @@ public class RpcClientImpl extends AbstractRpcClient {
}
if (connsToClose != null) {
for (Connection conn : connsToClose) {
- conn.markClosed(new InterruptedIOException("RpcClient is closing"));
- conn.close();
+ if (conn.markClosed(new InterruptedIOException("RpcClient is closing"))) {
+ conn.close();
+ }
}
}
// wait until all connections are closed
while (!connections.isEmpty()) {
try {
- Thread.sleep(100);
+ Thread.sleep(10);
} catch (InterruptedException e) {
LOG.info("Interrupted while stopping the client. We still have " + connections.size() +
" connections.");