diff --git a/CHANGES.txt b/CHANGES.txt index 0f8acacacd..a5941588d2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -217,6 +217,9 @@ Trunk (unreleased changes) HADOOP-6558. Return null in HarFileSystem.getFileChecksum(..) since no checksum algorithm is implemented. (szetszwo) + HADOOP-6572. Makes sure that SASL encryption and push to responder + queue for the RPC response happens atomically. (Kan Zhang via ddas) + Release 0.21.0 - Unreleased INCOMPATIBLE CHANGES diff --git a/src/java/org/apache/hadoop/ipc/Server.java b/src/java/org/apache/hadoop/ipc/Server.java index cbbfc6c256..b338b00283 100644 --- a/src/java/org/apache/hadoop/ipc/Server.java +++ b/src/java/org/apache/hadoop/ipc/Server.java @@ -1198,17 +1198,22 @@ public Writable run() throws Exception { error = StringUtils.stringifyException(e); } CurCall.set(null); - setupResponse(buf, call, - (error == null) ? Status.SUCCESS : Status.ERROR, - value, errorClass, error); - // Discard the large buf and reset it back to - // smaller size to freeup heap - if (buf.size() > MAX_RESP_BUF_SIZE) { - LOG.warn("Large response size " + buf.size() + " for call " + - call.toString()); - buf = new ByteArrayOutputStream(INITIAL_RESP_BUF_SIZE); + synchronized (call.connection.responseQueue) { + // setupResponse() needs to be sync'ed together with + // responder.doResponse() since setupResponse may use + // SASL to encrypt response data and SASL enforces + // its own message ordering. + setupResponse(buf, call, (error == null) ? Status.SUCCESS + : Status.ERROR, value, errorClass, error); + // Discard the large buf and reset it back to + // smaller size to freeup heap + if (buf.size() > MAX_RESP_BUF_SIZE) { + LOG.warn("Large response size " + buf.size() + " for call " + + call.toString()); + buf = new ByteArrayOutputStream(INITIAL_RESP_BUF_SIZE); + } + responder.doRespond(call); } - responder.doRespond(call); } catch (InterruptedException e) { if (running) { // unexpected -- log it LOG.info(getName() + " caught: " +