mdbx-windows: use manual-reset events to avoid non-atomic races.

Change-Id: I93b9f114c7c1a205dba18dcc363cf4ba8a27d7e0
This commit is contained in:
Leonid Yuriev 2019-12-09 10:59:57 +03:00
parent 041188c5e2
commit bf6d09a878
2 changed files with 23 additions and 12 deletions

View File

@ -13851,22 +13851,26 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) {
mdbx_copy *my = arg;
uint8_t *ptr;
int toggle = 0;
int rc;
mdbx_condmutex_lock(&my->mc_condmutex);
while (!my->mc_error) {
while (!my->mc_new)
mdbx_condmutex_wait(&my->mc_condmutex);
while (!my->mc_new && !my->mc_error) {
int err = mdbx_condmutex_wait(&my->mc_condmutex);
if (err != MDBX_SUCCESS) {
my->mc_error = err;
goto bailout;
}
}
if (my->mc_new == 0 + MDBX_EOF) /* 0 buffers, just EOF */
break;
size_t wsize = my->mc_wlen[toggle];
ptr = my->mc_wbuf[toggle];
again:
if (wsize > 0 && !my->mc_error) {
rc = mdbx_write(my->mc_fd, ptr, wsize);
if (rc != MDBX_SUCCESS) {
my->mc_error = rc;
break;
int err = mdbx_write(my->mc_fd, ptr, wsize);
if (err != MDBX_SUCCESS) {
my->mc_error = err;
goto bailout;
}
}
@ -13883,6 +13887,7 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) {
my->mc_new--;
mdbx_condmutex_signal(&my->mc_condmutex);
}
bailout:
mdbx_condmutex_unlock(&my->mc_condmutex);
return (THREAD_RESULT)0;
}
@ -13895,8 +13900,11 @@ static int __cold mdbx_env_cthr_toggle(mdbx_copy *my, int adjust) {
mdbx_condmutex_lock(&my->mc_condmutex);
my->mc_new += (short)adjust;
mdbx_condmutex_signal(&my->mc_condmutex);
while (my->mc_new & 2) /* both buffers in use */
mdbx_condmutex_wait(&my->mc_condmutex);
while (!my->mc_error && (my->mc_new & 2) /* both buffers in use */) {
int err = mdbx_condmutex_wait(&my->mc_condmutex);
if (err != MDBX_SUCCESS)
my->mc_error = err;
}
mdbx_condmutex_unlock(&my->mc_condmutex);
my->mc_toggle ^= (adjust & 1);

View File

@ -371,11 +371,11 @@ MDBX_INTERNAL_FUNC int mdbx_condmutex_init(mdbx_condmutex_t *condmutex) {
#if defined(_WIN32) || defined(_WIN64)
int rc = MDBX_SUCCESS;
condmutex->event = NULL;
condmutex->mutex = CreateMutex(NULL, FALSE, NULL);
condmutex->mutex = CreateMutexW(NULL, FALSE, NULL);
if (!condmutex->mutex)
return GetLastError();
condmutex->event = CreateEvent(NULL, FALSE, FALSE, NULL);
condmutex->event = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!condmutex->event) {
rc = GetLastError();
(void)CloseHandle(condmutex->mutex);
@ -459,8 +459,11 @@ MDBX_INTERNAL_FUNC int mdbx_condmutex_wait(mdbx_condmutex_t *condmutex) {
#if defined(_WIN32) || defined(_WIN64)
DWORD code =
SignalObjectAndWait(condmutex->mutex, condmutex->event, INFINITE, FALSE);
if (code == WAIT_OBJECT_0)
if (code == WAIT_OBJECT_0) {
code = WaitForSingleObject(condmutex->mutex, INFINITE);
if (code == WAIT_OBJECT_0)
return ResetEvent(condmutex->event) ? MDBX_SUCCESS : GetLastError();
}
return waitstatus2errcode(code);
#else
return pthread_cond_wait(&condmutex->cond, &condmutex->mutex);