提交 60aa28a7 authored 作者: Andrei Tokar's avatar Andrei Tokar

fix #1672, switch MVStore.state back to volatile from Atomic

上级 734f8029
...@@ -185,7 +185,7 @@ public class MVStore implements AutoCloseable { ...@@ -185,7 +185,7 @@ public class MVStore implements AutoCloseable {
private volatile boolean reuseSpace = true; private volatile boolean reuseSpace = true;
private final AtomicInteger state = new AtomicInteger(); private volatile int state;
private final FileStore fileStore; private final FileStore fileStore;
...@@ -960,10 +960,11 @@ public class MVStore implements AutoCloseable { ...@@ -960,10 +960,11 @@ public class MVStore implements AutoCloseable {
// isClosed() would wait until closure is done and then we jump out of the loop. // isClosed() would wait until closure is done and then we jump out of the loop.
// This is a subtle difference between !isClosed() and isOpen(). // This is a subtle difference between !isClosed() and isOpen().
while (!isClosed()) { while (!isClosed()) {
if (state.compareAndSet(STATE_OPEN, STATE_STOPPING)) {
try {
stopBackgroundThread(normalShutdown); stopBackgroundThread(normalShutdown);
storeLock.lock(); storeLock.lock();
try {
if (state == STATE_OPEN) {
state = STATE_STOPPING;
try { try {
try { try {
if (normalShutdown && fileStore != null && !fileStore.isReadOnly()) { if (normalShutdown && fileStore != null && !fileStore.isReadOnly()) {
...@@ -979,7 +980,7 @@ public class MVStore implements AutoCloseable { ...@@ -979,7 +980,7 @@ public class MVStore implements AutoCloseable {
shrinkFileIfPossible(0); shrinkFileIfPossible(0);
} }
state.set(STATE_CLOSING); state = STATE_CLOSING;
// release memory early - this is important when called // release memory early - this is important when called
// because of out of memory // because of out of memory
...@@ -1000,11 +1001,11 @@ public class MVStore implements AutoCloseable { ...@@ -1000,11 +1001,11 @@ public class MVStore implements AutoCloseable {
} }
} }
} finally { } finally {
storeLock.unlock(); state = STATE_CLOSED;
} }
} finally {
state.set(STATE_CLOSED);
} }
} finally {
storeLock.unlock();
} }
} }
} }
...@@ -2806,7 +2807,7 @@ public class MVStore implements AutoCloseable { ...@@ -2806,7 +2807,7 @@ public class MVStore implements AutoCloseable {
} }
private boolean isOpen() { private boolean isOpen() {
return state.get() == STATE_OPEN; return state == STATE_OPEN;
} }
/** /**
...@@ -2817,27 +2818,17 @@ public class MVStore implements AutoCloseable { ...@@ -2817,27 +2818,17 @@ public class MVStore implements AutoCloseable {
if (isOpen()) { if (isOpen()) {
return false; return false;
} }
int millis = 1; storeLock.lock();
while (state.get() != STATE_CLOSED) {
/*
* We need to wait for completion of close procedure. This is
* required because otherwise database may be closed too early while
* underlying storage still has unreleased resources. The quickly
* following connection attempts fail with The file is locked
* exception.
*/
try { try {
Thread.sleep(millis++); assert state == STATE_CLOSED;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
return true; return true;
} finally {
storeLock.unlock();
}
} }
private boolean isOpenOrStopping() { private boolean isOpenOrStopping() {
return state.get() <= STATE_STOPPING; return state <= STATE_STOPPING;
} }
private void stopBackgroundThread(boolean waitForIt) { private void stopBackgroundThread(boolean waitForIt) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论