MAPREDUCE-2947. Fixed race condition in AuxiliaryServices. Contributed by Vinod K V.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1166849 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Arun Murthy 2011-09-08 18:40:27 +00:00
parent 70f9ace412
commit 6b6ef7b8e3
3 changed files with 28 additions and 17 deletions

View File

@ -1230,6 +1230,9 @@ Release 0.23.0 - Unreleased
MAPREDUCE-2942. TestNMAuditLogger.testNMAuditLoggerWithIP failing (Thomas Graves MAPREDUCE-2942. TestNMAuditLogger.testNMAuditLoggerWithIP failing (Thomas Graves
via mahadev) via mahadev)
MAPREDUCE-2947. Fixed race condition in AuxiliaryServices. (vinodkv via
acmurthy)
Release 0.22.0 - Unreleased Release 0.22.0 - Unreleased
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -48,20 +48,20 @@ public class StartContainerResponsePBImpl extends ProtoBase<StartContainerRespon
viaProto = true; viaProto = true;
} }
public StartContainerResponseProto getProto() { public synchronized StartContainerResponseProto getProto() {
mergeLocalToProto(); mergeLocalToProto();
proto = viaProto ? proto : builder.build(); proto = viaProto ? proto : builder.build();
viaProto = true; viaProto = true;
return proto; return proto;
} }
private void mergeLocalToBuilder() { private synchronized void mergeLocalToBuilder() {
if (this.serviceResponse != null) { if (this.serviceResponse != null) {
addServiceResponseToProto(); addServiceResponseToProto();
} }
} }
private void mergeLocalToProto() { private synchronized void mergeLocalToProto() {
if (viaProto) { if (viaProto) {
maybeInitBuilder(); maybeInitBuilder();
} }
@ -70,7 +70,7 @@ public class StartContainerResponsePBImpl extends ProtoBase<StartContainerRespon
viaProto = true; viaProto = true;
} }
private void maybeInitBuilder() { private synchronized void maybeInitBuilder() {
if (viaProto || builder == null) { if (viaProto || builder == null) {
builder = StartContainerResponseProto.newBuilder(proto); builder = StartContainerResponseProto.newBuilder(proto);
} }
@ -79,17 +79,17 @@ public class StartContainerResponsePBImpl extends ProtoBase<StartContainerRespon
@Override @Override
public Map<String, ByteBuffer> getAllServiceResponse() { public synchronized Map<String, ByteBuffer> getAllServiceResponse() {
initServiceResponse(); initServiceResponse();
return this.serviceResponse; return this.serviceResponse;
} }
@Override @Override
public ByteBuffer getServiceResponse(String key) { public synchronized ByteBuffer getServiceResponse(String key) {
initServiceResponse(); initServiceResponse();
return this.serviceResponse.get(key); return this.serviceResponse.get(key);
} }
private void initServiceResponse() { private synchronized void initServiceResponse() {
if (this.serviceResponse != null) { if (this.serviceResponse != null) {
return; return;
} }
@ -103,14 +103,14 @@ public class StartContainerResponsePBImpl extends ProtoBase<StartContainerRespon
} }
@Override @Override
public void addAllServiceResponse(final Map<String, ByteBuffer> serviceResponse) { public synchronized void addAllServiceResponse(final Map<String, ByteBuffer> serviceResponse) {
if (serviceResponse == null) if (serviceResponse == null)
return; return;
initServiceResponse(); initServiceResponse();
this.serviceResponse.putAll(serviceResponse); this.serviceResponse.putAll(serviceResponse);
} }
private void addServiceResponseToProto() { private synchronized void addServiceResponseToProto() {
maybeInitBuilder(); maybeInitBuilder();
builder.clearServiceResponse(); builder.clearServiceResponse();
if (serviceResponse == null) if (serviceResponse == null)
@ -118,24 +118,24 @@ public class StartContainerResponsePBImpl extends ProtoBase<StartContainerRespon
Iterable<StringBytesMapProto> iterable = new Iterable<StringBytesMapProto>() { Iterable<StringBytesMapProto> iterable = new Iterable<StringBytesMapProto>() {
@Override @Override
public Iterator<StringBytesMapProto> iterator() { public synchronized Iterator<StringBytesMapProto> iterator() {
return new Iterator<StringBytesMapProto>() { return new Iterator<StringBytesMapProto>() {
Iterator<String> keyIter = serviceResponse.keySet().iterator(); Iterator<String> keyIter = serviceResponse.keySet().iterator();
@Override @Override
public void remove() { public synchronized void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public StringBytesMapProto next() { public synchronized StringBytesMapProto next() {
String key = keyIter.next(); String key = keyIter.next();
return StringBytesMapProto.newBuilder().setKey(key).setValue(convertToProtoFormat(serviceResponse.get(key))).build(); return StringBytesMapProto.newBuilder().setKey(key).setValue(convertToProtoFormat(serviceResponse.get(key))).build();
} }
@Override @Override
public boolean hasNext() { public synchronized boolean hasNext() {
return keyIter.hasNext(); return keyIter.hasNext();
} }
}; };
@ -144,17 +144,17 @@ public class StartContainerResponsePBImpl extends ProtoBase<StartContainerRespon
builder.addAllServiceResponse(iterable); builder.addAllServiceResponse(iterable);
} }
@Override @Override
public void setServiceResponse(String key, ByteBuffer val) { public synchronized void setServiceResponse(String key, ByteBuffer val) {
initServiceResponse(); initServiceResponse();
this.serviceResponse.put(key, val); this.serviceResponse.put(key, val);
} }
@Override @Override
public void removeServiceResponse(String key) { public synchronized void removeServiceResponse(String key) {
initServiceResponse(); initServiceResponse();
this.serviceResponse.remove(key); this.serviceResponse.remove(key);
} }
@Override @Override
public void clearServiceResponse() { public synchronized void clearServiceResponse() {
initServiceResponse(); initServiceResponse();
this.serviceResponse.clear(); this.serviceResponse.clear();
} }

View File

@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -72,7 +73,14 @@ public class AuxServices extends AbstractService
* the the name of the service as defined in the configuration. * the the name of the service as defined in the configuration.
*/ */
public Map<String, ByteBuffer> getMeta() { public Map<String, ByteBuffer> getMeta() {
return Collections.unmodifiableMap(serviceMeta); Map<String, ByteBuffer> metaClone = new HashMap<String, ByteBuffer>(
serviceMeta.size());
synchronized (serviceMeta) {
for (Entry<String, ByteBuffer> entry : serviceMeta.entrySet()) {
metaClone.put(entry.getKey(), entry.getValue().duplicate());
}
}
return metaClone;
} }
@Override @Override