When enabled, ReleaseSemaphore will be done by the client process without a server call. However, notification to the server is required and a rather ugly but temporary SIGUSR1 mechanism is implemented (will be changed soon). --- dlls/ntdll/server.c | 14 ++++++++++++++ dlls/ntdll/sync.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 95111ad..763a90d 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -682,6 +682,20 @@ unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, a } }
+/* notify server that we've released a lock as it won't actually wait (block) + * on any locks and may have a thread suspended waiting for this lock to be + * released */ +void ntdll_server_notify_lock_release(void) +{ + TRACE_(ntdllsync)("server_pid = %u\n", server_pid); + if (server_pid && server_pid != -1) + { + if (kill(server_pid, SIGUSR1)) + { + perror("kill"); + } + } +}
/*********************************************************************** * wine_server_send_fd (NTDLL.@) diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index f4ac276..2fa90af 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -494,7 +494,38 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla */ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous ) { - NTSTATUS ret; + NTSTATUS ret = 0; +#if 1 + struct ntdll_semaphore *sem = (void *)ntdll_handle_find(handle); + + /* if we know this handle, then manage it client-side, otherwise, it may be a stale handle + * that another thread already closed */ + if (sem) + { + TRACE_(ntdllsync)("handle = %p, count = %u, previous = %p) sem = %s\n", + handle, count, previous, ntdll_object_dump(&sem->obj)); + + assert(sem->p); + assert(sem->obj.type_id == NTDLL_OBJ_TYPE_SEMAPHORE); + + ret = semaphore_up(sem, count, previous); + ntdll_object_release(&sem->obj); + + switch (ret) + { + case STATUS_SUCCESS: + return 1; + + case STATUS_NOT_IMPLEMENTED: + /* fall through to server call */ + break; + + default: + ERR("semaphore_up return %08x\n", ret); + return 0; + } + } +#endif SERVER_START_REQ( release_semaphore ) { req->handle = wine_server_obj_handle( handle );