提交 20b9c9e9 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Wait for MVStore close completion

上级 143635c9
...@@ -147,6 +147,27 @@ public class MVStore implements AutoCloseable { ...@@ -147,6 +147,27 @@ public class MVStore implements AutoCloseable {
*/ */
private static final int MARKED_FREE = 10_000_000; private static final int MARKED_FREE = 10_000_000;
/**
* Storage is open.
*/
private static final int STATE_OPEN = 0;
/**
* Storage is stopping now. Background writer thread finishes its work
* during this process.
*/
private static final int STATE_STOPPING = 1;
/**
* Storage is closing now.
*/
private static final int STATE_CLOSING = 2;
/**
* Storage is closed.
*/
private static final int STATE_CLOSED = 3;
/** /**
* Lock which governs access to major store operations: store(), close(), ... * Lock which governs access to major store operations: store(), close(), ...
* It should used in a non-reentrant fashion. * It should used in a non-reentrant fashion.
...@@ -162,7 +183,7 @@ public class MVStore implements AutoCloseable { ...@@ -162,7 +183,7 @@ public class MVStore implements AutoCloseable {
private volatile boolean reuseSpace = true; private volatile boolean reuseSpace = true;
private volatile boolean closed; private volatile int state;
private final FileStore fileStore; private final FileStore fileStore;
...@@ -414,7 +435,7 @@ public class MVStore implements AutoCloseable { ...@@ -414,7 +435,7 @@ public class MVStore implements AutoCloseable {
} }
private void panic(IllegalStateException e) { private void panic(IllegalStateException e) {
if (!closed) { if (state == STATE_OPEN) {
handleException(e); handleException(e);
panicException = e; panicException = e;
closeImmediately(); closeImmediately();
...@@ -918,7 +939,7 @@ public class MVStore implements AutoCloseable { ...@@ -918,7 +939,7 @@ public class MVStore implements AutoCloseable {
*/ */
@Override @Override
public void close() { public void close() {
if (closed) { if (isClosed()) {
return; return;
} }
FileStore f = fileStore; FileStore f = fileStore;
...@@ -949,11 +970,13 @@ public class MVStore implements AutoCloseable { ...@@ -949,11 +970,13 @@ public class MVStore implements AutoCloseable {
} }
private void closeStore(boolean shrinkIfPossible) { private void closeStore(boolean shrinkIfPossible) {
if (closed) { if (isClosed()) {
return; return;
} }
state = STATE_STOPPING;
try {
stopBackgroundThread(); stopBackgroundThread();
closed = true; state = STATE_CLOSING;
storeLock.lock(); storeLock.lock();
try { try {
try { try {
...@@ -981,6 +1004,9 @@ public class MVStore implements AutoCloseable { ...@@ -981,6 +1004,9 @@ public class MVStore implements AutoCloseable {
} finally { } finally {
storeLock.unlock(); storeLock.unlock();
} }
} finally {
state = STATE_CLOSED;
}
} }
/** /**
...@@ -1142,7 +1168,7 @@ public class MVStore implements AutoCloseable { ...@@ -1142,7 +1168,7 @@ public class MVStore implements AutoCloseable {
private void store() { private void store() {
try { try {
if (!closed && hasUnsavedChangesInternal()) { if (isOpenOrStopping() && hasUnsavedChangesInternal()) {
currentStoreVersion = currentVersion; currentStoreVersion = currentVersion;
if (fileStore == null) { if (fileStore == null) {
lastStoredVersion = currentVersion; lastStoredVersion = currentVersion;
...@@ -1719,7 +1745,7 @@ public class MVStore implements AutoCloseable { ...@@ -1719,7 +1745,7 @@ public class MVStore implements AutoCloseable {
if (savedPercent < minPercent) { if (savedPercent < minPercent) {
return; return;
} }
if (!closed) { if (isOpenOrStopping()) {
sync(); sync();
} }
fileStore.truncate(end); fileStore.truncate(end);
...@@ -2392,7 +2418,7 @@ public class MVStore implements AutoCloseable { ...@@ -2392,7 +2418,7 @@ public class MVStore implements AutoCloseable {
* @param map the map * @param map the map
*/ */
void beforeWrite(MVMap<?, ?> map) { void beforeWrite(MVMap<?, ?> map) {
if (saveNeeded && fileStore != null && !closed) { if (saveNeeded && fileStore != null && isOpenOrStopping()) {
saveNeeded = false; saveNeeded = false;
// check again, because it could have been written by now // check again, because it could have been written by now
if (unsavedMemory > autoCommitMemory && autoCommitMemory > 0) { if (unsavedMemory > autoCommitMemory && autoCommitMemory > 0) {
...@@ -2599,7 +2625,7 @@ public class MVStore implements AutoCloseable { ...@@ -2599,7 +2625,7 @@ public class MVStore implements AutoCloseable {
} }
private void checkOpen() { private void checkOpen() {
if (closed) { if (!isOpenOrStopping()) {
throw DataUtils.newIllegalStateException(DataUtils.ERROR_CLOSED, throw DataUtils.newIllegalStateException(DataUtils.ERROR_CLOSED,
"This store is closed", panicException); "This store is closed", panicException);
} }
...@@ -2718,7 +2744,7 @@ public class MVStore implements AutoCloseable { ...@@ -2718,7 +2744,7 @@ public class MVStore implements AutoCloseable {
*/ */
void writeInBackground() { void writeInBackground() {
try { try {
if (closed) { if (!isOpenOrStopping()) {
return; return;
} }
...@@ -2780,7 +2806,23 @@ public class MVStore implements AutoCloseable { ...@@ -2780,7 +2806,23 @@ public class MVStore implements AutoCloseable {
} }
public boolean isClosed() { public boolean isClosed() {
return closed; if (state == STATE_OPEN) {
return false;
}
int millis = 1;
while (state != STATE_CLOSED) {
try {
Thread.sleep(millis++);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
return true;
}
private boolean isOpenOrStopping() {
return state <= STATE_STOPPING;
} }
private void stopBackgroundThread() { private void stopBackgroundThread() {
...@@ -2825,7 +2867,7 @@ public class MVStore implements AutoCloseable { ...@@ -2825,7 +2867,7 @@ public class MVStore implements AutoCloseable {
} }
stopBackgroundThread(); stopBackgroundThread();
// start the background thread if needed // start the background thread if needed
if (millis > 0) { if (millis > 0 && state == STATE_OPEN) {
int sleep = Math.max(1, millis / 10); int sleep = Math.max(1, millis / 10);
BackgroundWriterThread t = BackgroundWriterThread t =
new BackgroundWriterThread(this, sleep, new BackgroundWriterThread(this, sleep,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论