@@ -248,113 +248,60 @@ void uv_mutex_unlock(uv_mutex_t* mutex) {
248
248
LeaveCriticalSection (mutex );
249
249
}
250
250
251
+ /* Ensure that the ABI for this type remains stable in v1.x */
252
+ #ifdef _WIN64
253
+ STATIC_ASSERT (sizeof (uv_rwlock_t ) == 80 );
254
+ #else
255
+ STATIC_ASSERT (sizeof (uv_rwlock_t ) == 48 );
256
+ #endif
251
257
252
258
int uv_rwlock_init (uv_rwlock_t * rwlock ) {
253
- /* Initialize the semaphore that acts as the write lock. */
254
- HANDLE handle = CreateSemaphoreW (NULL , 1 , 1 , NULL );
255
- if (handle == NULL )
256
- return uv_translate_sys_error (GetLastError ());
257
- rwlock -> state_ .write_semaphore_ = handle ;
258
-
259
- /* Initialize the critical section protecting the reader count. */
260
- InitializeCriticalSection (& rwlock -> state_ .num_readers_lock_ );
261
-
262
- /* Initialize the reader count. */
263
- rwlock -> state_ .num_readers_ = 0 ;
259
+ memset (rwlock , 0 , sizeof (* rwlock ));
260
+ InitializeSRWLock (& rwlock -> read_write_lock_ );
264
261
265
262
return 0 ;
266
263
}
267
264
268
265
269
266
void uv_rwlock_destroy (uv_rwlock_t * rwlock ) {
270
- DeleteCriticalSection ( & rwlock -> state_ . num_readers_lock_ );
271
- CloseHandle ( rwlock -> state_ . write_semaphore_ );
267
+ /* SRWLock does not need explicit destruction so long as there are no waiting threads
268
+ See: https://docs.microsoft.com/windows/win32/api/synchapi/nf-synchapi-initializesrwlock#remarks */
272
269
}
273
270
274
271
275
272
void uv_rwlock_rdlock (uv_rwlock_t * rwlock ) {
276
- /* Acquire the lock that protects the reader count. */
277
- EnterCriticalSection (& rwlock -> state_ .num_readers_lock_ );
278
-
279
- /* Increase the reader count, and lock for write if this is the first
280
- * reader.
281
- */
282
- if (++ rwlock -> state_ .num_readers_ == 1 ) {
283
- DWORD r = WaitForSingleObject (rwlock -> state_ .write_semaphore_ , INFINITE );
284
- if (r != WAIT_OBJECT_0 )
285
- uv_fatal_error (GetLastError (), "WaitForSingleObject" );
286
- }
287
-
288
- /* Release the lock that protects the reader count. */
289
- LeaveCriticalSection (& rwlock -> state_ .num_readers_lock_ );
273
+ AcquireSRWLockShared (& rwlock -> read_write_lock_ );
290
274
}
291
275
292
276
293
277
int uv_rwlock_tryrdlock (uv_rwlock_t * rwlock ) {
294
- int err ;
295
-
296
- if (!TryEnterCriticalSection (& rwlock -> state_ .num_readers_lock_ ))
278
+ if (!TryAcquireSRWLockShared (& rwlock -> read_write_lock_ ))
297
279
return UV_EBUSY ;
298
280
299
- err = 0 ;
300
-
301
- if (rwlock -> state_ .num_readers_ == 0 ) {
302
- /* Currently there are no other readers, which means that the write lock
303
- * needs to be acquired.
304
- */
305
- DWORD r = WaitForSingleObject (rwlock -> state_ .write_semaphore_ , 0 );
306
- if (r == WAIT_OBJECT_0 )
307
- rwlock -> state_ .num_readers_ ++ ;
308
- else if (r == WAIT_TIMEOUT )
309
- err = UV_EBUSY ;
310
- else if (r == WAIT_FAILED )
311
- uv_fatal_error (GetLastError (), "WaitForSingleObject" );
312
-
313
- } else {
314
- /* The write lock has already been acquired because there are other
315
- * active readers.
316
- */
317
- rwlock -> state_ .num_readers_ ++ ;
318
- }
319
-
320
- LeaveCriticalSection (& rwlock -> state_ .num_readers_lock_ );
321
- return err ;
281
+ return 0 ;
322
282
}
323
283
324
284
325
285
void uv_rwlock_rdunlock (uv_rwlock_t * rwlock ) {
326
- EnterCriticalSection (& rwlock -> state_ .num_readers_lock_ );
327
-
328
- if (-- rwlock -> state_ .num_readers_ == 0 ) {
329
- if (!ReleaseSemaphore (rwlock -> state_ .write_semaphore_ , 1 , NULL ))
330
- uv_fatal_error (GetLastError (), "ReleaseSemaphore" );
331
- }
332
-
333
- LeaveCriticalSection (& rwlock -> state_ .num_readers_lock_ );
286
+ ReleaseSRWLockShared (& rwlock -> read_write_lock_ );
334
287
}
335
288
336
289
337
290
void uv_rwlock_wrlock (uv_rwlock_t * rwlock ) {
338
- DWORD r = WaitForSingleObject (rwlock -> state_ .write_semaphore_ , INFINITE );
339
- if (r != WAIT_OBJECT_0 )
340
- uv_fatal_error (GetLastError (), "WaitForSingleObject" );
291
+ AcquireSRWLockExclusive (& rwlock -> read_write_lock_ );
341
292
}
342
293
343
294
344
295
int uv_rwlock_trywrlock (uv_rwlock_t * rwlock ) {
345
- DWORD r = WaitForSingleObject (rwlock -> state_ .write_semaphore_ , 0 );
346
- if (r == WAIT_OBJECT_0 )
347
- return 0 ;
348
- else if (r == WAIT_TIMEOUT )
296
+ if (!TryAcquireSRWLockExclusive (& rwlock -> read_write_lock_ ))
349
297
return UV_EBUSY ;
350
- else
351
- uv_fatal_error ( GetLastError (), "WaitForSingleObject" ) ;
298
+
299
+ return 0 ;
352
300
}
353
301
354
302
355
303
void uv_rwlock_wrunlock (uv_rwlock_t * rwlock ) {
356
- if (!ReleaseSemaphore (rwlock -> state_ .write_semaphore_ , 1 , NULL ))
357
- uv_fatal_error (GetLastError (), "ReleaseSemaphore" );
304
+ ReleaseSRWLockExclusive (& rwlock -> read_write_lock_ );
358
305
}
359
306
360
307
0 commit comments