HDFS-10183. Prevent race condition during class initialization. Contributed by Pavel Avgustinov.
This commit is contained in:
parent
28e2244390
commit
f40969a141
|
@ -40,7 +40,7 @@ class FSEditLogAsync extends FSEditLog implements Runnable {
|
||||||
// use separate mutex to avoid possible deadlock when stopping the thread.
|
// use separate mutex to avoid possible deadlock when stopping the thread.
|
||||||
private final Object syncThreadLock = new Object();
|
private final Object syncThreadLock = new Object();
|
||||||
private Thread syncThread;
|
private Thread syncThread;
|
||||||
private static ThreadLocal<Edit> threadEdit = new ThreadLocal<Edit>();
|
private static final ThreadLocal<Edit> THREAD_EDIT = new ThreadLocal<Edit>();
|
||||||
|
|
||||||
// requires concurrent access from caller threads and syncing thread.
|
// requires concurrent access from caller threads and syncing thread.
|
||||||
private final BlockingQueue<Edit> editPendingQ =
|
private final BlockingQueue<Edit> editPendingQ =
|
||||||
|
@ -114,16 +114,16 @@ class FSEditLogAsync extends FSEditLog implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
void logEdit(final FSEditLogOp op) {
|
void logEdit(final FSEditLogOp op) {
|
||||||
Edit edit = getEditInstance(op);
|
Edit edit = getEditInstance(op);
|
||||||
threadEdit.set(edit);
|
THREAD_EDIT.set(edit);
|
||||||
enqueueEdit(edit);
|
enqueueEdit(edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logSync() {
|
public void logSync() {
|
||||||
Edit edit = threadEdit.get();
|
Edit edit = THREAD_EDIT.get();
|
||||||
if (edit != null) {
|
if (edit != null) {
|
||||||
// do NOT remove to avoid expunge & rehash penalties.
|
// do NOT remove to avoid expunge & rehash penalties.
|
||||||
threadEdit.set(null);
|
THREAD_EDIT.set(null);
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("logSync " + edit);
|
LOG.debug("logSync " + edit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ public abstract class FSEditLogOp {
|
||||||
int rpcCallId;
|
int rpcCallId;
|
||||||
|
|
||||||
public static class OpInstanceCache {
|
public static class OpInstanceCache {
|
||||||
private static ThreadLocal<OpInstanceCacheMap> cache =
|
private static final ThreadLocal<OpInstanceCacheMap> CACHE =
|
||||||
new ThreadLocal<OpInstanceCacheMap>() {
|
new ThreadLocal<OpInstanceCacheMap>() {
|
||||||
@Override
|
@Override
|
||||||
protected OpInstanceCacheMap initialValue() {
|
protected OpInstanceCacheMap initialValue() {
|
||||||
|
@ -188,7 +188,7 @@ public abstract class FSEditLogOp {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends FSEditLogOp> T get(FSEditLogOpCodes opCode) {
|
public <T extends FSEditLogOp> T get(FSEditLogOpCodes opCode) {
|
||||||
return useCache ? (T)cache.get().get(opCode) : (T)newInstance(opCode);
|
return useCache ? (T)CACHE.get().get(opCode) : (T)newInstance(opCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FSEditLogOp newInstance(FSEditLogOpCodes opCode) {
|
private static FSEditLogOp newInstance(FSEditLogOpCodes opCode) {
|
||||||
|
|
Loading…
Reference in New Issue