mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-06 18:34:13 +08:00
mdbx-windows: use manual-reset events to avoid non-atomic races.
Change-Id: I93b9f114c7c1a205dba18dcc363cf4ba8a27d7e0
This commit is contained in:
parent
041188c5e2
commit
bf6d09a878
@ -13851,22 +13851,26 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) {
|
|||||||
mdbx_copy *my = arg;
|
mdbx_copy *my = arg;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
int toggle = 0;
|
int toggle = 0;
|
||||||
int rc;
|
|
||||||
|
|
||||||
mdbx_condmutex_lock(&my->mc_condmutex);
|
mdbx_condmutex_lock(&my->mc_condmutex);
|
||||||
while (!my->mc_error) {
|
while (!my->mc_error) {
|
||||||
while (!my->mc_new)
|
while (!my->mc_new && !my->mc_error) {
|
||||||
mdbx_condmutex_wait(&my->mc_condmutex);
|
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 */
|
if (my->mc_new == 0 + MDBX_EOF) /* 0 buffers, just EOF */
|
||||||
break;
|
break;
|
||||||
size_t wsize = my->mc_wlen[toggle];
|
size_t wsize = my->mc_wlen[toggle];
|
||||||
ptr = my->mc_wbuf[toggle];
|
ptr = my->mc_wbuf[toggle];
|
||||||
again:
|
again:
|
||||||
if (wsize > 0 && !my->mc_error) {
|
if (wsize > 0 && !my->mc_error) {
|
||||||
rc = mdbx_write(my->mc_fd, ptr, wsize);
|
int err = mdbx_write(my->mc_fd, ptr, wsize);
|
||||||
if (rc != MDBX_SUCCESS) {
|
if (err != MDBX_SUCCESS) {
|
||||||
my->mc_error = rc;
|
my->mc_error = err;
|
||||||
break;
|
goto bailout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13883,6 +13887,7 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) {
|
|||||||
my->mc_new--;
|
my->mc_new--;
|
||||||
mdbx_condmutex_signal(&my->mc_condmutex);
|
mdbx_condmutex_signal(&my->mc_condmutex);
|
||||||
}
|
}
|
||||||
|
bailout:
|
||||||
mdbx_condmutex_unlock(&my->mc_condmutex);
|
mdbx_condmutex_unlock(&my->mc_condmutex);
|
||||||
return (THREAD_RESULT)0;
|
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);
|
mdbx_condmutex_lock(&my->mc_condmutex);
|
||||||
my->mc_new += (short)adjust;
|
my->mc_new += (short)adjust;
|
||||||
mdbx_condmutex_signal(&my->mc_condmutex);
|
mdbx_condmutex_signal(&my->mc_condmutex);
|
||||||
while (my->mc_new & 2) /* both buffers in use */
|
while (!my->mc_error && (my->mc_new & 2) /* both buffers in use */) {
|
||||||
mdbx_condmutex_wait(&my->mc_condmutex);
|
int err = mdbx_condmutex_wait(&my->mc_condmutex);
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
my->mc_error = err;
|
||||||
|
}
|
||||||
mdbx_condmutex_unlock(&my->mc_condmutex);
|
mdbx_condmutex_unlock(&my->mc_condmutex);
|
||||||
|
|
||||||
my->mc_toggle ^= (adjust & 1);
|
my->mc_toggle ^= (adjust & 1);
|
||||||
|
@ -371,11 +371,11 @@ MDBX_INTERNAL_FUNC int mdbx_condmutex_init(mdbx_condmutex_t *condmutex) {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
int rc = MDBX_SUCCESS;
|
int rc = MDBX_SUCCESS;
|
||||||
condmutex->event = NULL;
|
condmutex->event = NULL;
|
||||||
condmutex->mutex = CreateMutex(NULL, FALSE, NULL);
|
condmutex->mutex = CreateMutexW(NULL, FALSE, NULL);
|
||||||
if (!condmutex->mutex)
|
if (!condmutex->mutex)
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
|
|
||||||
condmutex->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
condmutex->event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
if (!condmutex->event) {
|
if (!condmutex->event) {
|
||||||
rc = GetLastError();
|
rc = GetLastError();
|
||||||
(void)CloseHandle(condmutex->mutex);
|
(void)CloseHandle(condmutex->mutex);
|
||||||
@ -459,8 +459,11 @@ MDBX_INTERNAL_FUNC int mdbx_condmutex_wait(mdbx_condmutex_t *condmutex) {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
DWORD code =
|
DWORD code =
|
||||||
SignalObjectAndWait(condmutex->mutex, condmutex->event, INFINITE, FALSE);
|
SignalObjectAndWait(condmutex->mutex, condmutex->event, INFINITE, FALSE);
|
||||||
if (code == WAIT_OBJECT_0)
|
if (code == WAIT_OBJECT_0) {
|
||||||
code = WaitForSingleObject(condmutex->mutex, INFINITE);
|
code = WaitForSingleObject(condmutex->mutex, INFINITE);
|
||||||
|
if (code == WAIT_OBJECT_0)
|
||||||
|
return ResetEvent(condmutex->event) ? MDBX_SUCCESS : GetLastError();
|
||||||
|
}
|
||||||
return waitstatus2errcode(code);
|
return waitstatus2errcode(code);
|
||||||
#else
|
#else
|
||||||
return pthread_cond_wait(&condmutex->cond, &condmutex->mutex);
|
return pthread_cond_wait(&condmutex->cond, &condmutex->mutex);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user