 
            From: Elizabeth Figura zfigura@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58794 --- dlls/ntdll/unix/sync.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index e67bc4d3f1e..aadb7f1dbaa 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -702,14 +702,21 @@ static NTSTATUS get_inproc_sync( HANDLE handle, enum inproc_sync_type desired_ty * and we need to use an uninterrupted section to prevent reentrancy. * We also need fd_cache_mutex to protect against the same race with * NtClose, that is, to prevent the object from being cached again between - * close_inproc_sync() and close_handle. */ + * close_inproc_sync() and close_handle. + * + * The mutex also protects cache_inproc_sync(). Accessing the cache is + * done without a lock, but populating it currently is not. */ server_enter_uninterrupted_section( &fd_cache_mutex, &sigset ); - if ((sync = get_cached_inproc_sync( handle ))) ret = STATUS_SUCCESS; - else ret = get_server_inproc_sync( handle, stack ); + if (!(sync = get_cached_inproc_sync( handle ))) + { + if ((ret = get_server_inproc_sync( handle, stack ))) + { + server_leave_uninterrupted_section( &fd_cache_mutex, &sigset ); + return ret; + } + sync = cache_inproc_sync( handle, stack ); + } server_leave_uninterrupted_section( &fd_cache_mutex, &sigset ); - if (ret) return ret; - - if (!sync) sync = cache_inproc_sync( handle, stack ); }
if (desired_type != INPROC_SYNC_UNKNOWN && desired_type != sync->type)

