mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 17:14:12 +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;
|
||||
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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user