diff --git a/src/xpdev/rwlockwrap.c b/src/xpdev/rwlockwrap.c
index 519913599be9538cc6e729f08a9bb14f5aa5a70e..4b98f4f6b0644d156fcf2d7fbc6c2571dc1d629e 100644
--- a/src/xpdev/rwlockwrap.c
+++ b/src/xpdev/rwlockwrap.c
@@ -34,6 +34,8 @@ rwlock_init(rwlock_t *lock)
 {
 	InitializeCriticalSection(&lock->lk);
 	InitializeCriticalSection(&lock->wlk);
+	lock->zeror = CreateEvent(NULL, TRUE, TRUE, NULL);
+	lock->zerow = CreateEvent(NULL, TRUE, TRUE, NULL);
 	lock->readers = 0;
 	lock->writers = 0;
 	lock->writers_waiting = 0;
@@ -55,6 +57,10 @@ rwlock_rdlock(rwlock_t *lock)
 	}
 	while(rc->count == 0 && (lock->writers || lock->writers_waiting)) {
 		LeaveCriticalSection(&lock->lk);
+		if (WaitForSingleObject(lock->zerow, INFINITE) != WAIT_OBJECT_0) {
+			EnterCriticalSection(&lock->lk);
+			continue;
+		}
 		// Wait for current writer to release
 		EnterCriticalSection(&lock->wlk);
 		EnterCriticalSection(&lock->lk);
@@ -72,12 +78,14 @@ rwlock_rdlock(rwlock_t *lock)
 		else {
 			lock->readers++;
 			rc->count++;
+			ResetEvent(lock->zeror);
 			LeaveCriticalSection(&lock->lk);
 			LeaveCriticalSection(&lock->wlk);
 			return TRUE;
 		}
 	}
 	lock->readers++;
+	ResetEvent(lock->zeror);
 	rc->count++;
 	LeaveCriticalSection(&lock->lk);
 	return TRUE;
@@ -98,6 +106,7 @@ rwlock_tryrdlock(rwlock_t *lock)
 	if (rc->count || (lock->writers == 0 && lock->writers_waiting == 0)) {
 		rc->count++;
 		lock->readers++;
+		ResetEvent(lock->zeror);
 		ret = TRUE;
 	}
 	LeaveCriticalSection(&lock->lk);
@@ -110,6 +119,7 @@ rwlock_wrlock(rwlock_t *lock)
 	BOOL ret = FALSE;
 	EnterCriticalSection(&lock->lk);
 	lock->writers_waiting++;
+	ResetEvent(lock->zerow);
 	LeaveCriticalSection(&lock->lk);
 	EnterCriticalSection(&lock->wlk);
 	EnterCriticalSection(&lock->lk);
@@ -117,7 +127,10 @@ rwlock_wrlock(rwlock_t *lock)
 	while (lock->readers) {
 		LeaveCriticalSection(&lock->lk);
 		LeaveCriticalSection(&lock->wlk);
-		Sleep(1);
+		if (WaitForSingleObject(lock->zeror, INFINITE) != WAIT_OBJECT_0) {
+			EnterCriticalSection(&lock->lk);
+			continue;
+		}
 		EnterCriticalSection(&lock->wlk);
 		EnterCriticalSection(&lock->lk);
 	}
@@ -128,6 +141,7 @@ rwlock_wrlock(rwlock_t *lock)
 	else {
 		lock->writers_waiting--;
 		lock->writers++;
+		ResetEvent(lock->zerow);
 		lock->writer = GetCurrentThreadId();
 		ret = TRUE;
 	}
@@ -144,6 +158,7 @@ rwlock_trywrlock(rwlock_t *lock)
 		// Prevent recursing on writer locks
 		if (lock->readers == 0 && lock->writers == 0) {
 			lock->writers++;
+			ResetEvent(lock->zerow);
 			lock->writer = GetCurrentThreadId();
 			LeaveCriticalSection(&lock->lk);
 			return TRUE;
@@ -166,6 +181,8 @@ rwlock_unlock(rwlock_t *lock)
 	if (lock->writers) {
 		if (lock->writer == GetCurrentThreadId()) {
 			lock->writers--;
+			if ((lock->writers_waiting + lock->writers) == 0)
+				SetEvent(lock->zerow);
 			LeaveCriticalSection(&lock->lk);
 			LeaveCriticalSection(&lock->wlk);
 			return TRUE;
@@ -182,6 +199,8 @@ rwlock_unlock(rwlock_t *lock)
 				*prev = rc->next;
 				free(rc);
 			}
+			if (lock->readers == 0)
+				SetEvent(lock->zeror);
 			LeaveCriticalSection(&lock->lk);
 			return TRUE;
 		}
diff --git a/src/xpdev/rwlockwrap.h b/src/xpdev/rwlockwrap.h
index e75dfe5bc6c14c911707ef578ee176fb00fbecdc..258bc000c084e4449d990d1078f7209035b9ff08 100644
--- a/src/xpdev/rwlockwrap.h
+++ b/src/xpdev/rwlockwrap.h
@@ -28,6 +28,8 @@ struct rwlock_reader_thread {
 typedef struct {
 	CRITICAL_SECTION lk;       // Protects access to all elements
 	CRITICAL_SECTION wlk;      // Locked by an active writer
+	HANDLE zeror;              // Event set whenever there are zero readers
+	HANDLE zerow;              // Event set whenever writers_waiting + writers is zero
 	unsigned readers;
 	unsigned writers;
 	unsigned writers_waiting;