[PATCH 6/9] ntdll: ReleaseSemaphore performed locally

Daniel Santos daniel.santos at pobox.com
Sun Sep 13 17:16:03 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).
---
 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 );
-- 
2.4.6




More information about the wine-devel mailing list