HBASE-21061 Fix inconsistent synchronization in RpcServer
move variables that we don't need synchronized access to out of the critical block. Signed-off-by: Mike Drob <mdrob@apache.org>
This commit is contained in:
parent
d07cab18a6
commit
3e45e0202b
|
@ -1640,7 +1640,7 @@ public class RpcServer implements RpcServerInterface, ConfigurationObserver {
|
|||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public synchronized int readAndProcess() throws IOException, InterruptedException {
|
||||
public int readAndProcess() throws IOException, InterruptedException {
|
||||
// If we have not read the connection setup preamble, look to see if that is on the wire.
|
||||
if (!connectionPreambleRead) {
|
||||
int count = readPreamble();
|
||||
|
@ -1668,6 +1668,16 @@ public class RpcServer implements RpcServerInterface, ConfigurationObserver {
|
|||
}
|
||||
}
|
||||
|
||||
final boolean useWrap = this.useWrap;
|
||||
final BlockingService service = this.service;
|
||||
final boolean headerAndPreambleRead = connectionHeaderRead && connectionPreambleRead;
|
||||
final boolean canUseRequestTooBig = headerAndPreambleRead &&
|
||||
VersionInfoUtil.hasMinimumVersion(connectionHeader.getVersionInfo(),
|
||||
RequestTooBigException.MAJOR_VERSION, RequestTooBigException.MINOR_VERSION);
|
||||
|
||||
// we're guarding against data being modified concurrently
|
||||
// while trying to keep other instance members out of the block
|
||||
synchronized(this) {
|
||||
// We have read a length and we have read the preamble. It is either the connection header
|
||||
// or it is a request.
|
||||
if (data == null) {
|
||||
|
@ -1691,7 +1701,7 @@ public class RpcServer implements RpcServerInterface, ConfigurationObserver {
|
|||
+ "\" on server to override this limit (not recommended)";
|
||||
LOG.warn(msg);
|
||||
|
||||
if (connectionHeaderRead && connectionPreambleRead) {
|
||||
if (headerAndPreambleRead) {
|
||||
incRpcCount();
|
||||
// Construct InputStream for the non-blocking SocketChannel
|
||||
// We need the InputStream because we want to read only the request header
|
||||
|
@ -1714,13 +1724,12 @@ public class RpcServer implements RpcServerInterface, ConfigurationObserver {
|
|||
RequestHeader header = (RequestHeader) builder.build();
|
||||
|
||||
// Notify the client about the offending request
|
||||
Call reqTooBig = new Call(header.getCallId(), this.service, null, null, null,
|
||||
Call reqTooBig = new Call(header.getCallId(), service, null, null, null,
|
||||
null, this, responder, 0, null, this.addr,0);
|
||||
metrics.exception(REQUEST_TOO_BIG_EXCEPTION);
|
||||
// Make sure the client recognizes the underlying exception
|
||||
// Otherwise, throw a DoNotRetryIOException.
|
||||
if (VersionInfoUtil.hasMinimumVersion(connectionHeader.getVersionInfo(),
|
||||
RequestTooBigException.MAJOR_VERSION, RequestTooBigException.MINOR_VERSION)) {
|
||||
if (canUseRequestTooBig) {
|
||||
setupResponse(null, reqTooBig, REQUEST_TOO_BIG_EXCEPTION, msg);
|
||||
} else {
|
||||
setupResponse(null, reqTooBig, new DoNotRetryIOException(), msg);
|
||||
|
@ -1748,6 +1757,7 @@ public class RpcServer implements RpcServerInterface, ConfigurationObserver {
|
|||
if (count >= 0 && data.remaining() == 0) { // count==0 if dataLength == 0
|
||||
process();
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue