[PATCH 7/9] ntdll: ReleaseSemaphore performed locally

Daniel Santos daniel.santos at pobox.com
Thu Sep 10 18:26:09 CDT 2015


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).

Signed-off-by: Daniel Santos <daniel.santos at pobox.com>
---
 dlls/ntdll/server.c | 14 ++++++++++++++
 dlls/ntdll/sync.c   | 31 +++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

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 84a3ab6..a26e40c 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -487,6 +487,37 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla
 NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous )
 {
     NTSTATUS ret;
+
+    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 STATUS_SUCCESS;
+
+        case STATUS_NOT_IMPLEMENTED:
+            /* fall through to server call */
+            break;
+
+        default:
+            ERR("semaphore_up return %08x\n", ret);
+            return ret;
+        }
+    }
+
     SERVER_START_REQ( release_semaphore )
     {
         req->handle = wine_server_obj_handle( handle );
-- 
2.4.6




More information about the wine-devel mailing list