File patches.obscpio of Package wine-pure
07070100B68EA6000081A4000003E8000003E80000000168AA560300000624000001030000000200000000000000000000004400000000patches/Do-not-handle-IMAGE_FILE_LARGE_ADDRESS_AWARE-on-WoW64.patchFrom 617fbfeac720552802bdb704d162d5de1f99ccdb Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sun, 27 Jul 2025 22:34:45 +0300
Subject: [PATCH] Do not handle IMAGE_FILE_LARGE_ADDRESS_AWARE on WoW64
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The header IMAGE_FILE_LARGE_ADDRESS_AWARE SOMEHOW breaks the work of a number of pirates and not
very installers. Without WoW64 they aren't broken, just because IMAGE_FILE_LARGE_ADDRESS_AWARE is
not processed, instead there is a hardcoded user_space_limit to 0x7fff0000 with which everything
works. I don’t know what’s wrong with the Wine implementation, but I prefer all applications to work
out of box. However, you can still force the use of LAA by using the WINE_LARGE_ADDRESS_AWARE
environment variable.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/ntdll/unix/virtual.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index c5d73456762..7edf597349e 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -4921,8 +4921,7 @@ BOOL WINAPI __wine_needs_override_large_address_aware(void)
static BOOL is_large_address_aware(void)
{
- return (main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)
- || __wine_needs_override_large_address_aware();
+ return __wine_needs_override_large_address_aware();
}
/***********************************************************************
--
2.50.1
07070100B69336000081A4000003E8000003E80000000168AA560300000363000001030000000200000000000000000000003A00000000patches/explorer-prefer-wayland-over-x11-by-default.patchFrom 9ad3e7bbfbc635c6146d0eee664fca868dfde5d8 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sun, 24 Nov 2024 13:39:52 +0300
Subject: [PATCH 2/2] explorer: Prefer Wayland over X11 by default
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
programs/explorer/desktop.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index e526b468b7d..060104427ce 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -39,7 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(explorer);
#define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769))
#define DESKTOP_ALL_ACCESS 0x01ff
-static const WCHAR default_driver[] = L"mac,x11,wayland";
+static const WCHAR default_driver[] = L"mac,wayland,x11";
static BOOL using_root = TRUE;
--
2.47.0
07070100B69337000081A4000003E8000003E80000000168AA560300000C3A000001030000000200000000000000000000003C00000000patches/Avoid-winemenubuilder-to-startup-explorer.exe.patchFrom cc622577f11883628a4f13b567b1884cc8bb576d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=3D=3FUTF-8=3Fq=3FBernhard=3D20=3DC3=3D9Cbelacker=3F=3D?=
<bernhardu@mailbox.org>
Date: Sat, 12 Dec 2020 22:36:59 +0100
Subject: [PATCH] Avoid winemenubuilder to startup explorer.exe.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/win32u/defwnd.c | 19 +++++++++++++++++++
programs/winemenubuilder/winemenubuilder.c | 11 +++++++++++
2 files changed, 30 insertions(+)
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c
index 0cbb41d8604..ae982be0c0d 100644
--- a/dlls/win32u/defwnd.c
+++ b/dlls/win32u/defwnd.c
@@ -26,6 +26,7 @@
#include "ntgdi_private.h"
#include "ntuser_private.h"
+#include "ntstatus.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(win);
@@ -2984,6 +2985,24 @@ LRESULT desktop_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
NtAddAtom( bufferW, asciiz_to_unicode( bufferW, buffer ) - sizeof(WCHAR), &atom );
NtUserSetProp( hwnd, wine_display_device_guidW, ULongToHandle( atom ) );
+
+ {
+ char full_name[60];
+ WCHAR full_nameW[60];
+ UNICODE_STRING name_str;
+ OBJECT_ATTRIBUTES event_attr;
+ HANDLE event;
+
+ sprintf( full_name, "\\BaseNamedObjects\\Session\\%u\\__wine_desktop_created", NtCurrentTeb()->Peb->SessionId );
+ name_str.Buffer = full_nameW;
+ name_str.MaximumLength = asciiz_to_unicode( full_nameW, full_name );
+ name_str.Length = name_str.MaximumLength - sizeof(WCHAR);
+ InitializeObjectAttributes( &event_attr, &name_str, OBJ_OPENIF, NULL, NULL );
+ if (NtCreateEvent( &event, EVENT_ALL_ACCESS, &event_attr, NotificationEvent, FALSE ) != STATUS_SUCCESS)
+ ERR("Creating event %s failed.\n", debugstr_w(full_nameW));
+ else if (NtSetEvent( event, NULL ) != STATUS_SUCCESS)
+ ERR("Setting event %s failed.\n", debugstr_w(full_nameW));
+ }
}
return TRUE;
}
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 36569fa9d5f..103cb1de328 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -2895,6 +2895,17 @@ int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int sh
if (!init_xdg())
return 1;
+ {
+ const WCHAR event_name[] = L"__wine_desktop_created";
+ HANDLE event;
+ event = CreateEventW(NULL, TRUE, FALSE, event_name);
+ if (!event)
+ ERR("Creating event %s failed.\n", debugstr_w(event_name));
+ else if (WaitForSingleObject(event, INFINITE) == WAIT_FAILED)
+ ERR("Waiting on event %s failed.\n", debugstr_w(event_name));
+ CloseHandle(event);
+ }
+
hr = CoInitialize(NULL);
if (FAILED(hr))
{
--
2.48.1
07070100B69338000081A4000003E8000003E80000000168AA560300000B4A000001030000000200000000000000000000003D00000000patches/0004-wineboot-Generate-better-DigitalProductId.patchFrom cdf0ced4bfbffcccbca1957b1c8904794d27db0e Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Fri, 7 Feb 2025 22:28:26 +0300
Subject: [PATCH 4/5] wineboot: Generate better DigitalProductId.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
programs/wineboot/wineboot.c | 46 ++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 7a428479959..682614b28ed 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -79,6 +79,8 @@
#include <setupapi.h>
#include <wininet.h>
#include <newdev.h>
+#include <wincrypt.h>
+#include "ntsecapi.h"
#include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
@@ -1958,6 +1960,49 @@ static void usage( int status )
exit( status );
}
+static void create_digitalproductid(void)
+{
+ BYTE digital_product_id[0xa4];
+ char product_id[256];
+ LSTATUS status;
+ unsigned int i;
+ DWORD size;
+ DWORD type;
+ HKEY key;
+ if ((status = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion",
+ 0, KEY_ALL_ACCESS, &key )))
+ return;
+ size = sizeof(product_id);
+ status = RegQueryValueExA( key, "ProductId", NULL, &type, (BYTE *)product_id, &size );
+ if (status) goto done;
+ if (!size) goto done;
+ if (product_id[size - 1])
+ {
+ if (size == sizeof(product_id)) goto done;
+ product_id[size++] = 0;
+ }
+ if (!RegQueryValueExA( key, "DigitalProductId", NULL, &type, NULL, &size ) && size == sizeof(digital_product_id))
+ {
+ if (RegQueryValueExA( key, "DigitalProductId", NULL, &type, digital_product_id, &size ))
+ goto done;
+ for (i = 0; i < size; ++i)
+ if (digital_product_id[i]) break;
+ if (i < size) goto done;
+ }
+ memset( digital_product_id, 0, sizeof(digital_product_id) );
+ *(DWORD *)digital_product_id = sizeof(digital_product_id);
+ digital_product_id[4] = 3;
+ strcpy( (char *)digital_product_id + 8, product_id );
+ *(DWORD *)(digital_product_id + 0x20) = 0x0cec;
+ *(DWORD *)(digital_product_id + 0x34) = 0x0cec;
+ strcpy( (char *)digital_product_id + 0x24, "[TH] X19-99481" );
+ digital_product_id[0x42] = 8;
+ RtlGenRandom( digital_product_id + 0x38, 0x18 );
+ RegSetValueExA( key, "DigitalProductId", 0, REG_BINARY, digital_product_id, sizeof(digital_product_id) );
+done:
+ RegCloseKey( key );
+}
+
int __cdecl main( int argc, char *argv[] )
{
/* First, set the current directory to SystemRoot */
@@ -2067,6 +2112,7 @@ int __cdecl main( int argc, char *argv[] )
}
if (init || update) update_wineprefix( update );
+ create_digitalproductid();
create_volatile_environment_registry_key();
create_proxy_settings();
--
2.48.1
07070100B69339000081A4000003E8000003E80000000168AA560300001188000001030000000200000000000000000000004300000000patches/winex11.drv-Recognize-the-keyboard-in-a-locale-indep.patchFrom 4023d07595072cc6f78f87d1c1c22eaaab910216 Mon Sep 17 00:00:00 2001
From: Giovanni Mascellani <gmascellani@codeweavers.com>
Date: Mon, 7 Dec 2020 09:31:52 +0100
Subject: [PATCH] winex11.drv: Recognize the keyboard in a locale-independent
way.
Try to recognize the keyboard comparing keysyms instead of converting
them to multibyte strings, which makes the process locale-dependent and
therefore more fragile.
Unfortunately this means that the layout tables might need to be
updated. However, this change is known to fix the recognitions of a few
keys in the French layout.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=30984
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45605
CW-Bug-Id: #16793
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/winex11.drv/keyboard.c | 62 +++++++++++++++++++------------------
1 file changed, 32 insertions(+), 30 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 18437c8a7f4..4b0abef9c15 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1500,6 +1500,35 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
return TRUE;
}
+/* From the point of view of this function there are two types of
+ * keys: those for which the mapping to vkey and scancode depends on
+ * the keyboard layout (i.e., letters, numbers, punctuation) and those
+ * for which it doesn't (control keys); since this function is used to
+ * recognize the keyboard layout and map keysyms to vkeys and
+ * scancodes, we are only concerned about the first type, and map
+ * everything in the second type to zero.
+ */
+static char keysym_to_char( KeySym keysym )
+{
+ /* Dead keys */
+ if (0xfe50 <= keysym && keysym < 0xfed0)
+ return KEYBOARD_MapDeadKeysym( keysym );
+
+ /* Control keys (there is nothing allocated below 0xfc00, but I
+ take some margin in case something is added in the future) */
+ if (0xf000 <= keysym && keysym < 0x10000)
+ return 0;
+
+ /* XFree86 vendor keys */
+ if (0x10000000 <= keysym)
+ return 0;
+
+ /* "Normal" keys: return last octet, because our tables don't have
+ more than that; it would be better to extend the tables and
+ compare the whole keysym, but it's a lot of work... */
+ return keysym & 0xff;
+}
+
/**********************************************************************
* X11DRV_KEYBOARD_DetectLayout
*
@@ -1530,22 +1559,7 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
/* get data for keycode from X server */
for (i = 0; i < syms; i++) {
if (!(keysym = XkbKeycodeToKeysym( display, keyc, 0, i ))) continue;
- /* Allow both one-byte and two-byte national keysyms */
- if ((keysym < 0x8000) && (keysym != ' '))
- {
- if (!XkbTranslateKeySym(display, &keysym, 0, &ckey[keyc][i], 1, NULL))
- {
- TRACE("XKB could not translate keysym %04lx\n", keysym);
- /* FIXME: query what keysym is used as Mode_switch, fill XKeyEvent
- * with appropriate ShiftMask and Mode_switch, use XLookupString
- * to get character in the local encoding.
- */
- ckey[keyc][i] = keysym & 0xFF;
- }
- }
- else {
- ckey[keyc][i] = KEYBOARD_MapDeadKeysym(keysym);
- }
+ ckey[keyc][i] = keysym_to_char(keysym);
}
}
@@ -1721,20 +1735,8 @@ void X11DRV_InitKeyboard( Display *display )
/* we seem to need to search the layout-dependent scancodes */
int maxlen=0,maxval=-1,ok;
for (i=0; i<syms; i++) {
- keysym = XkbKeycodeToKeysym( display, keyc, 0, i );
- if ((keysym<0x8000) && (keysym!=' '))
- {
- if (!XkbTranslateKeySym(display, &keysym, 0, &ckey[i], 1, NULL))
- {
- /* FIXME: query what keysym is used as Mode_switch, fill XKeyEvent
- * with appropriate ShiftMask and Mode_switch, use XLookupString
- * to get character in the local encoding.
- */
- ckey[i] = (keysym <= 0x7F) ? keysym : 0;
- }
- } else {
- ckey[i] = KEYBOARD_MapDeadKeysym(keysym);
- }
+ keysym = XkbKeycodeToKeysym( display, keyc, 0, i );
+ ckey[i] = keysym_to_char(keysym);
}
/* find key with longest match streak */
for (keyn=0; keyn<MAIN_LEN; keyn++) {
--
2.48.1
07070100B6933A000081A4000003E8000003E80000000168AA560300000C13000001030000000200000000000000000000004800000000patches/0003-wineboot-On-prefix-upgrade-update-win10-build-number.patchFrom 8e7dd70648183eef1e6e089ea36ad7f869a15b84 Mon Sep 17 00:00:00 2001
From: Andrew Eikum <aeikum@codeweavers.com>
Date: Fri, 7 Feb 2025 22:27:12 +0300
Subject: [PATCH 3/5] wineboot: On prefix upgrade, update win10 build number
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
programs/wineboot/wineboot.c | 38 ++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 698648548a1..7a428479959 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -1761,6 +1761,43 @@ static void update_user_profile(void)
LocalFree(sid);
}
+static void update_win_version(void)
+{
+ static const WCHAR win10_buildW[] = L"19045";
+ static const WCHAR win10_ntW[] = L"6.3";
+ HKEY cv_h;
+ DWORD type, sz;
+ WCHAR current_version[256];
+ if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion",
+ 0, KEY_ALL_ACCESS, &cv_h) == ERROR_SUCCESS){
+ /* get the current windows version */
+ sz = sizeof(current_version);
+ if(RegQueryValueExW(cv_h, L"CurrentVersion", NULL, &type, (BYTE *)current_version, &sz) == ERROR_SUCCESS &&
+ type == REG_SZ){
+ if(!wcscmp(current_version, L"6.3") || !wcscmp(current_version, L"10.0")){
+ RegSetValueExW(cv_h, L"CurrentVersion", 0, REG_SZ, (const BYTE *)win10_ntW, sizeof(win10_ntW));
+ RegSetValueExW(cv_h, L"CurrentBuild", 0, REG_SZ, (const BYTE *)win10_buildW, sizeof(win10_buildW));
+ RegSetValueExW(cv_h, L"CurrentBuildNumber", 0, REG_SZ, (const BYTE *)win10_buildW, sizeof(win10_buildW));
+ }
+ }
+ RegCloseKey(cv_h);
+ }
+ if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion",
+ 0, KEY_ALL_ACCESS, &cv_h) == ERROR_SUCCESS){
+ /* get the current windows version */
+ sz = sizeof(current_version);
+ if(RegQueryValueExW(cv_h, L"CurrentVersion", NULL, &type, (BYTE *)current_version, &sz) == ERROR_SUCCESS &&
+ type == REG_SZ){
+ if(!wcscmp(current_version, L"6.3") || !wcscmp(current_version, L"10.0")){
+ RegSetValueExW(cv_h, L"CurrentVersion", 0, REG_SZ, (const BYTE *)win10_ntW, sizeof(win10_ntW));
+ RegSetValueExW(cv_h, L"CurrentBuild", 0, REG_SZ, (const BYTE *)win10_buildW, sizeof(win10_buildW));
+ RegSetValueExW(cv_h, L"CurrentBuildNumber", 0, REG_SZ, (const BYTE *)win10_buildW, sizeof(win10_buildW));
+ }
+ }
+ RegCloseKey(cv_h);
+ }
+}
+
/* execute rundll32 on the wine.inf file if necessary */
static void update_wineprefix( BOOL force )
{
@@ -1819,6 +1856,7 @@ static void update_wineprefix( BOOL force )
}
install_root_pnp_devices();
update_user_profile();
+ update_win_version();
TRACE( "wine: configuration in %s has been updated.\n", debugstr_w(prettyprint_configdir()) );
}
--
2.48.1
07070100B6933B000081A4000003E8000003E80000000168AA5603000001FF000001030000000200000000000000000000004100000000patches/kernelbase-Fix-uninitialized-structs-in-OpenThread.patchdiff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c
index bc8210bd43a..c3b3f020ad6 100644
--- a/dlls/kernelbase/thread.c
+++ b/dlls/kernelbase/thread.c
@@ -344,6 +344,7 @@ HANDLE WINAPI DECLSPEC_HOTPATCH OpenThread( DWORD access, BOOL inherit, DWORD id
OBJECT_ATTRIBUTES attr;
CLIENT_ID cid;
+ memset(&attr, 0, sizeof(attr));
InitializeObjectAttributes( &attr, NULL, inherit ? OBJ_INHERIT : 0, 0, NULL );
cid.UniqueProcess = 0;
cid.UniqueThread = ULongToHandle( id );
07070100B6933C000081A4000003E8000003E80000000168AA56030000074B000001030000000200000000000000000000004400000000patches/0005-wineboot-Load-root-certificates-on-prefix-update.patchFrom 4a154c6dda5dae012871d4487ceb18de95090052 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Fri, 7 Feb 2025 22:29:49 +0300
Subject: [PATCH 5/5] wineboot: Load root certificates on prefix update.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
programs/wineboot/Makefile.in | 2 +-
programs/wineboot/wineboot.c | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in
index d346b8984b1..9eaa95c9ad5 100644
--- a/programs/wineboot/Makefile.in
+++ b/programs/wineboot/Makefile.in
@@ -1,6 +1,6 @@
MODULE = wineboot.exe
IMPORTS = uuid advapi32 ws2_32 kernelbase
-DELAYIMPORTS = shell32 shlwapi version user32 gdi32 setupapi newdev wininet
+DELAYIMPORTS = shell32 shlwapi version user32 gdi32 setupapi newdev wininet crypt32
EXTRADLLFLAGS = -mconsole
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index cb036c9853a..b8171a973f9 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -1798,6 +1798,14 @@ static void update_win_version(void)
}
}
+static void update_root_certs(void)
+{
+ HCERTSTORE store;
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG
+ | CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root");
+ CertCloseStore( store, 0 );
+}
+
/* execute rundll32 on the wine.inf file if necessary */
static void update_wineprefix( BOOL force )
{
@@ -1857,6 +1865,7 @@ static void update_wineprefix( BOOL force )
install_root_pnp_devices();
update_user_profile();
update_win_version();
+ update_root_certs();
TRACE( "wine: configuration in %s has been updated.\n", debugstr_w(prettyprint_configdir()) );
}
--
2.48.1
07070100B6933D000081A4000003E8000003E80000000168AA5603000671BC000001030000000200000000000000000000002300000000patches/ntsync-10.13-staging.patchFrom 494478eea1899f8b6224d0213d3bae5d9dd4fc36 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 15:59:07 +0300
Subject: [PATCH 01/57] Revert "server: Keep owned mutex syncs alive until
abandoned."
This reverts commit 934514db7c2d080672f9db56212afe5550928af2.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/kernel32/tests/sync.c | 27 ++-------------------------
server/mutex.c | 5 ++---
2 files changed, 4 insertions(+), 28 deletions(-)
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
index 49f5002f651..5023b9540e5 100644
--- a/dlls/kernel32/tests/sync.c
+++ b/dlls/kernel32/tests/sync.c
@@ -230,35 +230,12 @@ static void test_temporary_objects(void)
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
}
-struct test_mutex_thread_params
-{
- HANDLE mutex;
- HANDLE start_event;
- HANDLE stop_event;
- BOOL owner;
-};
-
-static DWORD WINAPI test_mutex_thread(void *arg)
-{
- struct test_mutex_thread_params *params = arg;
- DWORD ret;
-
- ret = WaitForSingleObject(params->mutex, INFINITE);
- if (params->owner) ok(!ret, "got %#lx\n", ret);
- else ok(ret == WAIT_ABANDONED, "got %#lx\n", ret);
- SetEvent(params->start_event);
-
- ret = WaitForSingleObject(params->stop_event, INFINITE);
- ok(!ret, "got %#lx\n", ret);
- return 0;
-}
-
static void test_mutex(void)
{
DWORD wait_ret;
BOOL ret;
- HANDLE hCreated, hOpened, owner_thread, waiter_thread;
- struct test_mutex_thread_params params;
+ HANDLE hCreated;
+ HANDLE hOpened;
int i;
DWORD failed = 0;
diff --git a/server/mutex.c b/server/mutex.c
index e370d301472..573fcda1083 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -97,7 +97,6 @@ static void do_grab( struct mutex_sync *mutex, struct thread *thread )
if (!mutex->count++) /* FIXME: avoid wrap-around */
{
assert( !mutex->owner );
- grab_object( mutex );
mutex->owner = thread;
list_add_head( &thread->mutex_list, &mutex->entry );
}
@@ -117,7 +116,6 @@ static int do_release( struct mutex_sync *mutex, struct thread *thread, int coun
list_remove( &mutex->entry );
mutex->owner = NULL;
wake_up( &mutex->obj, 0 );
- release_object( mutex );
}
return 1;
}
@@ -133,7 +131,8 @@ static void mutex_sync_destroy( struct object *obj )
{
struct mutex_sync *mutex = (struct mutex_sync *)obj;
assert( obj->ops == &mutex_sync_ops );
- assert( !mutex->count );
+
+ if (mutex->count) do_release( mutex, current, mutex->count );
}
static int mutex_sync_signaled( struct object *obj, struct wait_queue_entry *entry )
--
2.50.1
From 979aefdc5bf5b0f033f83b1d28cb14ef0728e745 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 15:59:24 +0300
Subject: [PATCH 02/57] Revert "server: Use a signaled flag for message queue
sync."
This reverts commit 991bf42f1052db41bb9b2e178b8af7a51be95ca7.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/queue.c | 62 +++++++++++++++++++++++---------------------------
1 file changed, 29 insertions(+), 33 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 18fe5bee82d..523733e7e9b 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -116,7 +116,6 @@ struct msg_queue
{
struct object obj; /* object header */
struct fd *fd; /* optional file descriptor to poll */
- int signaled; /* queue is signaled from fd POLLIN or masks */
int paint_count; /* pending paint messages count */
int hotkey_count; /* pending hotkey messages count */
int quit_message; /* is there a pending quit message? */
@@ -307,7 +306,6 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
if ((queue = alloc_object( &msg_queue_ops )))
{
queue->fd = NULL;
- queue->signaled = 0;
queue->paint_count = 0;
queue->hotkey_count = 0;
queue->quit_message = 0;
@@ -711,18 +709,6 @@ void add_queue_hook_count( struct thread *thread, unsigned int index, int count
assert( thread->queue->shared->hooks_count[index] >= 0 );
}
-static void signal_queue_sync( struct msg_queue *queue )
-{
- if (queue->signaled) return;
- queue->signaled = 1;
- wake_up( &queue->obj, 0 );
-}
-
-static void reset_queue_sync( struct msg_queue *queue )
-{
- queue->signaled = 0;
-}
-
/* check the queue status */
static inline int is_signaled( struct msg_queue *queue )
{
@@ -749,7 +735,7 @@ static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits )
}
SHARED_WRITE_END;
- if (is_signaled( queue )) signal_queue_sync( queue );
+ if (is_signaled( queue )) wake_up( &queue->obj, 0 );
}
/* clear some queue bits */
@@ -769,7 +755,6 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
if (queue->keystate_lock) unlock_input_keystate( queue->input );
queue->keystate_lock = 0;
}
- if (!is_signaled( queue )) reset_queue_sync( queue );
}
/* check if message is matched by the filter */
@@ -1302,11 +1287,7 @@ static int msg_queue_select( struct msg_queue *queue, int events )
}
queue->waiting = !!events;
- if (queue->fd)
- {
- if (events && check_fd_events( queue->fd, POLLIN )) signal_queue_sync( queue );
- else set_fd_events( queue->fd, events );
- }
+ if (queue->fd) set_fd_events( queue->fd, events );
return 1;
}
@@ -1345,8 +1326,18 @@ static void msg_queue_dump( struct object *obj, int verbose )
static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct msg_queue *queue = (struct msg_queue *)obj;
- assert( obj->ops == &msg_queue_ops );
- return queue->signaled;
+ int ret = 0;
+
+ if (queue->fd)
+ {
+ if ((ret = check_fd_events( queue->fd, POLLIN )))
+ /* stop waiting on select() if we are signaled */
+ set_fd_events( queue->fd, 0 );
+ else if (queue->waiting)
+ /* restart waiting on poll() if we are no longer signaled */
+ set_fd_events( queue->fd, POLLIN );
+ }
+ return ret || is_signaled( queue );
}
static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry )
@@ -1360,7 +1351,6 @@ static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *en
shared->changed_mask = 0;
}
SHARED_WRITE_END;
- reset_queue_sync( queue );
}
static void msg_queue_destroy( struct object *obj )
@@ -1415,7 +1405,7 @@ static void msg_queue_poll_event( struct fd *fd, int event )
if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 );
else set_fd_events( queue->fd, 0 );
- signal_queue_sync( queue );
+ wake_up( &queue->obj, 0 );
}
static void thread_input_dump( struct object *obj, int verbose )
@@ -3188,9 +3178,20 @@ DECL_HANDLER(set_queue_mask)
reply->wake_bits = queue_shm->wake_bits;
reply->changed_bits = queue_shm->changed_bits;
- if (!is_signaled( queue )) reset_queue_sync( queue );
- else if (!req->skip_wait) signal_queue_sync( queue );
- else msg_queue_satisfied( &queue->obj, NULL );
+ if (is_signaled( queue ))
+ {
+ /* if skip wait is set, do what would have been done in the subsequent wait */
+ if (req->skip_wait)
+ {
+ SHARED_WRITE_BEGIN( queue_shm, queue_shm_t )
+ {
+ shared->wake_mask = 0;
+ shared->changed_mask = 0;
+ }
+ SHARED_WRITE_END;
+ }
+ else wake_up( &queue->obj, 0 );
+ }
}
}
@@ -3211,8 +3212,6 @@ DECL_HANDLER(get_queue_status)
shared->changed_bits &= ~req->clear_bits;
}
SHARED_WRITE_END;
-
- if (!is_signaled( queue )) reset_queue_sync( queue );
}
else reply->wake_bits = reply->changed_bits = 0;
}
@@ -3411,8 +3410,6 @@ DECL_HANDLER(get_message)
}
SHARED_WRITE_END;
- if (!is_signaled( queue )) reset_queue_sync( queue );
-
/* then check for posted messages */
if ((filter & QS_POSTMESSAGE) &&
get_posted_message( queue, queue->ignore_post_msg, get_win, req->get_first, req->get_last, req->flags, reply ))
@@ -3482,7 +3479,6 @@ DECL_HANDLER(get_message)
}
SHARED_WRITE_END;
- reset_queue_sync( queue );
set_error( STATUS_PENDING ); /* FIXME */
return;
--
2.50.1
From 4a1c2a26c070c196d82bd2857f38787b2715d1b8 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 15:59:30 +0300
Subject: [PATCH 03/57] Revert "server: Use a flag to keep track of message
queue waits."
This reverts commit 1f033324c34021fc594d7886c6d92262adcf816a.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/queue.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 523733e7e9b..4b8fdf677fd 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -133,7 +133,6 @@ struct msg_queue
struct hook_table *hooks; /* hook table */
timeout_t last_get_msg; /* time of last get message call */
int keystate_lock; /* owns an input keystate lock */
- int waiting; /* is thread waiting on queue */
queue_shm_t *shared; /* queue in session shared memory */
unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
};
@@ -318,7 +317,6 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue->last_get_msg = current_time;
queue->keystate_lock = 0;
queue->ignore_post_msg = 0;
- queue->waiting = 0;
list_init( &queue->send_result );
list_init( &queue->callback_result );
list_init( &queue->pending_timers );
@@ -1273,21 +1271,16 @@ static void cleanup_results( struct msg_queue *queue )
/* check if the thread owning the queue is hung (not checking for messages) */
static int is_queue_hung( struct msg_queue *queue )
{
+ struct wait_queue_entry *entry;
+
if (current_time - queue->last_get_msg <= 5 * TICKS_PER_SEC)
return 0; /* less than 5 seconds since last get message -> not hung */
- return !queue->waiting;
-}
-static int msg_queue_select( struct msg_queue *queue, int events )
-{
- if (queue->waiting == !!events)
+ LIST_FOR_EACH_ENTRY( entry, &queue->obj.wait_queue, struct wait_queue_entry, entry )
{
- set_error( STATUS_ACCESS_DENIED );
- return 0;
+ if (get_wait_queue_thread(entry)->queue == queue)
+ return 0; /* thread is waiting on queue -> not hung */
}
- queue->waiting = !!events;
-
- if (queue->fd) set_fd_events( queue->fd, events );
return 1;
}
@@ -1302,7 +1295,8 @@ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *ent
return 0;
}
- if (!msg_queue_select( queue, POLLIN )) return 0;
+ if (queue->fd && list_empty( &obj->wait_queue )) /* first on the queue */
+ set_fd_events( queue->fd, POLLIN );
add_queue( obj, entry );
return 1;
}
@@ -1312,7 +1306,8 @@ static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *
struct msg_queue *queue = (struct msg_queue *)obj;
remove_queue( obj, entry );
- msg_queue_select( queue, 0 );
+ if (queue->fd && list_empty( &obj->wait_queue )) /* last on the queue is gone */
+ set_fd_events( queue->fd, 0 );
}
static void msg_queue_dump( struct object *obj, int verbose )
@@ -1333,7 +1328,7 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr
if ((ret = check_fd_events( queue->fd, POLLIN )))
/* stop waiting on select() if we are signaled */
set_fd_events( queue->fd, 0 );
- else if (queue->waiting)
+ else if (!list_empty( &obj->wait_queue ))
/* restart waiting on poll() if we are no longer signaled */
set_fd_events( queue->fd, POLLIN );
}
--
2.50.1
From ef5d1db29f0b86a0b9ec91833a11c7500c196730 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 15:59:36 +0300
Subject: [PATCH 04/57] Revert "server: Split semaphore to a dedicated sync
object."
This reverts commit 9e05682f68fe20fb4df029ae39ecace786b3571a.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/semaphore.c | 172 ++++++++++++++-------------------------------
1 file changed, 51 insertions(+), 121 deletions(-)
diff --git a/server/semaphore.c b/server/semaphore.c
index 4b31bfe806c..304a821bcec 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -50,119 +50,30 @@ struct type_descr semaphore_type =
},
};
-struct semaphore_sync
-{
- struct object obj; /* object header */
- unsigned int count; /* current count */
- unsigned int max; /* maximum possible count */
-};
-
-static void semaphore_sync_dump( struct object *obj, int verbose );
-static int semaphore_sync_signaled( struct object *obj, struct wait_queue_entry *entry );
-static void semaphore_sync_satisfied( struct object *obj, struct wait_queue_entry *entry );
-
-static const struct object_ops semaphore_sync_ops =
-{
- sizeof(struct semaphore_sync), /* size */
- &no_type, /* type */
- semaphore_sync_dump, /* dump */
- add_queue, /* add_queue */
- remove_queue, /* remove_queue */
- semaphore_sync_signaled, /* signaled */
- semaphore_sync_satisfied, /* satisfied */
- no_signal, /* signal */
- no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
- default_map_access, /* map_access */
- default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
- default_get_full_name, /* get_full_name */
- no_lookup_name, /* lookup_name */
- directory_link_name, /* link_name */
- default_unlink_name, /* unlink_name */
- no_open_file, /* open_file */
- no_kernel_obj_list, /* get_kernel_obj_list */
- no_close_handle, /* close_handle */
- no_destroy /* destroy */
-};
-
-static int release_semaphore( struct semaphore_sync *sem, unsigned int count,
- unsigned int *prev )
-{
- if (prev) *prev = sem->count;
- if (sem->count + count < sem->count || sem->count + count > sem->max)
- {
- set_error( STATUS_SEMAPHORE_LIMIT_EXCEEDED );
- return 0;
- }
- else if (sem->count)
- {
- /* there cannot be any thread to wake up if the count is != 0 */
- sem->count += count;
- }
- else
- {
- sem->count = count;
- wake_up( &sem->obj, count );
- }
- return 1;
-}
-
-static void semaphore_sync_dump( struct object *obj, int verbose )
-{
- struct semaphore_sync *sem = (struct semaphore_sync *)obj;
- assert( obj->ops == &semaphore_sync_ops );
- fprintf( stderr, "Semaphore count=%d max=%d\n", sem->count, sem->max );
-}
-
-static int semaphore_sync_signaled( struct object *obj, struct wait_queue_entry *entry )
-{
- struct semaphore_sync *sem = (struct semaphore_sync *)obj;
- assert( obj->ops == &semaphore_sync_ops );
- return (sem->count > 0);
-}
-
-static void semaphore_sync_satisfied( struct object *obj, struct wait_queue_entry *entry )
-{
- struct semaphore_sync *sem = (struct semaphore_sync *)obj;
- assert( obj->ops == &semaphore_sync_ops );
- assert( sem->count );
- sem->count--;
-}
-
-static struct semaphore_sync *create_semaphore_sync( unsigned int initial, unsigned int max )
-{
- struct semaphore_sync *sem;
-
- if (!(sem = alloc_object( &semaphore_sync_ops ))) return NULL;
- sem->count = initial;
- sem->max = max;
- return sem;
-}
-
struct semaphore
{
- struct object obj; /* object header */
- struct semaphore_sync *sync; /* semaphore sync object */
+ struct object obj; /* object header */
+ unsigned int count; /* current count */
+ unsigned int max; /* maximum possible count */
};
static void semaphore_dump( struct object *obj, int verbose );
-static struct object *semaphore_get_sync( struct object *obj );
+static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry );
+static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry );
static int semaphore_signal( struct object *obj, unsigned int access );
-static void semaphore_destroy( struct object *obj );
static const struct object_ops semaphore_ops =
{
sizeof(struct semaphore), /* size */
&semaphore_type, /* type */
semaphore_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ semaphore_signaled, /* signaled */
+ semaphore_satisfied, /* satisfied */
semaphore_signal, /* signal */
no_get_fd, /* get_fd */
- semaphore_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -173,9 +84,10 @@ static const struct object_ops semaphore_ops =
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
no_close_handle, /* close_handle */
- semaphore_destroy, /* destroy */
+ no_destroy /* destroy */
};
+
static struct semaphore *create_semaphore( struct object *root, const struct unicode_str *name,
unsigned int attr, unsigned int initial, unsigned int max,
const struct security_descriptor *sd )
@@ -192,30 +104,55 @@ static struct semaphore *create_semaphore( struct object *root, const struct uni
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- sem->sync = NULL;
-
- if (!(sem->sync = create_semaphore_sync( initial, max )))
- {
- release_object( sem );
- return NULL;
- }
+ sem->count = initial;
+ sem->max = max;
}
}
return sem;
}
+static int release_semaphore( struct semaphore *sem, unsigned int count,
+ unsigned int *prev )
+{
+ if (prev) *prev = sem->count;
+ if (sem->count + count < sem->count || sem->count + count > sem->max)
+ {
+ set_error( STATUS_SEMAPHORE_LIMIT_EXCEEDED );
+ return 0;
+ }
+ else if (sem->count)
+ {
+ /* there cannot be any thread to wake up if the count is != 0 */
+ sem->count += count;
+ }
+ else
+ {
+ sem->count = count;
+ wake_up( &sem->obj, count );
+ }
+ return 1;
+}
+
static void semaphore_dump( struct object *obj, int verbose )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );
- sem->sync->obj.ops->dump( &sem->sync->obj, verbose );
+ fprintf( stderr, "Semaphore count=%d max=%d\n", sem->count, sem->max );
}
-static struct object *semaphore_get_sync( struct object *obj )
+static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );
- return grab_object( sem->sync );
+ return (sem->count > 0);
+}
+
+static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct semaphore *sem = (struct semaphore *)obj;
+ assert( obj->ops == &semaphore_ops );
+ assert( sem->count );
+ sem->count--;
}
static int semaphore_signal( struct object *obj, unsigned int access )
@@ -228,14 +165,7 @@ static int semaphore_signal( struct object *obj, unsigned int access )
set_error( STATUS_ACCESS_DENIED );
return 0;
}
- return release_semaphore( sem->sync, 1, NULL );
-}
-
-static void semaphore_destroy( struct object *obj )
-{
- struct semaphore *sem = (struct semaphore *)obj;
- assert( obj->ops == &semaphore_ops );
- if (sem->sync) release_object( sem->sync );
+ return release_semaphore( sem, 1, NULL );
}
/* create a semaphore */
@@ -279,7 +209,7 @@ DECL_HANDLER(release_semaphore)
if ((sem = (struct semaphore *)get_handle_obj( current->process, req->handle,
SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
{
- release_semaphore( sem->sync, req->count, &reply->prev_count );
+ release_semaphore( sem, req->count, &reply->prev_count );
release_object( sem );
}
}
@@ -292,8 +222,8 @@ DECL_HANDLER(query_semaphore)
if ((sem = (struct semaphore *)get_handle_obj( current->process, req->handle,
SEMAPHORE_QUERY_STATE, &semaphore_ops )))
{
- reply->current = sem->sync->count;
- reply->max = sem->sync->max;
+ reply->current = sem->count;
+ reply->max = sem->max;
release_object( sem );
}
}
--
2.50.1
From 318f661c117daee8897bf46d066c99e1febba196 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 15:59:42 +0300
Subject: [PATCH 05/57] Revert "server: Split mutex to a dedicated sync
object."
This reverts commit 672c3a561f5cd1cd6937c702fe2fe05397f41375.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/mutex.c | 166 ++++++++++++++-----------------------------------
1 file changed, 47 insertions(+), 119 deletions(-)
diff --git a/server/mutex.c b/server/mutex.c
index 573fcda1083..90cc594c741 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -50,30 +50,31 @@ struct type_descr mutex_type =
},
};
-struct mutex_sync
+struct mutex
{
- struct object obj; /* object header */
- struct thread *owner; /* mutex owner */
- unsigned int count; /* recursion count */
- int abandoned; /* has it been abandoned? */
- struct list entry; /* entry in owner thread mutex list */
+ struct object obj; /* object header */
+ struct thread *owner; /* mutex owner */
+ unsigned int count; /* recursion count */
+ int abandoned; /* has it been abandoned? */
+ struct list entry; /* entry in owner thread mutex list */
};
-static void mutex_sync_dump( struct object *obj, int verbose );
-static int mutex_sync_signaled( struct object *obj, struct wait_queue_entry *entry );
-static void mutex_sync_satisfied( struct object *obj, struct wait_queue_entry *entry );
-static void mutex_sync_destroy( struct object *obj );
+static void mutex_dump( struct object *obj, int verbose );
+static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry );
+static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry );
+static void mutex_destroy( struct object *obj );
+static int mutex_signal( struct object *obj, unsigned int access );
-static const struct object_ops mutex_sync_ops =
+static const struct object_ops mutex_ops =
{
- sizeof(struct mutex_sync), /* size */
- &no_type, /* type */
- mutex_sync_dump, /* dump */
+ sizeof(struct mutex), /* size */
+ &mutex_type, /* type */
+ mutex_dump, /* dump */
add_queue, /* add_queue */
remove_queue, /* remove_queue */
- mutex_sync_signaled, /* signaled */
- mutex_sync_satisfied, /* satisfied */
- no_signal, /* signal */
+ mutex_signaled, /* signaled */
+ mutex_satisfied, /* satisfied */
+ mutex_signal, /* signal */
no_get_fd, /* get_fd */
default_get_sync, /* get_sync */
default_map_access, /* map_access */
@@ -86,11 +87,12 @@ static const struct object_ops mutex_sync_ops =
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
no_close_handle, /* close_handle */
- mutex_sync_destroy, /* destroy */
+ mutex_destroy /* destroy */
};
+
/* grab a mutex for a given thread */
-static void do_grab( struct mutex_sync *mutex, struct thread *thread )
+static void do_grab( struct mutex *mutex, struct thread *thread )
{
assert( !mutex->count || (mutex->owner == thread) );
@@ -103,7 +105,7 @@ static void do_grab( struct mutex_sync *mutex, struct thread *thread )
}
/* release a mutex once the recursion count is 0 */
-static int do_release( struct mutex_sync *mutex, struct thread *thread, int count )
+static int do_release( struct mutex *mutex, struct thread *thread, int count )
{
if (!mutex->count || (mutex->owner != thread))
{
@@ -120,87 +122,6 @@ static int do_release( struct mutex_sync *mutex, struct thread *thread, int coun
return 1;
}
-static void mutex_sync_dump( struct object *obj, int verbose )
-{
- struct mutex_sync *mutex = (struct mutex_sync *)obj;
- assert( obj->ops == &mutex_sync_ops );
- fprintf( stderr, "Mutex count=%u owner=%p\n", mutex->count, mutex->owner );
-}
-
-static void mutex_sync_destroy( struct object *obj )
-{
- struct mutex_sync *mutex = (struct mutex_sync *)obj;
- assert( obj->ops == &mutex_sync_ops );
-
- if (mutex->count) do_release( mutex, current, mutex->count );
-}
-
-static int mutex_sync_signaled( struct object *obj, struct wait_queue_entry *entry )
-{
- struct mutex_sync *mutex = (struct mutex_sync *)obj;
- assert( obj->ops == &mutex_sync_ops );
- return (!mutex->count || (mutex->owner == get_wait_queue_thread( entry )));
-}
-
-static void mutex_sync_satisfied( struct object *obj, struct wait_queue_entry *entry )
-{
- struct mutex_sync *mutex = (struct mutex_sync *)obj;
- assert( obj->ops == &mutex_sync_ops );
-
- do_grab( mutex, get_wait_queue_thread( entry ));
- if (mutex->abandoned) make_wait_abandoned( entry );
- mutex->abandoned = 0;
-}
-
-static struct mutex_sync *create_mutex_sync( int owned )
-{
- struct mutex_sync *mutex;
-
- if (!(mutex = alloc_object( &mutex_sync_ops ))) return NULL;
- mutex->count = 0;
- mutex->owner = NULL;
- mutex->abandoned = 0;
- if (owned) do_grab( mutex, current );
-
- return mutex;
-}
-
-struct mutex
-{
- struct object obj; /* object header */
- struct mutex_sync *sync; /* mutex sync object */
-};
-
-static void mutex_dump( struct object *obj, int verbose );
-static struct object *mutex_get_sync( struct object *obj );
-static int mutex_signal( struct object *obj, unsigned int access );
-static void mutex_destroy( struct object *obj );
-
-static const struct object_ops mutex_ops =
-{
- sizeof(struct mutex), /* size */
- &mutex_type, /* type */
- mutex_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
- mutex_signal, /* signal */
- no_get_fd, /* get_fd */
- mutex_get_sync, /* get_sync */
- default_map_access, /* map_access */
- default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
- default_get_full_name, /* get_full_name */
- no_lookup_name, /* lookup_name */
- directory_link_name, /* link_name */
- default_unlink_name, /* unlink_name */
- no_open_file, /* open_file */
- no_kernel_obj_list, /* get_kernel_obj_list */
- no_close_handle, /* close_handle */
- mutex_destroy, /* destroy */
-};
-
static struct mutex *create_mutex( struct object *root, const struct unicode_str *name,
unsigned int attr, int owned, const struct security_descriptor *sd )
{
@@ -211,13 +132,10 @@ static struct mutex *create_mutex( struct object *root, const struct unicode_str
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- mutex->sync = NULL;
-
- if (!(mutex->sync = create_mutex_sync( owned )))
- {
- release_object( mutex );
- return NULL;
- }
+ mutex->count = 0;
+ mutex->owner = NULL;
+ mutex->abandoned = 0;
+ if (owned) do_grab( mutex, current );
}
}
return mutex;
@@ -229,7 +147,7 @@ void abandon_mutexes( struct thread *thread )
while ((ptr = list_head( &thread->mutex_list )) != NULL)
{
- struct mutex_sync *mutex = LIST_ENTRY( ptr, struct mutex_sync, entry );
+ struct mutex *mutex = LIST_ENTRY( ptr, struct mutex, entry );
assert( mutex->owner == thread );
mutex->abandoned = 1;
do_release( mutex, thread, mutex->count );
@@ -240,14 +158,24 @@ static void mutex_dump( struct object *obj, int verbose )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
- mutex->sync->obj.ops->dump( &mutex->sync->obj, verbose );
+ fprintf( stderr, "Mutex count=%u owner=%p\n", mutex->count, mutex->owner );
}
-static struct object *mutex_get_sync( struct object *obj )
+static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
- return grab_object( mutex->sync );
+ return (!mutex->count || (mutex->owner == get_wait_queue_thread( entry )));
+}
+
+static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct mutex *mutex = (struct mutex *)obj;
+ assert( obj->ops == &mutex_ops );
+
+ do_grab( mutex, get_wait_queue_thread( entry ));
+ if (mutex->abandoned) make_wait_abandoned( entry );
+ mutex->abandoned = 0;
}
static int mutex_signal( struct object *obj, unsigned int access )
@@ -260,14 +188,14 @@ static int mutex_signal( struct object *obj, unsigned int access )
set_error( STATUS_ACCESS_DENIED );
return 0;
}
- return do_release( mutex->sync, current, 1 );
+ return do_release( mutex, current, 1 );
}
static void mutex_destroy( struct object *obj )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
- if (mutex->sync) release_object( mutex->sync );
+ if (mutex->count) do_release( mutex, current, mutex->count );
}
/* create a mutex */
@@ -311,8 +239,8 @@ DECL_HANDLER(release_mutex)
if ((mutex = (struct mutex *)get_handle_obj( current->process, req->handle,
0, &mutex_ops )))
{
- reply->prev_count = mutex->sync->count;
- do_release( mutex->sync, current, 1 );
+ reply->prev_count = mutex->count;
+ do_release( mutex, current, 1 );
release_object( mutex );
}
}
@@ -325,9 +253,9 @@ DECL_HANDLER(query_mutex)
if ((mutex = (struct mutex *)get_handle_obj( current->process, req->handle,
MUTANT_QUERY_STATE, &mutex_ops )))
{
- reply->count = mutex->sync->count;
- reply->owned = (mutex->sync->owner == current);
- reply->abandoned = mutex->sync->abandoned;
+ reply->count = mutex->count;
+ reply->owned = (mutex->owner == current);
+ reply->abandoned = mutex->abandoned;
release_object( mutex );
}
--
2.50.1
From 29aa3ca8d8db7b6d293d8cd5bd211d15615fa25d Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 15:59:48 +0300
Subject: [PATCH 06/57] Revert "server: Move some checks inside of mutex
do_release."
This reverts commit e9f795e0663c7761cdbf69dc37b227a6645a3711.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/mutex.c | 44 +++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/server/mutex.c b/server/mutex.c
index 90cc594c741..4737b6f711b 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -105,21 +105,13 @@ static void do_grab( struct mutex *mutex, struct thread *thread )
}
/* release a mutex once the recursion count is 0 */
-static int do_release( struct mutex *mutex, struct thread *thread, int count )
+static void do_release( struct mutex *mutex )
{
- if (!mutex->count || (mutex->owner != thread))
- {
- set_error( STATUS_MUTANT_NOT_OWNED );
- return 0;
- }
- if (!(mutex->count -= count))
- {
- /* remove the mutex from the thread list of owned mutexes */
- list_remove( &mutex->entry );
- mutex->owner = NULL;
- wake_up( &mutex->obj, 0 );
- }
- return 1;
+ assert( !mutex->count );
+ /* remove the mutex from the thread list of owned mutexes */
+ list_remove( &mutex->entry );
+ mutex->owner = NULL;
+ wake_up( &mutex->obj, 0 );
}
static struct mutex *create_mutex( struct object *root, const struct unicode_str *name,
@@ -149,8 +141,9 @@ void abandon_mutexes( struct thread *thread )
{
struct mutex *mutex = LIST_ENTRY( ptr, struct mutex, entry );
assert( mutex->owner == thread );
+ mutex->count = 0;
mutex->abandoned = 1;
- do_release( mutex, thread, mutex->count );
+ do_release( mutex );
}
}
@@ -188,14 +181,23 @@ static int mutex_signal( struct object *obj, unsigned int access )
set_error( STATUS_ACCESS_DENIED );
return 0;
}
- return do_release( mutex, current, 1 );
+ if (!mutex->count || (mutex->owner != current))
+ {
+ set_error( STATUS_MUTANT_NOT_OWNED );
+ return 0;
+ }
+ if (!--mutex->count) do_release( mutex );
+ return 1;
}
static void mutex_destroy( struct object *obj )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
- if (mutex->count) do_release( mutex, current, mutex->count );
+
+ if (!mutex->count) return;
+ mutex->count = 0;
+ do_release( mutex );
}
/* create a mutex */
@@ -239,8 +241,12 @@ DECL_HANDLER(release_mutex)
if ((mutex = (struct mutex *)get_handle_obj( current->process, req->handle,
0, &mutex_ops )))
{
- reply->prev_count = mutex->count;
- do_release( mutex, current, 1 );
+ if (!mutex->count || (mutex->owner != current)) set_error( STATUS_MUTANT_NOT_OWNED );
+ else
+ {
+ reply->prev_count = mutex->count;
+ if (!--mutex->count) do_release( mutex );
+ }
release_object( mutex );
}
}
--
2.50.1
From 3526d932262001e27a7849115d8b81931085412c Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:01:41 +0300
Subject: [PATCH 07/57] Revert "server: Get rid of the console signaled flag."
This reverts commit ddc15b268365533cae7cc8108cb7114c00f41657.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/server/console.c b/server/console.c
index f0cb6689d4b..8c9c395ab41 100644
--- a/server/console.c
+++ b/server/console.c
@@ -54,6 +54,7 @@ struct console
{
struct object obj; /* object header */
struct event_sync *sync; /* sync object for wait/signal */
+ int signaled; /* is console signaled */
struct thread *renderer; /* console renderer thread */
struct screen_buffer *active; /* active screen buffer */
struct console_server *server; /* console server object */
@@ -544,6 +545,7 @@ static struct object *create_console(void)
if (!(console = alloc_object( &console_ops ))) return NULL;
console->sync = NULL;
console->renderer = NULL;
+ console->signaled = 0;
console->active = NULL;
console->server = NULL;
console->fd = NULL;
@@ -1588,8 +1590,16 @@ DECL_HANDLER(get_next_console_request)
if (!server->console->renderer) server->console->renderer = current;
- if (!req->signal) reset_sync( server->console->sync );
- else signal_sync( server->console->sync );
+ if (!req->signal)
+ {
+ server->console->signaled = 0;
+ reset_sync( server->console->sync );
+ }
+ else if (!server->console->signaled)
+ {
+ server->console->signaled = 1;
+ signal_sync( server->console->sync );
+ }
if (req->read)
{
--
2.50.1
From a27628cae3820cdd7339e6efba6d971fde5489a6 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:01:47 +0300
Subject: [PATCH 08/57] Revert "server: Use the console sync for console output
objects."
This reverts commit 1154224db42bedbec7b1b14239245d0ce0699d27.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/server/console.c b/server/console.c
index 8c9c395ab41..54cb091d452 100644
--- a/server/console.c
+++ b/server/console.c
@@ -365,15 +365,14 @@ static const struct fd_ops console_input_fd_ops =
struct console_output
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct fd *fd; /* pseudo-fd */
struct list entry; /* entry in console->outputs */
struct console *console; /* associated console at creation time */
};
static void console_output_dump( struct object *obj, int verbose );
+static int console_output_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *console_output_get_fd( struct object *obj );
-static struct object *console_output_get_sync( struct object *obj );
static struct object *console_output_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
static void console_output_destroy( struct object *obj );
@@ -383,13 +382,13 @@ static const struct object_ops console_output_ops =
sizeof(struct console_output), /* size */
&device_type, /* type */
console_output_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ console_output_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
console_output_get_fd, /* get_fd */
- console_output_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -1377,7 +1376,6 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni
name->len = 0;
if (!(console_output = alloc_object( &console_output_ops ))) return NULL;
- console_output->sync = (struct event_sync *)grab_object( current->process->console->sync );
console_output->fd = alloc_pseudo_fd( &console_output_fd_ops, &console_output->obj,
FILE_SYNCHRONOUS_IO_NONALERT );
if (!console_output->fd)
@@ -1511,18 +1509,19 @@ static void console_output_dump( struct object *obj, int verbose )
fputs( "console Output device\n", stderr );
}
-static struct fd *console_output_get_fd( struct object *obj )
+static int console_output_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct console_output *console_output = (struct console_output *)obj;
assert( obj->ops == &console_output_ops );
- return (struct fd *)grab_object( console_output->fd );
+ if (!console_output->console) return 0;
+ return console_output->console->signaled;
}
-static struct object *console_output_get_sync( struct object *obj )
+static struct fd *console_output_get_fd( struct object *obj )
{
struct console_output *console_output = (struct console_output *)obj;
assert( obj->ops == &console_output_ops );
- return grab_object( console_output->sync );
+ return (struct fd *)grab_object( console_output->fd );
}
static struct object *console_output_open_file( struct object *obj, unsigned int access,
@@ -1538,7 +1537,6 @@ static void console_output_destroy( struct object *obj )
assert( obj->ops == &console_output_ops );
if (console_output->fd) release_object( console_output->fd );
if (console_output->console) list_remove( &console_output->entry );
- if (console_output->sync) release_object( console_output->sync );
}
static void console_output_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
@@ -1576,6 +1574,7 @@ DECL_HANDLER(get_next_console_request)
{
struct console_host_ioctl *ioctl = NULL, *next;
struct console_server *server;
+ struct console_output *output;
struct iosb *iosb = NULL;
server = (struct console_server *)get_handle_obj( current->process, req->handle, 0, &console_server_ops );
@@ -1599,6 +1598,8 @@ DECL_HANDLER(get_next_console_request)
{
server->console->signaled = 1;
signal_sync( server->console->sync );
+ LIST_FOR_EACH_ENTRY( output, &server->console->outputs, struct console_output, entry )
+ wake_up( &output->obj, 0 );
}
if (req->read)
--
2.50.1
From 36759c9c71f26ab3d031fab1e761347995321fb8 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:01:51 +0300
Subject: [PATCH 09/57] Revert "server: Use the console sync for console input
objects."
This reverts commit abcf0d172fd930a6cd3596696965cb6fefb71c32.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/server/console.c b/server/console.c
index 54cb091d452..343ccfa7463 100644
--- a/server/console.c
+++ b/server/console.c
@@ -304,17 +304,16 @@ static const struct object_ops console_device_ops =
struct console_input
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct fd *fd; /* pseudo-fd */
struct list entry; /* entry in console->inputs */
struct console *console; /* associated console at creation time */
};
static void console_input_dump( struct object *obj, int verbose );
+static int console_input_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct object *console_input_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
static struct fd *console_input_get_fd( struct object *obj );
-static struct object *console_input_get_sync( struct object *obj );
static void console_input_destroy( struct object *obj );
static const struct object_ops console_input_ops =
@@ -322,13 +321,13 @@ static const struct object_ops console_input_ops =
sizeof(struct console_input), /* size */
&device_type, /* type */
console_input_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ console_input_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
console_input_get_fd, /* get_fd */
- console_input_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -1351,7 +1350,6 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni
name->len = 0;
if (!(console_input = alloc_object( &console_input_ops ))) return NULL;
- console_input->sync = (struct event_sync *)grab_object( current->process->console->sync );
console_input->fd = alloc_pseudo_fd( &console_input_fd_ops, &console_input->obj,
FILE_SYNCHRONOUS_IO_NONALERT );
if (!console_input->fd)
@@ -1438,18 +1436,19 @@ static void console_input_dump( struct object *obj, int verbose )
fputs( "console Input device\n", stderr );
}
-static struct fd *console_input_get_fd( struct object *obj )
+static int console_input_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct console_input *console_input = (struct console_input *)obj;
assert( obj->ops == &console_input_ops );
- return (struct fd *)grab_object( console_input->fd );
+ if (!console_input->console) return 0;
+ return console_input->console->signaled;
}
-static struct object *console_input_get_sync( struct object *obj )
+static struct fd *console_input_get_fd( struct object *obj )
{
struct console_input *console_input = (struct console_input *)obj;
assert( obj->ops == &console_input_ops );
- return grab_object( console_input->sync );
+ return (struct fd *)grab_object( console_input->fd );
}
static struct object *console_input_open_file( struct object *obj, unsigned int access,
@@ -1465,7 +1464,6 @@ static void console_input_destroy( struct object *obj )
assert( obj->ops == &console_input_ops );
if (console_input->fd) release_object( console_input->fd );
if (console_input->console) list_remove( &console_input->entry );
- if (console_input->sync) release_object( console_input->sync );
}
static void console_input_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
@@ -1575,6 +1573,7 @@ DECL_HANDLER(get_next_console_request)
struct console_host_ioctl *ioctl = NULL, *next;
struct console_server *server;
struct console_output *output;
+ struct console_input *input;
struct iosb *iosb = NULL;
server = (struct console_server *)get_handle_obj( current->process, req->handle, 0, &console_server_ops );
@@ -1598,6 +1597,8 @@ DECL_HANDLER(get_next_console_request)
{
server->console->signaled = 1;
signal_sync( server->console->sync );
+ LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
+ wake_up( &input->obj, 0 );
LIST_FOR_EACH_ENTRY( output, &server->console->outputs, struct console_output, entry )
wake_up( &output->obj, 0 );
}
--
2.50.1
From aaf8269b74b29b1105435d48af76c67514292b80 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:01:55 +0300
Subject: [PATCH 10/57] Revert "server: Use the console sync for screen buffers
objects."
This reverts commit ab6e72ea054df8e2e3917a71521527dd215eab61.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 43 +++++++++++++++++++++----------------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/server/console.c b/server/console.c
index 343ccfa7463..6b85ecc8a54 100644
--- a/server/console.c
+++ b/server/console.c
@@ -211,7 +211,6 @@ struct font_info
struct screen_buffer
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct list entry; /* entry in list of all screen buffers */
struct console *input; /* associated console input */
unsigned int id; /* buffer id */
@@ -221,8 +220,8 @@ struct screen_buffer
static void screen_buffer_dump( struct object *obj, int verbose );
static void screen_buffer_destroy( struct object *obj );
+static int screen_buffer_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *screen_buffer_get_fd( struct object *obj );
-static struct object *screen_buffer_get_sync( struct object *obj );
static struct object *screen_buffer_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
@@ -231,13 +230,13 @@ static const struct object_ops screen_buffer_ops =
sizeof(struct screen_buffer), /* size */
&file_type, /* type */
screen_buffer_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ screen_buffer_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
screen_buffer_get_fd, /* get_fd */
- screen_buffer_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -645,8 +644,9 @@ static struct object *create_screen_buffer( struct console *console )
return NULL;
}
- if (!(screen_buffer = alloc_object( &screen_buffer_ops ))) return NULL;
- screen_buffer->sync = (struct event_sync *)grab_object( console->sync );
+ if (!(screen_buffer = alloc_object( &screen_buffer_ops )))
+ return NULL;
+
screen_buffer->id = ++console->last_id;
screen_buffer->input = console;
init_async_queue( &screen_buffer->ioctl_q );
@@ -777,11 +777,7 @@ static void console_destroy( struct object *obj )
LIST_FOR_EACH_ENTRY( output, &console->outputs, struct console_output, entry )
output->console = NULL;
- if (console->sync)
- {
- reset_sync( console->sync );
- release_object( console->sync );
- }
+ if (console->sync) release_object( console->sync );
free_async_queue( &console->ioctl_q );
free_async_queue( &console->read_q );
@@ -862,10 +858,17 @@ static void screen_buffer_destroy( struct object *obj )
screen_buffer->id, NULL, NULL );
}
free_async_queue( &screen_buffer->ioctl_q );
- if (screen_buffer->sync) release_object( screen_buffer->sync );
if (screen_buffer->fd) release_object( screen_buffer->fd );
}
+static int screen_buffer_signaled( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
+ assert( obj->ops == &screen_buffer_ops );
+ if (!screen_buffer->input) return 0;
+ return screen_buffer->input->signaled;
+}
+
static struct object *screen_buffer_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options )
{
@@ -882,13 +885,6 @@ static struct fd *screen_buffer_get_fd( struct object *obj )
return NULL;
}
-static struct object *screen_buffer_get_sync( struct object *obj )
-{
- struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
- assert( obj->ops == &screen_buffer_ops );
- return grab_object( screen_buffer->sync );
-}
-
static void console_server_dump( struct object *obj, int verbose )
{
assert( obj->ops == &console_server_ops );
@@ -1571,6 +1567,7 @@ struct object *create_console_device( struct object *root, const struct unicode_
DECL_HANDLER(get_next_console_request)
{
struct console_host_ioctl *ioctl = NULL, *next;
+ struct screen_buffer *screen_buffer;
struct console_server *server;
struct console_output *output;
struct console_input *input;
@@ -1597,6 +1594,8 @@ DECL_HANDLER(get_next_console_request)
{
server->console->signaled = 1;
signal_sync( server->console->sync );
+ LIST_FOR_EACH_ENTRY( screen_buffer, &server->console->screen_buffers, struct screen_buffer, entry )
+ wake_up( &screen_buffer->obj, 0 );
LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
wake_up( &input->obj, 0 );
LIST_FOR_EACH_ENTRY( output, &server->console->outputs, struct console_output, entry )
--
2.50.1
From 68918e3522f48a9b0023406f9b20007060621480 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:03 +0300
Subject: [PATCH 11/57] Revert "server: Use an event sync for console server
objects."
This reverts commit 2c7b34959e701aabb528b5271fc97c67eb5f5bb4.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 53 +++++++++++++++++++++++-------------------------
1 file changed, 25 insertions(+), 28 deletions(-)
diff --git a/server/console.c b/server/console.c
index 6b85ecc8a54..6665d0a0836 100644
--- a/server/console.c
+++ b/server/console.c
@@ -135,7 +135,6 @@ struct console_host_ioctl
struct console_server
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct fd *fd; /* pseudo-fd for ioctls */
struct console *console; /* attached console */
struct list queue; /* ioctl queue */
@@ -148,8 +147,8 @@ struct console_server
static void console_server_dump( struct object *obj, int verbose );
static void console_server_destroy( struct object *obj );
+static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *console_server_get_fd( struct object *obj );
-static struct object *console_server_get_sync( struct object *obj );
static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
unsigned int attr, struct object *root );
static struct object *console_server_open_file( struct object *obj, unsigned int access,
@@ -160,13 +159,13 @@ static const struct object_ops console_server_ops =
sizeof(struct console_server), /* size */
&file_type, /* type */
console_server_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ console_server_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
console_server_get_fd, /* get_fd */
- console_server_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -588,7 +587,7 @@ static int queue_host_ioctl( struct console_server *server, unsigned int code, u
queue_async( queue, async );
}
list_add_tail( &server->queue, &ioctl->entry );
- signal_sync( server->sync );
+ wake_up( &server->obj, 0 );
if (async) set_error( STATUS_PENDING );
return 1;
}
@@ -620,7 +619,7 @@ static void disconnect_console_server( struct console_server *server )
assert( server->console->server == server );
server->console->server = NULL;
server->console = NULL;
- signal_sync( server->sync );
+ wake_up( &server->obj, 0 );
}
}
@@ -896,7 +895,6 @@ static void console_server_destroy( struct object *obj )
struct console_server *server = (struct console_server *)obj;
assert( obj->ops == &console_server_ops );
disconnect_console_server( server );
- if (server->sync) release_object( server->sync );
if (server->fd) release_object( server->fd );
}
@@ -932,25 +930,24 @@ static struct object *console_server_lookup_name( struct object *obj, struct uni
release_object( screen_buffer );
server->console->server = server;
- if (list_empty( &server->queue )) reset_sync( server->sync );
return &server->console->obj;
}
return NULL;
}
-static struct fd *console_server_get_fd( struct object* obj )
+static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct console_server *server = (struct console_server*)obj;
assert( obj->ops == &console_server_ops );
- return (struct fd *)grab_object( server->fd );
+ return !server->console || !list_empty( &server->queue );
}
-static struct object *console_server_get_sync( struct object *obj )
+static struct fd *console_server_get_fd( struct object* obj )
{
- struct console_server *server = (struct console_server *)obj;
+ struct console_server *server = (struct console_server*)obj;
assert( obj->ops == &console_server_ops );
- return grab_object( server->sync );
+ return (struct fd *)grab_object( server->fd );
}
static struct object *console_server_open_file( struct object *obj, unsigned int access,
@@ -964,23 +961,21 @@ static struct object *create_console_server( void )
struct console_server *server;
if (!(server = alloc_object( &console_server_ops ))) return NULL;
- server->sync = NULL;
- server->fd = NULL;
server->console = NULL;
server->busy = 0;
server->once_input = 0;
server->term_fd = -1;
list_init( &server->queue );
list_init( &server->read_queue );
-
- if (!(server->sync = create_event_sync( 1, 1 ))) goto error;
- if (!(server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT ))) goto error;
+ server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT );
+ if (!server->fd)
+ {
+ release_object( server );
+ return NULL;
+ }
allow_fd_caching(server->fd);
- return &server->obj;
-error:
- release_object( server );
- return NULL;
+ return &server->obj;
}
static int is_blocking_read_ioctl( unsigned int code )
@@ -1644,7 +1639,11 @@ DECL_HANDLER(get_next_console_request)
free( ioctl );
if (iosb) release_object( iosb );
- if (req->read) goto done;
+ if (req->read)
+ {
+ release_object( server );
+ return;
+ }
server->busy = 0;
}
@@ -1703,7 +1702,5 @@ DECL_HANDLER(get_next_console_request)
set_error( STATUS_PENDING );
}
-done:
- if (list_empty( &server->queue )) reset_sync( server->sync );
release_object( server );
}
--
2.50.1
From dc77362bd5e6fe3ac99963b90b9344cc305f8bbf Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:08 +0300
Subject: [PATCH 12/57] Revert "server: Use an event sync for console objects."
This reverts commit 3cbcd8de50ce97cd65bc5a3b6ccf09f0110b7a31.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 67 ++++++++++++++++++++++++------------------------
1 file changed, 33 insertions(+), 34 deletions(-)
diff --git a/server/console.c b/server/console.c
index 6665d0a0836..d3c5317728e 100644
--- a/server/console.c
+++ b/server/console.c
@@ -53,7 +53,6 @@ struct history_line
struct console
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
int signaled; /* is console signaled */
struct thread *renderer; /* console renderer thread */
struct screen_buffer *active; /* active screen buffer */
@@ -69,25 +68,26 @@ struct console
static void console_dump( struct object *obj, int verbose );
static void console_destroy( struct object *obj );
+static int console_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *console_get_fd( struct object *obj );
-static struct object *console_get_sync( struct object *obj );
static struct object *console_lookup_name( struct object *obj, struct unicode_str *name,
unsigned int attr, struct object *root );
static struct object *console_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
+static int console_add_queue( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops console_ops =
{
sizeof(struct console), /* size */
&file_type, /* type */
console_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ console_add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ console_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
console_get_fd, /* get_fd */
- console_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -479,18 +479,10 @@ static const struct fd_ops console_connection_fd_ops =
static int queue_host_ioctl( struct console_server *server, unsigned int code, unsigned int output,
struct async *async, struct async_queue *queue );
-static struct fd *console_get_fd( struct object *obj )
+static int console_add_queue( struct object *obj, struct wait_queue_entry *entry )
{
- struct console *console = (struct console *)obj;
+ struct console *console = (struct console*)obj;
assert( obj->ops == &console_ops );
- return (struct fd *)grab_object( console->fd );
-}
-
-static struct object *console_get_sync( struct object *obj )
-{
- struct console *console = (struct console *)obj;
- assert( obj->ops == &console_ops );
-
/* before waiting, ensure conhost's input thread has been started */
if (console->server && !console->server->once_input)
{
@@ -498,8 +490,20 @@ static struct object *console_get_sync( struct object *obj )
if (console->server->term_fd == -1)
queue_host_ioctl( console->server, IOCTL_CONDRV_PEEK, 0, NULL, NULL );
}
+ return add_queue( &console->obj, entry );
+}
+
+static int console_signaled( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct console *console = (struct console*)obj;
+ return console->signaled;
+}
- return grab_object( console->sync );
+static struct fd *console_get_fd( struct object *obj )
+{
+ struct console *console = (struct console *)obj;
+ assert( obj->ops == &console_ops );
+ return (struct fd *)grab_object( console->fd );
}
static enum server_fd_type console_get_fd_type( struct fd *fd )
@@ -538,8 +542,9 @@ static struct object *create_console(void)
{
struct console *console;
- if (!(console = alloc_object( &console_ops ))) return NULL;
- console->sync = NULL;
+ if (!(console = alloc_object( &console_ops )))
+ return NULL;
+
console->renderer = NULL;
console->signaled = 0;
console->active = NULL;
@@ -552,14 +557,14 @@ static struct object *create_console(void)
init_async_queue( &console->ioctl_q );
init_async_queue( &console->read_q );
- if (!(console->sync = create_event_sync( 1, 0 ))) goto error;
- if (!(console->fd = alloc_pseudo_fd( &console_fd_ops, &console->obj, FILE_SYNCHRONOUS_IO_NONALERT ))) goto error;
+ console->fd = alloc_pseudo_fd( &console_fd_ops, &console->obj, FILE_SYNCHRONOUS_IO_NONALERT );
+ if (!console->fd)
+ {
+ release_object( console );
+ return NULL;
+ }
allow_fd_caching( console->fd );
return &console->obj;
-
-error:
- release_object( console );
- return NULL;
}
static void console_host_ioctl_terminate( struct console_host_ioctl *call, unsigned int status )
@@ -776,8 +781,6 @@ static void console_destroy( struct object *obj )
LIST_FOR_EACH_ENTRY( output, &console->outputs, struct console_output, entry )
output->console = NULL;
- if (console->sync) release_object( console->sync );
-
free_async_queue( &console->ioctl_q );
free_async_queue( &console->read_q );
if (console->fd)
@@ -1580,15 +1583,11 @@ DECL_HANDLER(get_next_console_request)
if (!server->console->renderer) server->console->renderer = current;
- if (!req->signal)
- {
- server->console->signaled = 0;
- reset_sync( server->console->sync );
- }
+ if (!req->signal) server->console->signaled = 0;
else if (!server->console->signaled)
{
server->console->signaled = 1;
- signal_sync( server->console->sync );
+ wake_up( &server->console->obj, 0 );
LIST_FOR_EACH_ENTRY( screen_buffer, &server->console->screen_buffers, struct screen_buffer, entry )
wake_up( &screen_buffer->obj, 0 );
LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
--
2.50.1
From cea799238cf44c3fa600cd1549d8d550a80497ec Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:18 +0300
Subject: [PATCH 13/57] Revert "server: Use an event sync for timer objects."
This reverts commit 2cf619e2e4bf5695770d75482a1302fa7279c944.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/timer.c | 37 ++++++++++++++++++-------------------
1 file changed, 18 insertions(+), 19 deletions(-)
diff --git a/server/timer.c b/server/timer.c
index 522fc6a7113..f85fa66ed47 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -53,7 +53,6 @@ struct type_descr timer_type =
struct timer
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
int manual; /* manual reset */
int signaled; /* current signaled state */
unsigned int period; /* timer period in ms */
@@ -65,7 +64,8 @@ struct timer
};
static void timer_dump( struct object *obj, int verbose );
-static struct object *timer_get_sync( struct object *obj );
+static int timer_signaled( struct object *obj, struct wait_queue_entry *entry );
+static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry );
static void timer_destroy( struct object *obj );
static const struct object_ops timer_ops =
@@ -73,13 +73,13 @@ static const struct object_ops timer_ops =
sizeof(struct timer), /* size */
&timer_type, /* type */
timer_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ timer_signaled, /* signaled */
+ timer_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- timer_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -105,19 +105,12 @@ static struct timer *create_timer( struct object *root, const struct unicode_str
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- timer->sync = NULL;
timer->manual = manual;
timer->signaled = 0;
timer->when = 0;
timer->period = 0;
timer->timeout = NULL;
timer->thread = NULL;
-
- if (!(timer->sync = create_event_sync( manual, 0 )))
- {
- release_object( timer );
- return NULL;
- }
}
}
return timer;
@@ -157,8 +150,9 @@ static void timer_callback( void *private )
}
else timer->timeout = NULL;
+ /* wake up waiters */
timer->signaled = 1;
- signal_sync( timer->sync );
+ wake_up( &timer->obj, 0 );
}
/* cancel a running timer */
@@ -189,7 +183,6 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
{
period = 0; /* period doesn't make any sense for a manual timer */
timer->signaled = 0;
- reset_sync( timer->sync );
}
timer->when = (expire <= 0) ? expire - monotonic_time : max( expire, current_time );
timer->period = period;
@@ -210,11 +203,18 @@ static void timer_dump( struct object *obj, int verbose )
timer->manual, get_timeout_str(timeout), timer->period );
}
-static struct object *timer_get_sync( struct object *obj )
+static int timer_signaled( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct timer *timer = (struct timer *)obj;
+ assert( obj->ops == &timer_ops );
+ return timer->signaled;
+}
+
+static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
struct timer *timer = (struct timer *)obj;
assert( obj->ops == &timer_ops );
- return grab_object( timer->sync );
+ if (!timer->manual) timer->signaled = 0;
}
static void timer_destroy( struct object *obj )
@@ -224,7 +224,6 @@ static void timer_destroy( struct object *obj )
if (timer->timeout) remove_timeout_user( timer->timeout );
if (timer->thread) release_object( timer->thread );
- if (timer->sync) release_object( timer->sync );
}
/* create a timer */
--
2.50.1
From 0bd35d3c4cd372af6b41af64cc13975c9bca9889 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:22 +0300
Subject: [PATCH 14/57] Revert "server: Use an event sync for completion port
objects."
This reverts commit 863366bb5e5dcb6779574e5c4ee2c22c2dae925d.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/completion.c | 44 ++++++++++++++++++--------------------------
1 file changed, 18 insertions(+), 26 deletions(-)
diff --git a/server/completion.c b/server/completion.c
index a2028a89823..fd623b36d5a 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -72,11 +72,11 @@ struct completion_wait
struct completion
{
- struct object obj;
- struct event_sync *sync;
- struct list queue;
- struct list wait_queue;
- unsigned int depth;
+ struct object obj;
+ struct list queue;
+ struct list wait_queue;
+ unsigned int depth;
+ int closed;
};
static void completion_wait_dump( struct object*, int );
@@ -155,7 +155,7 @@ static void completion_wait_satisfied( struct object *obj, struct wait_queue_ent
}
static void completion_dump( struct object*, int );
-static struct object *completion_get_sync( struct object * );
+static int completion_signaled( struct object *obj, struct wait_queue_entry *entry );
static int completion_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
static void completion_destroy( struct object * );
@@ -164,13 +164,13 @@ static const struct object_ops completion_ops =
sizeof(struct completion), /* size */
&completion_type, /* type */
completion_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ completion_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- completion_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -193,8 +193,6 @@ static void completion_destroy( struct object *obj)
{
free( tmp );
}
-
- if (completion->sync) release_object( completion->sync );
}
static void completion_dump( struct object *obj, int verbose )
@@ -205,11 +203,11 @@ static void completion_dump( struct object *obj, int verbose )
fprintf( stderr, "Completion depth=%u\n", completion->depth );
}
-static struct object *completion_get_sync( struct object *obj )
+static int completion_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct completion *completion = (struct completion *)obj;
- assert( obj->ops == &completion_ops );
- return grab_object( completion->sync );
+
+ return !list_empty( &completion->queue ) || completion->closed;
}
static int completion_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
@@ -230,7 +228,8 @@ static int completion_close_handle( struct object *obj, struct process *process,
cleanup_thread_completion( wait->thread );
}
}
- signal_sync( completion->sync );
+ completion->closed = 1;
+ wake_up( obj, 0 );
return 1;
}
@@ -274,16 +273,10 @@ static struct completion *create_completion( struct object *root, const struct u
{
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
- completion->sync = NULL;
list_init( &completion->queue );
list_init( &completion->wait_queue );
completion->depth = 0;
-
- if (!(completion->sync = create_event_sync( 1, 0 )))
- {
- release_object( completion );
- return NULL;
- }
+ completion->closed = 0;
}
}
@@ -316,7 +309,7 @@ void add_completion( struct completion *completion, apc_param_t ckey, apc_param_
wake_up( &wait->obj, 1 );
if (list_empty( &completion->queue )) return;
}
- if (!list_empty( &completion->queue )) signal_sync( completion->sync );
+ if (!list_empty( &completion->queue )) wake_up( &completion->obj, 0 );
}
/* create a completion */
@@ -417,7 +410,6 @@ DECL_HANDLER(remove_completion)
reply->information = msg->information;
free( msg );
reply->wait_handle = 0;
- if (list_empty( &completion->queue )) reset_sync( completion->sync );
}
release_object( completion );
--
2.50.1
From 4e5ebe8dd41014b0113eb0aa47a1277a765af416 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:26 +0300
Subject: [PATCH 15/57] Revert "server: Use an event sync for device manager
objects."
This reverts commit a508517830acca5246f7a70a9f2730d1c4977a3b.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/device.c | 34 ++++++++++------------------------
1 file changed, 10 insertions(+), 24 deletions(-)
diff --git a/server/device.c b/server/device.c
index f4b3f19028b..892ec98c44f 100644
--- a/server/device.c
+++ b/server/device.c
@@ -89,7 +89,6 @@ static const struct object_ops irp_call_ops =
struct device_manager
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct list devices; /* list of devices */
struct list requests; /* list of pending irps across all devices */
struct irp_call *current_call; /* call currently executed on client side */
@@ -97,7 +96,7 @@ struct device_manager
};
static void device_manager_dump( struct object *obj, int verbose );
-static struct object *device_manager_get_sync( struct object *obj );
+static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry );
static void device_manager_destroy( struct object *obj );
static const struct object_ops device_manager_ops =
@@ -105,13 +104,13 @@ static const struct object_ops device_manager_ops =
sizeof(struct device_manager), /* size */
&no_type, /* type */
device_manager_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ device_manager_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- device_manager_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -423,7 +422,7 @@ static void add_irp_to_queue( struct device_manager *manager, struct irp_call *i
irp->thread = thread ? (struct thread *)grab_object( thread ) : NULL;
if (irp->file) list_add_tail( &irp->file->requests, &irp->dev_entry );
list_add_tail( &manager->requests, &irp->mgr_entry );
- if (list_head( &manager->requests ) == &irp->mgr_entry) signal_sync( manager->sync );
+ if (list_head( &manager->requests ) == &irp->mgr_entry) wake_up( &manager->obj, 0 ); /* first one */
}
static struct object *device_open_file( struct object *obj, unsigned int access,
@@ -753,7 +752,6 @@ struct object *create_unix_device( struct object *root, const struct unicode_str
/* terminate requests when the underlying device is deleted */
static void delete_file( struct device_file *file )
{
- struct device_manager *manager = file->device->manager;
struct irp_call *irp, *next;
/* the pending requests may be the only thing holding a reference to the file */
@@ -766,7 +764,6 @@ static void delete_file( struct device_file *file )
set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 );
}
- if (list_empty( &manager->requests )) reset_sync( manager->sync );
release_object( file );
}
@@ -791,11 +788,11 @@ static void device_manager_dump( struct object *obj, int verbose )
fprintf( stderr, "Device manager\n" );
}
-static struct object *device_manager_get_sync( struct object *obj )
+static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct device_manager *manager = (struct device_manager *)obj;
- assert( obj->ops == &device_manager_ops );
- return grab_object( manager->sync );
+
+ return !list_empty( &manager->requests );
}
static void device_manager_destroy( struct object *obj )
@@ -832,8 +829,6 @@ static void device_manager_destroy( struct object *obj )
assert( !irp->file && !irp->async );
release_object( irp );
}
-
- if (manager->sync) release_object( manager->sync );
}
static struct device_manager *create_device_manager(void)
@@ -842,17 +837,10 @@ static struct device_manager *create_device_manager(void)
if ((manager = alloc_object( &device_manager_ops )))
{
- manager->sync = NULL;
manager->current_call = NULL;
list_init( &manager->devices );
list_init( &manager->requests );
wine_rb_init( &manager->kernel_objects, compare_kernel_object );
-
- if (!(manager->sync = create_event_sync( 1, 0 )))
- {
- release_object( manager );
- return NULL;
- }
}
return manager;
}
@@ -1039,8 +1027,6 @@ DECL_HANDLER(get_next_device_request)
}
list_remove( &irp->mgr_entry );
list_init( &irp->mgr_entry );
- if (list_empty( &manager->requests )) reset_sync( manager->sync );
-
/* we already own the object if it's only on manager queue */
if (irp->file) grab_object( irp );
manager->current_call = irp;
--
2.50.1
From 5158d277e0432aa836a90d3ccb63b51842772e2e Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:31 +0300
Subject: [PATCH 16/57] Revert "server: Use an event sync for debug objects."
This reverts commit 3e1da591b28da1c8736962b9d1e4faaccdaa9f54.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/debugger.c | 31 ++++++++++---------------------
1 file changed, 10 insertions(+), 21 deletions(-)
diff --git a/server/debugger.c b/server/debugger.c
index 2956ee17b8e..5f8b0ffc8fe 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -70,7 +70,6 @@ struct type_descr debug_obj_type =
struct debug_obj
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct list event_queue; /* pending events queue */
unsigned int flags; /* debug flags */
};
@@ -106,7 +105,7 @@ static const struct object_ops debug_event_ops =
};
static void debug_obj_dump( struct object *obj, int verbose );
-static struct object *debug_obj_get_sync( struct object *obj );
+static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry );
static void debug_obj_destroy( struct object *obj );
static const struct object_ops debug_obj_ops =
@@ -114,13 +113,13 @@ static const struct object_ops debug_obj_ops =
sizeof(struct debug_obj), /* size */
&debug_obj_type, /* type */
debug_obj_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ debug_obj_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- debug_obj_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -256,7 +255,7 @@ static void link_event( struct debug_obj *debug_obj, struct debug_event *event )
{
/* grab reference since debugger could be killed while trying to wake up */
grab_object( debug_obj );
- signal_sync( debug_obj->sync );
+ wake_up( &debug_obj->obj, 0 );
release_object( debug_obj );
}
}
@@ -269,7 +268,7 @@ static void resume_event( struct debug_obj *debug_obj, struct debug_event *event
if (!event->sender->process->debug_event)
{
grab_object( debug_obj );
- signal_sync( debug_obj->sync );
+ wake_up( &debug_obj->obj, 0 );
release_object( debug_obj );
}
}
@@ -330,11 +329,11 @@ static void debug_obj_dump( struct object *obj, int verbose )
debug_obj->event_queue.next, debug_obj->event_queue.prev );
}
-static struct object *debug_obj_get_sync( struct object *obj )
+static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct debug_obj *debug_obj = (struct debug_obj *)obj;
assert( obj->ops == &debug_obj_ops );
- return grab_object( debug_obj->sync );
+ return find_event_to_send( debug_obj ) != NULL;
}
static void debug_obj_destroy( struct object *obj )
@@ -349,8 +348,6 @@ static void debug_obj_destroy( struct object *obj )
/* free all pending events */
while ((ptr = list_head( &debug_obj->event_queue )))
unlink_event( debug_obj, LIST_ENTRY( ptr, struct debug_event, entry ));
-
- if (debug_obj->sync) release_object( debug_obj->sync );
}
struct debug_obj *get_debug_obj( struct process *process, obj_handle_t handle, unsigned int access )
@@ -368,15 +365,8 @@ static struct debug_obj *create_debug_obj( struct object *root, const struct uni
{
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
- debug_obj->sync = NULL;
debug_obj->flags = flags;
list_init( &debug_obj->event_queue );
-
- if (!(debug_obj->sync = create_event_sync( 1, 0 )))
- {
- release_object( debug_obj );
- return NULL;
- }
}
}
return debug_obj;
@@ -594,7 +584,6 @@ DECL_HANDLER(wait_debug_event)
reply->tid = get_thread_id( event->sender );
alloc_event_handles( event, current->process );
set_reply_data( &event->data, min( get_reply_max_size(), sizeof(event->data) ));
- if (!find_event_to_send( debug_obj )) reset_sync( debug_obj->sync );
}
else
{
--
2.50.1
From 7a982b335129bb5c23820e0555711ec065ee0636 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:35 +0300
Subject: [PATCH 17/57] Revert "server: Use an event sync for debug event
objects."
This reverts commit 61e52ce7674a82248623bab434eecff8402fecd7.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/debugger.c | 33 ++++++++++-----------------------
1 file changed, 10 insertions(+), 23 deletions(-)
diff --git a/server/debugger.c b/server/debugger.c
index 5f8b0ffc8fe..43d01fbf246 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -43,7 +43,6 @@ enum debug_event_state { EVENT_QUEUED, EVENT_SENT, EVENT_DELAYED, EVENT_CONTINUE
struct debug_event
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct list entry; /* entry in event queue */
struct thread *sender; /* thread which sent this event */
struct file *file; /* file object for events that need one */
@@ -76,7 +75,7 @@ struct debug_obj
static void debug_event_dump( struct object *obj, int verbose );
-static struct object *debug_event_get_sync( struct object *obj );
+static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry );
static void debug_event_destroy( struct object *obj );
static const struct object_ops debug_event_ops =
@@ -84,13 +83,13 @@ static const struct object_ops debug_event_ops =
sizeof(struct debug_event), /* size */
&no_type, /* type */
debug_event_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ debug_event_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- debug_event_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -264,7 +263,6 @@ static void link_event( struct debug_obj *debug_obj, struct debug_event *event )
static void resume_event( struct debug_obj *debug_obj, struct debug_event *event )
{
event->state = EVENT_QUEUED;
- reset_sync( event->sync );
if (!event->sender->process->debug_event)
{
grab_object( debug_obj );
@@ -277,7 +275,6 @@ static void resume_event( struct debug_obj *debug_obj, struct debug_event *event
static void delay_event( struct debug_obj *debug_obj, struct debug_event *event )
{
event->state = EVENT_DELAYED;
- reset_sync( event->sync );
if (event->sender->process->debug_event == event) event->sender->process->debug_event = NULL;
}
@@ -304,11 +301,11 @@ static void debug_event_dump( struct object *obj, int verbose )
debug_event->sender, debug_event->data.code, debug_event->state );
}
-static struct object *debug_event_get_sync( struct object *obj )
+static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct debug_event *debug_event = (struct debug_event *)obj;
assert( obj->ops == &debug_event_ops );
- return grab_object( debug_event->sync );
+ return debug_event->state == EVENT_CONTINUED;
}
static void debug_event_destroy( struct object *obj )
@@ -316,7 +313,6 @@ static void debug_event_destroy( struct object *obj )
struct debug_event *event = (struct debug_event *)obj;
assert( obj->ops == &debug_event_ops );
- if (event->sync) release_object( event->sync );
if (event->file) release_object( event->file );
release_object( event->sender );
}
@@ -412,7 +408,7 @@ static int continue_debug_event( struct debug_obj *debug_obj, struct process *pr
assert( event->sender->process->debug_event == event );
event->status = status;
event->state = EVENT_CONTINUED;
- signal_sync( event->sync );
+ wake_up( &event->obj, 0 );
unlink_event( debug_obj, event );
resume_process( process );
return 1;
@@ -433,20 +429,12 @@ static struct debug_event *alloc_debug_event( struct thread *thread, int code, c
/* build the event */
if (!(event = alloc_object( &debug_event_ops ))) return NULL;
- event->sync = NULL;
event->state = EVENT_QUEUED;
event->sender = (struct thread *)grab_object( thread );
event->file = NULL;
memset( &event->data, 0, sizeof(event->data) );
fill_debug_event[code - DbgCreateThreadStateChange]( event, arg );
event->data.code = code;
-
- if (!(event->sync = create_event_sync( 1, 0 )))
- {
- release_object( event );
- return NULL;
- }
-
return event;
}
@@ -532,7 +520,7 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj )
assert( event->state != EVENT_CONTINUED );
event->status = DBG_CONTINUE;
event->state = EVENT_CONTINUED;
- signal_sync( event->sync );
+ wake_up( &event->obj, 0 );
unlink_event( debug_obj, event );
/* from queued debug event */
resume_process( process );
@@ -578,7 +566,6 @@ DECL_HANDLER(wait_debug_event)
if ((event = find_event_to_send( debug_obj )))
{
event->state = EVENT_SENT;
- reset_sync( event->sync );
event->sender->process->debug_event = event;
reply->pid = get_process_id( event->sender->process );
reply->tid = get_thread_id( event->sender );
--
2.50.1
From 5b480686d652229fad9849f6ebd36f8609d90ac0 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:40 +0300
Subject: [PATCH 18/57] Revert "server: Use an event sync for file lock
objects."
This reverts commit d71bddb52069b8b0a61cef5c2a65d5b30e9662a2.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/fd.c | 43 ++++++++++++++++---------------------------
1 file changed, 16 insertions(+), 27 deletions(-)
diff --git a/server/fd.c b/server/fd.c
index 3febfdad266..8b9133e102b 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -278,7 +278,6 @@ static const struct object_ops inode_ops =
struct file_lock
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct fd *fd; /* fd owning this lock */
struct list fd_entry; /* entry in list of locks on a given fd */
struct list inode_entry; /* entry in inode list of locks */
@@ -290,21 +289,20 @@ struct file_lock
};
static void file_lock_dump( struct object *obj, int verbose );
-static struct object *file_lock_get_sync( struct object *obj );
-static void file_lock_destroy( struct object *obj );
+static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops file_lock_ops =
{
sizeof(struct file_lock), /* size */
&no_type, /* type */
file_lock_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ file_lock_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- file_lock_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -315,7 +313,7 @@ static const struct object_ops file_lock_ops =
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
no_close_handle, /* close_handle */
- file_lock_destroy, /* destroy */
+ no_destroy /* destroy */
};
@@ -1323,18 +1321,11 @@ static void file_lock_dump( struct object *obj, int verbose )
fprintf( stderr, "\n" );
}
-static struct object *file_lock_get_sync( struct object *obj )
+static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct file_lock *lock = (struct file_lock *)obj;
- assert( obj->ops == &file_lock_ops );
- return grab_object( lock->sync );
-}
-
-static void file_lock_destroy( struct object *obj )
-{
- struct file_lock *lock = (struct file_lock *)obj;
- assert( obj->ops == &file_lock_ops );
- if (lock->sync) release_object( lock->sync );
+ /* lock is signaled if it has lost its owner */
+ return !lock->process;
}
/* set (or remove) a Unix lock if possible for the given range */
@@ -1516,24 +1507,22 @@ static struct file_lock *add_lock( struct fd *fd, int shared, file_pos_t start,
struct file_lock *lock;
if (!(lock = alloc_object( &file_lock_ops ))) return NULL;
- lock->sync = NULL;
lock->shared = shared;
lock->start = start;
lock->end = end;
lock->fd = fd;
lock->process = current->process;
- if (!(lock->sync = create_event_sync( 1, 0 ))) goto error;
/* now try to set a Unix lock */
- if (!set_unix_lock( lock->fd, lock->start, lock->end, lock->shared ? F_RDLCK : F_WRLCK )) goto error;
+ if (!set_unix_lock( lock->fd, lock->start, lock->end, lock->shared ? F_RDLCK : F_WRLCK ))
+ {
+ release_object( lock );
+ return NULL;
+ }
list_add_tail( &fd->locks, &lock->fd_entry );
list_add_tail( &fd->inode->locks, &lock->inode_entry );
list_add_tail( &lock->process->locks, &lock->proc_entry );
return lock;
-
-error:
- release_object( lock );
- return NULL;
}
/* remove an existing lock */
@@ -1547,7 +1536,7 @@ static void remove_lock( struct file_lock *lock, int remove_unix )
if (remove_unix) remove_unix_locks( lock->fd, lock->start, lock->end );
if (list_empty( &inode->locks )) inode_close_pending( inode, 1 );
lock->process = NULL;
- signal_sync( lock->sync );
+ wake_up( &lock->obj, 0 );
release_object( lock );
}
--
2.50.1
From 51360b00486f97898b2df5feb5b85abbabc14e5b Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:45 +0300
Subject: [PATCH 19/57] Revert "server: Use an event sync for startup info
objects."
This reverts commit 3d8543646f9a43a81b7e51d927962e7eb0331c50.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/process.c | 38 ++++++++++++++------------------------
1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/server/process.c b/server/process.c
index 37a75dc1c45..bc74c89600f 100644
--- a/server/process.c
+++ b/server/process.c
@@ -139,16 +139,15 @@ static const struct fd_ops process_fd_ops =
struct startup_info
{
- struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
- struct process *process; /* created process */
- data_size_t info_size; /* size of startup info */
- data_size_t data_size; /* size of whole startup data */
- struct startup_info_data *data; /* data for startup info */
+ struct object obj; /* object header */
+ struct process *process; /* created process */
+ data_size_t info_size; /* size of startup info */
+ data_size_t data_size; /* size of whole startup data */
+ struct startup_info_data *data; /* data for startup info */
};
static void startup_info_dump( struct object *obj, int verbose );
-static struct object *startup_info_get_sync( struct object *obj );
+static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry );
static void startup_info_destroy( struct object *obj );
static const struct object_ops startup_info_ops =
@@ -156,13 +155,13 @@ static const struct object_ops startup_info_ops =
sizeof(struct startup_info), /* size */
&no_type, /* type */
startup_info_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ startup_info_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- startup_info_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -564,7 +563,7 @@ static void set_process_startup_state( struct process *process, enum startup_sta
if (process->startup_state == STARTUP_IN_PROGRESS) process->startup_state = state;
if (process->startup_info)
{
- signal_sync( process->startup_info->sync );
+ wake_up( &process->startup_info->obj, 0 );
release_object( process->startup_info );
process->startup_info = NULL;
}
@@ -889,7 +888,6 @@ static void startup_info_destroy( struct object *obj )
assert( obj->ops == &startup_info_ops );
free( info->data );
if (info->process) release_object( info->process );
- if (info->sync) release_object( info->sync );
}
static void startup_info_dump( struct object *obj, int verbose )
@@ -904,11 +902,10 @@ static void startup_info_dump( struct object *obj, int verbose )
fputc( '\n', stderr );
}
-static struct object *startup_info_get_sync( struct object *obj )
+static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct startup_info *info = (struct startup_info *)obj;
- assert( obj->ops == &startup_info_ops );
- return grab_object( info->sync );
+ return info->process && info->process->startup_state != STARTUP_IN_PROGRESS;
}
/* get a process from an id (and increment the refcount) */
@@ -1218,16 +1215,9 @@ DECL_HANDLER(new_process)
release_object( parent );
return;
}
- info->sync = NULL;
info->process = NULL;
info->data = NULL;
- if (!(info->sync = create_event_sync( 1, 0 )))
- {
- close( socket_fd );
- goto done;
- }
-
info_ptr = get_req_data_after_objattr( objattr, &info->data_size );
if ((req->handles_size & 3) || req->handles_size > info->data_size)
--
2.50.1
From 35d9372af8a8b47a62c189f5cdae4a0886b0bfc8 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:50 +0300
Subject: [PATCH 20/57] Revert "server: Use an event sync for process objects."
This reverts commit 712d996b829712f3e6cc80d085430a45b864fd6e.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/process.c | 22 +++++++++-------------
server/process.h | 1 -
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/server/process.c b/server/process.c
index bc74c89600f..aefe077440a 100644
--- a/server/process.c
+++ b/server/process.c
@@ -90,7 +90,7 @@ struct type_descr process_type =
};
static void process_dump( struct object *obj, int verbose );
-static struct object *process_get_sync( struct object *obj );
+static int process_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int process_map_access( struct object *obj, unsigned int access );
static struct security_descriptor *process_get_sd( struct object *obj );
static void process_poll_event( struct fd *fd, int event );
@@ -103,13 +103,13 @@ static const struct object_ops process_ops =
sizeof(struct process), /* size */
&process_type, /* type */
process_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ process_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- process_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
process_map_access, /* map_access */
process_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -662,7 +662,6 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
close( fd );
goto error;
}
- process->sync = NULL;
process->parent_id = 0;
process->debug_obj = NULL;
process->debug_event = NULL;
@@ -721,7 +720,6 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
goto error;
}
if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj, 0 ))) goto error;
- if (!(process->sync = create_event_sync( 1, 0 ))) goto error;
/* create the handle table */
if (!parent)
@@ -795,7 +793,6 @@ static void process_destroy( struct object *obj )
if (process->idle_event) release_object( process->idle_event );
if (process->id) free_ptid( process->id );
if (process->token) release_object( process->token );
- if (process->sync) release_object( process->sync );
list_remove( &process->rawinput_entry );
free( process->rawinput_devices );
free( process->dir_cache );
@@ -811,11 +808,10 @@ static void process_dump( struct object *obj, int verbose )
fprintf( stderr, "Process id=%04x handles=%p\n", process->id, process->handles );
}
-static struct object *process_get_sync( struct object *obj )
+static int process_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct process *process = (struct process *)obj;
- assert( obj->ops == &process_ops );
- return grab_object( process->sync );
+ return !process->running_threads;
}
static unsigned int process_map_access( struct object *obj, unsigned int access )
@@ -997,7 +993,7 @@ static void process_killed( struct process *process )
finish_process_tracing( process );
release_job_process( process );
start_sigkill_timer( process );
- signal_sync( process->sync );
+ wake_up( &process->obj, 0 );
}
/* add a thread to a process running threads list */
diff --git a/server/process.h b/server/process.h
index 2564a4f96d1..dfe8d628538 100644
--- a/server/process.h
+++ b/server/process.h
@@ -36,7 +36,6 @@ enum startup_state { STARTUP_IN_PROGRESS, STARTUP_DONE, STARTUP_ABORTED };
struct process
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct list entry; /* entry in system-wide process list */
process_id_t parent_id; /* parent process id (at the time of creation) */
struct list thread_list; /* thread list */
--
2.50.1
From b535b420edd2081ab0193e571dcdb0ba7df44b84 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:02:57 +0300
Subject: [PATCH 21/57] Revert "server: Use an event sync for job objects."
This reverts commit ddb2e9d332cef8d7ea5811c6650ea06e8f68166c.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/process.c | 54 +++++++++++++++++++++---------------------------
1 file changed, 23 insertions(+), 31 deletions(-)
diff --git a/server/process.c b/server/process.c
index aefe077440a..f90e725ca93 100644
--- a/server/process.c
+++ b/server/process.c
@@ -192,24 +192,24 @@ struct type_descr job_type =
};
static void job_dump( struct object *obj, int verbose );
-static struct object *job_get_sync( struct object *obj );
+static int job_signaled( struct object *obj, struct wait_queue_entry *entry );
static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
static void job_destroy( struct object *obj );
struct job
{
- struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
- struct list process_list; /* list of processes */
- int num_processes; /* count of running processes */
- int total_processes; /* count of processes which have been assigned */
- unsigned int limit_flags; /* limit flags */
- int terminating; /* job is terminating */
- struct completion *completion_port; /* associated completion port */
- apc_param_t completion_key; /* key to send with completion messages */
- struct job *parent;
- struct list parent_job_entry; /* list entry for parent job */
- struct list child_job_list; /* list of child jobs */
+ struct object obj; /* object header */
+ struct list process_list; /* list of processes */
+ int num_processes; /* count of running processes */
+ int total_processes; /* count of processes which have been assigned */
+ unsigned int limit_flags; /* limit flags */
+ int terminating; /* job is terminating */
+ int signaled; /* job is signaled */
+ struct completion *completion_port; /* associated completion port */
+ apc_param_t completion_key; /* key to send with completion messages */
+ struct job *parent;
+ struct list parent_job_entry; /* list entry for parent job */
+ struct list child_job_list; /* list of child jobs */
};
static const struct object_ops job_ops =
@@ -217,13 +217,13 @@ static const struct object_ops job_ops =
sizeof(struct job), /* size */
&job_type, /* type */
job_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ job_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- job_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -247,22 +247,16 @@ static struct job *create_job_object( struct object *root, const struct unicode_
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- job->sync = NULL;
list_init( &job->process_list );
list_init( &job->child_job_list );
job->num_processes = 0;
job->total_processes = 0;
job->limit_flags = 0;
job->terminating = 0;
+ job->signaled = 0;
job->completion_port = NULL;
job->completion_key = 0;
job->parent = NULL;
-
- if (!(job->sync = create_event_sync( 1, 0 )))
- {
- release_object( job );
- return NULL;
- }
}
}
return job;
@@ -417,7 +411,8 @@ static void terminate_job( struct job *job, int exit_code )
if (process->running_threads) terminate_process( process, NULL, exit_code );
}
job->terminating = 0;
- signal_sync( job->sync );
+ job->signaled = 1;
+ wake_up( &job->obj, 0 );
}
static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
@@ -448,8 +443,6 @@ static void job_destroy( struct object *obj )
list_remove( &job->parent_job_entry );
release_object( job->parent );
}
-
- if (job->sync) release_object( job->sync );
}
static void job_dump( struct object *obj, int verbose )
@@ -460,11 +453,10 @@ static void job_dump( struct object *obj, int verbose )
list_count(&job->process_list), list_count(&job->child_job_list), job->parent );
}
-static struct object *job_get_sync( struct object *obj )
+static int job_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct job *job = (struct job *)obj;
- assert( obj->ops == &job_ops );
- return grab_object( job->sync );
+ return job->signaled;
}
struct ptid_entry
--
2.50.1
From 745e311670d5fe26475eeb473e8e28339ba9c8f7 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:02 +0300
Subject: [PATCH 22/57] Revert "server: Use an event sync for thread objects."
This reverts commit 7cdb776d4f0ab660e69a2e4169bbec5bbe0715c1.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/thread.c | 34 +++++++++++++++-------------------
server/thread.h | 1 -
2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/server/thread.c b/server/thread.c
index 3003c4bc930..2315e0a6115 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -189,7 +189,7 @@ struct type_descr thread_type =
};
static void dump_thread( struct object *obj, int verbose );
-static struct object *thread_get_sync( struct object *obj );
+static int thread_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int thread_map_access( struct object *obj, unsigned int access );
static void thread_poll_event( struct fd *fd, int event );
static struct list *thread_get_kernel_obj_list( struct object *obj );
@@ -200,13 +200,13 @@ static const struct object_ops thread_ops =
sizeof(struct thread), /* size */
&thread_type, /* type */
dump_thread, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ thread_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- thread_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
thread_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -396,7 +396,6 @@ static inline void init_thread_structure( struct thread *thread )
{
int i;
- thread->sync = NULL;
thread->unix_pid = -1; /* not known yet */
thread->unix_tid = -1; /* not known yet */
thread->context = NULL;
@@ -557,8 +556,11 @@ struct thread *create_thread( int fd, struct process *process, const struct secu
release_object( thread );
return NULL;
}
- if (!(thread->request_fd = create_anonymous_fd( &thread_fd_ops, fd, &thread->obj, 0 ))) goto error;
- if (!(thread->sync = create_event_sync( 1, 0 ))) goto error;
+ if (!(thread->request_fd = create_anonymous_fd( &thread_fd_ops, fd, &thread->obj, 0 )))
+ {
+ release_object( thread );
+ return NULL;
+ }
if (process->desktop)
{
@@ -573,10 +575,6 @@ struct thread *create_thread( int fd, struct process *process, const struct secu
set_fd_events( thread->request_fd, POLLIN ); /* start listening to events */
add_process_thread( thread->process, thread );
return thread;
-
-error:
- release_object( thread );
- return NULL;
}
/* handle a client event */
@@ -653,7 +651,6 @@ static void destroy_thread( struct object *obj )
release_object( thread->process );
if (thread->id) free_ptid( thread->id );
if (thread->token) release_object( thread->token );
- if (thread->sync) release_object( thread->sync );
}
/* dump a thread on stdout for debugging purposes */
@@ -666,11 +663,10 @@ static void dump_thread( struct object *obj, int verbose )
thread->id, thread->unix_pid, thread->unix_tid, thread->state );
}
-static struct object *thread_get_sync( struct object *obj )
+static int thread_signaled( struct object *obj, struct wait_queue_entry *entry )
{
- struct thread *thread = (struct thread *)obj;
- assert( obj->ops == &thread_ops );
- return grab_object( thread->sync );
+ struct thread *mythread = (struct thread *)obj;
+ return (mythread->state == TERMINATED);
}
static unsigned int thread_map_access( struct object *obj, unsigned int access )
@@ -1581,7 +1577,7 @@ void kill_thread( struct thread *thread, int violent_death )
}
kill_console_processes( thread, 0 );
abandon_mutexes( thread );
- signal_sync( thread->sync );
+ wake_up( &thread->obj, 0 );
if (violent_death) send_thread_signal( thread, SIGQUIT );
cleanup_thread( thread );
remove_process_thread( thread->process, thread );
diff --git a/server/thread.h b/server/thread.h
index b33a00d9f26..7a4eb983733 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -50,7 +50,6 @@ struct inflight_fd
struct thread
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct list entry; /* entry in system-wide thread list */
struct list proc_entry; /* entry in per-process thread list */
struct list desktop_entry; /* entry in per-desktop thread list */
--
2.50.1
From af66a3c89ccf659b0c87ed85ba011da9d5080e92 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:07 +0300
Subject: [PATCH 23/57] Revert "server: Use an event sync for context objects."
This reverts commit ab9ebea38308ac9f8adf7824813b6b3f975ce872.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/thread.c | 45 ++++++++++++++-------------------------------
1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/server/thread.c b/server/thread.c
index 2315e0a6115..2f46f837df4 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -130,10 +130,9 @@ static const struct object_ops thread_apc_ops =
struct context
{
- struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
- unsigned int status; /* status of the context */
- struct context_data regs[2]; /* context data */
+ struct object obj; /* object header */
+ unsigned int status; /* status of the context */
+ struct context_data regs[2];/* context data */
};
#define CTX_NATIVE 0 /* context for native machine */
#define CTX_WOW 1 /* context if thread is inside WoW */
@@ -142,21 +141,20 @@ struct context
static const unsigned int system_flags = SERVER_CTX_DEBUG_REGISTERS;
static void dump_context( struct object *obj, int verbose );
-static struct object *context_get_sync( struct object *obj );
-static void context_destroy( struct object *obj );
+static int context_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops context_ops =
{
sizeof(struct context), /* size */
&no_type, /* type */
dump_context, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ context_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- context_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -167,7 +165,7 @@ static const struct object_ops context_ops =
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
no_close_handle, /* close_handle */
- context_destroy, /* destroy */
+ no_destroy /* destroy */
};
@@ -462,35 +460,20 @@ static void dump_context( struct object *obj, int verbose )
}
-static struct object *context_get_sync( struct object *obj )
+static int context_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct context *context = (struct context *)obj;
- assert( obj->ops == &context_ops );
- return grab_object( context->sync );
+ return context->status != STATUS_PENDING;
}
-static void context_destroy( struct object *obj )
-{
- struct context *context = (struct context *)obj;
- assert( obj->ops == &context_ops );
- if (context->sync) release_object( context->sync );
-}
static struct context *create_thread_context( struct thread *thread )
{
struct context *context;
if (!(context = alloc_object( &context_ops ))) return NULL;
- context->sync = NULL;
context->status = STATUS_PENDING;
memset( &context->regs, 0, sizeof(context->regs) );
context->regs[CTX_NATIVE].machine = native_machine;
-
- if (!(context->sync = create_event_sync( 1, 0 )))
- {
- release_object( context );
- return NULL;
- }
-
return context;
}
@@ -606,7 +589,7 @@ static void cleanup_thread( struct thread *thread )
if (thread->context)
{
thread->context->status = STATUS_ACCESS_DENIED;
- signal_sync( thread->context->sync );
+ wake_up( &thread->context->obj, 0 );
release_object( thread->context );
thread->context = NULL;
}
@@ -1934,7 +1917,7 @@ DECL_HANDLER(select)
}
ctx->status = STATUS_SUCCESS;
current->suspend_cookie = req->cookie;
- signal_sync( ctx->sync );
+ wake_up( &ctx->obj, 0 );
}
if (!req->cookie) goto invalid_param;
--
2.50.1
From 3ab3463aeceb391ae685d648857e3e903716cdad Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:14 +0300
Subject: [PATCH 24/57] Revert "server: Use an event sync for thread apc
objects."
This reverts commit 413a06dc4c0a6e90cf8faea0baf39d97fe7ff45b.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/thread.c | 34 ++++++++++++----------------------
1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/server/thread.c b/server/thread.c
index 2f46f837df4..033f7a1e801 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -85,7 +85,6 @@ struct thread_wait
struct thread_apc
{
struct object obj; /* object header */
- struct event_sync *sync; /* sync object for wait/signal */
struct list entry; /* queue linked list */
struct thread *caller; /* thread that queued this apc */
struct object *owner; /* object that queued this apc */
@@ -96,7 +95,7 @@ struct thread_apc
};
static void dump_thread_apc( struct object *obj, int verbose );
-static struct object *thread_apc_get_sync( struct object *obj );
+static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry );
static void thread_apc_destroy( struct object *obj );
static void clear_apc_queue( struct list *queue );
@@ -105,13 +104,13 @@ static const struct object_ops thread_apc_ops =
sizeof(struct thread_apc), /* size */
&no_type, /* type */
dump_thread_apc, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ thread_apc_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- thread_apc_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -668,11 +667,10 @@ static void dump_thread_apc( struct object *obj, int verbose )
fprintf( stderr, "APC owner=%p type=%u\n", apc->owner, apc->call.type );
}
-static struct object *thread_apc_get_sync( struct object *obj )
+static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct thread_apc *apc = (struct thread_apc *)obj;
- assert( obj->ops == &thread_apc_ops );
- return grab_object( apc->sync );
+ return apc->executed;
}
static void thread_apc_destroy( struct object *obj )
@@ -688,7 +686,6 @@ static void thread_apc_destroy( struct object *obj )
async_set_result( apc->owner, apc->call.async_io.status, 0 );
release_object( apc->owner );
}
- if (apc->sync) release_object( apc->sync );
reserve_obj_unbind( apc->reserve );
}
@@ -699,7 +696,6 @@ static struct thread_apc *create_apc( struct object *owner, const union apc_call
if ((apc = alloc_object( &thread_apc_ops )))
{
- apc->sync = NULL;
if (call_data) apc->call = *call_data;
else apc->call.type = APC_NONE;
apc->caller = NULL;
@@ -708,12 +704,6 @@ static struct thread_apc *create_apc( struct object *owner, const union apc_call
apc->executed = 0;
apc->result.type = APC_NONE;
if (owner) grab_object( owner );
-
- if (!(apc->sync = create_event_sync( 1, 0 )))
- {
- release_object( apc );
- return NULL;
- }
}
return apc;
}
@@ -1448,7 +1438,7 @@ void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_ty
if (apc->owner != owner) continue;
list_remove( &apc->entry );
apc->executed = 1;
- signal_sync( apc->sync );
+ wake_up( &apc->obj, 0 );
release_object( apc );
return;
}
@@ -1478,7 +1468,7 @@ static void clear_apc_queue( struct list *queue )
struct thread_apc *apc = LIST_ENTRY( ptr, struct thread_apc, entry );
list_remove( &apc->entry );
apc->executed = 1;
- signal_sync( apc->sync );
+ wake_up( &apc->obj, 0 );
release_object( apc );
}
}
@@ -1941,7 +1931,7 @@ DECL_HANDLER(select)
apc->result.create_thread.handle = handle;
clear_error(); /* ignore errors from the above calls */
}
- signal_sync( apc->sync );
+ wake_up( &apc->obj, 0 );
close_handle( current->process, req->prev_apc );
release_object( apc );
}
@@ -1964,7 +1954,7 @@ DECL_HANDLER(select)
else
{
apc->executed = 1;
- signal_sync( apc->sync );
+ wake_up( &apc->obj, 0 );
}
release_object( apc );
}
--
2.50.1
From ab079fe05951759bfdad33eb80424ab6080d8af5 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:20 +0300
Subject: [PATCH 25/57] Revert "server: Use an event sync for fd objects."
This reverts commit 59b580e485cebfcea7d45c994addb3ca784998bf.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/event.c | 6 +++---
server/fd.c | 54 +++++++++++++++++++++----------------------------
server/object.h | 5 -----
3 files changed, 26 insertions(+), 39 deletions(-)
diff --git a/server/event.c b/server/event.c
index c69554fc657..e0fd122e6ad 100644
--- a/server/event.c
+++ b/server/event.c
@@ -87,7 +87,7 @@ static const struct object_ops event_sync_ops =
no_destroy /* destroy */
};
-struct event_sync *create_event_sync( int manual, int signaled )
+static struct event_sync *create_event_sync( int manual, int signaled )
{
struct event_sync *event;
@@ -113,14 +113,14 @@ static int event_sync_signaled( struct object *obj, struct wait_queue_entry *ent
return event->signaled;
}
-void signal_sync( struct event_sync *event )
+static void signal_sync( struct event_sync *event )
{
event->signaled = 1;
/* wake up all waiters if manual reset, a single one otherwise */
wake_up( &event->obj, !event->manual );
}
-void reset_sync( struct event_sync *event )
+static void reset_sync( struct event_sync *event )
{
event->signaled = 0;
}
diff --git a/server/fd.c b/server/fd.c
index 8b9133e102b..5f083a2df13 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -134,7 +134,6 @@ struct fd
{
struct object obj; /* object header */
const struct fd_ops *fd_ops; /* file descriptor operations */
- struct event_sync *sync; /* sync object for wait/signal */
struct inode *inode; /* inode that this fd belongs to */
struct list inode_entry; /* entry in inode fd list */
struct closed_fd *closed; /* structure to store the unix fd at destroy time */
@@ -151,6 +150,7 @@ struct fd
int unix_fd; /* unix file descriptor */
unsigned int no_fd_status;/* status to return when unix_fd is -1 */
unsigned int cacheable :1;/* can the fd be cached on the client side? */
+ unsigned int signaled :1; /* is the fd signaled? */
unsigned int fs_locks :1; /* can we use filesystem locks for this fd? */
int poll_index; /* index of fd in poll array */
struct async_queue read_q; /* async readers of this fd */
@@ -162,7 +162,7 @@ struct fd
};
static void fd_dump( struct object *obj, int verbose );
-static struct object *fd_get_sync( struct object *obj );
+static int fd_signaled( struct object *obj, struct wait_queue_entry *entry );
static void fd_destroy( struct object *obj );
static const struct object_ops fd_ops =
@@ -170,13 +170,13 @@ static const struct object_ops fd_ops =
sizeof(struct fd), /* size */
&no_type, /* type */
fd_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -1645,12 +1645,6 @@ static void fd_dump( struct object *obj, int verbose )
fprintf( stderr, "\n" );
}
-static struct object *fd_get_sync( struct object *obj )
-{
- struct fd *fd = (struct fd *)obj;
- return grab_object( fd->sync );
-}
-
static void fd_destroy( struct object *obj )
{
struct fd *fd = (struct fd *)obj;
@@ -1675,7 +1669,6 @@ static void fd_destroy( struct object *obj )
if (fd->unix_fd != -1) close( fd->unix_fd );
free( fd->unix_name );
}
- if (fd->sync) release_object( fd->sync );
}
/* check if the desired access is possible without violating */
@@ -1776,7 +1769,6 @@ static struct fd *alloc_fd_object(void)
if (!fd) return NULL;
fd->fd_ops = NULL;
- fd->sync = NULL;
fd->user = NULL;
fd->inode = NULL;
fd->closed = NULL;
@@ -1790,6 +1782,7 @@ static struct fd *alloc_fd_object(void)
fd->nt_name = NULL;
fd->nt_namelen = 0;
fd->cacheable = 0;
+ fd->signaled = 1;
fd->fs_locks = 1;
fd->poll_index = -1;
fd->completion = NULL;
@@ -1800,14 +1793,12 @@ static struct fd *alloc_fd_object(void)
list_init( &fd->inode_entry );
list_init( &fd->locks );
- if (!(fd->sync = create_event_sync( 1, 1 ))) goto error;
- if ((fd->poll_index = add_poll_user( fd )) == -1) goto error;
-
+ if ((fd->poll_index = add_poll_user( fd )) == -1)
+ {
+ release_object( fd );
+ return NULL;
+ }
return fd;
-
-error:
- release_object( fd );
- return NULL;
}
/* allocate a pseudo fd object, for objects that need to behave like files but don't have a unix fd */
@@ -1818,7 +1809,6 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
if (!fd) return NULL;
fd->fd_ops = fd_user_ops;
- fd->sync = NULL;
fd->user = user;
fd->inode = NULL;
fd->closed = NULL;
@@ -1832,6 +1822,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
fd->nt_namelen = 0;
fd->unix_fd = -1;
fd->cacheable = 0;
+ fd->signaled = 1;
fd->fs_locks = 0;
fd->poll_index = -1;
fd->completion = NULL;
@@ -1842,12 +1833,6 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
init_async_queue( &fd->wait_q );
list_init( &fd->inode_entry );
list_init( &fd->locks );
-
- if (!(fd->sync = create_event_sync( 1, 1 )))
- {
- release_object( fd );
- return NULL;
- }
return fd;
}
@@ -2321,8 +2306,8 @@ int is_fd_removable( struct fd *fd )
void set_fd_signaled( struct fd *fd, int signaled )
{
if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return;
- if (signaled) signal_sync( fd->sync );
- else reset_sync( fd->sync );
+ fd->signaled = signaled;
+ if (signaled) wake_up( &fd->obj, 0 );
}
/* check if events are pending and if yes return which one(s) */
@@ -2339,6 +2324,13 @@ int check_fd_events( struct fd *fd, int events )
return pfd.revents;
}
+static int fd_signaled( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct fd *fd = (struct fd *)obj;
+ assert( obj->ops == &fd_ops );
+ return fd->signaled;
+}
+
/* default get_sync() routine for objects that poll() on an fd */
struct object *default_fd_get_sync( struct object *obj )
{
diff --git a/server/object.h b/server/object.h
index d8067b145c7..2ac54876ddf 100644
--- a/server/object.h
+++ b/server/object.h
@@ -221,14 +221,9 @@ static inline void *mem_append( void *ptr, const void *src, data_size_t len )
/* event functions */
-struct event_sync;
struct event;
struct keyed_event;
-extern struct event_sync *create_event_sync( int manual, int signaled );
-extern void signal_sync( struct event_sync *sync );
-extern void reset_sync( struct event_sync *sync );
-
extern struct event *create_event( struct object *root, const struct unicode_str *name,
unsigned int attr, int manual_reset, int initial_state,
const struct security_descriptor *sd );
--
2.50.1
From c7271a6338c36c7a72edcd73f8b42665be565716 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:25 +0300
Subject: [PATCH 26/57] Revert "server: Introduce a new event sync object."
This reverts commit 2d7fa762a4d36e379a76a1d964c0682d4da4f42c.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/event.c | 170 ++++++++++++-------------------------------------
1 file changed, 42 insertions(+), 128 deletions(-)
diff --git a/server/event.c b/server/event.c
index e0fd122e6ad..8d4a78d988a 100644
--- a/server/event.c
+++ b/server/event.c
@@ -50,122 +50,32 @@ struct type_descr event_type =
},
};
-struct event_sync
-{
- struct object obj; /* object header */
- unsigned int manual : 1; /* is it a manual reset event? */
- unsigned int signaled : 1; /* event has been signaled */
-};
-
-static void event_sync_dump( struct object *obj, int verbose );
-static int event_sync_signaled( struct object *obj, struct wait_queue_entry *entry );
-static void event_sync_satisfied( struct object *obj, struct wait_queue_entry *entry );
-static int event_sync_signal( struct object *obj, unsigned int access );
-
-static const struct object_ops event_sync_ops =
-{
- sizeof(struct event_sync), /* size */
- &no_type, /* type */
- event_sync_dump, /* dump */
- add_queue, /* add_queue */
- remove_queue, /* remove_queue */
- event_sync_signaled, /* signaled */
- event_sync_satisfied, /* satisfied */
- event_sync_signal, /* signal */
- no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
- default_map_access, /* map_access */
- default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
- default_get_full_name, /* get_full_name */
- no_lookup_name, /* lookup_name */
- directory_link_name, /* link_name */
- default_unlink_name, /* unlink_name */
- no_open_file, /* open_file */
- no_kernel_obj_list, /* get_kernel_obj_list */
- no_close_handle, /* close_handle */
- no_destroy /* destroy */
-};
-
-static struct event_sync *create_event_sync( int manual, int signaled )
-{
- struct event_sync *event;
-
- if (!(event = alloc_object( &event_sync_ops ))) return NULL;
- event->manual = manual;
- event->signaled = signaled;
-
- return event;
-}
-
-static void event_sync_dump( struct object *obj, int verbose )
-{
- struct event_sync *event = (struct event_sync *)obj;
- assert( obj->ops == &event_sync_ops );
- fprintf( stderr, "Event manual=%d signaled=%d\n",
- event->manual, event->signaled );
-}
-
-static int event_sync_signaled( struct object *obj, struct wait_queue_entry *entry )
-{
- struct event_sync *event = (struct event_sync *)obj;
- assert( obj->ops == &event_sync_ops );
- return event->signaled;
-}
-
-static void signal_sync( struct event_sync *event )
-{
- event->signaled = 1;
- /* wake up all waiters if manual reset, a single one otherwise */
- wake_up( &event->obj, !event->manual );
-}
-
-static void reset_sync( struct event_sync *event )
-{
- event->signaled = 0;
-}
-
-static void event_sync_satisfied( struct object *obj, struct wait_queue_entry *entry )
-{
- struct event_sync *event = (struct event_sync *)obj;
- assert( obj->ops == &event_sync_ops );
- /* Reset if it's an auto-reset event */
- if (!event->manual) reset_sync( event );
-}
-
-static int event_sync_signal( struct object *obj, unsigned int access )
-{
- struct event_sync *event = (struct event_sync *)obj;
- assert( obj->ops == &event_sync_ops );
- signal_sync( event );
- return 1;
-}
-
struct event
{
- struct object obj; /* object header */
- struct event_sync *sync; /* event sync object */
- struct list kernel_object; /* list of kernel object pointers */
+ struct object obj; /* object header */
+ struct list kernel_object; /* list of kernel object pointers */
+ int manual_reset; /* is it a manual reset event? */
+ int signaled; /* event has been signaled */
};
static void event_dump( struct object *obj, int verbose );
-static struct object *event_get_sync( struct object *obj );
+static int event_signaled( struct object *obj, struct wait_queue_entry *entry );
+static void event_satisfied( struct object *obj, struct wait_queue_entry *entry );
static int event_signal( struct object *obj, unsigned int access);
static struct list *event_get_kernel_obj_list( struct object *obj );
-static void event_destroy( struct object *obj );
static const struct object_ops event_ops =
{
sizeof(struct event), /* size */
&event_type, /* type */
event_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ event_signaled, /* signaled */
+ event_satisfied, /* satisfied */
event_signal, /* signal */
no_get_fd, /* get_fd */
- event_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -176,7 +86,7 @@ static const struct object_ops event_ops =
no_open_file, /* open_file */
event_get_kernel_obj_list, /* get_kernel_obj_list */
no_close_handle, /* close_handle */
- event_destroy, /* destroy */
+ no_destroy /* destroy */
};
@@ -239,14 +149,9 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- event->sync = NULL;
list_init( &event->kernel_object );
-
- if (!(event->sync = create_event_sync( manual_reset, initial_state )))
- {
- release_object( event );
- return NULL;
- }
+ event->manual_reset = manual_reset;
+ event->signaled = initial_state;
}
}
return event;
@@ -257,28 +162,47 @@ struct event *get_event_obj( struct process *process, obj_handle_t handle, unsig
return (struct event *)get_handle_obj( process, handle, access, &event_ops );
}
+static void pulse_event( struct event *event )
+{
+ event->signaled = 1;
+ /* wake up all waiters if manual reset, a single one otherwise */
+ wake_up( &event->obj, !event->manual_reset );
+ event->signaled = 0;
+}
+
void set_event( struct event *event )
{
- signal_sync( event->sync );
+ event->signaled = 1;
+ /* wake up all waiters if manual reset, a single one otherwise */
+ wake_up( &event->obj, !event->manual_reset );
}
void reset_event( struct event *event )
{
- reset_sync( event->sync );
+ event->signaled = 0;
}
static void event_dump( struct object *obj, int verbose )
{
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
- event->sync->obj.ops->dump( &event->sync->obj, verbose );
+ fprintf( stderr, "Event manual=%d signaled=%d\n",
+ event->manual_reset, event->signaled );
}
-static struct object *event_get_sync( struct object *obj )
+static int event_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
- return grab_object( event->sync );
+ return event->signaled;
+}
+
+static void event_satisfied( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct event *event = (struct event *)obj;
+ assert( obj->ops == &event_ops );
+ /* Reset if it's an auto-reset event */
+ if (!event->manual_reset) event->signaled = 0;
}
static int event_signal( struct object *obj, unsigned int access )
@@ -301,14 +225,6 @@ static struct list *event_get_kernel_obj_list( struct object *obj )
return &event->kernel_object;
}
-static void event_destroy( struct object *obj )
-{
- struct event *event = (struct event *)obj;
- assert( obj->ops == &event_ops );
-
- if (event->sync) release_object( event->sync );
-}
-
struct keyed_event *create_keyed_event( struct object *root, const struct unicode_str *name,
unsigned int attr, const struct security_descriptor *sd )
{
@@ -402,13 +318,11 @@ DECL_HANDLER(event_op)
struct event *event;
if (!(event = get_event_obj( current->process, req->handle, EVENT_MODIFY_STATE ))) return;
-
- reply->state = event->sync->signaled;
+ reply->state = event->signaled;
switch(req->op)
{
case PULSE_EVENT:
- set_event( event );
- reset_event( event );
+ pulse_event( event );
break;
case SET_EVENT:
set_event( event );
@@ -430,8 +344,8 @@ DECL_HANDLER(query_event)
if (!(event = get_event_obj( current->process, req->handle, EVENT_QUERY_STATE ))) return;
- reply->manual_reset = event->sync->manual;
- reply->state = event->sync->signaled;
+ reply->manual_reset = event->manual_reset;
+ reply->state = event->signaled;
release_object( event );
}
--
2.50.1
From daa046be5f3fb42f419b7c0c6eb478e39633c47f Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:31 +0300
Subject: [PATCH 27/57] Revert "server: Redirect fd-based objects sync to the
fd."
This reverts commit 4bd194a99c1440c117a19ff8b38e662ed39a186c.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/change.c | 10 +++++-----
server/device.c | 10 +++++-----
server/fd.c | 26 +++++++++-----------------
server/file.c | 10 +++++-----
server/file.h | 2 +-
server/mailslot.c | 20 ++++++++++----------
server/named_pipe.c | 40 ++++++++++++++++++++--------------------
server/serial.c | 10 +++++-----
server/sock.c | 10 +++++-----
9 files changed, 65 insertions(+), 73 deletions(-)
diff --git a/server/change.c b/server/change.c
index be3251a1eef..eaa21732cbb 100644
--- a/server/change.c
+++ b/server/change.c
@@ -109,13 +109,13 @@ static const struct object_ops dir_ops =
sizeof(struct dir), /* size */
&file_type, /* type */
dir_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
dir_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
dir_get_sd, /* get_sd */
dir_set_sd, /* set_sd */
diff --git a/server/device.c b/server/device.c
index 892ec98c44f..d4cdacf7132 100644
--- a/server/device.c
+++ b/server/device.c
@@ -215,13 +215,13 @@ static const struct object_ops device_file_ops =
sizeof(struct device_file), /* size */
&file_type, /* type */
device_file_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
device_file_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/fd.c b/server/fd.c
index 5f083a2df13..a38394e1cb4 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -162,7 +162,6 @@ struct fd
};
static void fd_dump( struct object *obj, int verbose );
-static int fd_signaled( struct object *obj, struct wait_queue_entry *entry );
static void fd_destroy( struct object *obj );
static const struct object_ops fd_ops =
@@ -170,10 +169,10 @@ static const struct object_ops fd_ops =
sizeof(struct fd), /* size */
&no_type, /* type */
fd_dump, /* dump */
- add_queue, /* add_queue */
- remove_queue, /* remove_queue */
- fd_signaled, /* signaled */
- no_satisfied, /* satisfied */
+ no_add_queue, /* add_queue */
+ NULL, /* remove_queue */
+ NULL, /* signaled */
+ NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
default_get_sync, /* get_sync */
@@ -2307,7 +2306,7 @@ void set_fd_signaled( struct fd *fd, int signaled )
{
if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return;
fd->signaled = signaled;
- if (signaled) wake_up( &fd->obj, 0 );
+ if (signaled) wake_up( fd->user, 0 );
}
/* check if events are pending and if yes return which one(s) */
@@ -2324,20 +2323,13 @@ int check_fd_events( struct fd *fd, int events )
return pfd.revents;
}
-static int fd_signaled( struct object *obj, struct wait_queue_entry *entry )
-{
- struct fd *fd = (struct fd *)obj;
- assert( obj->ops == &fd_ops );
- return fd->signaled;
-}
-
-/* default get_sync() routine for objects that poll() on an fd */
-struct object *default_fd_get_sync( struct object *obj )
+/* default signaled() routine for objects that poll() on an fd */
+int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct fd *fd = get_obj_fd( obj );
- struct object *sync = get_obj_sync( &fd->obj );
+ int ret = fd->signaled;
release_object( fd );
- return sync;
+ return ret;
}
/* default get_full_name() routine for objects with an fd */
diff --git a/server/file.c b/server/file.c
index 654b082aa40..708f4e10f88 100644
--- a/server/file.c
+++ b/server/file.c
@@ -120,13 +120,13 @@ static const struct object_ops file_ops =
sizeof(struct file), /* size */
&file_type, /* type */
file_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
file_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
file_get_sd, /* get_sd */
file_set_sd, /* set_sd */
diff --git a/server/file.h b/server/file.h
index 2a3d83f903f..69c0efdb5b5 100644
--- a/server/file.h
+++ b/server/file.h
@@ -108,7 +108,7 @@ extern void set_fd_signaled( struct fd *fd, int signaled );
extern char *dup_fd_name( struct fd *root, const char *name ) __WINE_DEALLOC(free) __WINE_MALLOC;
extern void get_nt_name( struct fd *fd, struct unicode_str *name );
-extern struct object *default_fd_get_sync( struct object *obj );
+extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry );
extern WCHAR *default_fd_get_full_name( struct object *obj, data_size_t max, data_size_t *ret_len );
extern int default_fd_get_poll_events( struct fd *fd );
extern void default_poll_event( struct fd *fd, int event );
diff --git a/server/mailslot.c b/server/mailslot.c
index 430566d044d..15b9909caf2 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -79,13 +79,13 @@ static const struct object_ops mailslot_ops =
sizeof(struct mailslot), /* size */
&file_type, /* type */
mailslot_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
mailslot_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
mailslot_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -238,13 +238,13 @@ static const struct object_ops mailslot_device_file_ops =
sizeof(struct mailslot_device_file), /* size */
&file_type, /* type */
mailslot_device_file_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
mailslot_device_file_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index e67b25bac5d..d83428233f4 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -165,13 +165,13 @@ static const struct object_ops pipe_server_ops =
sizeof(struct pipe_server), /* size */
&file_type, /* type */
pipe_server_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
pipe_end_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
pipe_end_get_sd, /* get_sd */
pipe_end_set_sd, /* set_sd */
@@ -210,13 +210,13 @@ static const struct object_ops pipe_client_ops =
sizeof(struct pipe_end), /* size */
&file_type, /* type */
pipe_client_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
pipe_end_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
pipe_end_get_sd, /* get_sd */
pipe_end_set_sd, /* set_sd */
@@ -291,13 +291,13 @@ static const struct object_ops named_pipe_device_file_ops =
sizeof(struct named_pipe_device_file), /* size */
&file_type, /* type */
named_pipe_device_file_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
named_pipe_device_file_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -342,13 +342,13 @@ static const struct object_ops named_pipe_dir_ops =
sizeof(struct named_pipe_device_file), /* size */
&file_type, /* type */
named_pipe_dir_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
named_pipe_dir_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/serial.c b/server/serial.c
index 66cb4aabfbc..fc0939e402b 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -88,13 +88,13 @@ static const struct object_ops serial_ops =
sizeof(struct serial), /* size */
&file_type, /* type */
serial_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
serial_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/sock.c b/server/sock.c
index 191160562f6..15337fbe2df 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -488,13 +488,13 @@ static const struct object_ops sock_ops =
sizeof(struct sock), /* size */
&file_type, /* type */
sock_dump, /* dump */
- NULL, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
- NULL, /* satisfied */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
+ no_satisfied, /* satisfied */
no_signal, /* signal */
sock_get_fd, /* get_fd */
- default_fd_get_sync, /* get_sync */
+ default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
--
2.50.1
From 6d357dcbf16d2d203fbf239643944143e2f0cf5c Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:38 +0300
Subject: [PATCH 28/57] Revert "server: Add an operation to retrieve an object
sync."
This reverts commit acde7e3bdcdd5c5f44748dc0b9db624a8cbdf2bc.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/async.c | 2 --
server/atom.c | 1 -
server/change.c | 1 -
server/clipboard.c | 1 -
server/completion.c | 2 --
server/console.c | 7 -------
server/debugger.c | 2 --
server/device.c | 4 ----
server/directory.c | 2 --
server/event.c | 2 --
server/fd.c | 4 ----
server/file.c | 1 -
server/handle.c | 1 -
server/hook.c | 1 -
server/mailslot.c | 4 ----
server/mapping.c | 3 ---
server/mutex.c | 1 -
server/named_pipe.c | 6 ------
server/object.c | 7 -------
server/object.h | 4 ----
server/process.c | 3 ---
server/queue.c | 2 --
server/registry.c | 1 -
server/request.c | 1 -
server/semaphore.c | 1 -
server/serial.c | 1 -
server/signal.c | 1 -
server/sock.c | 3 ---
server/symlink.c | 1 -
server/thread.c | 45 ++++++---------------------------------------
server/timer.c | 1 -
server/token.c | 1 -
server/window.c | 1 -
server/winstation.c | 2 --
34 files changed, 6 insertions(+), 114 deletions(-)
diff --git a/server/async.c b/server/async.c
index 4068f744567..62459b18419 100644
--- a/server/async.c
+++ b/server/async.c
@@ -81,7 +81,6 @@ static const struct object_ops async_ops =
async_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -703,7 +702,6 @@ static const struct object_ops iosb_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/atom.c b/server/atom.c
index f3b0d1abffb..a333c54d006 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -81,7 +81,6 @@ static const struct object_ops atom_table_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/change.c b/server/change.c
index eaa21732cbb..200dd4b4e9e 100644
--- a/server/change.c
+++ b/server/change.c
@@ -115,7 +115,6 @@ static const struct object_ops dir_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
dir_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
dir_get_sd, /* get_sd */
dir_set_sd, /* set_sd */
diff --git a/server/clipboard.c b/server/clipboard.c
index 59a50354b48..91f159bc7c9 100644
--- a/server/clipboard.c
+++ b/server/clipboard.c
@@ -79,7 +79,6 @@ static const struct object_ops clipboard_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/completion.c b/server/completion.c
index fd623b36d5a..99680ae0680 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -95,7 +95,6 @@ static const struct object_ops completion_wait_ops =
completion_wait_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -170,7 +169,6 @@ static const struct object_ops completion_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/console.c b/server/console.c
index d3c5317728e..25b8fea0c6c 100644
--- a/server/console.c
+++ b/server/console.c
@@ -87,7 +87,6 @@ static const struct object_ops console_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
console_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -165,7 +164,6 @@ static const struct object_ops console_server_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
console_server_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -235,7 +233,6 @@ static const struct object_ops screen_buffer_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
screen_buffer_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -285,7 +282,6 @@ static const struct object_ops console_device_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -325,7 +321,6 @@ static const struct object_ops console_input_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
console_input_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -385,7 +380,6 @@ static const struct object_ops console_output_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
console_output_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -444,7 +438,6 @@ static const struct object_ops console_connection_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
console_connection_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/debugger.c b/server/debugger.c
index 43d01fbf246..39a740e07e5 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -89,7 +89,6 @@ static const struct object_ops debug_event_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -118,7 +117,6 @@ static const struct object_ops debug_obj_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/device.c b/server/device.c
index d4cdacf7132..2e3c5eb5bff 100644
--- a/server/device.c
+++ b/server/device.c
@@ -69,7 +69,6 @@ static const struct object_ops irp_call_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -110,7 +109,6 @@ static const struct object_ops device_manager_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -168,7 +166,6 @@ static const struct object_ops device_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -221,7 +218,6 @@ static const struct object_ops device_file_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
device_file_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/directory.c b/server/directory.c
index c56c216d6d5..7253388d7e1 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -72,7 +72,6 @@ static const struct object_ops object_type_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -123,7 +122,6 @@ static const struct object_ops directory_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/event.c b/server/event.c
index 8d4a78d988a..ad7c09acc99 100644
--- a/server/event.c
+++ b/server/event.c
@@ -75,7 +75,6 @@ static const struct object_ops event_ops =
event_satisfied, /* satisfied */
event_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -123,7 +122,6 @@ static const struct object_ops keyed_event_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/fd.c b/server/fd.c
index a38394e1cb4..085d2f6e368 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -175,7 +175,6 @@ static const struct object_ops fd_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -217,7 +216,6 @@ static const struct object_ops device_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -258,7 +256,6 @@ static const struct object_ops inode_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -301,7 +298,6 @@ static const struct object_ops file_lock_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/file.c b/server/file.c
index 708f4e10f88..dc4fb0c0ea5 100644
--- a/server/file.c
+++ b/server/file.c
@@ -126,7 +126,6 @@ static const struct object_ops file_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
file_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
file_get_sd, /* get_sd */
file_set_sd, /* set_sd */
diff --git a/server/handle.c b/server/handle.c
index ddcf03accb2..8a90fdc090c 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -129,7 +129,6 @@ static const struct object_ops handle_table_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/hook.c b/server/hook.c
index 7ba1f3ea9bf..4c55c565968 100644
--- a/server/hook.c
+++ b/server/hook.c
@@ -84,7 +84,6 @@ static const struct object_ops hook_table_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/mailslot.c b/server/mailslot.c
index 15b9909caf2..420e3d67345 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -85,7 +85,6 @@ static const struct object_ops mailslot_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
mailslot_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
mailslot_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -147,7 +146,6 @@ static const struct object_ops mail_writer_ops =
NULL, /* satisfied */
no_signal, /* signal */
mail_writer_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
mail_writer_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -213,7 +211,6 @@ static const struct object_ops mailslot_device_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -244,7 +241,6 @@ static const struct object_ops mailslot_device_file_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
mailslot_device_file_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/mapping.c b/server/mapping.c
index c3f57b6394c..7edadcbbeda 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -70,7 +70,6 @@ static const struct object_ops ranges_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -107,7 +106,6 @@ static const struct object_ops shared_map_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -181,7 +179,6 @@ static const struct object_ops mapping_ops =
NULL, /* satisfied */
no_signal, /* signal */
mapping_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/mutex.c b/server/mutex.c
index 4737b6f711b..af0efe72132 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -76,7 +76,6 @@ static const struct object_ops mutex_ops =
mutex_satisfied, /* satisfied */
mutex_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index d83428233f4..f1263013bf1 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -122,7 +122,6 @@ static const struct object_ops named_pipe_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
named_pipe_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -171,7 +170,6 @@ static const struct object_ops pipe_server_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
pipe_end_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
pipe_end_get_sd, /* get_sd */
pipe_end_set_sd, /* set_sd */
@@ -216,7 +214,6 @@ static const struct object_ops pipe_client_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
pipe_end_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
pipe_end_get_sd, /* get_sd */
pipe_end_set_sd, /* set_sd */
@@ -265,7 +262,6 @@ static const struct object_ops named_pipe_device_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -297,7 +293,6 @@ static const struct object_ops named_pipe_device_file_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
named_pipe_device_file_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -348,7 +343,6 @@ static const struct object_ops named_pipe_dir_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
named_pipe_dir_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/object.c b/server/object.c
index 9371ca0ef4c..1ff8ede0efc 100644
--- a/server/object.c
+++ b/server/object.c
@@ -112,7 +112,6 @@ static const struct object_ops apc_reserve_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -137,7 +136,6 @@ static const struct object_ops completion_reserve_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -643,11 +641,6 @@ struct fd *no_get_fd( struct object *obj )
return NULL;
}
-struct object *default_get_sync( struct object *obj )
-{
- return grab_object( obj );
-}
-
unsigned int default_map_access( struct object *obj, unsigned int access )
{
return map_access( access, &obj->ops->type->mapping );
diff --git a/server/object.h b/server/object.h
index 2ac54876ddf..f9f4a5f7462 100644
--- a/server/object.h
+++ b/server/object.h
@@ -84,8 +84,6 @@ struct object_ops
int (*signal)(struct object *, unsigned int);
/* return an fd object that can be used to read/write from the object */
struct fd *(*get_fd)(struct object *);
- /* return a sync that can be used to wait/signal the object */
- struct object *(*get_sync)(struct object *);
/* map access rights to the specific rights for this object */
unsigned int (*map_access)(struct object *, unsigned int);
/* returns the security descriptor of the object */
@@ -172,8 +170,6 @@ extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void no_satisfied( struct object *obj, struct wait_queue_entry *entry );
extern int no_signal( struct object *obj, unsigned int access );
extern struct fd *no_get_fd( struct object *obj );
-extern struct object *default_get_sync( struct object *obj );
-static inline struct object *get_obj_sync( struct object *obj ) { return obj->ops->get_sync( obj ); }
extern unsigned int default_map_access( struct object *obj, unsigned int access );
extern struct security_descriptor *default_get_sd( struct object *obj );
extern int default_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
diff --git a/server/process.c b/server/process.c
index f90e725ca93..5561461dc95 100644
--- a/server/process.c
+++ b/server/process.c
@@ -109,7 +109,6 @@ static const struct object_ops process_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
process_map_access, /* map_access */
process_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -161,7 +160,6 @@ static const struct object_ops startup_info_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -223,7 +221,6 @@ static const struct object_ops job_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/queue.c b/server/queue.c
index 4b8fdf677fd..f57ea874ee5 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -169,7 +169,6 @@ static const struct object_ops msg_queue_ops =
msg_queue_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -207,7 +206,6 @@ static const struct object_ops thread_input_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/registry.c b/server/registry.c
index b59bd63f9c6..082cc462e21 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -183,7 +183,6 @@ static const struct object_ops key_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
key_map_access, /* map_access */
key_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/request.c b/server/request.c
index 835ea30cec3..2254315b79e 100644
--- a/server/request.c
+++ b/server/request.c
@@ -92,7 +92,6 @@ static const struct object_ops master_socket_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/semaphore.c b/server/semaphore.c
index 304a821bcec..53b42a886df 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -73,7 +73,6 @@ static const struct object_ops semaphore_ops =
semaphore_satisfied, /* satisfied */
semaphore_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/serial.c b/server/serial.c
index fc0939e402b..209f2e9174e 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -94,7 +94,6 @@ static const struct object_ops serial_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
serial_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/signal.c b/server/signal.c
index 078951af6e4..19b76d44c16 100644
--- a/server/signal.c
+++ b/server/signal.c
@@ -65,7 +65,6 @@ static const struct object_ops handler_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/sock.c b/server/sock.c
index 15337fbe2df..1c22af5e1db 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -494,7 +494,6 @@ static const struct object_ops sock_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
sock_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -3897,7 +3896,6 @@ static const struct object_ops ifchange_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
ifchange_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -4119,7 +4117,6 @@ static const struct object_ops socket_device_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/symlink.c b/server/symlink.c
index 238dcfad1c7..55638a502bd 100644
--- a/server/symlink.c
+++ b/server/symlink.c
@@ -74,7 +74,6 @@ static const struct object_ops symlink_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/thread.c b/server/thread.c
index 033f7a1e801..f3528711b99 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -110,7 +110,6 @@ static const struct object_ops thread_apc_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -153,7 +152,6 @@ static const struct object_ops context_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -203,7 +201,6 @@ static const struct object_ops thread_ops =
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
thread_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -966,36 +963,6 @@ void set_wait_status( struct wait_queue_entry *entry, int status )
entry->wait->status = status;
}
-static void object_sync_satisfied( struct object *obj, struct wait_queue_entry *entry )
-{
- struct object *sync = get_obj_sync( obj );
- sync->ops->satisfied( sync, entry );
- release_object( sync );
-}
-
-static void object_sync_remove_queue( struct object *obj, struct wait_queue_entry *entry )
-{
- struct object *sync = get_obj_sync( obj );
- sync->ops->remove_queue( sync, entry );
- release_object( sync );
-}
-
-static int object_sync_add_queue( struct object *obj, struct wait_queue_entry *entry )
-{
- struct object *sync = get_obj_sync( obj );
- int ret = sync->ops->add_queue( sync, entry );
- release_object( sync );
- return ret;
-}
-
-static int object_sync_signaled( struct object *obj, struct wait_queue_entry *entry )
-{
- struct object *sync = get_obj_sync( obj );
- int ret = sync->ops->signaled( sync, entry );
- release_object( sync );
- return ret;
-}
-
/* finish waiting */
static unsigned int end_wait( struct thread *thread, unsigned int status )
{
@@ -1012,19 +979,19 @@ static unsigned int end_wait( struct thread *thread, unsigned int status )
if (wait->select == SELECT_WAIT_ALL)
{
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
- object_sync_satisfied( entry->obj, entry );
+ entry->obj->ops->satisfied( entry->obj, entry );
}
else
{
entry = wait->queues + status;
- object_sync_satisfied( entry->obj, entry );
+ entry->obj->ops->satisfied( entry->obj, entry );
}
status = wait->status;
if (wait->abandoned) status += STATUS_ABANDONED_WAIT_0;
}
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
{
- object_sync_remove_queue( entry->obj, entry );
+ entry->obj->ops->remove_queue( entry->obj, entry );
release_object( entry->obj );
entry->obj = NULL;
}
@@ -1057,7 +1024,7 @@ static int wait_on( const union select_op *select_op, unsigned int count, struct
{
struct object *obj = objects[i];
entry->wait = wait;
- if (!object_sync_add_queue( obj, entry ))
+ if (!obj->ops->add_queue( obj, entry ))
{
wait->count = i;
end_wait( current, get_error() );
@@ -1112,13 +1079,13 @@ static int check_wait( struct thread *thread )
/* Note: we must check them all anyway, as some objects may
* want to do something when signaled, even if others are not */
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
- not_ok |= !object_sync_signaled( entry->obj, entry );
+ not_ok |= !entry->obj->ops->signaled( entry->obj, entry );
if (!not_ok) return STATUS_WAIT_0;
}
else
{
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
- if (object_sync_signaled( entry->obj, entry )) return i;
+ if (entry->obj->ops->signaled( entry->obj, entry )) return i;
}
if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC;
diff --git a/server/timer.c b/server/timer.c
index f85fa66ed47..bfd74de5d4b 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -79,7 +79,6 @@ static const struct object_ops timer_ops =
timer_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/token.c b/server/token.c
index 5ce7298211e..3cdb9e5be5f 100644
--- a/server/token.c
+++ b/server/token.c
@@ -148,7 +148,6 @@ static const struct object_ops token_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
token_set_sd, /* set_sd */
diff --git a/server/window.c b/server/window.c
index 0729534ad6c..1cad3989f6d 100644
--- a/server/window.c
+++ b/server/window.c
@@ -111,7 +111,6 @@ static const struct object_ops window_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
diff --git a/server/winstation.c b/server/winstation.c
index bb5596f9a03..b3746090ccf 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -79,7 +79,6 @@ static const struct object_ops winstation_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
@@ -120,7 +119,6 @@ static const struct object_ops desktop_ops =
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
- default_get_sync, /* get_sync */
default_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
--
2.50.1
From 9c69c7fb6d77966d59e6efdaf953f0908961c21d Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 16:03:42 +0300
Subject: [PATCH 29/57] Revert "server: Move object grab/release out of
(add|remove)_queue."
This reverts commit 465d29d35f8b75bff6856f9bee8535804ed6ced5.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/thread.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/server/thread.c b/server/thread.c
index f3528711b99..b580220c02a 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -928,6 +928,8 @@ int resume_thread( struct thread *thread )
/* add a thread to an object wait queue; return 1 if OK, 0 on error */
int add_queue( struct object *obj, struct wait_queue_entry *entry )
{
+ grab_object( obj );
+ entry->obj = obj;
list_add_tail( &obj->wait_queue, &entry->entry );
return 1;
}
@@ -936,6 +938,7 @@ int add_queue( struct object *obj, struct wait_queue_entry *entry )
void remove_queue( struct object *obj, struct wait_queue_entry *entry )
{
list_remove( &entry->entry );
+ release_object( obj );
}
struct thread *get_wait_queue_thread( struct wait_queue_entry *entry )
@@ -990,11 +993,7 @@ static unsigned int end_wait( struct thread *thread, unsigned int status )
if (wait->abandoned) status += STATUS_ABANDONED_WAIT_0;
}
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
- {
entry->obj->ops->remove_queue( entry->obj, entry );
- release_object( entry->obj );
- entry->obj = NULL;
- }
if (wait->user) remove_timeout_user( wait->user );
free( wait );
return status;
@@ -1031,7 +1030,6 @@ static int wait_on( const union select_op *select_op, unsigned int count, struct
return 0;
}
- entry->obj = grab_object( obj );
if (obj == (struct object *)current->queue) idle = 1;
}
--
2.50.1
From 6d59cd4ab0f3bf852a4680fdf3a25b3c29740716 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 10 Feb 2025 16:18:15 -0600
Subject: [PATCH 30/57] ntdll: Add stub functions for in-process
synchronization.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/ntdll/unix/sync.c | 114 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 117915beb19..1c36532f13b 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -301,6 +301,59 @@ static unsigned int validate_open_object_attributes( const OBJECT_ATTRIBUTES *at
}
+static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_query_semaphore( HANDLE handle, SEMAPHORE_BASIC_INFORMATION *info )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_set_event( HANDLE handle, LONG *prev_state )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_reset_event( HANDLE handle, LONG *prev_state )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_pulse_event( HANDLE handle, LONG *prev_state )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_query_event( HANDLE handle, EVENT_BASIC_INFORMATION *info )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_release_mutex( HANDLE handle, LONG *prev_count )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_query_mutex( HANDLE handle, MUTANT_BASIC_INFORMATION *info )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
+ BOOLEAN alertable, const LARGE_INTEGER *timeout )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait,
+ BOOLEAN alertable, const LARGE_INTEGER *timeout )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
/******************************************************************************
* NtCreateSemaphore (NTDLL.@)
*/
@@ -375,6 +428,12 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla
if (len != sizeof(SEMAPHORE_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
+ if ((ret = inproc_query_semaphore( handle, out )) != STATUS_NOT_IMPLEMENTED)
+ {
+ if (!ret && ret_len) *ret_len = sizeof(SEMAPHORE_BASIC_INFORMATION);
+ return ret;
+ }
+
SERVER_START_REQ( query_semaphore )
{
req->handle = wine_server_obj_handle( handle );
@@ -397,6 +456,11 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, ULONG *previous
{
unsigned int ret;
+ TRACE( "handle %p, count %u, prev_count %p\n", handle, (int)count, previous );
+
+ if ((ret = inproc_release_semaphore( handle, count, previous )) != STATUS_NOT_IMPLEMENTED)
+ return ret;
+
SERVER_START_REQ( release_semaphore )
{
req->handle = wine_server_obj_handle( handle );
@@ -473,6 +537,11 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, LONG *prev_state )
{
unsigned int ret;
+ TRACE( "handle %p, prev_state %p\n", handle, prev_state );
+
+ if ((ret = inproc_set_event( handle, prev_state )) != STATUS_NOT_IMPLEMENTED)
+ return ret;
+
SERVER_START_REQ( event_op )
{
req->handle = wine_server_obj_handle( handle );
@@ -492,6 +561,11 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, LONG *prev_state )
{
unsigned int ret;
+ TRACE( "handle %p, prev_state %p\n", handle, prev_state );
+
+ if ((ret = inproc_reset_event( handle, prev_state )) != STATUS_NOT_IMPLEMENTED)
+ return ret;
+
SERVER_START_REQ( event_op )
{
req->handle = wine_server_obj_handle( handle );
@@ -521,6 +595,11 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, LONG *prev_state )
{
unsigned int ret;
+ TRACE( "handle %p, prev_state %p\n", handle, prev_state );
+
+ if ((ret = inproc_pulse_event( handle, prev_state )) != STATUS_NOT_IMPLEMENTED)
+ return ret;
+
SERVER_START_REQ( event_op )
{
req->handle = wine_server_obj_handle( handle );
@@ -552,6 +631,12 @@ NTSTATUS WINAPI NtQueryEvent( HANDLE handle, EVENT_INFORMATION_CLASS class,
if (len != sizeof(EVENT_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
+ if ((ret = inproc_query_event( handle, out )) != STATUS_NOT_IMPLEMENTED)
+ {
+ if (!ret && ret_len) *ret_len = sizeof(EVENT_BASIC_INFORMATION);
+ return ret;
+ }
+
SERVER_START_REQ( query_event )
{
req->handle = wine_server_obj_handle( handle );
@@ -627,6 +712,11 @@ NTSTATUS WINAPI NtReleaseMutant( HANDLE handle, LONG *prev_count )
{
unsigned int ret;
+ TRACE( "handle %p, prev_count %p\n", handle, prev_count );
+
+ if ((ret = inproc_release_mutex( handle, prev_count )) != STATUS_NOT_IMPLEMENTED)
+ return ret;
+
SERVER_START_REQ( release_mutex )
{
req->handle = wine_server_obj_handle( handle );
@@ -657,6 +747,12 @@ NTSTATUS WINAPI NtQueryMutant( HANDLE handle, MUTANT_INFORMATION_CLASS class,
if (len != sizeof(MUTANT_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
+ if ((ret = inproc_query_mutex( handle, out )) != STATUS_NOT_IMPLEMENTED)
+ {
+ if (!ret && ret_len) *ret_len = sizeof(MUTANT_BASIC_INFORMATION);
+ return ret;
+ }
+
SERVER_START_REQ( query_mutex )
{
req->handle = wine_server_obj_handle( handle );
@@ -1572,11 +1668,25 @@ NTSTATUS WINAPI NtQueryTimer( HANDLE handle, TIMER_INFORMATION_CLASS class,
NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
BOOLEAN alertable, const LARGE_INTEGER *timeout )
{
+ unsigned int ret;
union select_op select_op;
UINT i, flags = SELECT_INTERRUPTIBLE;
if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
+ if (TRACE_ON(sync))
+ {
+ TRACE( "wait_any %u, alertable %u, handles {%p", wait_any, alertable, handles[0] );
+ for (i = 1; i < count; i++) TRACE( ", %p", handles[i] );
+ TRACE( "}, timeout %s\n", debugstr_timeout(timeout) );
+ }
+
+ if ((ret = inproc_wait( count, handles, wait_any, alertable, timeout )) != STATUS_NOT_IMPLEMENTED)
+ {
+ TRACE( "-> %#x\n", ret );
+ return ret;
+ }
+
if (alertable) flags |= SELECT_ALERTABLE;
select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL;
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
@@ -1601,9 +1711,13 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait,
{
union select_op select_op;
UINT flags = SELECT_INTERRUPTIBLE;
+ NTSTATUS ret;
if (!signal) return STATUS_INVALID_HANDLE;
+ if ((ret = inproc_signal_and_wait( signal, wait, alertable, timeout )) != STATUS_NOT_IMPLEMENTED)
+ return ret;
+
if (alertable) flags |= SELECT_ALERTABLE;
select_op.signal_and_wait.op = SELECT_SIGNAL_AND_WAIT;
select_op.signal_and_wait.wait = wine_server_obj_handle( wait );
--
2.50.1
From 2372e42973d4ee00398f432b6209809e34cf5b0b Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 10 Feb 2025 16:44:49 -0600
Subject: [PATCH 31/57] ntdll: Retrieve and cache an ntsync device in wait
calls.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
configure | 6 ++
configure.ac | 1 +
dlls/ntdll/unix/server.c | 8 +--
dlls/ntdll/unix/sync.c | 107 +++++++++++++++++++++++++++++++++
dlls/ntdll/unix/unix_private.h | 3 +
include/config.h.in | 3 +
include/wine/server_protocol.h | 15 +++++
server/Makefile.in | 1 +
server/inproc_sync.c | 72 ++++++++++++++++++++++
server/protocol.def | 5 ++
server/request_handlers.h | 3 +
server/request_trace.h | 7 +++
12 files changed, 227 insertions(+), 4 deletions(-)
create mode 100644 server/inproc_sync.c
diff --git a/configure b/configure
index 248be30dd8f..6d16fef3608 100755
--- a/configure
+++ b/configure
@@ -10001,6 +10001,12 @@ if test "x$ac_cv_header_linux_major_h" = xyes
then :
printf "%s\n" "#define HAVE_LINUX_MAJOR_H 1" >>confdefs.h
+fi
+ac_fn_c_check_header_compile "$LINENO" "linux/ntsync.h" "ac_cv_header_linux_ntsync_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_ntsync_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_LINUX_NTSYNC_H 1" >>confdefs.h
+
fi
ac_fn_c_check_header_compile "$LINENO" "linux/param.h" "ac_cv_header_linux_param_h" "$ac_includes_default"
if test "x$ac_cv_header_linux_param_h" = xyes
diff --git a/configure.ac b/configure.ac
index 5c142c721fd..48b073935d7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -682,6 +682,7 @@ AC_CHECK_HEADERS(\
linux/input.h \
linux/ioctl.h \
linux/major.h \
+ linux/ntsync.h \
linux/param.h \
linux/seccomp.h \
linux/serial.h \
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 1aa0d5c0b8d..8d8f286b3fc 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -124,7 +124,7 @@ sigset_t server_block_set; /* signals to block during server calls */
static int fd_socket = -1; /* socket to exchange file descriptors with the server */
static int initial_cwd = -1;
static pid_t server_pid;
-static pthread_mutex_t fd_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t fd_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
/* atomically exchange a 64-bit value */
static inline LONG64 interlocked_xchg64( LONG64 *dest, LONG64 val )
@@ -981,7 +981,7 @@ void wine_server_send_fd( int fd )
*
* Receive a file descriptor passed from the server.
*/
-static int receive_fd( obj_handle_t *handle )
+int wine_server_receive_fd( obj_handle_t *handle )
{
struct iovec vec;
struct msghdr msghdr;
@@ -1176,7 +1176,7 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
if (type) *type = reply->type;
if (options) *options = reply->options;
access = reply->access;
- if ((fd = receive_fd( &fd_handle )) != -1)
+ if ((fd = wine_server_receive_fd( &fd_handle )) != -1)
{
assert( wine_server_ptr_handle(fd_handle) == handle );
*needs_close = (!reply->cacheable ||
@@ -1652,7 +1652,7 @@ size_t server_init_process(void)
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
/* receive the first thread request fd on the main socket */
- ntdll_get_thread_data()->request_fd = receive_fd( &version );
+ ntdll_get_thread_data()->request_fd = wine_server_receive_fd( &version );
#ifdef SO_PASSCRED
/* now that we hopefully received the server_pid, disable SO_PASSCRED */
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 1c36532f13b..e7b9cac6575 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -57,6 +57,9 @@
#ifdef HAVE_KQUEUE
# include <sys/event.h>
#endif
+#ifdef HAVE_LINUX_NTSYNC_H
+# include <linux/ntsync.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -301,6 +304,44 @@ static unsigned int validate_open_object_attributes( const OBJECT_ATTRIBUTES *at
}
+#ifdef NTSYNC_IOC_EVENT_READ
+
+static int get_linux_sync_device(void)
+{
+ static LONG device = -2;
+
+ if (device == -2)
+ {
+ obj_handle_t handle;
+ sigset_t sigset;
+ NTSTATUS ret;
+ int fd = -1;
+
+ /* We need to use fd_cache_mutex here to protect against races with
+ * other threads trying to receive fds for the fd cache,
+ * and we need to use an uninterrupted section to prevent reentrancy. */
+ server_enter_uninterrupted_section( &fd_cache_mutex, &sigset );
+
+ if (device == -2)
+ {
+ SERVER_START_REQ( get_linux_sync_device )
+ {
+ if (!(ret = wine_server_call( req )))
+ {
+ fd = wine_server_receive_fd( &handle );
+ assert( !handle );
+ }
+ }
+ SERVER_END_REQ;
+
+ device = fd;
+ }
+
+ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset );
+ }
+ return device;
+}
+
static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count )
{
return STATUS_NOT_IMPLEMENTED;
@@ -344,15 +385,81 @@ static NTSTATUS inproc_query_mutex( HANDLE handle, MUTANT_BASIC_INFORMATION *inf
static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
BOOLEAN alertable, const LARGE_INTEGER *timeout )
{
+ int device;
+
+ if ((device = get_linux_sync_device()) < 0)
+ return STATUS_NOT_IMPLEMENTED;
+
return STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait,
BOOLEAN alertable, const LARGE_INTEGER *timeout )
+{
+ int device;
+
+ if ((device = get_linux_sync_device()) < 0)
+ return STATUS_NOT_IMPLEMENTED;
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+#else
+
+static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_query_semaphore( HANDLE handle, SEMAPHORE_BASIC_INFORMATION *info )
{
return STATUS_NOT_IMPLEMENTED;
}
+static NTSTATUS inproc_set_event( HANDLE handle, LONG *prev_state )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_reset_event( HANDLE handle, LONG *prev_state )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_pulse_event( HANDLE handle, LONG *prev_state )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_query_event( HANDLE handle, EVENT_BASIC_INFORMATION *info )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_release_mutex( HANDLE handle, LONG *prev_count )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_query_mutex( HANDLE handle, MUTANT_BASIC_INFORMATION *info )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
+ BOOLEAN alertable, const LARGE_INTEGER *timeout )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait,
+ BOOLEAN alertable, const LARGE_INTEGER *timeout )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+#endif
+
/******************************************************************************
* NtCreateSemaphore (NTDLL.@)
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 11d8221bdff..b14a6e52d62 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -222,6 +222,8 @@ extern NTSTATUS load_start_exe( UNICODE_STRING *nt_name, void **module );
extern ULONG_PTR redirect_arm64ec_rva( void *module, ULONG_PTR rva, const IMAGE_ARM64EC_METADATA *metadata );
extern void start_server( BOOL debug );
+extern pthread_mutex_t fd_cache_mutex;
+
extern unsigned int server_call_unlocked( void *req_ptr );
extern void server_enter_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
extern void server_leave_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
@@ -234,6 +236,7 @@ extern unsigned int server_queue_process_apc( HANDLE process, const union apc_ca
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
int *needs_close, enum server_fd_type *type, unsigned int *options );
extern void wine_server_send_fd( int fd );
+extern int wine_server_receive_fd( obj_handle_t *handle );
extern void process_exit_wrapper( int status ) DECLSPEC_NORETURN;
extern size_t server_init_process(void);
extern void server_init_process_done(void);
diff --git a/include/config.h.in b/include/config.h.in
index 376d2835ec4..cf05cc62998 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -198,6 +198,9 @@
/* Define to 1 if you have the <linux/major.h> header file. */
#undef HAVE_LINUX_MAJOR_H
+/* Define to 1 if you have the <linux/ntsync.h> header file. */
+#undef HAVE_LINUX_NTSYNC_H
+
/* Define to 1 if you have the <linux/param.h> header file. */
#undef HAVE_LINUX_PARAM_H
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 751297f9720..93d5267fdb1 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -5977,6 +5977,18 @@ struct set_keyboard_repeat_reply
};
+
+struct get_linux_sync_device_request
+{
+ struct request_header __header;
+ char __pad_12[4];
+};
+struct get_linux_sync_device_reply
+{
+ struct reply_header __header;
+};
+
+
enum request
{
REQ_new_process,
@@ -6276,6 +6288,7 @@ enum request
REQ_get_next_process,
REQ_get_next_thread,
REQ_set_keyboard_repeat,
+ REQ_get_linux_sync_device,
REQ_NB_REQUESTS
};
@@ -6580,6 +6593,7 @@ union generic_request
struct get_next_process_request get_next_process_request;
struct get_next_thread_request get_next_thread_request;
struct set_keyboard_repeat_request set_keyboard_repeat_request;
+ struct get_linux_sync_device_request get_linux_sync_device_request;
};
union generic_reply
{
@@ -6882,6 +6896,7 @@ union generic_reply
struct get_next_process_reply get_next_process_reply;
struct get_next_thread_reply get_next_thread_reply;
struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
+ struct get_linux_sync_device_reply get_linux_sync_device_reply;
};
#define SERVER_PROTOCOL_VERSION 885
diff --git a/server/Makefile.in b/server/Makefile.in
index 6e4e68d6ebf..57250fd0332 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -16,6 +16,7 @@ SOURCES = \
file.c \
handle.c \
hook.c \
+ inproc_sync.c \
mach.c \
mailslot.c \
main.c \
diff --git a/server/inproc_sync.c b/server/inproc_sync.c
new file mode 100644
index 00000000000..de07f674bda
--- /dev/null
+++ b/server/inproc_sync.c
@@ -0,0 +1,72 @@
+/*
+ * In-process synchronization primitives
+ *
+ * Copyright (C) 2021-2022 Elizabeth Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+
+#include "file.h"
+#include "handle.h"
+#include "request.h"
+#include "thread.h"
+
+#ifdef HAVE_LINUX_NTSYNC_H
+# include <linux/ntsync.h>
+#endif
+
+#ifdef NTSYNC_IOC_EVENT_READ
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static int get_linux_device(void)
+{
+ static int fd = -2;
+
+ if (fd == -2)
+ fd = open( "/dev/ntsync", O_CLOEXEC | O_RDONLY );
+
+ return fd;
+}
+
+#endif
+
+
+DECL_HANDLER(get_linux_sync_device)
+{
+#ifdef NTSYNC_IOC_EVENT_READ
+ int fd;
+
+ if ((fd = get_linux_device()) >= 0)
+ send_client_fd( current->process, fd, 0 );
+ else
+ set_error( STATUS_NOT_IMPLEMENTED );
+#else
+ set_error( STATUS_NOT_IMPLEMENTED );
+#endif
+}
diff --git a/server/protocol.def b/server/protocol.def
index 0ca4c0551c4..e84de4368d5 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -4143,3 +4143,8 @@ struct handle_info
@REPLY
int enable; /* previous state of auto-repeat enable */
@END
+
+
+/* Obtain a fd for the ntsync device */
+@REQ(get_linux_sync_device)
+@END
diff --git a/server/request_handlers.h b/server/request_handlers.h
index c28f98a5c3f..dfed7904738 100644
--- a/server/request_handlers.h
+++ b/server/request_handlers.h
@@ -304,6 +304,7 @@ DECL_HANDLER(resume_process);
DECL_HANDLER(get_next_process);
DECL_HANDLER(get_next_thread);
DECL_HANDLER(set_keyboard_repeat);
+DECL_HANDLER(get_linux_sync_device);
typedef void (*req_handler)( const void *req, void *reply );
static const req_handler req_handlers[REQ_NB_REQUESTS] =
@@ -605,6 +606,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_next_process,
(req_handler)req_get_next_thread,
(req_handler)req_set_keyboard_repeat,
+ (req_handler)req_get_linux_sync_device,
};
C_ASSERT( sizeof(abstime_t) == 8 );
@@ -2302,3 +2304,4 @@ C_ASSERT( offsetof(struct set_keyboard_repeat_request, period) == 20 );
C_ASSERT( sizeof(struct set_keyboard_repeat_request) == 24 );
C_ASSERT( offsetof(struct set_keyboard_repeat_reply, enable) == 8 );
C_ASSERT( sizeof(struct set_keyboard_repeat_reply) == 16 );
+C_ASSERT( sizeof(struct get_linux_sync_device_request) == 16 );
diff --git a/server/request_trace.h b/server/request_trace.h
index ecb3cf6f26a..6fd490ca68e 100644
--- a/server/request_trace.h
+++ b/server/request_trace.h
@@ -3399,6 +3399,10 @@ static void dump_set_keyboard_repeat_reply( const struct set_keyboard_repeat_rep
fprintf( stderr, " enable=%d", req->enable );
}
+static void dump_get_linux_sync_device_request( const struct get_linux_sync_device_request *req )
+{
+}
+
typedef void (*dump_func)( const void *req );
static const dump_func req_dumpers[REQ_NB_REQUESTS] =
@@ -3700,6 +3704,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_get_next_process_request,
(dump_func)dump_get_next_thread_request,
(dump_func)dump_set_keyboard_repeat_request,
+ (dump_func)dump_get_linux_sync_device_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
@@ -4001,6 +4006,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_get_next_process_reply,
(dump_func)dump_get_next_thread_reply,
(dump_func)dump_set_keyboard_repeat_reply,
+ NULL,
};
static const char * const req_names[REQ_NB_REQUESTS] =
@@ -4302,6 +4308,7 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"get_next_process",
"get_next_thread",
"set_keyboard_repeat",
+ "get_linux_sync_device",
};
static const struct
--
2.50.1
From c3de93b3a7b71de8a61c8b5a7784a2b54f5c90f6 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 14:31:06 -0600
Subject: [PATCH 32/57] server: Add an object operation to retrieve an
in-process synchronization object.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
include/wine/server_protocol.h | 12 ++++++++++++
server/async.c | 2 ++
server/atom.c | 1 +
server/change.c | 1 +
server/clipboard.c | 1 +
server/completion.c | 2 ++
server/console.c | 7 +++++++
server/debugger.c | 2 ++
server/device.c | 4 ++++
server/directory.c | 2 ++
server/event.c | 2 ++
server/fd.c | 4 ++++
server/file.c | 1 +
server/handle.c | 1 +
server/hook.c | 1 +
server/mailslot.c | 4 ++++
server/mapping.c | 3 +++
server/mutex.c | 1 +
server/named_pipe.c | 6 ++++++
server/object.c | 7 +++++++
server/object.h | 7 +++++++
server/process.c | 3 +++
server/protocol.def | 12 ++++++++++++
server/queue.c | 2 ++
server/registry.c | 1 +
server/request.c | 1 +
server/semaphore.c | 1 +
server/serial.c | 1 +
server/signal.c | 1 +
server/sock.c | 3 +++
server/symlink.c | 1 +
server/thread.c | 3 +++
server/timer.c | 1 +
server/token.c | 1 +
server/window.c | 1 +
server/winstation.c | 2 ++
36 files changed, 105 insertions(+)
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 93d5267fdb1..f7a6a42c405 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -5976,6 +5976,18 @@ struct set_keyboard_repeat_reply
char __pad_12[4];
};
+enum inproc_sync_type
+{
+ INPROC_SYNC_UNKNOWN,
+ INPROC_SYNC_AUTO_EVENT,
+ INPROC_SYNC_MANUAL_EVENT,
+ INPROC_SYNC_SEMAPHORE,
+ INPROC_SYNC_MUTEX,
+ INPROC_SYNC_AUTO_SERVER,
+ INPROC_SYNC_MANUAL_SERVER,
+ INPROC_SYNC_QUEUE,
+};
+
struct get_linux_sync_device_request
diff --git a/server/async.c b/server/async.c
index 62459b18419..f68b4b60006 100644
--- a/server/async.c
+++ b/server/async.c
@@ -90,6 +90,7 @@ static const struct object_ops async_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
async_destroy /* destroy */
};
@@ -711,6 +712,7 @@ static const struct object_ops iosb_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
iosb_destroy /* destroy */
};
diff --git a/server/atom.c b/server/atom.c
index a333c54d006..7f7a9bc81b7 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -90,6 +90,7 @@ static const struct object_ops atom_table_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
atom_table_destroy /* destroy */
};
diff --git a/server/change.c b/server/change.c
index 200dd4b4e9e..f65b865d138 100644
--- a/server/change.c
+++ b/server/change.c
@@ -124,6 +124,7 @@ static const struct object_ops dir_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
dir_close_handle, /* close_handle */
dir_destroy /* destroy */
};
diff --git a/server/clipboard.c b/server/clipboard.c
index 91f159bc7c9..a2258ae869d 100644
--- a/server/clipboard.c
+++ b/server/clipboard.c
@@ -88,6 +88,7 @@ static const struct object_ops clipboard_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
clipboard_destroy /* destroy */
};
diff --git a/server/completion.c b/server/completion.c
index 99680ae0680..ac598e85229 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -104,6 +104,7 @@ static const struct object_ops completion_wait_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
completion_wait_destroy /* destroy */
};
@@ -178,6 +179,7 @@ static const struct object_ops completion_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
completion_close_handle, /* close_handle */
completion_destroy /* destroy */
};
diff --git a/server/console.c b/server/console.c
index 25b8fea0c6c..7070314ed8d 100644
--- a/server/console.c
+++ b/server/console.c
@@ -96,6 +96,7 @@ static const struct object_ops console_ops =
NULL, /* unlink_name */
console_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_destroy /* destroy */
};
@@ -173,6 +174,7 @@ static const struct object_ops console_server_ops =
NULL, /* unlink_name */
console_server_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_server_destroy /* destroy */
};
@@ -242,6 +244,7 @@ static const struct object_ops screen_buffer_ops =
NULL, /* unlink_name */
screen_buffer_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
screen_buffer_destroy /* destroy */
};
@@ -291,6 +294,7 @@ static const struct object_ops console_device_ops =
default_unlink_name, /* unlink_name */
console_device_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
@@ -330,6 +334,7 @@ static const struct object_ops console_input_ops =
default_unlink_name, /* unlink_name */
console_input_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_input_destroy /* destroy */
};
@@ -389,6 +394,7 @@ static const struct object_ops console_output_ops =
default_unlink_name, /* unlink_name */
console_output_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_output_destroy /* destroy */
};
@@ -447,6 +453,7 @@ static const struct object_ops console_connection_ops =
default_unlink_name, /* unlink_name */
console_connection_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
console_connection_close_handle, /* close_handle */
console_connection_destroy /* destroy */
};
diff --git a/server/debugger.c b/server/debugger.c
index 39a740e07e5..cab5f95eefd 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -98,6 +98,7 @@ static const struct object_ops debug_event_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
debug_event_destroy /* destroy */
};
@@ -126,6 +127,7 @@ static const struct object_ops debug_obj_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
debug_obj_destroy /* destroy */
};
diff --git a/server/device.c b/server/device.c
index 2e3c5eb5bff..1f9ceffd8d0 100644
--- a/server/device.c
+++ b/server/device.c
@@ -78,6 +78,7 @@ static const struct object_ops irp_call_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
irp_call_destroy /* destroy */
};
@@ -118,6 +119,7 @@ static const struct object_ops device_manager_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
device_manager_destroy /* destroy */
};
@@ -175,6 +177,7 @@ static const struct object_ops device_ops =
default_unlink_name, /* unlink_name */
device_open_file, /* open_file */
device_get_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
device_destroy /* destroy */
};
@@ -227,6 +230,7 @@ static const struct object_ops device_file_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
device_file_get_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
device_file_close_handle, /* close_handle */
device_file_destroy /* destroy */
};
diff --git a/server/directory.c b/server/directory.c
index 7253388d7e1..c2830ffef3d 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -81,6 +81,7 @@ static const struct object_ops object_type_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
@@ -131,6 +132,7 @@ static const struct object_ops directory_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
directory_destroy /* destroy */
};
diff --git a/server/event.c b/server/event.c
index ad7c09acc99..c19cfa5ba3e 100644
--- a/server/event.c
+++ b/server/event.c
@@ -84,6 +84,7 @@ static const struct object_ops event_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
event_get_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
@@ -131,6 +132,7 @@ static const struct object_ops keyed_event_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
diff --git a/server/fd.c b/server/fd.c
index 085d2f6e368..c6a0e366aca 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -184,6 +184,7 @@ static const struct object_ops fd_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
fd_destroy /* destroy */
};
@@ -225,6 +226,7 @@ static const struct object_ops device_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
device_destroy /* destroy */
};
@@ -265,6 +267,7 @@ static const struct object_ops inode_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
inode_destroy /* destroy */
};
@@ -307,6 +310,7 @@ static const struct object_ops file_lock_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
diff --git a/server/file.c b/server/file.c
index dc4fb0c0ea5..a35da0eb1b3 100644
--- a/server/file.c
+++ b/server/file.c
@@ -135,6 +135,7 @@ static const struct object_ops file_ops =
NULL, /* unlink_name */
file_open_file, /* open_file */
file_get_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
file_destroy /* destroy */
};
diff --git a/server/handle.c b/server/handle.c
index 8a90fdc090c..b8e2d3423c0 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -138,6 +138,7 @@ static const struct object_ops handle_table_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
handle_table_destroy /* destroy */
};
diff --git a/server/hook.c b/server/hook.c
index 4c55c565968..fcb3dbcfbea 100644
--- a/server/hook.c
+++ b/server/hook.c
@@ -93,6 +93,7 @@ static const struct object_ops hook_table_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
hook_table_destroy /* destroy */
};
diff --git a/server/mailslot.c b/server/mailslot.c
index 420e3d67345..edee2534e6e 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -94,6 +94,7 @@ static const struct object_ops mailslot_ops =
default_unlink_name, /* unlink_name */
mailslot_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mailslot_destroy /* destroy */
};
@@ -155,6 +156,7 @@ static const struct object_ops mail_writer_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mail_writer_destroy /* destroy */
};
@@ -220,6 +222,7 @@ static const struct object_ops mailslot_device_ops =
default_unlink_name, /* unlink_name */
mailslot_device_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mailslot_device_destroy /* destroy */
};
@@ -250,6 +253,7 @@ static const struct object_ops mailslot_device_file_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mailslot_device_file_destroy /* destroy */
};
diff --git a/server/mapping.c b/server/mapping.c
index 7edadcbbeda..5cd62e2fb77 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -79,6 +79,7 @@ static const struct object_ops ranges_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
ranges_destroy /* destroy */
};
@@ -115,6 +116,7 @@ static const struct object_ops shared_map_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
shared_map_destroy /* destroy */
};
@@ -188,6 +190,7 @@ static const struct object_ops mapping_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mapping_destroy /* destroy */
};
diff --git a/server/mutex.c b/server/mutex.c
index af0efe72132..4218423ebac 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -85,6 +85,7 @@ static const struct object_ops mutex_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mutex_destroy /* destroy */
};
diff --git a/server/named_pipe.c b/server/named_pipe.c
index f1263013bf1..8713c2a8360 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -131,6 +131,7 @@ static const struct object_ops named_pipe_ops =
default_unlink_name, /* unlink_name */
named_pipe_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
named_pipe_destroy /* destroy */
};
@@ -179,6 +180,7 @@ static const struct object_ops pipe_server_ops =
NULL, /* unlink_name */
pipe_server_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
async_close_obj_handle, /* close_handle */
pipe_server_destroy /* destroy */
};
@@ -223,6 +225,7 @@ static const struct object_ops pipe_client_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
async_close_obj_handle, /* close_handle */
pipe_end_destroy /* destroy */
};
@@ -271,6 +274,7 @@ static const struct object_ops named_pipe_device_ops =
default_unlink_name, /* unlink_name */
named_pipe_device_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
named_pipe_device_destroy /* destroy */
};
@@ -302,6 +306,7 @@ static const struct object_ops named_pipe_device_file_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
named_pipe_device_file_destroy /* destroy */
};
@@ -352,6 +357,7 @@ static const struct object_ops named_pipe_dir_ops =
NULL, /* unlink_name */
named_pipe_dir_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
named_pipe_dir_destroy /* destroy */
};
diff --git a/server/object.c b/server/object.c
index 1ff8ede0efc..cdc7ed5353b 100644
--- a/server/object.c
+++ b/server/object.c
@@ -121,6 +121,7 @@ static const struct object_ops apc_reserve_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
@@ -145,6 +146,7 @@ static const struct object_ops completion_reserve_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
@@ -641,6 +643,11 @@ struct fd *no_get_fd( struct object *obj )
return NULL;
}
+int no_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ return -1;
+}
+
unsigned int default_map_access( struct object *obj, unsigned int access )
{
return map_access( access, &obj->ops->type->mapping );
diff --git a/server/object.h b/server/object.h
index f9f4a5f7462..07f4bb67d6b 100644
--- a/server/object.h
+++ b/server/object.h
@@ -42,6 +42,7 @@ struct async;
struct async_queue;
struct winstation;
struct object_type;
+struct inproc_sync;
struct unicode_str
@@ -103,6 +104,8 @@ struct object_ops
unsigned int options);
/* return list of kernel objects */
struct list *(*get_kernel_obj_list)(struct object *);
+ /* get a client-waitable in-process synchronization fd for this object */
+ int (*get_inproc_sync)(struct object *, enum inproc_sync_type *type);
/* close a handle to this object */
int (*close_handle)(struct object *,struct process *,obj_handle_t);
/* destroy on refcount == 0 */
@@ -234,6 +237,10 @@ extern void reset_event( struct event *event );
extern void abandon_mutexes( struct thread *thread );
+/* in-process synchronization functions */
+
+extern int no_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
+
/* serial functions */
int get_serial_async_timeout(struct object *obj, int type, int count);
diff --git a/server/process.c b/server/process.c
index 5561461dc95..d5f3c1963cb 100644
--- a/server/process.c
+++ b/server/process.c
@@ -118,6 +118,7 @@ static const struct object_ops process_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
process_get_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
process_destroy /* destroy */
};
@@ -169,6 +170,7 @@ static const struct object_ops startup_info_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
startup_info_destroy /* destroy */
};
@@ -230,6 +232,7 @@ static const struct object_ops job_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
job_close_handle, /* close_handle */
job_destroy /* destroy */
};
diff --git a/server/protocol.def b/server/protocol.def
index e84de4368d5..1ed8960d303 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -4144,6 +4144,18 @@ struct handle_info
int enable; /* previous state of auto-repeat enable */
@END
+enum inproc_sync_type
+{
+ INPROC_SYNC_UNKNOWN,
+ INPROC_SYNC_AUTO_EVENT,
+ INPROC_SYNC_MANUAL_EVENT,
+ INPROC_SYNC_SEMAPHORE,
+ INPROC_SYNC_MUTEX,
+ INPROC_SYNC_AUTO_SERVER,
+ INPROC_SYNC_MANUAL_SERVER,
+ INPROC_SYNC_QUEUE,
+};
+
/* Obtain a fd for the ntsync device */
@REQ(get_linux_sync_device)
diff --git a/server/queue.c b/server/queue.c
index f57ea874ee5..23fb453aedb 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -178,6 +178,7 @@ static const struct object_ops msg_queue_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
msg_queue_destroy /* destroy */
};
@@ -215,6 +216,7 @@ static const struct object_ops thread_input_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
thread_input_destroy /* destroy */
};
diff --git a/server/registry.c b/server/registry.c
index 082cc462e21..d28a7793257 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -192,6 +192,7 @@ static const struct object_ops key_ops =
key_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
key_close_handle, /* close_handle */
key_destroy /* destroy */
};
diff --git a/server/request.c b/server/request.c
index 2254315b79e..24a4f779e68 100644
--- a/server/request.c
+++ b/server/request.c
@@ -101,6 +101,7 @@ static const struct object_ops master_socket_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
master_socket_destroy /* destroy */
};
diff --git a/server/semaphore.c b/server/semaphore.c
index 53b42a886df..094741bf36d 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -82,6 +82,7 @@ static const struct object_ops semaphore_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
diff --git a/server/serial.c b/server/serial.c
index 209f2e9174e..df242058a43 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -103,6 +103,7 @@ static const struct object_ops serial_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
serial_destroy /* destroy */
};
diff --git a/server/signal.c b/server/signal.c
index 19b76d44c16..85d16baa98c 100644
--- a/server/signal.c
+++ b/server/signal.c
@@ -74,6 +74,7 @@ static const struct object_ops handler_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
handler_destroy /* destroy */
};
diff --git a/server/sock.c b/server/sock.c
index 1c22af5e1db..a4353c9963a 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -503,6 +503,7 @@ static const struct object_ops sock_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
sock_close_handle, /* close_handle */
sock_destroy /* destroy */
};
@@ -3905,6 +3906,7 @@ static const struct object_ops ifchange_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
ifchange_destroy /* destroy */
};
@@ -4126,6 +4128,7 @@ static const struct object_ops socket_device_ops =
default_unlink_name, /* unlink_name */
socket_device_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
diff --git a/server/symlink.c b/server/symlink.c
index 55638a502bd..5f8db81eec9 100644
--- a/server/symlink.c
+++ b/server/symlink.c
@@ -83,6 +83,7 @@ static const struct object_ops symlink_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
symlink_destroy /* destroy */
};
diff --git a/server/thread.c b/server/thread.c
index b580220c02a..b0bd041d7ba 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -119,6 +119,7 @@ static const struct object_ops thread_apc_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
thread_apc_destroy /* destroy */
};
@@ -161,6 +162,7 @@ static const struct object_ops context_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
no_destroy /* destroy */
};
@@ -210,6 +212,7 @@ static const struct object_ops thread_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
thread_get_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
destroy_thread /* destroy */
};
diff --git a/server/timer.c b/server/timer.c
index bfd74de5d4b..0fb36338959 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -88,6 +88,7 @@ static const struct object_ops timer_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
timer_destroy /* destroy */
};
diff --git a/server/token.c b/server/token.c
index 3cdb9e5be5f..87cfde364be 100644
--- a/server/token.c
+++ b/server/token.c
@@ -157,6 +157,7 @@ static const struct object_ops token_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
token_destroy /* destroy */
};
diff --git a/server/window.c b/server/window.c
index 1cad3989f6d..5978022866f 100644
--- a/server/window.c
+++ b/server/window.c
@@ -120,6 +120,7 @@ static const struct object_ops window_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
window_destroy /* destroy */
};
diff --git a/server/winstation.c b/server/winstation.c
index b3746090ccf..4b8a4972971 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -88,6 +88,7 @@ static const struct object_ops winstation_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
winstation_close_handle, /* close_handle */
winstation_destroy /* destroy */
};
@@ -128,6 +129,7 @@ static const struct object_ops desktop_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
+ no_get_inproc_sync, /* get_inproc_sync */
desktop_close_handle, /* close_handle */
desktop_destroy /* destroy */
};
--
2.50.1
From 12dac72205f3beb885210e8087b63e6c44c139e8 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Thu, 13 Mar 2025 14:09:42 -0500
Subject: [PATCH 33/57] server: Create in-process synchronization objects for
events.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/event.c | 65 ++++++++++++++++++++++++++++++++++----------
server/inproc_sync.c | 59 ++++++++++++++++++++++++++++++++++++++++
server/object.h | 4 +++
3 files changed, 113 insertions(+), 15 deletions(-)
diff --git a/server/event.c b/server/event.c
index c19cfa5ba3e..6f1b0bec022 100644
--- a/server/event.c
+++ b/server/event.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
+#include <unistd.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -55,7 +56,11 @@ struct event
struct object obj; /* object header */
struct list kernel_object; /* list of kernel object pointers */
int manual_reset; /* is it a manual reset event? */
- int signaled; /* event has been signaled */
+ union
+ {
+ int signaled; /* event has been signaled */
+ int inproc_sync; /* in-process synchronization object */
+ } u;
};
static void event_dump( struct object *obj, int verbose );
@@ -63,6 +68,8 @@ static int event_signaled( struct object *obj, struct wait_queue_entry *entry );
static void event_satisfied( struct object *obj, struct wait_queue_entry *entry );
static int event_signal( struct object *obj, unsigned int access);
static struct list *event_get_kernel_obj_list( struct object *obj );
+static int event_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
+static void event_destroy( struct object *obj );
static const struct object_ops event_ops =
{
@@ -84,9 +91,9 @@ static const struct object_ops event_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
event_get_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ event_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
- no_destroy /* destroy */
+ event_destroy /* destroy */
};
@@ -151,7 +158,10 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
/* initialize it if it didn't already exist */
list_init( &event->kernel_object );
event->manual_reset = manual_reset;
- event->signaled = initial_state;
+ if (use_inproc_sync())
+ event->u.inproc_sync = create_inproc_event( event->manual_reset, initial_state );
+ else
+ event->u.signaled = initial_state;
}
}
return event;
@@ -164,22 +174,32 @@ struct event *get_event_obj( struct process *process, obj_handle_t handle, unsig
static void pulse_event( struct event *event )
{
- event->signaled = 1;
+ event->u.signaled = 1;
/* wake up all waiters if manual reset, a single one otherwise */
wake_up( &event->obj, !event->manual_reset );
- event->signaled = 0;
+ event->u.signaled = 0;
}
void set_event( struct event *event )
{
- event->signaled = 1;
- /* wake up all waiters if manual reset, a single one otherwise */
- wake_up( &event->obj, !event->manual_reset );
+ if (use_inproc_sync())
+ {
+ set_inproc_event( event->u.inproc_sync );
+ }
+ else
+ {
+ event->u.signaled = 1;
+ /* wake up all waiters if manual reset, a single one otherwise */
+ wake_up( &event->obj, !event->manual_reset );
+ }
}
void reset_event( struct event *event )
{
- event->signaled = 0;
+ if (use_inproc_sync())
+ reset_inproc_event( event->u.inproc_sync );
+ else
+ event->u.signaled = 0;
}
static void event_dump( struct object *obj, int verbose )
@@ -187,14 +207,14 @@ static void event_dump( struct object *obj, int verbose )
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
fprintf( stderr, "Event manual=%d signaled=%d\n",
- event->manual_reset, event->signaled );
+ event->manual_reset, event->u.signaled );
}
static int event_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
- return event->signaled;
+ return event->u.signaled;
}
static void event_satisfied( struct object *obj, struct wait_queue_entry *entry )
@@ -202,7 +222,7 @@ static void event_satisfied( struct object *obj, struct wait_queue_entry *entry
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
/* Reset if it's an auto-reset event */
- if (!event->manual_reset) event->signaled = 0;
+ if (!event->manual_reset) event->u.signaled = 0;
}
static int event_signal( struct object *obj, unsigned int access )
@@ -225,6 +245,21 @@ static struct list *event_get_kernel_obj_list( struct object *obj )
return &event->kernel_object;
}
+static int event_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct event *event = (struct event *)obj;
+
+ *type = event->manual_reset ? INPROC_SYNC_MANUAL_EVENT : INPROC_SYNC_AUTO_EVENT;
+ return event->u.inproc_sync;
+}
+
+static void event_destroy( struct object *obj )
+{
+ struct event *event = (struct event *)obj;
+
+ if (use_inproc_sync()) close( event->u.inproc_sync );
+}
+
struct keyed_event *create_keyed_event( struct object *root, const struct unicode_str *name,
unsigned int attr, const struct security_descriptor *sd )
{
@@ -318,7 +353,7 @@ DECL_HANDLER(event_op)
struct event *event;
if (!(event = get_event_obj( current->process, req->handle, EVENT_MODIFY_STATE ))) return;
- reply->state = event->signaled;
+ reply->state = event->u.signaled;
switch(req->op)
{
case PULSE_EVENT:
@@ -345,7 +380,7 @@ DECL_HANDLER(query_event)
if (!(event = get_event_obj( current->process, req->handle, EVENT_QUERY_STATE ))) return;
reply->manual_reset = event->manual_reset;
- reply->state = event->signaled;
+ reply->state = event->u.signaled;
release_object( event );
}
diff --git a/server/inproc_sync.c b/server/inproc_sync.c
index de07f674bda..da148496285 100644
--- a/server/inproc_sync.c
+++ b/server/inproc_sync.c
@@ -54,6 +54,65 @@ static int get_linux_device(void)
return fd;
}
+int use_inproc_sync(void)
+{
+ return 0;
+}
+
+int create_inproc_event( int manual_reset, int signaled )
+{
+ struct ntsync_event_args args;
+ int device;
+
+ if ((device = get_linux_device()) < 0) return -1;
+
+ args.signaled = signaled;
+ args.manual = manual_reset;
+ return ioctl( device, NTSYNC_IOC_CREATE_EVENT, &args );
+}
+
+void set_inproc_event( int event )
+{
+ __u32 count;
+
+ if (!use_inproc_sync()) return;
+
+ if (debug_level) fprintf( stderr, "set_inproc_event %d\n", event );
+
+ ioctl( event, NTSYNC_IOC_EVENT_SET, &count );
+}
+
+void reset_inproc_event( int event )
+{
+ __u32 count;
+
+ if (!use_inproc_sync()) return;
+
+ if (debug_level) fprintf( stderr, "reset_inproc_event %d\n", event );
+
+ ioctl( event, NTSYNC_IOC_EVENT_RESET, &count );
+}
+
+#else
+
+int use_inproc_sync(void)
+{
+ return 0;
+}
+
+int create_inproc_event( int manual_reset, int signaled )
+{
+ return -1;
+}
+
+void set_inproc_event( int event )
+{
+}
+
+void reset_inproc_event( int event )
+{
+}
+
#endif
diff --git a/server/object.h b/server/object.h
index 07f4bb67d6b..ba99feb1a05 100644
--- a/server/object.h
+++ b/server/object.h
@@ -239,7 +239,11 @@ extern void abandon_mutexes( struct thread *thread );
/* in-process synchronization functions */
+extern int use_inproc_sync(void);
+extern int create_inproc_event( int manual_reset, int signaled );
extern int no_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
+extern void set_inproc_event( int event );
+extern void reset_inproc_event( int event );
/* serial functions */
--
2.50.1
From 97b9c292e99baba88eb401ed25b695e67bf5aa6c Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Thu, 13 Mar 2025 14:32:22 -0500
Subject: [PATCH 34/57] server: Create in-process synchronization objects for
semaphores.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/inproc_sync.c | 17 ++++++++++++
server/object.h | 1 +
server/semaphore.c | 66 ++++++++++++++++++++++++++++++++------------
3 files changed, 67 insertions(+), 17 deletions(-)
diff --git a/server/inproc_sync.c b/server/inproc_sync.c
index da148496285..f2aee9ece3f 100644
--- a/server/inproc_sync.c
+++ b/server/inproc_sync.c
@@ -71,6 +71,18 @@ int create_inproc_event( int manual_reset, int signaled )
return ioctl( device, NTSYNC_IOC_CREATE_EVENT, &args );
}
+int create_inproc_semaphore( unsigned int count, unsigned int max )
+{
+ struct ntsync_sem_args args;
+ int device;
+
+ if ((device = get_linux_device()) < 0) return -1;
+
+ args.count = count;
+ args.max = max;
+ return ioctl( device, NTSYNC_IOC_CREATE_SEM, &args );
+}
+
void set_inproc_event( int event )
{
__u32 count;
@@ -105,6 +117,11 @@ int create_inproc_event( int manual_reset, int signaled )
return -1;
}
+int create_inproc_semaphore( unsigned int count, unsigned int max )
+{
+ return -1;
+}
+
void set_inproc_event( int event )
{
}
diff --git a/server/object.h b/server/object.h
index ba99feb1a05..eea8705912d 100644
--- a/server/object.h
+++ b/server/object.h
@@ -241,6 +241,7 @@ extern void abandon_mutexes( struct thread *thread );
extern int use_inproc_sync(void);
extern int create_inproc_event( int manual_reset, int signaled );
+extern int create_inproc_semaphore( unsigned int count, unsigned int max );
extern int no_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
extern void set_inproc_event( int event );
extern void reset_inproc_event( int event );
diff --git a/server/semaphore.c b/server/semaphore.c
index 094741bf36d..f3b8179f5fe 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
+#include <unistd.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -53,14 +54,23 @@ struct type_descr semaphore_type =
struct semaphore
{
struct object obj; /* object header */
- unsigned int count; /* current count */
- unsigned int max; /* maximum possible count */
+ union
+ {
+ struct
+ {
+ unsigned int count; /* current count */
+ unsigned int max; /* maximum possible count */
+ } s;
+ int inproc_sync; /* in-process synchronization object */
+ } u;
};
static void semaphore_dump( struct object *obj, int verbose );
static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry );
static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry );
static int semaphore_signal( struct object *obj, unsigned int access );
+static int semaphore_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
+static void semaphore_destroy( struct object *obj );
static const struct object_ops semaphore_ops =
{
@@ -82,9 +92,9 @@ static const struct object_ops semaphore_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ semaphore_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
- no_destroy /* destroy */
+ semaphore_destroy /* destroy */
};
@@ -104,8 +114,15 @@ static struct semaphore *create_semaphore( struct object *root, const struct uni
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- sem->count = initial;
- sem->max = max;
+ if (use_inproc_sync())
+ {
+ sem->u.inproc_sync = create_inproc_semaphore( initial, max );
+ }
+ else
+ {
+ sem->u.s.count = initial;
+ sem->u.s.max = max;
+ }
}
}
return sem;
@@ -114,20 +131,20 @@ static struct semaphore *create_semaphore( struct object *root, const struct uni
static int release_semaphore( struct semaphore *sem, unsigned int count,
unsigned int *prev )
{
- if (prev) *prev = sem->count;
- if (sem->count + count < sem->count || sem->count + count > sem->max)
+ if (prev) *prev = sem->u.s.count;
+ if (sem->u.s.count + count < sem->u.s.count || sem->u.s.count + count > sem->u.s.max)
{
set_error( STATUS_SEMAPHORE_LIMIT_EXCEEDED );
return 0;
}
- else if (sem->count)
+ else if (sem->u.s.count)
{
/* there cannot be any thread to wake up if the count is != 0 */
- sem->count += count;
+ sem->u.s.count += count;
}
else
{
- sem->count = count;
+ sem->u.s.count = count;
wake_up( &sem->obj, count );
}
return 1;
@@ -137,22 +154,22 @@ static void semaphore_dump( struct object *obj, int verbose )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );
- fprintf( stderr, "Semaphore count=%d max=%d\n", sem->count, sem->max );
+ fprintf( stderr, "Semaphore count=%d max=%d\n", sem->u.s.count, sem->u.s.max );
}
static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );
- return (sem->count > 0);
+ return (sem->u.s.count > 0);
}
static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );
- assert( sem->count );
- sem->count--;
+ assert( sem->u.s.count );
+ sem->u.s.count--;
}
static int semaphore_signal( struct object *obj, unsigned int access )
@@ -168,6 +185,21 @@ static int semaphore_signal( struct object *obj, unsigned int access )
return release_semaphore( sem, 1, NULL );
}
+static int semaphore_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct semaphore *semaphore = (struct semaphore *)obj;
+
+ *type = INPROC_SYNC_SEMAPHORE;
+ return semaphore->u.inproc_sync;
+}
+
+static void semaphore_destroy( struct object *obj )
+{
+ struct semaphore *semaphore = (struct semaphore *)obj;
+
+ if (use_inproc_sync()) close( semaphore->u.inproc_sync );
+}
+
/* create a semaphore */
DECL_HANDLER(create_semaphore)
{
@@ -222,8 +254,8 @@ DECL_HANDLER(query_semaphore)
if ((sem = (struct semaphore *)get_handle_obj( current->process, req->handle,
SEMAPHORE_QUERY_STATE, &semaphore_ops )))
{
- reply->current = sem->count;
- reply->max = sem->max;
+ reply->current = sem->u.s.count;
+ reply->max = sem->u.s.max;
release_object( sem );
}
}
--
2.50.1
From 0b20d8142ae14745dff57d88d986b931e6f61de9 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Thu, 13 Mar 2025 14:49:49 -0500
Subject: [PATCH 35/57] server: Create in-process synchronization objects for
mutexes.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/inproc_sync.c | 26 ++++++++++
server/mutex.c | 115 +++++++++++++++++++++++++++++--------------
server/object.h | 2 +
3 files changed, 107 insertions(+), 36 deletions(-)
diff --git a/server/inproc_sync.c b/server/inproc_sync.c
index f2aee9ece3f..6471364c4de 100644
--- a/server/inproc_sync.c
+++ b/server/inproc_sync.c
@@ -83,6 +83,18 @@ int create_inproc_semaphore( unsigned int count, unsigned int max )
return ioctl( device, NTSYNC_IOC_CREATE_SEM, &args );
}
+int create_inproc_mutex( thread_id_t owner, unsigned int count )
+{
+ struct ntsync_mutex_args args;
+ int device;
+
+ if ((device = get_linux_device()) < 0) return -1;
+
+ args.owner = owner;
+ args.count = count;
+ return ioctl( device, NTSYNC_IOC_CREATE_MUTEX, &args );
+}
+
void set_inproc_event( int event )
{
__u32 count;
@@ -105,6 +117,11 @@ void reset_inproc_event( int event )
ioctl( event, NTSYNC_IOC_EVENT_RESET, &count );
}
+void abandon_inproc_mutex( thread_id_t tid, int mutex )
+{
+ ioctl( mutex, NTSYNC_IOC_MUTEX_KILL, &tid );
+}
+
#else
int use_inproc_sync(void)
@@ -122,6 +139,11 @@ int create_inproc_semaphore( unsigned int count, unsigned int max )
return -1;
}
+int create_inproc_mutex( thread_id_t owner, unsigned int count )
+{
+ return -1;
+}
+
void set_inproc_event( int event )
{
}
@@ -130,6 +152,10 @@ void reset_inproc_event( int event )
{
}
+void abandon_inproc_mutex( thread_id_t tid, int mutex )
+{
+}
+
#endif
diff --git a/server/mutex.c b/server/mutex.c
index 4218423ebac..671e1a77e36 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
+#include <unistd.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -38,6 +39,8 @@
static const WCHAR mutex_name[] = {'M','u','t','a','n','t'};
+static struct list inproc_mutexes = LIST_INIT(inproc_mutexes);
+
struct type_descr mutex_type =
{
{ mutex_name, sizeof(mutex_name) }, /* name */
@@ -53,10 +56,21 @@ struct type_descr mutex_type =
struct mutex
{
struct object obj; /* object header */
- struct thread *owner; /* mutex owner */
- unsigned int count; /* recursion count */
- int abandoned; /* has it been abandoned? */
- struct list entry; /* entry in owner thread mutex list */
+ union
+ {
+ struct
+ {
+ struct thread *owner; /* mutex owner */
+ unsigned int count; /* recursion count */
+ int abandoned; /* has it been abandoned? */
+ struct list entry; /* entry in owner thread mutex list */
+ } server;
+ struct
+ {
+ int inproc_sync; /* in-process synchronization object */
+ struct list entry; /* entry in inproc_mutexes list */
+ } inproc;
+ } u;
};
static void mutex_dump( struct object *obj, int verbose );
@@ -64,6 +78,7 @@ static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry );
static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry );
static void mutex_destroy( struct object *obj );
static int mutex_signal( struct object *obj, unsigned int access );
+static int mutex_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static const struct object_ops mutex_ops =
{
@@ -85,7 +100,7 @@ static const struct object_ops mutex_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ mutex_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mutex_destroy /* destroy */
};
@@ -94,23 +109,23 @@ static const struct object_ops mutex_ops =
/* grab a mutex for a given thread */
static void do_grab( struct mutex *mutex, struct thread *thread )
{
- assert( !mutex->count || (mutex->owner == thread) );
+ assert( !mutex->u.server.count || (mutex->u.server.owner == thread) );
- if (!mutex->count++) /* FIXME: avoid wrap-around */
+ if (!mutex->u.server.count++) /* FIXME: avoid wrap-around */
{
- assert( !mutex->owner );
- mutex->owner = thread;
- list_add_head( &thread->mutex_list, &mutex->entry );
+ assert( !mutex->u.server.owner );
+ mutex->u.server.owner = thread;
+ list_add_head( &thread->mutex_list, &mutex->u.server.entry );
}
}
/* release a mutex once the recursion count is 0 */
static void do_release( struct mutex *mutex )
{
- assert( !mutex->count );
+ assert( !mutex->u.server.count );
/* remove the mutex from the thread list of owned mutexes */
- list_remove( &mutex->entry );
- mutex->owner = NULL;
+ list_remove( &mutex->u.server.entry );
+ mutex->u.server.owner = NULL;
wake_up( &mutex->obj, 0 );
}
@@ -124,10 +139,18 @@ static struct mutex *create_mutex( struct object *root, const struct unicode_str
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- mutex->count = 0;
- mutex->owner = NULL;
- mutex->abandoned = 0;
- if (owned) do_grab( mutex, current );
+ if (use_inproc_sync())
+ {
+ mutex->u.inproc.inproc_sync = create_inproc_mutex( owned ? current->id : 0, owned ? 1 : 0 );
+ list_add_tail( &inproc_mutexes, &mutex->u.inproc.entry );
+ }
+ else
+ {
+ mutex->u.server.count = 0;
+ mutex->u.server.owner = NULL;
+ mutex->u.server.abandoned = 0;
+ if (owned) do_grab( mutex, current );
+ }
}
}
return mutex;
@@ -135,30 +158,34 @@ static struct mutex *create_mutex( struct object *root, const struct unicode_str
void abandon_mutexes( struct thread *thread )
{
+ struct mutex *mutex;
struct list *ptr;
while ((ptr = list_head( &thread->mutex_list )) != NULL)
{
- struct mutex *mutex = LIST_ENTRY( ptr, struct mutex, entry );
- assert( mutex->owner == thread );
- mutex->count = 0;
- mutex->abandoned = 1;
+ mutex = LIST_ENTRY( ptr, struct mutex, u.server.entry );
+ assert( mutex->u.server.owner == thread );
+ mutex->u.server.count = 0;
+ mutex->u.server.abandoned = 1;
do_release( mutex );
}
+
+ LIST_FOR_EACH_ENTRY(mutex, &inproc_mutexes, struct mutex, u.inproc.entry)
+ abandon_inproc_mutex( thread->id, mutex->u.inproc.inproc_sync );
}
static void mutex_dump( struct object *obj, int verbose )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
- fprintf( stderr, "Mutex count=%u owner=%p\n", mutex->count, mutex->owner );
+ fprintf( stderr, "Mutex count=%u owner=%p\n", mutex->u.server.count, mutex->u.server.owner );
}
static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
- return (!mutex->count || (mutex->owner == get_wait_queue_thread( entry )));
+ return (!mutex->u.server.count || (mutex->u.server.owner == get_wait_queue_thread( entry )));
}
static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry )
@@ -167,8 +194,8 @@ static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry
assert( obj->ops == &mutex_ops );
do_grab( mutex, get_wait_queue_thread( entry ));
- if (mutex->abandoned) make_wait_abandoned( entry );
- mutex->abandoned = 0;
+ if (mutex->u.server.abandoned) make_wait_abandoned( entry );
+ mutex->u.server.abandoned = 0;
}
static int mutex_signal( struct object *obj, unsigned int access )
@@ -181,23 +208,39 @@ static int mutex_signal( struct object *obj, unsigned int access )
set_error( STATUS_ACCESS_DENIED );
return 0;
}
- if (!mutex->count || (mutex->owner != current))
+ if (!mutex->u.server.count || (mutex->u.server.owner != current))
{
set_error( STATUS_MUTANT_NOT_OWNED );
return 0;
}
- if (!--mutex->count) do_release( mutex );
+ if (!--mutex->u.server.count) do_release( mutex );
return 1;
}
+static int mutex_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct mutex *mutex = (struct mutex *)obj;
+
+ *type = INPROC_SYNC_MUTEX;
+ return mutex->u.inproc.inproc_sync;
+}
+
static void mutex_destroy( struct object *obj )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
- if (!mutex->count) return;
- mutex->count = 0;
- do_release( mutex );
+ if (use_inproc_sync())
+ {
+ close( mutex->u.inproc.inproc_sync );
+ list_remove( &mutex->u.inproc.entry );
+ }
+ else
+ {
+ if (!mutex->u.server.count) return;
+ mutex->u.server.count = 0;
+ do_release( mutex );
+ }
}
/* create a mutex */
@@ -241,11 +284,11 @@ DECL_HANDLER(release_mutex)
if ((mutex = (struct mutex *)get_handle_obj( current->process, req->handle,
0, &mutex_ops )))
{
- if (!mutex->count || (mutex->owner != current)) set_error( STATUS_MUTANT_NOT_OWNED );
+ if (!mutex->u.server.count || (mutex->u.server.owner != current)) set_error( STATUS_MUTANT_NOT_OWNED );
else
{
- reply->prev_count = mutex->count;
- if (!--mutex->count) do_release( mutex );
+ reply->prev_count = mutex->u.server.count;
+ if (!--mutex->u.server.count) do_release( mutex );
}
release_object( mutex );
}
@@ -259,9 +302,9 @@ DECL_HANDLER(query_mutex)
if ((mutex = (struct mutex *)get_handle_obj( current->process, req->handle,
MUTANT_QUERY_STATE, &mutex_ops )))
{
- reply->count = mutex->count;
- reply->owned = (mutex->owner == current);
- reply->abandoned = mutex->abandoned;
+ reply->count = mutex->u.server.count;
+ reply->owned = (mutex->u.server.owner == current);
+ reply->abandoned = mutex->u.server.abandoned;
release_object( mutex );
}
diff --git a/server/object.h b/server/object.h
index eea8705912d..d956b1d45ad 100644
--- a/server/object.h
+++ b/server/object.h
@@ -241,10 +241,12 @@ extern void abandon_mutexes( struct thread *thread );
extern int use_inproc_sync(void);
extern int create_inproc_event( int manual_reset, int signaled );
+extern int create_inproc_mutex( thread_id_t owner, unsigned int count );
extern int create_inproc_semaphore( unsigned int count, unsigned int max );
extern int no_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
extern void set_inproc_event( int event );
extern void reset_inproc_event( int event );
+extern void abandon_inproc_mutex( thread_id_t tid, int mutex );
/* serial functions */
--
2.50.1
From 18d25058bf729c589fee11cc5e695dd5cffb3ac8 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Thu, 11 Mar 2021 20:32:58 -0600
Subject: [PATCH 36/57] server: Create in-process synchronization objects for
completion ports.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/completion.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/server/completion.c b/server/completion.c
index ac598e85229..11e39c93a99 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -25,6 +25,7 @@
#include <stdarg.h>
#include <stdio.h>
+#include <unistd.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -77,6 +78,7 @@ struct completion
struct list wait_queue;
unsigned int depth;
int closed;
+ int inproc_sync;
};
static void completion_wait_dump( struct object*, int );
@@ -157,6 +159,7 @@ static void completion_wait_satisfied( struct object *obj, struct wait_queue_ent
static void completion_dump( struct object*, int );
static int completion_signaled( struct object *obj, struct wait_queue_entry *entry );
static int completion_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
+static int completion_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void completion_destroy( struct object * );
static const struct object_ops completion_ops =
@@ -179,7 +182,7 @@ static const struct object_ops completion_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ completion_get_inproc_sync,/* get_inproc_sync */
completion_close_handle, /* close_handle */
completion_destroy /* destroy */
};
@@ -193,6 +196,7 @@ static void completion_destroy( struct object *obj)
{
free( tmp );
}
+ if (use_inproc_sync()) close( completion->inproc_sync );
}
static void completion_dump( struct object *obj, int verbose )
@@ -230,6 +234,7 @@ static int completion_close_handle( struct object *obj, struct process *process,
}
completion->closed = 1;
wake_up( obj, 0 );
+ set_inproc_event( completion->inproc_sync );
return 1;
}
@@ -263,6 +268,14 @@ static struct completion_wait *create_completion_wait( struct thread *thread )
return wait;
}
+static int completion_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct completion *completion = (struct completion *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return completion->inproc_sync;
+}
+
static struct completion *create_completion( struct object *root, const struct unicode_str *name,
unsigned int attr, unsigned int concurrent,
const struct security_descriptor *sd )
@@ -277,6 +290,7 @@ static struct completion *create_completion( struct object *root, const struct u
list_init( &completion->wait_queue );
completion->depth = 0;
completion->closed = 0;
+ completion->inproc_sync = create_inproc_event( TRUE, FALSE );
}
}
@@ -309,7 +323,11 @@ void add_completion( struct completion *completion, apc_param_t ckey, apc_param_
wake_up( &wait->obj, 1 );
if (list_empty( &completion->queue )) return;
}
- if (!list_empty( &completion->queue )) wake_up( &completion->obj, 0 );
+ if (!list_empty( &completion->queue ))
+ {
+ wake_up( &completion->obj, 0 );
+ set_inproc_event( completion->inproc_sync );
+ }
}
/* create a completion */
@@ -410,6 +428,8 @@ DECL_HANDLER(remove_completion)
reply->information = msg->information;
free( msg );
reply->wait_handle = 0;
+ if (list_empty( &completion->queue ))
+ reset_inproc_event( completion->inproc_sync );
}
release_object( completion );
--
2.50.1
From 15e1790ce28c6300a9af0359325f3accb349fc6c Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Mar 2025 16:43:36 -0500
Subject: [PATCH 37/57] server: Create in-process synchronization objects for
consoles.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/server/console.c b/server/console.c
index 7070314ed8d..58263d5372b 100644
--- a/server/console.c
+++ b/server/console.c
@@ -54,6 +54,7 @@ struct console
{
struct object obj; /* object header */
int signaled; /* is console signaled */
+ int inproc_sync; /* in-process synchronization object */
struct thread *renderer; /* console renderer thread */
struct screen_buffer *active; /* active screen buffer */
struct console_server *server; /* console server object */
@@ -74,6 +75,7 @@ static struct object *console_lookup_name( struct object *obj, struct unicode_st
unsigned int attr, struct object *root );
static struct object *console_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
+static int console_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static int console_add_queue( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops console_ops =
@@ -96,7 +98,7 @@ static const struct object_ops console_ops =
NULL, /* unlink_name */
console_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ console_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_destroy /* destroy */
};
@@ -547,6 +549,7 @@ static struct object *create_console(void)
console->renderer = NULL;
console->signaled = 0;
+ console->inproc_sync = create_inproc_event( TRUE, console->signaled );
console->active = NULL;
console->server = NULL;
console->fd = NULL;
@@ -785,6 +788,7 @@ static void console_destroy( struct object *obj )
free_async_queue( &console->read_q );
if (console->fd)
release_object( console->fd );
+ if (use_inproc_sync()) close( console->inproc_sync );
}
static struct object *create_console_connection( struct console *console )
@@ -838,6 +842,22 @@ static struct object *console_open_file( struct object *obj, unsigned int access
return grab_object( obj );
}
+static int console_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct console *console = (struct console *)obj;
+
+ /* cf. console_add_queue() */
+ if (console->server && !console->server->once_input)
+ {
+ console->server->once_input = 1;
+ if (console->server->term_fd == -1)
+ queue_host_ioctl( console->server, IOCTL_CONDRV_PEEK, 0, NULL, NULL );
+ }
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return console->inproc_sync;
+}
+
static void screen_buffer_dump( struct object *obj, int verbose )
{
struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
@@ -1583,11 +1603,16 @@ DECL_HANDLER(get_next_console_request)
if (!server->console->renderer) server->console->renderer = current;
- if (!req->signal) server->console->signaled = 0;
+ if (!req->signal)
+ {
+ server->console->signaled = 0;
+ reset_inproc_event( server->console->inproc_sync );
+ }
else if (!server->console->signaled)
{
server->console->signaled = 1;
wake_up( &server->console->obj, 0 );
+ set_inproc_event( server->console->inproc_sync );
LIST_FOR_EACH_ENTRY( screen_buffer, &server->console->screen_buffers, struct screen_buffer, entry )
wake_up( &screen_buffer->obj, 0 );
LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
--
2.50.1
From e96aa03e891664e5e0c544233f844de4ff5d0ee1 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Mar 2025 17:06:29 -0500
Subject: [PATCH 38/57] server: Create in-process synchronization objects for
console servers.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/server/console.c b/server/console.c
index 58263d5372b..a0b553cece7 100644
--- a/server/console.c
+++ b/server/console.c
@@ -145,6 +145,7 @@ struct console_server
unsigned int once_input : 1; /* flag if input thread has already been requested */
int term_fd; /* UNIX terminal fd */
struct termios termios; /* original termios */
+ int inproc_sync; /* in-process synchronization object */
};
static void console_server_dump( struct object *obj, int verbose );
@@ -155,6 +156,7 @@ static struct object *console_server_lookup_name( struct object *obj, struct uni
unsigned int attr, struct object *root );
static struct object *console_server_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
+static int console_server_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static const struct object_ops console_server_ops =
{
@@ -176,7 +178,7 @@ static const struct object_ops console_server_ops =
NULL, /* unlink_name */
console_server_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ console_server_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_server_destroy /* destroy */
};
@@ -596,6 +598,7 @@ static int queue_host_ioctl( struct console_server *server, unsigned int code, u
}
list_add_tail( &server->queue, &ioctl->entry );
wake_up( &server->obj, 0 );
+ set_inproc_event( server->inproc_sync );
if (async) set_error( STATUS_PENDING );
return 1;
}
@@ -628,6 +631,7 @@ static void disconnect_console_server( struct console_server *server )
server->console->server = NULL;
server->console = NULL;
wake_up( &server->obj, 0 );
+ set_inproc_event( server->inproc_sync );
}
}
@@ -919,6 +923,7 @@ static void console_server_destroy( struct object *obj )
assert( obj->ops == &console_server_ops );
disconnect_console_server( server );
if (server->fd) release_object( server->fd );
+ if (use_inproc_sync()) close( server->inproc_sync );
}
static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
@@ -979,6 +984,14 @@ static struct object *console_server_open_file( struct object *obj, unsigned int
return grab_object( obj );
}
+static int console_server_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct console_server *server = (struct console_server *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return server->inproc_sync;
+}
+
static struct object *create_console_server( void )
{
struct console_server *server;
@@ -988,6 +1001,7 @@ static struct object *create_console_server( void )
server->busy = 0;
server->once_input = 0;
server->term_fd = -1;
+ server->inproc_sync = create_inproc_event( TRUE, TRUE );
list_init( &server->queue );
list_init( &server->read_queue );
server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT );
@@ -1642,6 +1656,9 @@ DECL_HANDLER(get_next_console_request)
list_remove( &ioctl->entry );
}
+ if (list_empty( &server->queue ))
+ reset_inproc_event( server->inproc_sync );
+
if (ioctl)
{
struct async *async = ioctl->async;
@@ -1726,5 +1743,8 @@ DECL_HANDLER(get_next_console_request)
set_error( STATUS_PENDING );
}
+ if (list_empty( &server->queue ))
+ reset_inproc_event( server->inproc_sync );
+
release_object( server );
}
--
2.50.1
From 8980f628ec6255e321111bad3966a7ee61722fb0 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Mar 2025 17:14:45 -0500
Subject: [PATCH 39/57] server: Create in-process synchronization objects for
screen buffers.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/server/console.c b/server/console.c
index a0b553cece7..2fde411ea1b 100644
--- a/server/console.c
+++ b/server/console.c
@@ -219,6 +219,7 @@ struct screen_buffer
unsigned int id; /* buffer id */
struct fd *fd; /* for bare console, attached output fd */
struct async_queue ioctl_q; /* ioctl queue */
+ int inproc_sync; /* in-process synchronization object */
};
static void screen_buffer_dump( struct object *obj, int verbose );
@@ -227,6 +228,7 @@ static int screen_buffer_signaled( struct object *obj, struct wait_queue_entry *
static struct fd *screen_buffer_get_fd( struct object *obj );
static struct object *screen_buffer_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
+static int screen_buffer_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static const struct object_ops screen_buffer_ops =
{
@@ -248,7 +250,7 @@ static const struct object_ops screen_buffer_ops =
NULL, /* unlink_name */
screen_buffer_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ screen_buffer_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
screen_buffer_destroy /* destroy */
};
@@ -660,6 +662,7 @@ static struct object *create_screen_buffer( struct console *console )
screen_buffer->id = ++console->last_id;
screen_buffer->input = console;
+ screen_buffer->inproc_sync = create_inproc_event( TRUE, console->signaled );
init_async_queue( &screen_buffer->ioctl_q );
list_add_head( &console->screen_buffers, &screen_buffer->entry );
@@ -780,7 +783,10 @@ static void console_destroy( struct object *obj )
console->active = NULL;
LIST_FOR_EACH_ENTRY( curr, &console->screen_buffers, struct screen_buffer, entry )
+ {
curr->input = NULL;
+ reset_inproc_event( curr->inproc_sync );
+ }
LIST_FOR_EACH_ENTRY( input, &console->inputs, struct console_input, entry )
input->console = NULL;
@@ -885,6 +891,7 @@ static void screen_buffer_destroy( struct object *obj )
}
free_async_queue( &screen_buffer->ioctl_q );
if (screen_buffer->fd) release_object( screen_buffer->fd );
+ if (use_inproc_sync()) close( screen_buffer->inproc_sync );
}
static int screen_buffer_signaled( struct object *obj, struct wait_queue_entry *entry )
@@ -901,6 +908,14 @@ static struct object *screen_buffer_open_file( struct object *obj, unsigned int
return grab_object( obj );
}
+static int screen_buffer_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return screen_buffer->inproc_sync;
+}
+
static struct fd *screen_buffer_get_fd( struct object *obj )
{
struct screen_buffer *screen_buffer = (struct screen_buffer*)obj;
@@ -1621,6 +1636,8 @@ DECL_HANDLER(get_next_console_request)
{
server->console->signaled = 0;
reset_inproc_event( server->console->inproc_sync );
+ LIST_FOR_EACH_ENTRY( screen_buffer, &server->console->screen_buffers, struct screen_buffer, entry )
+ reset_inproc_event( screen_buffer->inproc_sync );
}
else if (!server->console->signaled)
{
@@ -1628,7 +1645,10 @@ DECL_HANDLER(get_next_console_request)
wake_up( &server->console->obj, 0 );
set_inproc_event( server->console->inproc_sync );
LIST_FOR_EACH_ENTRY( screen_buffer, &server->console->screen_buffers, struct screen_buffer, entry )
+ {
wake_up( &screen_buffer->obj, 0 );
+ set_inproc_event( screen_buffer->inproc_sync );
+ }
LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
wake_up( &input->obj, 0 );
LIST_FOR_EACH_ENTRY( output, &server->console->outputs, struct console_output, entry )
--
2.50.1
From 0a538bb8130a0c8385a25a3c6496b5e53ac49e3e Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Mar 2025 17:30:31 -0500
Subject: [PATCH 40/57] server: Create in-process synchronization objects for
console inputs.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/server/console.c b/server/console.c
index 2fde411ea1b..7c7b0e6ad53 100644
--- a/server/console.c
+++ b/server/console.c
@@ -311,12 +311,14 @@ struct console_input
struct fd *fd; /* pseudo-fd */
struct list entry; /* entry in console->inputs */
struct console *console; /* associated console at creation time */
+ int inproc_sync; /* in-process synchronization object */
};
static void console_input_dump( struct object *obj, int verbose );
static int console_input_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct object *console_input_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
+static int console_input_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static struct fd *console_input_get_fd( struct object *obj );
static void console_input_destroy( struct object *obj );
@@ -340,7 +342,7 @@ static const struct object_ops console_input_ops =
default_unlink_name, /* unlink_name */
console_input_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ console_input_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_input_destroy /* destroy */
};
@@ -789,7 +791,10 @@ static void console_destroy( struct object *obj )
}
LIST_FOR_EACH_ENTRY( input, &console->inputs, struct console_input, entry )
+ {
input->console = NULL;
+ reset_inproc_event( input->inproc_sync );
+ }
LIST_FOR_EACH_ENTRY( output, &console->outputs, struct console_output, entry )
output->console = NULL;
@@ -1402,6 +1407,7 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni
}
console_input->console = current->process->console;
list_add_head( ¤t->process->console->inputs, &console_input->entry );
+ console_input->inproc_sync = create_inproc_event( TRUE, current->process->console->signaled );
return &console_input->obj;
}
@@ -1500,6 +1506,14 @@ static struct object *console_input_open_file( struct object *obj, unsigned int
return grab_object( obj );
}
+static int console_input_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct console_input *console_input = (struct console_input *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return console_input->inproc_sync;
+}
+
static void console_input_destroy( struct object *obj )
{
struct console_input *console_input = (struct console_input *)obj;
@@ -1507,6 +1521,7 @@ static void console_input_destroy( struct object *obj )
assert( obj->ops == &console_input_ops );
if (console_input->fd) release_object( console_input->fd );
if (console_input->console) list_remove( &console_input->entry );
+ if (use_inproc_sync()) close( console_input->inproc_sync );
}
static void console_input_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
@@ -1638,6 +1653,8 @@ DECL_HANDLER(get_next_console_request)
reset_inproc_event( server->console->inproc_sync );
LIST_FOR_EACH_ENTRY( screen_buffer, &server->console->screen_buffers, struct screen_buffer, entry )
reset_inproc_event( screen_buffer->inproc_sync );
+ LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
+ reset_inproc_event( input->inproc_sync );
}
else if (!server->console->signaled)
{
@@ -1650,7 +1667,10 @@ DECL_HANDLER(get_next_console_request)
set_inproc_event( screen_buffer->inproc_sync );
}
LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
+ {
wake_up( &input->obj, 0 );
+ set_inproc_event( input->inproc_sync );
+ }
LIST_FOR_EACH_ENTRY( output, &server->console->outputs, struct console_output, entry )
wake_up( &output->obj, 0 );
}
--
2.50.1
From 6c54e77e240761338d3a72be51cc3bbe19fb89c7 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Mar 2025 17:35:15 -0500
Subject: [PATCH 41/57] server: Create in-process synchronization objects for
console outputs.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/console.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/server/console.c b/server/console.c
index 7c7b0e6ad53..ee8a50aad8d 100644
--- a/server/console.c
+++ b/server/console.c
@@ -373,6 +373,7 @@ struct console_output
struct fd *fd; /* pseudo-fd */
struct list entry; /* entry in console->outputs */
struct console *console; /* associated console at creation time */
+ int inproc_sync; /* in-process synchronization object */
};
static void console_output_dump( struct object *obj, int verbose );
@@ -380,6 +381,7 @@ static int console_output_signaled( struct object *obj, struct wait_queue_entry
static struct fd *console_output_get_fd( struct object *obj );
static struct object *console_output_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options );
+static int console_output_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void console_output_destroy( struct object *obj );
static const struct object_ops console_output_ops =
@@ -402,7 +404,7 @@ static const struct object_ops console_output_ops =
default_unlink_name, /* unlink_name */
console_output_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ console_output_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
console_output_destroy /* destroy */
};
@@ -797,7 +799,10 @@ static void console_destroy( struct object *obj )
}
LIST_FOR_EACH_ENTRY( output, &console->outputs, struct console_output, entry )
+ {
output->console = NULL;
+ reset_inproc_event( output->inproc_sync );
+ }
free_async_queue( &console->ioctl_q );
free_async_queue( &console->read_q );
@@ -1432,6 +1437,7 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni
}
console_output->console = current->process->console;
list_add_head( ¤t->process->console->outputs, &console_output->entry );
+ console_output->inproc_sync = create_inproc_event( TRUE, current->process->console->signaled );
return &console_output->obj;
}
@@ -1586,6 +1592,14 @@ static struct object *console_output_open_file( struct object *obj, unsigned int
return grab_object( obj );
}
+static int console_output_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct console_output *console_output = (struct console_output *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return console_output->inproc_sync;
+}
+
static void console_output_destroy( struct object *obj )
{
struct console_output *console_output = (struct console_output *)obj;
@@ -1593,6 +1607,7 @@ static void console_output_destroy( struct object *obj )
assert( obj->ops == &console_output_ops );
if (console_output->fd) release_object( console_output->fd );
if (console_output->console) list_remove( &console_output->entry );
+ if (use_inproc_sync()) close( console_output->inproc_sync );
}
static void console_output_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
@@ -1655,6 +1670,8 @@ DECL_HANDLER(get_next_console_request)
reset_inproc_event( screen_buffer->inproc_sync );
LIST_FOR_EACH_ENTRY( input, &server->console->inputs, struct console_input, entry )
reset_inproc_event( input->inproc_sync );
+ LIST_FOR_EACH_ENTRY( output, &server->console->outputs, struct console_output, entry )
+ reset_inproc_event( output->inproc_sync );
}
else if (!server->console->signaled)
{
@@ -1672,7 +1689,10 @@ DECL_HANDLER(get_next_console_request)
set_inproc_event( input->inproc_sync );
}
LIST_FOR_EACH_ENTRY( output, &server->console->outputs, struct console_output, entry )
+ {
wake_up( &output->obj, 0 );
+ set_inproc_event( output->inproc_sync );
+ }
}
if (req->read)
--
2.50.1
From 64ce583ef340943844718b10eb2e2d5e00a2c77c Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:11:03 -0600
Subject: [PATCH 42/57] server: Create in-process synchronization objects for
debug objects.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/debugger.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/server/debugger.c b/server/debugger.c
index cab5f95eefd..2aaa87ed792 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -71,6 +71,7 @@ struct debug_obj
struct object obj; /* object header */
struct list event_queue; /* pending events queue */
unsigned int flags; /* debug flags */
+ int inproc_sync; /* in-process synchronization object */
};
@@ -105,6 +106,7 @@ static const struct object_ops debug_event_ops =
static void debug_obj_dump( struct object *obj, int verbose );
static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry );
+static int debug_obj_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void debug_obj_destroy( struct object *obj );
static const struct object_ops debug_obj_ops =
@@ -127,7 +129,7 @@ static const struct object_ops debug_obj_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ debug_obj_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
debug_obj_destroy /* destroy */
};
@@ -255,6 +257,7 @@ static void link_event( struct debug_obj *debug_obj, struct debug_event *event )
/* grab reference since debugger could be killed while trying to wake up */
grab_object( debug_obj );
wake_up( &debug_obj->obj, 0 );
+ set_inproc_event( debug_obj->inproc_sync );
release_object( debug_obj );
}
}
@@ -267,6 +270,7 @@ static void resume_event( struct debug_obj *debug_obj, struct debug_event *event
{
grab_object( debug_obj );
wake_up( &debug_obj->obj, 0 );
+ set_inproc_event( debug_obj->inproc_sync );
release_object( debug_obj );
}
}
@@ -332,6 +336,14 @@ static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entr
return find_event_to_send( debug_obj ) != NULL;
}
+static int debug_obj_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct debug_obj *debug_obj = (struct debug_obj *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return debug_obj->inproc_sync;
+}
+
static void debug_obj_destroy( struct object *obj )
{
struct list *ptr;
@@ -344,6 +356,8 @@ static void debug_obj_destroy( struct object *obj )
/* free all pending events */
while ((ptr = list_head( &debug_obj->event_queue )))
unlink_event( debug_obj, LIST_ENTRY( ptr, struct debug_event, entry ));
+
+ if (use_inproc_sync()) close( debug_obj->inproc_sync );
}
struct debug_obj *get_debug_obj( struct process *process, obj_handle_t handle, unsigned int access )
@@ -363,6 +377,7 @@ static struct debug_obj *create_debug_obj( struct object *root, const struct uni
{
debug_obj->flags = flags;
list_init( &debug_obj->event_queue );
+ debug_obj->inproc_sync = create_inproc_event( TRUE, FALSE );
}
}
return debug_obj;
@@ -571,6 +586,9 @@ DECL_HANDLER(wait_debug_event)
reply->tid = get_thread_id( event->sender );
alloc_event_handles( event, current->process );
set_reply_data( &event->data, min( get_reply_max_size(), sizeof(event->data) ));
+
+ if (!find_event_to_send( debug_obj ))
+ reset_inproc_event( debug_obj->inproc_sync );
}
else
{
--
2.50.1
From 99a8416aa0210a633b2a4a204564473f1e6c14e2 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 10 Mar 2021 11:02:42 -0600
Subject: [PATCH 43/57] server: Create in-process synchronization objects for
device managers.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/device.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/server/device.c b/server/device.c
index 1f9ceffd8d0..3c2bee4c485 100644
--- a/server/device.c
+++ b/server/device.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <unistd.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -93,10 +94,12 @@ struct device_manager
struct list requests; /* list of pending irps across all devices */
struct irp_call *current_call; /* call currently executed on client side */
struct wine_rb_tree kernel_objects; /* map of objects that have client side pointer associated */
+ int inproc_sync; /* in-process synchronization object */
};
static void device_manager_dump( struct object *obj, int verbose );
static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry );
+static int device_manager_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void device_manager_destroy( struct object *obj );
static const struct object_ops device_manager_ops =
@@ -119,7 +122,7 @@ static const struct object_ops device_manager_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ device_manager_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
device_manager_destroy /* destroy */
};
@@ -422,7 +425,12 @@ static void add_irp_to_queue( struct device_manager *manager, struct irp_call *i
irp->thread = thread ? (struct thread *)grab_object( thread ) : NULL;
if (irp->file) list_add_tail( &irp->file->requests, &irp->dev_entry );
list_add_tail( &manager->requests, &irp->mgr_entry );
- if (list_head( &manager->requests ) == &irp->mgr_entry) wake_up( &manager->obj, 0 ); /* first one */
+ if (list_head( &manager->requests ) == &irp->mgr_entry)
+ {
+ /* first one */
+ wake_up( &manager->obj, 0 );
+ set_inproc_event( manager->inproc_sync );
+ }
}
static struct object *device_open_file( struct object *obj, unsigned int access,
@@ -764,6 +772,9 @@ static void delete_file( struct device_file *file )
set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 );
}
+ if (list_empty( &file->device->manager->requests ))
+ reset_inproc_event( file->device->manager->inproc_sync );
+
release_object( file );
}
@@ -795,6 +806,14 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry
return !list_empty( &manager->requests );
}
+static int device_manager_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct device_manager *manager = (struct device_manager *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return manager->inproc_sync;
+}
+
static void device_manager_destroy( struct object *obj )
{
struct device_manager *manager = (struct device_manager *)obj;
@@ -829,6 +848,8 @@ static void device_manager_destroy( struct object *obj )
assert( !irp->file && !irp->async );
release_object( irp );
}
+
+ if (use_inproc_sync()) close( manager->inproc_sync );
}
static struct device_manager *create_device_manager(void)
@@ -838,6 +859,7 @@ static struct device_manager *create_device_manager(void)
if ((manager = alloc_object( &device_manager_ops )))
{
manager->current_call = NULL;
+ manager->inproc_sync = create_inproc_event( TRUE, FALSE );
list_init( &manager->devices );
list_init( &manager->requests );
wine_rb_init( &manager->kernel_objects, compare_kernel_object );
@@ -1027,6 +1049,10 @@ DECL_HANDLER(get_next_device_request)
}
list_remove( &irp->mgr_entry );
list_init( &irp->mgr_entry );
+
+ if (list_empty( &manager->requests ))
+ reset_inproc_event( manager->inproc_sync );
+
/* we already own the object if it's only on manager queue */
if (irp->file) grab_object( irp );
manager->current_call = irp;
--
2.50.1
From 7f372da682f0fccda5819a4ad48e7bb83577a2d6 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:13:20 -0600
Subject: [PATCH 44/57] server: Create in-process synchronization objects for
keyed events.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/event.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/server/event.c b/server/event.c
index 6f1b0bec022..2b93ae2fa76 100644
--- a/server/event.c
+++ b/server/event.c
@@ -114,10 +114,13 @@ struct type_descr keyed_event_type =
struct keyed_event
{
struct object obj; /* object header */
+ int inproc_sync; /* in-process synchronization object */
};
static void keyed_event_dump( struct object *obj, int verbose );
static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry );
+static int keyed_event_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
+static void keyed_event_destroy( struct object *obj );
static const struct object_ops keyed_event_ops =
{
@@ -139,9 +142,9 @@ static const struct object_ops keyed_event_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ keyed_event_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
- no_destroy /* destroy */
+ keyed_event_destroy /* destroy */
};
@@ -270,6 +273,7 @@ struct keyed_event *create_keyed_event( struct object *root, const struct unicod
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
+ event->inproc_sync = create_inproc_event( TRUE, TRUE );
}
}
return event;
@@ -313,6 +317,21 @@ static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *en
return 0;
}
+static int keyed_event_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct keyed_event *event = (struct keyed_event *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return event->inproc_sync;
+}
+
+static void keyed_event_destroy( struct object *obj )
+{
+ struct keyed_event *event = (struct keyed_event *)obj;
+
+ if (use_inproc_sync()) close( event->inproc_sync );
+}
+
/* create an event */
DECL_HANDLER(create_event)
{
--
2.50.1
From c4417145ba749dd13d38590d8ee8c0d0dfb29ec5 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:16:53 -0600
Subject: [PATCH 45/57] server: Create in-process synchronization objects for
processes.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/process.c | 15 ++++++++++++++-
server/process.h | 1 +
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/server/process.c b/server/process.c
index d5f3c1963cb..960342a1eaa 100644
--- a/server/process.c
+++ b/server/process.c
@@ -95,6 +95,7 @@ static unsigned int process_map_access( struct object *obj, unsigned int access
static struct security_descriptor *process_get_sd( struct object *obj );
static void process_poll_event( struct fd *fd, int event );
static struct list *process_get_kernel_obj_list( struct object *obj );
+static int process_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void process_destroy( struct object *obj );
static void terminate_process( struct process *process, struct thread *skip, int exit_code );
@@ -118,7 +119,7 @@ static const struct object_ops process_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
process_get_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ process_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
process_destroy /* destroy */
};
@@ -689,6 +690,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
process->rawinput_device_count = 0;
process->rawinput_mouse = NULL;
process->rawinput_kbd = NULL;
+ process->inproc_sync = create_inproc_event( TRUE, FALSE );
memset( &process->image_info, 0, sizeof(process->image_info) );
list_init( &process->rawinput_entry );
list_init( &process->kernel_object );
@@ -789,6 +791,8 @@ static void process_destroy( struct object *obj )
free( process->rawinput_devices );
free( process->dir_cache );
free( process->image );
+
+ if (use_inproc_sync()) close( process->inproc_sync );
}
/* dump a process on stdout for debugging purposes */
@@ -822,6 +826,14 @@ static struct list *process_get_kernel_obj_list( struct object *obj )
return &process->kernel_object;
}
+static int process_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct process *process = (struct process *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return process->inproc_sync;
+}
+
static struct security_descriptor *process_get_sd( struct object *obj )
{
static struct security_descriptor *process_default_sd;
@@ -986,6 +998,7 @@ static void process_killed( struct process *process )
release_job_process( process );
start_sigkill_timer( process );
wake_up( &process->obj, 0 );
+ set_inproc_event( process->inproc_sync );
}
/* add a thread to a process running threads list */
diff --git a/server/process.h b/server/process.h
index dfe8d628538..59ca4ecbabb 100644
--- a/server/process.h
+++ b/server/process.h
@@ -87,6 +87,7 @@ struct process
struct list rawinput_entry; /* entry in the rawinput process list */
struct list kernel_object; /* list of kernel object pointers */
struct pe_image_info image_info; /* main exe image info */
+ int inproc_sync; /* in-process synchronization object */
};
/* process functions */
--
2.50.1
From b2f8520e512715b4a9d103b14374e52157b5bab7 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:17:35 -0600
Subject: [PATCH 46/57] server: Create in-process synchronization objects for
jobs.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/process.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/server/process.c b/server/process.c
index 960342a1eaa..0c2ef8bb20d 100644
--- a/server/process.c
+++ b/server/process.c
@@ -194,6 +194,7 @@ struct type_descr job_type =
static void job_dump( struct object *obj, int verbose );
static int job_signaled( struct object *obj, struct wait_queue_entry *entry );
+static int job_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
static void job_destroy( struct object *obj );
@@ -211,6 +212,7 @@ struct job
struct job *parent;
struct list parent_job_entry; /* list entry for parent job */
struct list child_job_list; /* list of child jobs */
+ int inproc_sync; /* in-process synchronization object */
};
static const struct object_ops job_ops =
@@ -233,7 +235,7 @@ static const struct object_ops job_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ job_get_inproc_sync, /* get_inproc_sync */
job_close_handle, /* close_handle */
job_destroy /* destroy */
};
@@ -258,6 +260,7 @@ static struct job *create_job_object( struct object *root, const struct unicode_
job->completion_port = NULL;
job->completion_key = 0;
job->parent = NULL;
+ job->inproc_sync = create_inproc_event( TRUE, FALSE );
}
}
return job;
@@ -414,6 +417,15 @@ static void terminate_job( struct job *job, int exit_code )
job->terminating = 0;
job->signaled = 1;
wake_up( &job->obj, 0 );
+ set_inproc_event( job->inproc_sync );
+}
+
+static int job_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct job *job = (struct job *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return job->inproc_sync;
}
static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
@@ -444,6 +456,8 @@ static void job_destroy( struct object *obj )
list_remove( &job->parent_job_entry );
release_object( job->parent );
}
+
+ if (use_inproc_sync()) close( job->inproc_sync );
}
static void job_dump( struct object *obj, int verbose )
--
2.50.1
From acb737ad39091c72fab16c1839f1429bec610868 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:24:15 -0600
Subject: [PATCH 47/57] server: Create in-process synchronization objects for
message queues.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/queue.c | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 23fb453aedb..4717281ea0e 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -135,6 +135,7 @@ struct msg_queue
int keystate_lock; /* owns an input keystate lock */
queue_shm_t *shared; /* queue in session shared memory */
unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
+ int inproc_sync; /* in-process synchronization object */
};
struct hotkey
@@ -152,6 +153,7 @@ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *ent
static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry );
static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry );
+static int msg_queue_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void msg_queue_destroy( struct object *obj );
static void msg_queue_poll_event( struct fd *fd, int event );
static void thread_input_dump( struct object *obj, int verbose );
@@ -178,7 +180,7 @@ static const struct object_ops msg_queue_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ msg_queue_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
msg_queue_destroy /* destroy */
};
@@ -317,6 +319,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue->last_get_msg = current_time;
queue->keystate_lock = 0;
queue->ignore_post_msg = 0;
+ queue->inproc_sync = create_inproc_event( TRUE, FALSE );
list_init( &queue->send_result );
list_init( &queue->callback_result );
list_init( &queue->pending_timers );
@@ -733,7 +736,11 @@ static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits )
}
SHARED_WRITE_END;
- if (is_signaled( queue )) wake_up( &queue->obj, 0 );
+ if (is_signaled( queue ))
+ {
+ wake_up( &queue->obj, 0 );
+ set_inproc_event( queue->inproc_sync );
+ }
}
/* clear some queue bits */
@@ -753,6 +760,8 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
if (queue->keystate_lock) unlock_input_keystate( queue->input );
queue->keystate_lock = 0;
}
+ if (!is_signaled( queue ))
+ reset_inproc_event( queue->inproc_sync );
}
/* check if message is matched by the filter */
@@ -1346,6 +1355,15 @@ static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *en
shared->changed_mask = 0;
}
SHARED_WRITE_END;
+ reset_inproc_event( queue->inproc_sync );
+}
+
+static int msg_queue_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct msg_queue *queue = (struct msg_queue *)obj;
+
+ *type = INPROC_SYNC_QUEUE;
+ return queue->inproc_sync;
}
static void msg_queue_destroy( struct object *obj )
@@ -1391,6 +1409,7 @@ static void msg_queue_destroy( struct object *obj )
if (queue->hooks) release_object( queue->hooks );
if (queue->fd) release_object( queue->fd );
if (queue->shared) free_shared_object( queue->shared );
+ if (use_inproc_sync()) close( queue->inproc_sync );
}
static void msg_queue_poll_event( struct fd *fd, int event )
@@ -1401,6 +1420,7 @@ static void msg_queue_poll_event( struct fd *fd, int event )
if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 );
else set_fd_events( queue->fd, 0 );
wake_up( &queue->obj, 0 );
+ set_inproc_event( queue->inproc_sync );
}
static void thread_input_dump( struct object *obj, int verbose )
@@ -3185,7 +3205,15 @@ DECL_HANDLER(set_queue_mask)
}
SHARED_WRITE_END;
}
- else wake_up( &queue->obj, 0 );
+ else
+ {
+ wake_up( &queue->obj, 0 );
+ set_inproc_event( queue->inproc_sync );
+ }
+ }
+ else
+ {
+ reset_inproc_event( queue->inproc_sync );
}
}
}
@@ -3207,6 +3235,9 @@ DECL_HANDLER(get_queue_status)
shared->changed_bits &= ~req->clear_bits;
}
SHARED_WRITE_END;
+
+ if (!is_signaled( queue ))
+ reset_inproc_event( queue->inproc_sync );
}
else reply->wake_bits = reply->changed_bits = 0;
}
@@ -3405,6 +3436,9 @@ DECL_HANDLER(get_message)
}
SHARED_WRITE_END;
+ if (!is_signaled( queue ))
+ reset_inproc_event( queue->inproc_sync );
+
/* then check for posted messages */
if ((filter & QS_POSTMESSAGE) &&
get_posted_message( queue, queue->ignore_post_msg, get_win, req->get_first, req->get_last, req->flags, reply ))
@@ -3474,6 +3508,7 @@ DECL_HANDLER(get_message)
}
SHARED_WRITE_END;
+ reset_inproc_event( queue->inproc_sync );
set_error( STATUS_PENDING ); /* FIXME */
return;
--
2.50.1
From a4db0541ebb4e316c6306c8f8e43e8b0446e78e7 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:26:35 -0600
Subject: [PATCH 48/57] server: Create in-process synchronization objects for
threads.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/thread.c | 14 +++++++++++++-
server/thread.h | 1 +
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/server/thread.c b/server/thread.c
index b0bd041d7ba..f665bb86c3a 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -190,6 +190,7 @@ static int thread_signaled( struct object *obj, struct wait_queue_entry *entry )
static unsigned int thread_map_access( struct object *obj, unsigned int access );
static void thread_poll_event( struct fd *fd, int event );
static struct list *thread_get_kernel_obj_list( struct object *obj );
+static int thread_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void destroy_thread( struct object *obj );
static const struct object_ops thread_ops =
@@ -212,7 +213,7 @@ static const struct object_ops thread_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
thread_get_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ thread_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
destroy_thread /* destroy */
};
@@ -421,6 +422,7 @@ static inline void init_thread_structure( struct thread *thread )
thread->token = NULL;
thread->desc = NULL;
thread->desc_len = 0;
+ thread->inproc_sync = create_inproc_event( TRUE, FALSE );
thread->creation_time = current_time;
thread->exit_time = 0;
@@ -578,6 +580,14 @@ static struct list *thread_get_kernel_obj_list( struct object *obj )
return &thread->kernel_object;
}
+static int thread_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct thread *thread = (struct thread *)obj;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ return thread->inproc_sync;
+}
+
/* cleanup everything that is no longer needed by a dead thread */
/* used by destroy_thread and kill_thread */
static void cleanup_thread( struct thread *thread )
@@ -633,6 +643,7 @@ static void destroy_thread( struct object *obj )
release_object( thread->process );
if (thread->id) free_ptid( thread->id );
if (thread->token) release_object( thread->token );
+ if (use_inproc_sync()) close( thread->inproc_sync );
}
/* dump a thread on stdout for debugging purposes */
@@ -1519,6 +1530,7 @@ void kill_thread( struct thread *thread, int violent_death )
kill_console_processes( thread, 0 );
abandon_mutexes( thread );
wake_up( &thread->obj, 0 );
+ set_inproc_event( thread->inproc_sync );
if (violent_death) send_thread_signal( thread, SIGQUIT );
cleanup_thread( thread );
remove_process_thread( thread->process, thread );
diff --git a/server/thread.h b/server/thread.h
index 7a4eb983733..980ebd7d17c 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -96,6 +96,7 @@ struct thread
data_size_t desc_len; /* thread description length in bytes */
WCHAR *desc; /* thread description string */
struct completion_wait *completion_wait; /* completion port wait object the thread is associated with */
+ int inproc_sync; /* in-process synchronization object */
};
extern struct thread *current;
--
2.50.1
From 1d50c451efa7d8ee1d3904610a845adeb27f9ea2 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:29:38 -0600
Subject: [PATCH 49/57] server: Create in-process synchronization objects for
timers.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/timer.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/server/timer.c b/server/timer.c
index 0fb36338959..4d159653d63 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -26,6 +26,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <stdarg.h>
+#include <unistd.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -52,20 +53,22 @@ struct type_descr timer_type =
struct timer
{
- struct object obj; /* object header */
- int manual; /* manual reset */
- int signaled; /* current signaled state */
- unsigned int period; /* timer period in ms */
- abstime_t when; /* next expiration */
- struct timeout_user *timeout; /* timeout user */
- struct thread *thread; /* thread that set the APC function */
- client_ptr_t callback; /* callback APC function */
- client_ptr_t arg; /* callback argument */
+ struct object obj; /* object header */
+ int manual; /* manual reset */
+ int signaled; /* current signaled state */
+ unsigned int period; /* timer period in ms */
+ abstime_t when; /* next expiration */
+ struct timeout_user *timeout; /* timeout user */
+ struct thread *thread; /* thread that set the APC function */
+ client_ptr_t callback; /* callback APC function */
+ client_ptr_t arg; /* callback argument */
+ int inproc_sync; /* in-process synchronization object */
};
static void timer_dump( struct object *obj, int verbose );
static int timer_signaled( struct object *obj, struct wait_queue_entry *entry );
static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry );
+static int timer_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
static void timer_destroy( struct object *obj );
static const struct object_ops timer_ops =
@@ -88,7 +91,7 @@ static const struct object_ops timer_ops =
default_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ timer_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
timer_destroy /* destroy */
};
@@ -111,6 +114,7 @@ static struct timer *create_timer( struct object *root, const struct unicode_str
timer->period = 0;
timer->timeout = NULL;
timer->thread = NULL;
+ timer->inproc_sync = create_inproc_event( manual, FALSE );
}
}
return timer;
@@ -153,6 +157,7 @@ static void timer_callback( void *private )
/* wake up waiters */
timer->signaled = 1;
wake_up( &timer->obj, 0 );
+ set_inproc_event( timer->inproc_sync );
}
/* cancel a running timer */
@@ -183,6 +188,7 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
{
period = 0; /* period doesn't make any sense for a manual timer */
timer->signaled = 0;
+ reset_inproc_event( timer->inproc_sync );
}
timer->when = (expire <= 0) ? expire - monotonic_time : max( expire, current_time );
timer->period = period;
@@ -217,6 +223,14 @@ static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry
if (!timer->manual) timer->signaled = 0;
}
+static int timer_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct timer *timer = (struct timer *)obj;
+
+ *type = timer->manual ? INPROC_SYNC_MANUAL_SERVER : INPROC_SYNC_AUTO_SERVER;
+ return timer->inproc_sync;
+}
+
static void timer_destroy( struct object *obj )
{
struct timer *timer = (struct timer *)obj;
@@ -224,6 +238,7 @@ static void timer_destroy( struct object *obj )
if (timer->timeout) remove_timeout_user( timer->timeout );
if (timer->thread) release_object( timer->thread );
+ if (use_inproc_sync()) close( timer->inproc_sync );
}
/* create a timer */
--
2.50.1
From 08effd6967085f6433a4689bf177605d1b81b95b Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 17:40:57 -0600
Subject: [PATCH 50/57] server: Create in-process synchronization objects for
fd-based objects.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
server/change.c | 2 +-
server/device.c | 2 +-
server/fd.c | 25 ++++++++++++++++++++++++-
server/file.c | 2 +-
server/file.h | 1 +
server/mailslot.c | 6 +++---
server/named_pipe.c | 8 ++++----
server/serial.c | 2 +-
server/sock.c | 2 +-
9 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/server/change.c b/server/change.c
index f65b865d138..53445dfd360 100644
--- a/server/change.c
+++ b/server/change.c
@@ -124,7 +124,7 @@ static const struct object_ops dir_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
dir_close_handle, /* close_handle */
dir_destroy /* destroy */
};
diff --git a/server/device.c b/server/device.c
index 3c2bee4c485..8c5ac281537 100644
--- a/server/device.c
+++ b/server/device.c
@@ -233,7 +233,7 @@ static const struct object_ops device_file_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
device_file_get_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
device_file_close_handle, /* close_handle */
device_file_destroy /* destroy */
};
diff --git a/server/fd.c b/server/fd.c
index c6a0e366aca..793b58c9275 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -159,6 +159,7 @@ struct fd
struct completion *completion; /* completion object attached to this fd */
apc_param_t comp_key; /* completion key to set in completion events */
unsigned int comp_flags; /* completion flags */
+ int inproc_sync; /* in-process synchronization object */
};
static void fd_dump( struct object *obj, int verbose );
@@ -1668,6 +1669,7 @@ static void fd_destroy( struct object *obj )
if (fd->unix_fd != -1) close( fd->unix_fd );
free( fd->unix_name );
}
+ if (use_inproc_sync()) close( fd->inproc_sync );
}
/* check if the desired access is possible without violating */
@@ -1786,6 +1788,7 @@ static struct fd *alloc_fd_object(void)
fd->poll_index = -1;
fd->completion = NULL;
fd->comp_flags = 0;
+ fd->inproc_sync = create_inproc_event( TRUE, fd->signaled );
init_async_queue( &fd->read_q );
init_async_queue( &fd->write_q );
init_async_queue( &fd->wait_q );
@@ -1826,6 +1829,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
fd->poll_index = -1;
fd->completion = NULL;
fd->comp_flags = 0;
+ fd->inproc_sync = create_inproc_event( TRUE, fd->signaled );
fd->no_fd_status = STATUS_BAD_DEVICE_TYPE;
init_async_queue( &fd->read_q );
init_async_queue( &fd->write_q );
@@ -2306,7 +2310,15 @@ void set_fd_signaled( struct fd *fd, int signaled )
{
if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return;
fd->signaled = signaled;
- if (signaled) wake_up( fd->user, 0 );
+ if (signaled)
+ {
+ wake_up( fd->user, 0 );
+ set_inproc_event( fd->inproc_sync );
+ }
+ else
+ {
+ reset_inproc_event( fd->inproc_sync );
+ }
}
/* check if events are pending and if yes return which one(s) */
@@ -2348,6 +2360,17 @@ WCHAR *default_fd_get_full_name( struct object *obj, data_size_t max, data_size_
return ret;
}
+int default_fd_get_inproc_sync( struct object *obj, enum inproc_sync_type *type )
+{
+ struct fd *fd = get_obj_fd( obj );
+ int ret;
+
+ *type = INPROC_SYNC_MANUAL_SERVER;
+ ret = fd->inproc_sync;
+ release_object( fd );
+ return ret;
+}
+
int default_fd_get_poll_events( struct fd *fd )
{
int events = 0;
diff --git a/server/file.c b/server/file.c
index a35da0eb1b3..cc8795f510d 100644
--- a/server/file.c
+++ b/server/file.c
@@ -135,7 +135,7 @@ static const struct object_ops file_ops =
NULL, /* unlink_name */
file_open_file, /* open_file */
file_get_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
file_destroy /* destroy */
};
diff --git a/server/file.h b/server/file.h
index 69c0efdb5b5..bfb48b5a598 100644
--- a/server/file.h
+++ b/server/file.h
@@ -110,6 +110,7 @@ extern void get_nt_name( struct fd *fd, struct unicode_str *name );
extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry );
extern WCHAR *default_fd_get_full_name( struct object *obj, data_size_t max, data_size_t *ret_len );
+extern int default_fd_get_inproc_sync( struct object *obj, enum inproc_sync_type *type );
extern int default_fd_get_poll_events( struct fd *fd );
extern void default_poll_event( struct fd *fd, int event );
extern void fd_cancel_async( struct fd *fd, struct async *async );
diff --git a/server/mailslot.c b/server/mailslot.c
index edee2534e6e..bd52815c614 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -94,7 +94,7 @@ static const struct object_ops mailslot_ops =
default_unlink_name, /* unlink_name */
mailslot_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync,/* get_inproc_sync */
no_close_handle, /* close_handle */
mailslot_destroy /* destroy */
};
@@ -156,7 +156,7 @@ static const struct object_ops mail_writer_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mail_writer_destroy /* destroy */
};
@@ -253,7 +253,7 @@ static const struct object_ops mailslot_device_file_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
mailslot_device_file_destroy /* destroy */
};
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 8713c2a8360..607d3d6e06e 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -180,7 +180,7 @@ static const struct object_ops pipe_server_ops =
NULL, /* unlink_name */
pipe_server_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
async_close_obj_handle, /* close_handle */
pipe_server_destroy /* destroy */
};
@@ -225,7 +225,7 @@ static const struct object_ops pipe_client_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
async_close_obj_handle, /* close_handle */
pipe_end_destroy /* destroy */
};
@@ -306,7 +306,7 @@ static const struct object_ops named_pipe_device_file_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
named_pipe_device_file_destroy /* destroy */
};
@@ -357,7 +357,7 @@ static const struct object_ops named_pipe_dir_ops =
NULL, /* unlink_name */
named_pipe_dir_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
named_pipe_dir_destroy /* destroy */
};
diff --git a/server/serial.c b/server/serial.c
index df242058a43..93753328d4d 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -103,7 +103,7 @@ static const struct object_ops serial_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
no_close_handle, /* close_handle */
serial_destroy /* destroy */
};
diff --git a/server/sock.c b/server/sock.c
index a4353c9963a..71a65c26b83 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -503,7 +503,7 @@ static const struct object_ops sock_ops =
NULL, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
- no_get_inproc_sync, /* get_inproc_sync */
+ default_fd_get_inproc_sync, /* get_inproc_sync */
sock_close_handle, /* close_handle */
sock_destroy /* destroy */
};
--
2.50.1
From fde1345b32be77a069d5ad5a4d2d839be446a7d8 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Wed, 19 Mar 2025 19:32:55 -0500
Subject: [PATCH 51/57] server: Add a request to retrieve the in-process
synchronization object from a handle.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
include/wine/server_protocol.h | 18 +++++++++++++++++-
server/inproc_sync.c | 26 ++++++++++++++++++++++++++
server/protocol.def | 8 ++++++++
server/request_handlers.h | 7 +++++++
server/request_trace.h | 14 ++++++++++++++
5 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index f7a6a42c405..d36e8c2b192 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -6001,6 +6001,19 @@ struct get_linux_sync_device_reply
};
+struct get_linux_sync_obj_request
+{
+ struct request_header __header;
+ obj_handle_t handle;
+};
+struct get_linux_sync_obj_reply
+{
+ struct reply_header __header;
+ int type;
+ unsigned int access;
+};
+
+
enum request
{
REQ_new_process,
@@ -6301,6 +6314,7 @@ enum request
REQ_get_next_thread,
REQ_set_keyboard_repeat,
REQ_get_linux_sync_device,
+ REQ_get_linux_sync_obj,
REQ_NB_REQUESTS
};
@@ -6606,6 +6620,7 @@ union generic_request
struct get_next_thread_request get_next_thread_request;
struct set_keyboard_repeat_request set_keyboard_repeat_request;
struct get_linux_sync_device_request get_linux_sync_device_request;
+ struct get_linux_sync_obj_request get_linux_sync_obj_request;
};
union generic_reply
{
@@ -6909,8 +6924,9 @@ union generic_reply
struct get_next_thread_reply get_next_thread_reply;
struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
struct get_linux_sync_device_reply get_linux_sync_device_reply;
+ struct get_linux_sync_obj_reply get_linux_sync_obj_reply;
};
-#define SERVER_PROTOCOL_VERSION 885
+#define SERVER_PROTOCOL_VERSION 886
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/inproc_sync.c b/server/inproc_sync.c
index 6471364c4de..c6f79081b6f 100644
--- a/server/inproc_sync.c
+++ b/server/inproc_sync.c
@@ -172,3 +172,29 @@ DECL_HANDLER(get_linux_sync_device)
set_error( STATUS_NOT_IMPLEMENTED );
#endif
}
+
+DECL_HANDLER(get_linux_sync_obj)
+{
+#ifdef NTSYNC_IOC_EVENT_READ
+ struct object *obj;
+ int fd;
+
+ if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
+ {
+ enum inproc_sync_type type;
+
+ if ((fd = obj->ops->get_inproc_sync( obj, &type )) >= 0)
+ {
+ reply->type = type;
+ reply->access = get_handle_access( current->process, req->handle );
+ send_client_fd( current->process, fd, req->handle );
+ }
+ else
+ set_error( STATUS_NOT_IMPLEMENTED );
+
+ release_object( obj );
+ }
+#else
+ set_error( STATUS_NOT_IMPLEMENTED );
+#endif
+}
diff --git a/server/protocol.def b/server/protocol.def
index 1ed8960d303..8571ec62a54 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -4160,3 +4160,11 @@ enum inproc_sync_type
/* Obtain a fd for the ntsync device */
@REQ(get_linux_sync_device)
@END
+
+/* Get the in-process synchronization fd associated with the waitable handle */
+@REQ(get_linux_sync_obj)
+ obj_handle_t handle; /* handle to the object */
+@REPLY
+ int type; /* object type */
+ unsigned int access; /* handle access rights */
+@END
diff --git a/server/request_handlers.h b/server/request_handlers.h
index dfed7904738..11ef472c579 100644
--- a/server/request_handlers.h
+++ b/server/request_handlers.h
@@ -305,6 +305,7 @@ DECL_HANDLER(get_next_process);
DECL_HANDLER(get_next_thread);
DECL_HANDLER(set_keyboard_repeat);
DECL_HANDLER(get_linux_sync_device);
+DECL_HANDLER(get_linux_sync_obj);
typedef void (*req_handler)( const void *req, void *reply );
static const req_handler req_handlers[REQ_NB_REQUESTS] =
@@ -607,6 +608,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_next_thread,
(req_handler)req_set_keyboard_repeat,
(req_handler)req_get_linux_sync_device,
+ (req_handler)req_get_linux_sync_obj,
};
C_ASSERT( sizeof(abstime_t) == 8 );
@@ -2305,3 +2307,8 @@ C_ASSERT( sizeof(struct set_keyboard_repeat_request) == 24 );
C_ASSERT( offsetof(struct set_keyboard_repeat_reply, enable) == 8 );
C_ASSERT( sizeof(struct set_keyboard_repeat_reply) == 16 );
C_ASSERT( sizeof(struct get_linux_sync_device_request) == 16 );
+C_ASSERT( offsetof(struct get_linux_sync_obj_request, handle) == 12 );
+C_ASSERT( sizeof(struct get_linux_sync_obj_request) == 16 );
+C_ASSERT( offsetof(struct get_linux_sync_obj_reply, type) == 8 );
+C_ASSERT( offsetof(struct get_linux_sync_obj_reply, access) == 12 );
+C_ASSERT( sizeof(struct get_linux_sync_obj_reply) == 16 );
diff --git a/server/request_trace.h b/server/request_trace.h
index 6fd490ca68e..92c94ce616f 100644
--- a/server/request_trace.h
+++ b/server/request_trace.h
@@ -3403,6 +3403,17 @@ static void dump_get_linux_sync_device_request( const struct get_linux_sync_devi
{
}
+static void dump_get_linux_sync_obj_request( const struct get_linux_sync_obj_request *req )
+{
+ fprintf( stderr, " handle=%04x", req->handle );
+}
+
+static void dump_get_linux_sync_obj_reply( const struct get_linux_sync_obj_reply *req )
+{
+ fprintf( stderr, " type=%d", req->type );
+ fprintf( stderr, ", access=%08x", req->access );
+}
+
typedef void (*dump_func)( const void *req );
static const dump_func req_dumpers[REQ_NB_REQUESTS] =
@@ -3705,6 +3716,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_get_next_thread_request,
(dump_func)dump_set_keyboard_repeat_request,
(dump_func)dump_get_linux_sync_device_request,
+ (dump_func)dump_get_linux_sync_obj_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
@@ -4007,6 +4019,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_get_next_thread_reply,
(dump_func)dump_set_keyboard_repeat_reply,
NULL,
+ (dump_func)dump_get_linux_sync_obj_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] =
@@ -4309,6 +4322,7 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"get_next_thread",
"set_keyboard_repeat",
"get_linux_sync_device",
+ "get_linux_sync_obj",
};
static const struct
--
2.50.1
From d8427b4e45c91b13876c5548f10c308bc028b200 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Tue, 9 Mar 2021 11:32:25 -0600
Subject: [PATCH 52/57] server: Introduce select_inproc_queue and
unselect_inproc_queue requests.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
include/wine/server_protocol.h | 32 +++++++++++++++++++++++-
server/protocol.def | 11 +++++++++
server/queue.c | 45 ++++++++++++++++++++++++++++++++++
server/request_handlers.h | 7 ++++++
server/request_trace.h | 15 ++++++++++++
5 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index d36e8c2b192..9b906a650c7 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -6014,6 +6014,30 @@ struct get_linux_sync_obj_reply
};
+
+struct select_inproc_queue_request
+{
+ struct request_header __header;
+ char __pad_12[4];
+};
+struct select_inproc_queue_reply
+{
+ struct reply_header __header;
+};
+
+
+
+struct unselect_inproc_queue_request
+{
+ struct request_header __header;
+ int signaled;
+};
+struct unselect_inproc_queue_reply
+{
+ struct reply_header __header;
+};
+
+
enum request
{
REQ_new_process,
@@ -6315,6 +6339,8 @@ enum request
REQ_set_keyboard_repeat,
REQ_get_linux_sync_device,
REQ_get_linux_sync_obj,
+ REQ_select_inproc_queue,
+ REQ_unselect_inproc_queue,
REQ_NB_REQUESTS
};
@@ -6621,6 +6647,8 @@ union generic_request
struct set_keyboard_repeat_request set_keyboard_repeat_request;
struct get_linux_sync_device_request get_linux_sync_device_request;
struct get_linux_sync_obj_request get_linux_sync_obj_request;
+ struct select_inproc_queue_request select_inproc_queue_request;
+ struct unselect_inproc_queue_request unselect_inproc_queue_request;
};
union generic_reply
{
@@ -6925,8 +6953,10 @@ union generic_reply
struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
struct get_linux_sync_device_reply get_linux_sync_device_reply;
struct get_linux_sync_obj_reply get_linux_sync_obj_reply;
+ struct select_inproc_queue_reply select_inproc_queue_reply;
+ struct unselect_inproc_queue_reply unselect_inproc_queue_reply;
};
-#define SERVER_PROTOCOL_VERSION 886
+#define SERVER_PROTOCOL_VERSION 887
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 8571ec62a54..f3e2226a3ba 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -4168,3 +4168,14 @@ enum inproc_sync_type
int type; /* object type */
unsigned int access; /* handle access rights */
@END
+
+
+/* Begin a client-side wait on a message queue */
+@REQ(select_inproc_queue)
+@END
+
+
+/* End a client-side wait on a message queue */
+@REQ(unselect_inproc_queue)
+ int signaled; /* was the queue signaled? */
+@END
diff --git a/server/queue.c b/server/queue.c
index 4717281ea0e..708d0eca899 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -136,6 +136,7 @@ struct msg_queue
queue_shm_t *shared; /* queue in session shared memory */
unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
int inproc_sync; /* in-process synchronization object */
+ int in_inproc_wait; /* are we in a client-side wait? */
};
struct hotkey
@@ -320,6 +321,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue->keystate_lock = 0;
queue->ignore_post_msg = 0;
queue->inproc_sync = create_inproc_event( TRUE, FALSE );
+ queue->in_inproc_wait = 0;
list_init( &queue->send_result );
list_init( &queue->callback_result );
list_init( &queue->pending_timers );
@@ -1290,6 +1292,10 @@ static int is_queue_hung( struct msg_queue *queue )
if (get_wait_queue_thread(entry)->queue == queue)
return 0; /* thread is waiting on queue -> not hung */
}
+
+ if (queue->in_inproc_wait)
+ return 0; /* thread is waiting on queue in absentia -> not hung */
+
return 1;
}
@@ -4312,3 +4318,42 @@ DECL_HANDLER(set_keyboard_repeat)
release_object( desktop );
}
+
+DECL_HANDLER(select_inproc_queue)
+{
+ struct msg_queue *queue = current->queue;
+
+ if (queue->in_inproc_wait)
+ {
+ set_error( STATUS_ACCESS_DENIED );
+ }
+ else
+ {
+ check_thread_queue_idle( current );
+
+ if (queue->fd)
+ set_fd_events( queue->fd, POLLIN );
+
+ queue->in_inproc_wait = 1;
+ }
+}
+
+DECL_HANDLER(unselect_inproc_queue)
+{
+ struct msg_queue *queue = current->queue;
+
+ if (!queue->in_inproc_wait)
+ {
+ set_error( STATUS_ACCESS_DENIED );
+ }
+ else
+ {
+ if (queue->fd)
+ set_fd_events( queue->fd, 0 );
+
+ if (req->signaled)
+ msg_queue_satisfied( &queue->obj, NULL );
+
+ queue->in_inproc_wait = 0;
+ }
+}
diff --git a/server/request_handlers.h b/server/request_handlers.h
index 11ef472c579..3a9717eb8df 100644
--- a/server/request_handlers.h
+++ b/server/request_handlers.h
@@ -306,6 +306,8 @@ DECL_HANDLER(get_next_thread);
DECL_HANDLER(set_keyboard_repeat);
DECL_HANDLER(get_linux_sync_device);
DECL_HANDLER(get_linux_sync_obj);
+DECL_HANDLER(select_inproc_queue);
+DECL_HANDLER(unselect_inproc_queue);
typedef void (*req_handler)( const void *req, void *reply );
static const req_handler req_handlers[REQ_NB_REQUESTS] =
@@ -609,6 +611,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_set_keyboard_repeat,
(req_handler)req_get_linux_sync_device,
(req_handler)req_get_linux_sync_obj,
+ (req_handler)req_select_inproc_queue,
+ (req_handler)req_unselect_inproc_queue,
};
C_ASSERT( sizeof(abstime_t) == 8 );
@@ -2312,3 +2316,6 @@ C_ASSERT( sizeof(struct get_linux_sync_obj_request) == 16 );
C_ASSERT( offsetof(struct get_linux_sync_obj_reply, type) == 8 );
C_ASSERT( offsetof(struct get_linux_sync_obj_reply, access) == 12 );
C_ASSERT( sizeof(struct get_linux_sync_obj_reply) == 16 );
+C_ASSERT( sizeof(struct select_inproc_queue_request) == 16 );
+C_ASSERT( offsetof(struct unselect_inproc_queue_request, signaled) == 12 );
+C_ASSERT( sizeof(struct unselect_inproc_queue_request) == 16 );
diff --git a/server/request_trace.h b/server/request_trace.h
index 92c94ce616f..d341cf13227 100644
--- a/server/request_trace.h
+++ b/server/request_trace.h
@@ -3414,6 +3414,15 @@ static void dump_get_linux_sync_obj_reply( const struct get_linux_sync_obj_reply
fprintf( stderr, ", access=%08x", req->access );
}
+static void dump_select_inproc_queue_request( const struct select_inproc_queue_request *req )
+{
+}
+
+static void dump_unselect_inproc_queue_request( const struct unselect_inproc_queue_request *req )
+{
+ fprintf( stderr, " signaled=%d", req->signaled );
+}
+
typedef void (*dump_func)( const void *req );
static const dump_func req_dumpers[REQ_NB_REQUESTS] =
@@ -3717,6 +3726,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_set_keyboard_repeat_request,
(dump_func)dump_get_linux_sync_device_request,
(dump_func)dump_get_linux_sync_obj_request,
+ (dump_func)dump_select_inproc_queue_request,
+ (dump_func)dump_unselect_inproc_queue_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
@@ -4020,6 +4031,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_set_keyboard_repeat_reply,
NULL,
(dump_func)dump_get_linux_sync_obj_reply,
+ NULL,
+ NULL,
};
static const char * const req_names[REQ_NB_REQUESTS] =
@@ -4323,6 +4336,8 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"set_keyboard_repeat",
"get_linux_sync_device",
"get_linux_sync_obj",
+ "select_inproc_queue",
+ "unselect_inproc_queue",
};
static const struct
--
2.50.1
From 96345f975362cbfc87d5e01b7f0eb1198c0c93c6 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Thu, 21 Apr 2022 16:11:14 -0500
Subject: [PATCH 53/57] server: Allow creating an event object for client-side
user APC signaling.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
include/wine/server_protocol.h | 19 ++++++++++++++++++-
server/protocol.def | 7 +++++++
server/request_handlers.h | 5 +++++
server/request_trace.h | 12 ++++++++++++
server/thread.c | 21 +++++++++++++++++++++
server/thread.h | 1 +
6 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 9b906a650c7..5d4a733134b 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -6038,6 +6038,20 @@ struct unselect_inproc_queue_reply
};
+
+struct get_inproc_alert_event_request
+{
+ struct request_header __header;
+ char __pad_12[4];
+};
+struct get_inproc_alert_event_reply
+{
+ struct reply_header __header;
+ obj_handle_t handle;
+ char __pad_12[4];
+};
+
+
enum request
{
REQ_new_process,
@@ -6341,6 +6355,7 @@ enum request
REQ_get_linux_sync_obj,
REQ_select_inproc_queue,
REQ_unselect_inproc_queue,
+ REQ_get_inproc_alert_event,
REQ_NB_REQUESTS
};
@@ -6649,6 +6664,7 @@ union generic_request
struct get_linux_sync_obj_request get_linux_sync_obj_request;
struct select_inproc_queue_request select_inproc_queue_request;
struct unselect_inproc_queue_request unselect_inproc_queue_request;
+ struct get_inproc_alert_event_request get_inproc_alert_event_request;
};
union generic_reply
{
@@ -6955,8 +6971,9 @@ union generic_reply
struct get_linux_sync_obj_reply get_linux_sync_obj_reply;
struct select_inproc_queue_reply select_inproc_queue_reply;
struct unselect_inproc_queue_reply unselect_inproc_queue_reply;
+ struct get_inproc_alert_event_reply get_inproc_alert_event_reply;
};
-#define SERVER_PROTOCOL_VERSION 887
+#define SERVER_PROTOCOL_VERSION 888
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index f3e2226a3ba..9b84b964ec9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -4179,3 +4179,10 @@ enum inproc_sync_type
@REQ(unselect_inproc_queue)
int signaled; /* was the queue signaled? */
@END
+
+
+/* Get an event handle to be used for thread alerts with in-process synchronization */
+@REQ(get_inproc_alert_event)
+@REPLY
+ obj_handle_t handle; /* handle to the event */
+@END
diff --git a/server/request_handlers.h b/server/request_handlers.h
index 3a9717eb8df..026c2cb2893 100644
--- a/server/request_handlers.h
+++ b/server/request_handlers.h
@@ -308,6 +308,7 @@ DECL_HANDLER(get_linux_sync_device);
DECL_HANDLER(get_linux_sync_obj);
DECL_HANDLER(select_inproc_queue);
DECL_HANDLER(unselect_inproc_queue);
+DECL_HANDLER(get_inproc_alert_event);
typedef void (*req_handler)( const void *req, void *reply );
static const req_handler req_handlers[REQ_NB_REQUESTS] =
@@ -613,6 +614,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_linux_sync_obj,
(req_handler)req_select_inproc_queue,
(req_handler)req_unselect_inproc_queue,
+ (req_handler)req_get_inproc_alert_event,
};
C_ASSERT( sizeof(abstime_t) == 8 );
@@ -2319,3 +2321,6 @@ C_ASSERT( sizeof(struct get_linux_sync_obj_reply) == 16 );
C_ASSERT( sizeof(struct select_inproc_queue_request) == 16 );
C_ASSERT( offsetof(struct unselect_inproc_queue_request, signaled) == 12 );
C_ASSERT( sizeof(struct unselect_inproc_queue_request) == 16 );
+C_ASSERT( sizeof(struct get_inproc_alert_event_request) == 16 );
+C_ASSERT( offsetof(struct get_inproc_alert_event_reply, handle) == 8 );
+C_ASSERT( sizeof(struct get_inproc_alert_event_reply) == 16 );
diff --git a/server/request_trace.h b/server/request_trace.h
index d341cf13227..e7bb89c6c72 100644
--- a/server/request_trace.h
+++ b/server/request_trace.h
@@ -3423,6 +3423,15 @@ static void dump_unselect_inproc_queue_request( const struct unselect_inproc_que
fprintf( stderr, " signaled=%d", req->signaled );
}
+static void dump_get_inproc_alert_event_request( const struct get_inproc_alert_event_request *req )
+{
+}
+
+static void dump_get_inproc_alert_event_reply( const struct get_inproc_alert_event_reply *req )
+{
+ fprintf( stderr, " handle=%04x", req->handle );
+}
+
typedef void (*dump_func)( const void *req );
static const dump_func req_dumpers[REQ_NB_REQUESTS] =
@@ -3728,6 +3737,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_get_linux_sync_obj_request,
(dump_func)dump_select_inproc_queue_request,
(dump_func)dump_unselect_inproc_queue_request,
+ (dump_func)dump_get_inproc_alert_event_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
@@ -4033,6 +4043,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] =
(dump_func)dump_get_linux_sync_obj_reply,
NULL,
NULL,
+ (dump_func)dump_get_inproc_alert_event_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] =
@@ -4338,6 +4349,7 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"get_linux_sync_obj",
"select_inproc_queue",
"unselect_inproc_queue",
+ "get_inproc_alert_event",
};
static const struct
diff --git a/server/thread.c b/server/thread.c
index f665bb86c3a..e8f0c40421c 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -423,6 +423,7 @@ static inline void init_thread_structure( struct thread *thread )
thread->desc = NULL;
thread->desc_len = 0;
thread->inproc_sync = create_inproc_event( TRUE, FALSE );
+ thread->inproc_alert_event = NULL;
thread->creation_time = current_time;
thread->exit_time = 0;
@@ -644,6 +645,7 @@ static void destroy_thread( struct object *obj )
if (thread->id) free_ptid( thread->id );
if (thread->token) release_object( thread->token );
if (use_inproc_sync()) close( thread->inproc_sync );
+ if (thread->inproc_alert_event) release_object( thread->inproc_alert_event );
}
/* dump a thread on stdout for debugging purposes */
@@ -1387,8 +1389,13 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
grab_object( apc );
list_add_tail( queue, &apc->entry );
if (!list_prev( queue, &apc->entry )) /* first one */
+ {
wake_thread( thread );
+ if (apc->call.type == APC_USER && thread->inproc_alert_event)
+ set_event( thread->inproc_alert_event );
+ }
+
return 1;
}
@@ -1419,6 +1426,8 @@ void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_ty
apc->executed = 1;
wake_up( &apc->obj, 0 );
release_object( apc );
+ if (list_empty( &thread->user_apc ) && thread->inproc_alert_event)
+ reset_event( thread->inproc_alert_event );
return;
}
}
@@ -1433,6 +1442,9 @@ static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system
{
apc = LIST_ENTRY( ptr, struct thread_apc, entry );
list_remove( ptr );
+
+ if (list_empty( &thread->user_apc ) && thread->inproc_alert_event)
+ reset_event( thread->inproc_alert_event );
}
return apc;
}
@@ -2301,3 +2313,12 @@ DECL_HANDLER(get_next_thread)
set_error( STATUS_NO_MORE_ENTRIES );
release_object( process );
}
+
+DECL_HANDLER(get_inproc_alert_event)
+{
+ if (!current->inproc_alert_event)
+ current->inproc_alert_event = create_event( NULL, NULL, 0, 1, !list_empty( ¤t->user_apc ), NULL );
+
+ if (current->inproc_alert_event)
+ reply->handle = alloc_handle( current->process, current->inproc_alert_event, SYNCHRONIZE, 0 );
+}
diff --git a/server/thread.h b/server/thread.h
index 980ebd7d17c..bd31c58466c 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -97,6 +97,7 @@ struct thread
WCHAR *desc; /* thread description string */
struct completion_wait *completion_wait; /* completion port wait object the thread is associated with */
int inproc_sync; /* in-process synchronization object */
+ struct event *inproc_alert_event; /* in-process synchronization alert event */
};
extern struct thread *current;
--
2.50.1
From 0c8462d7f2b470d3c17574083637f11144539839 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 8 Mar 2021 18:07:23 -0600
Subject: [PATCH 54/57] ntdll: Introduce a helper to wait on an internal server
handle.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/ntdll/unix/file.c | 2 +-
dlls/ntdll/unix/process.c | 2 +-
dlls/ntdll/unix/server.c | 17 ++++++++++++++++-
dlls/ntdll/unix/sync.c | 4 ++--
dlls/ntdll/unix/thread.c | 2 +-
dlls/ntdll/unix/unix_private.h | 3 ++-
6 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 2e6331b23a2..414a0ad10cf 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -7708,7 +7708,7 @@ NTSTATUS WINAPI NtLockFile( HANDLE file, HANDLE event, PIO_APC_ROUTINE apc, void
}
if (handle)
{
- NtWaitForSingleObject( handle, FALSE, NULL );
+ server_wait_for_object( handle, FALSE, NULL );
NtClose( handle );
}
else /* Unix lock conflict, sleep a bit and retry */
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c
index fdb81845a7e..1a6b07667ef 100644
--- a/dlls/ntdll/unix/process.c
+++ b/dlls/ntdll/unix/process.c
@@ -879,7 +879,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
/* wait for the new process info to be ready */
- NtWaitForSingleObject( process_info, FALSE, NULL );
+ server_wait_for_object( process_info, FALSE, NULL );
SERVER_START_REQ( get_new_process_info )
{
req->info = wine_server_obj_handle( process_info );
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 8d8f286b3fc..25c095537d5 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -838,6 +838,21 @@ unsigned int server_wait( const union select_op *select_op, data_size_t size, UI
}
+/* helper function to perform a server-side wait on an internal handle without
+ * using the fast synchronization path */
+unsigned int server_wait_for_object( HANDLE handle, BOOL alertable, const LARGE_INTEGER *timeout )
+{
+ union select_op select_op;
+ UINT flags = SELECT_INTERRUPTIBLE;
+
+ if (alertable) flags |= SELECT_ALERTABLE;
+
+ select_op.wait.op = SELECT_WAIT;
+ select_op.wait.handles[0] = wine_server_obj_handle( handle );
+ return server_wait( &select_op, offsetof( union select_op, wait.handles[1] ), flags, timeout );
+}
+
+
/***********************************************************************
* NtContinue (NTDLL.@)
*/
@@ -914,7 +929,7 @@ unsigned int server_queue_process_apc( HANDLE process, const union apc_call *cal
}
else
{
- NtWaitForSingleObject( handle, FALSE, NULL );
+ server_wait_for_object( handle, FALSE, NULL );
SERVER_START_REQ( get_apc_result )
{
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index e7b9cac6575..39c6fd4acba 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -2280,7 +2280,7 @@ NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE handle, ULONG_PTR *key, ULONG_PTR *
}
SERVER_END_REQ;
if (status != STATUS_PENDING) return status;
- if (!timeout || timeout->QuadPart) status = NtWaitForSingleObject( wait_handle, FALSE, timeout );
+ if (!timeout || timeout->QuadPart) status = server_wait_for_object( wait_handle, FALSE, timeout );
else status = STATUS_TIMEOUT;
if (status != WAIT_OBJECT_0) return status;
@@ -2344,7 +2344,7 @@ NTSTATUS WINAPI NtRemoveIoCompletionEx( HANDLE handle, FILE_IO_COMPLETION_INFORM
assert( status == STATUS_USER_APC );
goto done;
}
- if (!timeout || timeout->QuadPart) status = NtWaitForSingleObject( wait_handle, alertable, timeout );
+ if (!timeout || timeout->QuadPart) status = server_wait_for_object( wait_handle, alertable, timeout );
else status = STATUS_TIMEOUT;
if (status != WAIT_OBJECT_0) goto done;
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 6c1ea2d0a00..ab08dc57413 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -1832,7 +1832,7 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma
if (ret == STATUS_PENDING)
{
- NtWaitForSingleObject( context_handle, FALSE, NULL );
+ server_wait_for_object( context_handle, FALSE, NULL );
SERVER_START_REQ( get_thread_context )
{
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index b14a6e52d62..22bb0978803 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -231,6 +231,7 @@ extern unsigned int server_select( const union select_op *select_op, data_size_t
timeout_t abs_timeout, struct context_data *context, struct user_apc *user_apc );
extern unsigned int server_wait( const union select_op *select_op, data_size_t size, UINT flags,
const LARGE_INTEGER *timeout );
+extern unsigned int server_wait_for_object( HANDLE handle, BOOL alertable, const LARGE_INTEGER *timeout );
extern unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call,
union apc_result *result );
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
@@ -471,7 +472,7 @@ static inline struct async_data server_async( HANDLE handle, struct async_fileio
static inline NTSTATUS wait_async( HANDLE handle, BOOL alertable )
{
- return NtWaitForSingleObject( handle, alertable, NULL );
+ return server_wait_for_object( handle, alertable, NULL );
}
static inline BOOL in_wow64_call(void)
--
2.50.1
From 4dae5db2516caf93135c9013db901b2975eb61db Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Tue, 6 Apr 2021 15:37:02 -0500
Subject: [PATCH 55/57] ntdll: Use in-process synchronization objects.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/ntdll/unix/sync.c | 575 ++++++++++++++++++++++++++++++++-
dlls/ntdll/unix/unix_private.h | 2 +
dlls/ntdll/unix/virtual.c | 1 +
server/inproc_sync.c | 2 +-
4 files changed, 568 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 39c6fd4acba..8d26564de4b 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -30,9 +30,11 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <limits.h>
#include <signal.h>
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <sys/mman.h>
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
@@ -48,6 +50,7 @@
#endif
#include <string.h>
#include <stdarg.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@@ -342,66 +345,616 @@ static int get_linux_sync_device(void)
return device;
}
+/* It's possible for synchronization primitives to remain alive even after being
+ * closed, because a thread is still waiting on them. It's rare in practice, and
+ * documented as being undefined behaviour by Microsoft, but it works, and some
+ * applications rely on it. This means we need to refcount handles, and defer
+ * deleting them on the server side until the refcount reaches zero. We do this
+ * by having each client process hold a handle to the in-process synchronization
+ * object, as well as a private refcount. When the client refcount reaches zero,
+ * it closes the handle; when all handles are closed, the server deletes the
+ * in-process synchronization object.
+ *
+ * We want lookup of objects from the cache to be very fast; ideally, it should
+ * be lock-free. We achieve this by using atomic modifications to "refcount",
+ * and guaranteeing that all other fields are valid and correct *as long as*
+ * refcount is nonzero, and we store the entire structure in memory which will
+ * never be freed.
+ *
+ * This means that acquiring the object can't use a simple atomic increment; it
+ * has to use a compare-and-swap loop to ensure that it doesn't try to increment
+ * an object with a zero refcount. That's still leagues better than a real lock,
+ * though, and release can be a single atomic decrement.
+ *
+ * It also means that threads modifying the cache need to take a lock, to
+ * prevent other threads from writing to it concurrently.
+ *
+ * It's possible for an object currently in use (by a waiter) to be closed and
+ * the same handle immediately reallocated to a different object. This should be
+ * a very rare situation, and in that case we simply don't cache the handle.
+ */
+struct inproc_sync_cache_entry
+{
+ LONG refcount;
+ int fd;
+ unsigned int access;
+ unsigned short type; /* enum inproc_sync_type, stored as short to save space */
+ unsigned short closed;
+};
+
+
+static void release_inproc_sync_obj( struct inproc_sync_cache_entry *cache )
+{
+ /* save the fd now; as soon as the refcount hits 0 we cannot
+ * access the cache anymore */
+ int fd = cache->fd;
+ LONG refcount = InterlockedDecrement( &cache->refcount );
+
+ assert( refcount >= 0 );
+
+ if (!refcount)
+ close( fd );
+}
+
+
+static BOOL inproc_sync_types_match( enum inproc_sync_type a, enum inproc_sync_type b )
+{
+ if (a == b) return TRUE;
+ if (a == INPROC_SYNC_AUTO_EVENT && b == INPROC_SYNC_MANUAL_EVENT) return TRUE;
+ if (b == INPROC_SYNC_AUTO_EVENT && a == INPROC_SYNC_MANUAL_EVENT) return TRUE;
+ return FALSE;
+}
+
+
+/* returns a pointer to a cache entry; if the object could not be cached,
+ * returns "stack_cache" instead, which should be allocated on stack */
+static NTSTATUS get_inproc_sync_obj( HANDLE handle, enum inproc_sync_type desired_type,
+ ACCESS_MASK desired_access,
+ struct inproc_sync_cache_entry *stack_cache,
+ struct inproc_sync_cache_entry **ret_cache )
+{
+ struct inproc_sync_cache_entry *cache = stack_cache;
+ sigset_t sigset;
+ NTSTATUS ret;
+
+ /* We don't need the device right now, but if we can't access it, that
+ * means ntsync isn't available. Fail fast in that case. */
+ if (get_linux_sync_device() < 0)
+ return STATUS_NOT_IMPLEMENTED;
+
+ *ret_cache = stack_cache;
+
+ /* We need to use fd_cache_mutex here to protect against races with
+ * other threads trying to receive fds for the fd cache,
+ * and we need to use an uninterrupted section to prevent reentrancy. */
+ server_enter_uninterrupted_section( &fd_cache_mutex, &sigset );
+
+ SERVER_START_REQ( get_linux_sync_obj )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ if (!(ret = wine_server_call( req )))
+ {
+ obj_handle_t fd_handle;
+ cache->fd = wine_server_receive_fd( &fd_handle );
+ assert( wine_server_ptr_handle(fd_handle) == handle );
+ cache->access = reply->access;
+ cache->type = reply->type;
+ cache->refcount = 1;
+ cache->closed = FALSE;
+ }
+ }
+ SERVER_END_REQ;
+
+ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset );
+
+ if (ret) return ret;
+
+ if (desired_type && !inproc_sync_types_match( cache->type, desired_type ))
+ {
+ release_inproc_sync_obj( cache );
+ return STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if ((cache->access & desired_access) != desired_access)
+ {
+ release_inproc_sync_obj( cache );
+ return STATUS_ACCESS_DENIED;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS linux_release_semaphore_obj( int obj, ULONG count, ULONG *prev_count )
+{
+ NTSTATUS ret;
+
+ ret = ioctl( obj, NTSYNC_IOC_SEM_RELEASE, &count );
+ if (ret < 0)
+ {
+ if (errno == EOVERFLOW)
+ return STATUS_SEMAPHORE_LIMIT_EXCEEDED;
+ else
+ return errno_to_status( errno );
+ }
+ if (prev_count) *prev_count = count;
+ return STATUS_SUCCESS;
+}
+
+
static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_SEMAPHORE,
+ SEMAPHORE_MODIFY_STATE, &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_release_semaphore_obj( cache->fd, count, prev_count );
+
+ release_inproc_sync_obj( cache );
+ return ret;
}
+
+static NTSTATUS linux_query_semaphore_obj( int obj, SEMAPHORE_BASIC_INFORMATION *info )
+{
+ struct ntsync_sem_args args = {0};
+ NTSTATUS ret;
+
+ ret = ioctl( obj, NTSYNC_IOC_SEM_READ, &args );
+ if (ret < 0)
+ return errno_to_status( errno );
+ info->CurrentCount = args.count;
+ info->MaximumCount = args.max;
+ return STATUS_SUCCESS;
+}
+
+
static NTSTATUS inproc_query_semaphore( HANDLE handle, SEMAPHORE_BASIC_INFORMATION *info )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_SEMAPHORE,
+ SEMAPHORE_QUERY_STATE, &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_query_semaphore_obj( cache->fd, info );
+
+ release_inproc_sync_obj( cache );
+ return ret;
+}
+
+
+static NTSTATUS linux_set_event_obj( int obj, LONG *prev_state )
+{
+ NTSTATUS ret;
+ __u32 prev;
+
+ ret = ioctl( obj, NTSYNC_IOC_EVENT_SET, &prev );
+ if (ret < 0)
+ return errno_to_status( errno );
+ if (prev_state) *prev_state = prev;
+ return STATUS_SUCCESS;
}
+
static NTSTATUS inproc_set_event( HANDLE handle, LONG *prev_state )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT,
+ EVENT_MODIFY_STATE, &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_set_event_obj( cache->fd, prev_state );
+
+ release_inproc_sync_obj( cache );
+ return ret;
}
+
+static NTSTATUS linux_reset_event_obj( int obj, LONG *prev_state )
+{
+ NTSTATUS ret;
+ __u32 prev;
+
+ ret = ioctl( obj, NTSYNC_IOC_EVENT_RESET, &prev );
+ if (ret < 0)
+ return errno_to_status( errno );
+ if (prev_state) *prev_state = prev;
+ return STATUS_SUCCESS;
+}
+
+
static NTSTATUS inproc_reset_event( HANDLE handle, LONG *prev_state )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT,
+ EVENT_MODIFY_STATE, &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_reset_event_obj( cache->fd, prev_state );
+
+ release_inproc_sync_obj( cache );
+ return ret;
+}
+
+
+static NTSTATUS linux_pulse_event_obj( int obj, LONG *prev_state )
+{
+ NTSTATUS ret;
+ __u32 prev;
+
+ ret = ioctl( obj, NTSYNC_IOC_EVENT_PULSE, &prev );
+ if (ret < 0)
+ return errno_to_status( errno );
+ if (prev_state) *prev_state = prev;
+ return STATUS_SUCCESS;
}
+
static NTSTATUS inproc_pulse_event( HANDLE handle, LONG *prev_state )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT,
+ EVENT_MODIFY_STATE, &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_pulse_event_obj( cache->fd, prev_state );
+
+ release_inproc_sync_obj( cache );
+ return ret;
}
+
+static NTSTATUS linux_query_event_obj( int obj, enum inproc_sync_type type, EVENT_BASIC_INFORMATION *info )
+{
+ struct ntsync_event_args args = {0};
+ NTSTATUS ret;
+
+ ret = ioctl( obj, NTSYNC_IOC_EVENT_READ, &args );
+ if (ret < 0)
+ return errno_to_status( errno );
+ info->EventType = (type == INPROC_SYNC_AUTO_EVENT) ? SynchronizationEvent : NotificationEvent;
+ info->EventState = args.signaled;
+ return STATUS_SUCCESS;
+}
+
+
static NTSTATUS inproc_query_event( HANDLE handle, EVENT_BASIC_INFORMATION *info )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_AUTO_EVENT,
+ EVENT_QUERY_STATE, &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_query_event_obj( cache->fd, cache->type, info );
+
+ release_inproc_sync_obj( cache );
+ return ret;
}
+
+static NTSTATUS linux_release_mutex_obj( int obj, LONG *prev_count )
+{
+ struct ntsync_mutex_args args = {0};
+ NTSTATUS ret;
+
+ args.owner = GetCurrentThreadId();
+ ret = ioctl( obj, NTSYNC_IOC_MUTEX_UNLOCK, &args );
+
+ if (ret < 0)
+ {
+ if (errno == EOVERFLOW)
+ return STATUS_MUTANT_LIMIT_EXCEEDED;
+ else if (errno == EPERM)
+ return STATUS_MUTANT_NOT_OWNED;
+ else
+ return errno_to_status( errno );
+ }
+ if (prev_count) *prev_count = 1 - args.count;
+ return STATUS_SUCCESS;
+}
+
+
static NTSTATUS inproc_release_mutex( HANDLE handle, LONG *prev_count )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_MUTEX, 0, &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_release_mutex_obj( cache->fd, prev_count );
+
+ release_inproc_sync_obj( cache );
+ return ret;
}
+
+static NTSTATUS linux_query_mutex_obj( int obj, MUTANT_BASIC_INFORMATION *info )
+{
+ struct ntsync_mutex_args args = {0};
+ NTSTATUS ret;
+
+ ret = ioctl( obj, NTSYNC_IOC_MUTEX_READ, &args );
+
+ if (ret < 0)
+ {
+ if (errno == EOWNERDEAD)
+ {
+ info->AbandonedState = TRUE;
+ info->OwnedByCaller = FALSE;
+ info->CurrentCount = 1;
+ return STATUS_SUCCESS;
+ }
+ else
+ return errno_to_status( errno );
+ }
+ info->AbandonedState = FALSE;
+ info->OwnedByCaller = (args.owner == GetCurrentThreadId());
+ info->CurrentCount = 1 - args.count;
+ return STATUS_SUCCESS;
+}
+
+
static NTSTATUS inproc_query_mutex( HANDLE handle, MUTANT_BASIC_INFORMATION *info )
{
- return STATUS_NOT_IMPLEMENTED;
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ NTSTATUS ret;
+
+ if ((ret = get_inproc_sync_obj( handle, INPROC_SYNC_MUTEX, MUTANT_QUERY_STATE,
+ &stack_cache, &cache )))
+ return ret;
+
+ ret = linux_query_mutex_obj( cache->fd, info );
+
+ release_inproc_sync_obj( cache );
+ return ret;
+}
+
+static void select_queue(void)
+{
+ SERVER_START_REQ( select_inproc_queue )
+ {
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+}
+
+static void unselect_queue( BOOL signaled )
+{
+ SERVER_START_REQ( unselect_inproc_queue )
+ {
+ req->signaled = signaled;
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+}
+
+static int get_inproc_alert_obj(void)
+{
+ struct ntdll_thread_data *data = ntdll_get_thread_data();
+ struct inproc_sync_cache_entry stack_cache, *cache;
+ HANDLE alert_handle;
+ unsigned int ret;
+
+ if (data->linux_alert_obj == -1)
+ {
+ SERVER_START_REQ( get_inproc_alert_event )
+ {
+ if ((ret = wine_server_call( req )))
+ ERR( "failed to get inproc alert event, status %#x\n", ret );
+ alert_handle = wine_server_ptr_handle( reply->handle );
+ }
+ SERVER_END_REQ;
+
+ if ((ret = get_inproc_sync_obj( alert_handle, 0, SYNCHRONIZE, &stack_cache, &cache )))
+ ERR( "failed to get inproc alert obj, status %#x\n", ret );
+ data->linux_alert_obj = cache->fd;
+ /* Set the fd to -1 so release_inproc_sync_obj() won't close it.
+ * Manhandling the cache entry here is fine since we're the only thread
+ * that can access our own alert event. */
+ cache->fd = -1;
+ release_inproc_sync_obj( cache );
+ NtClose( alert_handle );
+ }
+
+ return data->linux_alert_obj;
+}
+
+static NTSTATUS linux_wait_objs( int device, const DWORD count, const int *objs,
+ BOOLEAN wait_any, BOOLEAN alertable, const LARGE_INTEGER *timeout )
+{
+ struct ntsync_wait_args args = {0};
+ unsigned long request;
+ struct timespec now;
+ int ret;
+
+ if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE)
+ {
+ args.timeout = ~(__u64)0;
+ }
+ else if (timeout->QuadPart <= 0)
+ {
+ clock_gettime( CLOCK_MONOTONIC, &now );
+ args.timeout = (now.tv_sec * NSECPERSEC) + now.tv_nsec + (-timeout->QuadPart * 100);
+ }
+ else
+ {
+ args.timeout = (timeout->QuadPart * 100) - (SECS_1601_TO_1970 * NSECPERSEC);
+ args.flags |= NTSYNC_WAIT_REALTIME;
+ }
+
+ args.objs = (uintptr_t)objs;
+ args.count = count;
+ args.owner = GetCurrentThreadId();
+ args.index = ~0u;
+
+ if (alertable)
+ args.alert = get_inproc_alert_obj();
+
+ if (wait_any || count == 1)
+ request = NTSYNC_IOC_WAIT_ANY;
+ else
+ request = NTSYNC_IOC_WAIT_ALL;
+
+ do
+ {
+ ret = ioctl( device, request, &args );
+ } while (ret < 0 && errno == EINTR);
+
+ if (!ret)
+ {
+ if (args.index == count)
+ {
+ static const LARGE_INTEGER timeout;
+
+ ret = server_wait( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, &timeout );
+ assert( ret == STATUS_USER_APC );
+ return ret;
+ }
+
+ return wait_any ? args.index : 0;
+ }
+ else if (errno == EOWNERDEAD)
+ return STATUS_ABANDONED + (wait_any ? args.index : 0);
+ else if (errno == ETIMEDOUT)
+ return STATUS_TIMEOUT;
+ else
+ return errno_to_status( errno );
}
static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
BOOLEAN alertable, const LARGE_INTEGER *timeout )
{
- int device;
+ struct inproc_sync_cache_entry stack_cache[64], *cache[64];
+ int device, objs[64];
+ HANDLE queue = NULL;
+ NTSTATUS ret;
+ DWORD i, j;
if ((device = get_linux_sync_device()) < 0)
return STATUS_NOT_IMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ for (i = 0; i < count; ++i)
+ {
+ if ((ret = get_inproc_sync_obj( handles[i], 0, SYNCHRONIZE, &stack_cache[i], &cache[i] )))
+ {
+ for (j = 0; j < i; ++j)
+ release_inproc_sync_obj( cache[j] );
+ return ret;
+ }
+ if (cache[i]->type == INPROC_SYNC_QUEUE)
+ queue = handles[i];
+
+ objs[i] = cache[i]->fd;
+ }
+
+ if (queue) select_queue();
+
+ ret = linux_wait_objs( device, count, objs, wait_any, alertable, timeout );
+
+ if (queue) unselect_queue( handles[ret] == queue );
+
+ for (i = 0; i < count; ++i)
+ release_inproc_sync_obj( cache[i] );
+
+ return ret;
}
static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait,
BOOLEAN alertable, const LARGE_INTEGER *timeout )
{
+ struct inproc_sync_cache_entry signal_stack_cache, *signal_cache;
+ struct inproc_sync_cache_entry wait_stack_cache, *wait_cache;
+ HANDLE queue = NULL;
+ NTSTATUS ret;
int device;
if ((device = get_linux_sync_device()) < 0)
return STATUS_NOT_IMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ if ((ret = get_inproc_sync_obj( signal, 0, 0, &signal_stack_cache, &signal_cache )))
+ return ret;
+
+ switch (signal_cache->type)
+ {
+ case INPROC_SYNC_SEMAPHORE:
+ if (!(signal_cache->access & SEMAPHORE_MODIFY_STATE))
+ {
+ release_inproc_sync_obj( signal_cache );
+ return STATUS_ACCESS_DENIED;
+ }
+ break;
+
+ case INPROC_SYNC_AUTO_EVENT:
+ case INPROC_SYNC_MANUAL_EVENT:
+ if (!(signal_cache->access & EVENT_MODIFY_STATE))
+ {
+ release_inproc_sync_obj( signal_cache );
+ return STATUS_ACCESS_DENIED;
+ }
+ break;
+
+ case INPROC_SYNC_MUTEX:
+ break;
+
+ default:
+ /* can't be signaled */
+ release_inproc_sync_obj( signal_cache );
+ return STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if ((ret = get_inproc_sync_obj( wait, 0, SYNCHRONIZE, &wait_stack_cache, &wait_cache )))
+ {
+ release_inproc_sync_obj( signal_cache );
+ return ret;
+ }
+
+ if (wait_cache->type == INPROC_SYNC_QUEUE)
+ queue = wait;
+
+ switch (signal_cache->type)
+ {
+ case INPROC_SYNC_SEMAPHORE:
+ ret = linux_release_semaphore_obj( signal_cache->fd, 1, NULL );
+ break;
+
+ case INPROC_SYNC_AUTO_EVENT:
+ case INPROC_SYNC_MANUAL_EVENT:
+ ret = linux_set_event_obj( signal_cache->fd, NULL );
+ break;
+
+ case INPROC_SYNC_MUTEX:
+ ret = linux_release_mutex_obj( signal_cache->fd, NULL );
+ break;
+
+ default:
+ assert( 0 );
+ break;
+ }
+
+ if (!ret)
+ {
+ if (queue) select_queue();
+ ret = linux_wait_objs( device, 1, &wait_cache->fd, TRUE, alertable, timeout );
+ if (queue) unselect_queue( !ret );
+ }
+
+ release_inproc_sync_obj( signal_cache );
+ release_inproc_sync_obj( wait_cache );
+ return ret;
}
#else
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 22bb0978803..84667d989dd 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -115,6 +115,7 @@ struct ntdll_thread_data
PRTL_THREAD_START_ROUTINE start; /* thread entry point */
void *param; /* thread entry point parameter */
void *jmp_buf; /* setjmp buffer for exception handling */
+ int linux_alert_obj; /* fd for the linux in-process alert event */
};
C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) );
@@ -401,6 +402,7 @@ extern void call_raise_user_exception_dispatcher(void);
#define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */
#define TICKSPERSEC 10000000
+#define NSECPERSEC 1000000000
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
static inline ULONGLONG ticks_from_time_t( time_t time )
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index d796783dbf4..a3a1eed08fd 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -4036,6 +4036,7 @@ static TEB *init_teb( void *ptr, BOOL is_wow )
thread_data->reply_fd = -1;
thread_data->wait_fd[0] = -1;
thread_data->wait_fd[1] = -1;
+ thread_data->linux_alert_obj = -1;
list_add_head( &teb_list, &thread_data->entry );
return teb;
}
diff --git a/server/inproc_sync.c b/server/inproc_sync.c
index c6f79081b6f..f3c6a37fc8c 100644
--- a/server/inproc_sync.c
+++ b/server/inproc_sync.c
@@ -56,7 +56,7 @@ static int get_linux_device(void)
int use_inproc_sync(void)
{
- return 0;
+ return get_linux_device() >= 0;
}
int create_inproc_event( int manual_reset, int signaled )
--
2.50.1
From 7ad496ca5460837c87fa43d9bc415d20d031f352 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Tue, 20 Apr 2021 17:55:59 -0500
Subject: [PATCH 56/57] ntdll: Use server_wait_for_object() when waiting on
only the queue object.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/ntdll/unix/sync.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 8d26564de4b..080d4654c76 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -861,6 +861,17 @@ static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_an
objs[i] = cache[i]->fd;
}
+ /* It's common to wait on the message queue alone. Some applications wait
+ * on it in fast paths, with a zero timeout. Since we take two server calls
+ * instead of one when going through inproc_wait(), and since we only need
+ * to go through that path if we're waiting on other objects, just delegate
+ * to the server if we're only waiting on the message queue. */
+ if (count == 1 && queue)
+ {
+ release_inproc_sync_obj( cache[0] );
+ return server_wait_for_object( handles[0], alertable, timeout );
+ }
+
if (queue) select_queue();
ret = linux_wait_objs( device, count, objs, wait_any, alertable, timeout );
--
2.50.1
From e43f8ac52e99831b4ee1d2aeea72f5fa4cd1cd84 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Fri, 12 Mar 2021 15:04:17 -0600
Subject: [PATCH 57/57] ntdll: Cache in-process synchronization objects.
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/ntdll/unix/server.c | 9 ++
dlls/ntdll/unix/sync.c | 190 +++++++++++++++++++++++++++++++--
dlls/ntdll/unix/unix_private.h | 2 +
3 files changed, 192 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 25c095537d5..a99d2784fb8 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -1883,12 +1883,17 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source, HANDLE
return result.dup_handle.status;
}
+ /* hold fd_cache_mutex to prevent the fd from being added again between the
+ * call to remove_fd_from_cache and close_handle */
server_enter_uninterrupted_section( &fd_cache_mutex, &sigset );
/* always remove the cached fd; if the server request fails we'll just
* retrieve it again */
if (options & DUPLICATE_CLOSE_SOURCE)
+ {
fd = remove_fd_from_cache( source );
+ close_inproc_sync_obj( source );
+ }
SERVER_START_REQ( dup_handle )
{
@@ -1954,12 +1959,16 @@ NTSTATUS WINAPI NtClose( HANDLE handle )
if (HandleToLong( handle ) >= ~5 && HandleToLong( handle ) <= ~0)
return STATUS_SUCCESS;
+ /* hold fd_cache_mutex to prevent the fd from being added again between the
+ * call to remove_fd_from_cache and close_handle */
server_enter_uninterrupted_section( &fd_cache_mutex, &sigset );
/* always remove the cached fd; if the server request fails we'll just
* retrieve it again */
fd = remove_fd_from_cache( handle );
+ close_inproc_sync_obj( handle );
+
SERVER_START_REQ( close_handle )
{
req->handle = wine_server_obj_handle( handle );
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 080d4654c76..428ffb33c8e 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -355,6 +355,12 @@ static int get_linux_sync_device(void)
* it closes the handle; when all handles are closed, the server deletes the
* in-process synchronization object.
*
+ * We also need this for signal-and-wait. The signal and wait operations aren't
+ * atomic, but we can't perform the signal and then return STATUS_INVALID_HANDLE
+ * for the wait—we need to either do both operations or neither. That means we
+ * need to grab references to both objects, and prevent them from being
+ * destroyed before we're done with them.
+ *
* We want lookup of objects from the cache to be very fast; ideally, it should
* be lock-free. We achieve this by using atomic modifications to "refcount",
* and guaranteeing that all other fields are valid and correct *as long as*
@@ -397,6 +403,117 @@ static void release_inproc_sync_obj( struct inproc_sync_cache_entry *cache )
}
+#define INPROC_SYNC_CACHE_BLOCK_SIZE (65536 / sizeof(struct inproc_sync_cache_entry))
+#define INPROC_SYNC_CACHE_ENTRIES 128
+
+static struct inproc_sync_cache_entry *inproc_sync_cache[INPROC_SYNC_CACHE_ENTRIES];
+static struct inproc_sync_cache_entry inproc_sync_cache_initial_block[INPROC_SYNC_CACHE_BLOCK_SIZE];
+
+static inline unsigned int inproc_sync_handle_to_index( HANDLE handle, unsigned int *entry )
+{
+ unsigned int idx = (wine_server_obj_handle(handle) >> 2) - 1;
+ *entry = idx / INPROC_SYNC_CACHE_BLOCK_SIZE;
+ return idx % INPROC_SYNC_CACHE_BLOCK_SIZE;
+}
+
+
+static struct inproc_sync_cache_entry *cache_inproc_sync_obj( HANDLE handle, obj_handle_t inproc_sync, int fd,
+ enum inproc_sync_type type, unsigned int access )
+{
+ unsigned int entry, idx = inproc_sync_handle_to_index( handle, &entry );
+ struct inproc_sync_cache_entry *cache;
+ int refcount;
+
+ /* don't cache pseudo-handles; waiting on them is pointless anyway */
+ if ((ULONG)(ULONG_PTR)handle > 0xfffffffa)
+ return FALSE;
+
+ if (entry >= INPROC_SYNC_CACHE_ENTRIES)
+ {
+ FIXME( "too many allocated handles, not caching %p\n", handle );
+ return NULL;
+ }
+
+ if (!inproc_sync_cache[entry]) /* do we need to allocate a new block of entries? */
+ {
+ if (!entry) inproc_sync_cache[0] = inproc_sync_cache_initial_block;
+ else
+ {
+ static const size_t size = INPROC_SYNC_CACHE_BLOCK_SIZE * sizeof(struct inproc_sync_cache_entry);
+ void *ptr = anon_mmap_alloc( size, PROT_READ | PROT_WRITE );
+ if (ptr == MAP_FAILED) return NULL;
+ if (InterlockedCompareExchangePointer( (void **)&inproc_sync_cache[entry], ptr, NULL ))
+ munmap( ptr, size ); /* someone beat us to it */
+ }
+ }
+
+ cache = &inproc_sync_cache[entry][idx];
+
+ if (InterlockedCompareExchange( &cache->refcount, 0, 0 ))
+ {
+ /* The handle is currently being used for another object (i.e. it was
+ * closed and then reused, but some thread is waiting on the old handle
+ * or otherwise simultaneously using the old object). We can't cache
+ * this object until the old one is completely destroyed. */
+ return NULL;
+ }
+
+ cache->fd = fd;
+ cache->type = type;
+ cache->access = access;
+ cache->closed = FALSE;
+ /* Make sure we set the other members before the refcount; this store needs
+ * release semantics [paired with the load in get_cached_inproc_sync_obj()].
+ * Set the refcount to 2 (one for the handle, one for the caller). */
+ refcount = InterlockedExchange( &cache->refcount, 2 );
+ assert( !refcount );
+
+ return cache;
+}
+
+
+/* returns the previous value */
+static inline LONG interlocked_inc_if_nonzero( LONG *dest )
+{
+ LONG val, tmp;
+ for (val = *dest;; val = tmp)
+ {
+ if (!val || (tmp = InterlockedCompareExchange( dest, val + 1, val )) == val)
+ break;
+ }
+ return val;
+}
+
+
+static struct inproc_sync_cache_entry *get_cached_inproc_sync_obj( HANDLE handle )
+{
+ unsigned int entry, idx = inproc_sync_handle_to_index( handle, &entry );
+ struct inproc_sync_cache_entry *cache;
+
+ if (entry >= INPROC_SYNC_CACHE_ENTRIES || !inproc_sync_cache[entry])
+ return NULL;
+
+ cache = &inproc_sync_cache[entry][idx];
+
+ /* this load needs acquire semantics [paired with the store in
+ * cache_inproc_sync_obj()] */
+ if (!interlocked_inc_if_nonzero( &cache->refcount ))
+ return NULL;
+
+ if (cache->closed)
+ {
+ /* The object is still being used, but "handle" has been closed. The
+ * handle value might have been reused for another object in the
+ * meantime, in which case we have to report that valid object, so
+ * force the caller to check the server. */
+ release_inproc_sync_obj( cache );
+ return NULL;
+ }
+
+ return cache;
+}
+
+
static BOOL inproc_sync_types_match( enum inproc_sync_type a, enum inproc_sync_type b )
{
if (a == b) return TRUE;
@@ -413,41 +530,77 @@ static NTSTATUS get_inproc_sync_obj( HANDLE handle, enum inproc_sync_type desire
struct inproc_sync_cache_entry *stack_cache,
struct inproc_sync_cache_entry **ret_cache )
{
- struct inproc_sync_cache_entry *cache = stack_cache;
+ struct inproc_sync_cache_entry *cache;
+ obj_handle_t inproc_sync_handle;
+ enum inproc_sync_type type;
+ unsigned int access;
sigset_t sigset;
NTSTATUS ret;
+ int fd;
/* We don't need the device right now, but if we can't access it, that
* means ntsync isn't available. Fail fast in that case. */
if (get_linux_sync_device() < 0)
return STATUS_NOT_IMPLEMENTED;
- *ret_cache = stack_cache;
+ /* try to find it in the cache already */
+ if ((cache = get_cached_inproc_sync_obj( handle )))
+ {
+ *ret_cache = cache;
+ return STATUS_SUCCESS;
+ }
/* We need to use fd_cache_mutex here to protect against races with
* other threads trying to receive fds for the fd cache,
- * and we need to use an uninterrupted section to prevent reentrancy. */
+ * 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_obj() and close_handle. */
server_enter_uninterrupted_section( &fd_cache_mutex, &sigset );
+ if ((cache = get_cached_inproc_sync_obj( handle )))
+ {
+ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset );
+ *ret_cache = cache;
+ return STATUS_SUCCESS;
+ }
+
+ /* try to retrieve it from the server */
SERVER_START_REQ( get_linux_sync_obj )
{
req->handle = wine_server_obj_handle( handle );
if (!(ret = wine_server_call( req )))
{
obj_handle_t fd_handle;
- cache->fd = wine_server_receive_fd( &fd_handle );
+ fd = wine_server_receive_fd( &fd_handle );
assert( wine_server_ptr_handle(fd_handle) == handle );
- cache->access = reply->access;
- cache->type = reply->type;
- cache->refcount = 1;
- cache->closed = FALSE;
+ access = reply->access;
+ type = reply->type;
}
}
SERVER_END_REQ;
+ if (ret)
+ {
+ server_leave_uninterrupted_section( &fd_cache_mutex, &sigset );
+ return ret;
+ }
+
+ cache = cache_inproc_sync_obj( handle, inproc_sync_handle, fd, type, access );
+
server_leave_uninterrupted_section( &fd_cache_mutex, &sigset );
- if (ret) return ret;
+ if (!cache)
+ {
+ cache = stack_cache;
+ cache->fd = fd;
+ cache->type = type;
+ cache->access = access;
+ cache->closed = FALSE;
+ cache->refcount = 1;
+ }
+
+ *ret_cache = cache;
if (desired_type && !inproc_sync_types_match( cache->type, desired_type ))
{
@@ -465,6 +618,21 @@ static NTSTATUS get_inproc_sync_obj( HANDLE handle, enum inproc_sync_type desire
}
+/* caller must hold fd_cache_mutex */
+void close_inproc_sync_obj( HANDLE handle )
+{
+ struct inproc_sync_cache_entry *cache = get_cached_inproc_sync_obj( handle );
+
+ if (cache)
+ {
+ cache->closed = TRUE;
+ /* once for the reference we just grabbed, and once for the handle */
+ release_inproc_sync_obj( cache );
+ release_inproc_sync_obj( cache );
+ }
+}
+
+
static NTSTATUS linux_release_semaphore_obj( int obj, ULONG count, ULONG *prev_count )
{
NTSTATUS ret;
@@ -970,6 +1138,10 @@ static NTSTATUS inproc_signal_and_wait( HANDLE signal, HANDLE wait,
#else
+void close_inproc_sync_obj( HANDLE handle )
+{
+}
+
static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count )
{
return STATUS_NOT_IMPLEMENTED;
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 84667d989dd..0db2d50e439 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -396,6 +396,8 @@ extern void dbg_init(void);
extern NTSTATUS call_user_apc_dispatcher( CONTEXT *context_ptr, unsigned int flags, ULONG_PTR arg1, ULONG_PTR arg2,
ULONG_PTR arg3, PNTAPCFUNC func, NTSTATUS status );
+extern void close_inproc_sync_obj( HANDLE handle );
+
extern NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context );
extern void call_raise_user_exception_dispatcher(void);
--
2.50.1
07070100B6933E000081A4000003E8000003E80000000168AA560300000C61000001030000000200000000000000000000003100000000patches/Add-workarounds-for-game-launchers.patchFrom ebc9e0914f293952405e622e440a05a253b1b038 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Sat, 19 Jul 2025 17:20:25 +0300
Subject: [PATCH] Add workarounds for game launchers
Based on Proton patch from Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/kernelbase/process.c | 57 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index b75963fef1d..9b78606f1cc 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -502,6 +502,38 @@ done:
return ret;
}
+static const WCHAR *hack_append_command_line( const WCHAR *cmd )
+{
+ static const struct
+ {
+ const WCHAR *exe_name;
+ const WCHAR *append;
+ }
+ options[] =
+ {
+ {L"UplayWebCore.exe", L" --use-gl=swiftshader"},
+ {L"Paradox Launcher.exe", L" --use-gl=swiftshader --in-process-gpu"},
+ {L"\\EpicOnlineServicesUIHelper", L" --use-gl=desktop"},
+ {L"Battle.net.exe", L" --in-process-gpu"},
+ {L"RSI Launcher.exe", L" --in-process-gpu"},
+ {L"EADesktop.exe", L" --in-process-gpu"},
+ {L"launcher_epic.exe", L" --in-process-gpu"},
+ };
+ unsigned int i;
+
+ if (!cmd) return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(options); ++i)
+ {
+ if (wcsstr( cmd, options[i].exe_name ))
+ {
+ FIXME( "HACK: appending %s to command line.\n", debugstr_w(options[i].append) );
+ return options[i].append;
+ }
+ }
+ return NULL;
+}
+
/**********************************************************************
* CreateProcessInternalW (kernelbase.@)
*/
@@ -518,6 +550,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
RTL_USER_PROCESS_PARAMETERS *params = NULL;
RTL_USER_PROCESS_INFORMATION rtl_info;
HANDLE parent = 0, debug = 0;
+ const WCHAR *append;
ULONG nt_flags = 0;
USHORT machine = 0;
NTSTATUS status;
@@ -539,7 +572,29 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
}
else
{
- if (!(tidy_cmdline = get_file_name( cmd_line, name, ARRAY_SIZE(name) ))) return FALSE;
+ WCHAR *cmdline_new = NULL;
+
+ if ((append = hack_append_command_line( cmd_line )))
+ {
+ cmdline_new = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(WCHAR)
+ * (lstrlenW(cmd_line) + lstrlenW(append) + 1) );
+ lstrcpyW(cmdline_new, cmd_line);
+ lstrcatW(cmdline_new, append);
+ }
+
+ tidy_cmdline = get_file_name( cmdline_new ? cmdline_new : cmd_line, name, ARRAY_SIZE(name) );
+
+ if (!tidy_cmdline)
+ {
+ HeapFree( GetProcessHeap(), 0, cmdline_new );
+ return FALSE;
+ }
+
+ if (cmdline_new)
+ {
+ if (cmdline_new == tidy_cmdline) cmd_line = NULL;
+ else HeapFree( GetProcessHeap(), 0, cmdline_new );
+ }
app_name = name;
}
--
2.50.1
07070100B6933F000081A4000003E8000003E80000000168AA560300000C82000001030000000200000000000000000000004800000000patches/0001-HACK-wine.inf-Add-native-builtin-overrides-for-msvcr.patchFrom ac40f35bbdead99900d16d9b3e3ea1337443f7ac Mon Sep 17 00:00:00 2001
From: Andrew Eikum <aeikum@codeweavers.com>
Date: Fri, 7 Feb 2025 22:22:59 +0300
Subject: [PATCH 1/5] HACK: wine.inf: Add native,builtin overrides for msvcrt
DLLs
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
loader/wine.inf.in | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index e6ff05570f0..04612cd2522 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -2874,6 +2874,37 @@ HKLM,Software\Wine\LicenseInformation,"Shell-InBoxGames-Shanghai-EnableGame",0x1
HKLM,Software\Wine\LicenseInformation,"Shell-InBoxGames-Solitaire-EnableGame",0x10001,0x00000001
HKLM,Software\Wine\LicenseInformation,"Shell-InBoxGames-SpiderSolitaire-EnableGame",0x10001,0x00000001
HKLM,Software\Wine\LicenseInformation,"Shell-PremiumInBoxGames-Chess-EnableGame",0x10001,0x00000001
+;;Likely want *80 and *90 too, but those require removing Wine's manifest files.
+HKCU,Software\Wine\DllOverrides,"atl100",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcp100",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcr100",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"vcomp100",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"atl110",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcp110",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcr110",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"vcomp110",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"atl120",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcp120",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcr120",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"vcomp120",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"api-ms-win-crt-conio-l1-1-0",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"api-ms-win-crt-heap-l1-1-0",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"api-ms-win-crt-locale-l1-1-0",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"api-ms-win-crt-math-l1-1-0",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"api-ms-win-crt-runtime-l1-1-0",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"api-ms-win-crt-stdio-l1-1-0",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"api-ms-win-crt-time-l1-1-0",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"atl140",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"concrt140",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcp140",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcp140_1",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcp140_codecvt_ids",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcp140_2",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"msvcr140",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"ucrtbase",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"vcomp140",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"vcruntime140",0x2,"native,builtin"
+HKCU,Software\Wine\DllOverrides,"vcruntime140_1",0x2,"native,builtin"
[ColorFiles]
srgb color space profile.icm,"@%11%\mscms.dll,-1"
--
2.48.1
07070100B69340000081A4000003E8000003E80000000168AA560300001932000001030000000200000000000000000000004300000000patches/ntdll-loader-add-support-for-overriding-IMAGE_FILE_L.patchFrom 07d32c24cc264e2a746d8e5054159f9aa893edbc Mon Sep 17 00:00:00 2001
From: Steven Noonan <steven@valvesoftware.com>
Date: Wed, 17 Oct 2018 04:13:37 -0700
Subject: [PATCH] ntdll/loader: add support for overriding
IMAGE_FILE_LARGE_ADDRESS_AWARE
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
dlls/kernel32/heap.c | 8 +++++++-
dlls/ntdll/ntdll.spec | 3 +++
dlls/ntdll/signal_arm64ec.c | 1 +
dlls/ntdll/unix/unix_private.h | 2 ++
dlls/ntdll/unix/virtual.c | 22 ++++++++++++++++++++--
dlls/wow64/system.c | 6 ++++++
6 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index 1ec2f5cce0d..10f6895478e 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -42,6 +42,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(globalmem);
+extern BOOL WINAPI __wine_needs_override_large_address_aware(void);
+
/***********************************************************************
* HeapCreate (KERNEL32.@)
*
@@ -424,6 +426,7 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
OSVERSIONINFOW osver;
#ifndef _WIN64
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( GetModuleHandleW(0) );
+ static int force_large_address_aware = -1;
#endif
/* Because GlobalMemoryStatus is identical to GlobalMemoryStatusEX save
@@ -450,6 +453,8 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
lpBuffer->dwAvailVirtual = memstatus.ullAvailVirtual;
#ifndef _WIN64
+ if (force_large_address_aware == -1)
+ force_large_address_aware = __wine_needs_override_large_address_aware();
if ( osver.dwMajorVersion >= 5 || osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
{
lpBuffer->dwTotalPhys = min( memstatus.ullTotalPhys, MAXDWORD );
@@ -463,7 +468,8 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
/* values are limited to 2Gb unless the app has the IMAGE_FILE_LARGE_ADDRESS_AWARE flag */
/* page file sizes are not limited (Adobe Illustrator 8 depends on this) */
- if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
+ if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) &&
+ !force_large_address_aware)
{
if (lpBuffer->dwTotalPhys > MAXLONG) lpBuffer->dwTotalPhys = MAXLONG;
if (lpBuffer->dwAvailPhys > MAXLONG) lpBuffer->dwAvailPhys = MAXLONG;
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 7c2e494e4ad..7dff2b6a0eb 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1757,3 +1757,6 @@
@ cdecl wine_get_version()
@ cdecl wine_get_build_id()
@ cdecl wine_get_host_version(ptr ptr)
+
+# Filesystem
+@ stdcall -syscall __wine_needs_override_large_address_aware()
diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c
index 0f4b55b60c4..001da1327a7 100644
--- a/dlls/ntdll/signal_arm64ec.c
+++ b/dlls/ntdll/signal_arm64ec.c
@@ -596,6 +596,7 @@ DEFINE_SYSCALL(NtWriteFileGather, (HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
DEFINE_SYSCALL(NtWriteRequestData, (HANDLE handle, LPC_MESSAGE *request, ULONG id, void *buffer, ULONG len, ULONG *retlen))
DEFINE_SYSCALL(NtWriteVirtualMemory, (HANDLE process, void *addr, const void *buffer, SIZE_T size, SIZE_T *bytes_written))
DEFINE_SYSCALL(NtYieldExecution, (void))
+DEFINE_SYSCALL_(BOOL, __wine_needs_override_large_address_aware, (void))
NTSTATUS SYSCALL_API NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR zero_bits,
SIZE_T *size_ptr, ULONG type, ULONG protect )
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index fa38f4b87ca..e2f3a5d1e44 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -590,4 +590,6 @@ static inline NTSTATUS map_section( HANDLE mapping, void **ptr, SIZE_T *size, UL
0, NULL, size, ViewShare, 0, protect );
}
+BOOL WINAPI __wine_needs_override_large_address_aware(void);
+
#endif /* __NTDLL_UNIX_PRIVATE_H */
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index e733e3ffdd6..5fb33757d36 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -4890,6 +4890,24 @@ static void virtual_release_address_space(void)
#endif /* _WIN64 */
+BOOL WINAPI __wine_needs_override_large_address_aware(void)
+{
+ static int needs_override = -1;
+
+ if (needs_override == -1)
+ {
+ const char *str = getenv( "WINE_LARGE_ADDRESS_AWARE" );
+
+ needs_override = (str ? atoi(str) == 1 : 0);
+ }
+ return needs_override;
+}
+
+static BOOL is_large_address_aware(void)
+{
+ return (main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)
+ || __wine_needs_override_large_address_aware();
+}
/***********************************************************************
* virtual_set_large_address_space
@@ -4901,7 +4919,7 @@ void virtual_set_large_address_space(void)
if (is_win64)
{
if (is_wow64())
- user_space_wow_limit = ((main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) ? limit_4g : limit_2g) - 1;
+ user_space_wow_limit = (is_large_address_aware() ? limit_4g : limit_2g) - 1;
#ifndef __APPLE__ /* don't free the zerofill section on macOS */
else if ((main_image_info.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) &&
(main_image_info.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE))
@@ -4910,7 +4928,7 @@ void virtual_set_large_address_space(void)
}
else
{
- if (!(main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)) return;
+ if (!is_large_address_aware()) return;
free_reserved_memory( (char *)0x80000000, address_space_limit );
}
user_space_limit = working_set_limit = address_space_limit;
diff --git a/dlls/wow64/system.c b/dlls/wow64/system.c
index fd10a0585ce..933a594f29b 100644
--- a/dlls/wow64/system.c
+++ b/dlls/wow64/system.c
@@ -857,3 +857,9 @@ NTSTATUS WINAPI wow64_NtWow64GetNativeSystemInformation( UINT *args )
return STATUS_INVALID_INFO_CLASS;
}
}
+
+BOOL WINAPI __wine_needs_override_large_address_aware(void);
+NTSTATUS WINAPI wow64___wine_needs_override_large_address_aware( UINT * args )
+{
+ return __wine_needs_override_large_address_aware();
+}
--
2.50.1
07070100B69341000081A4000003E8000003E80000000168AA560300002491000001030000000200000000000000000000002A00000000patches/winecfg-Add-tweaks-tab-page.patchFrom 67d81111cbbbcc799da7097b5a9222d4e8ac4107 Mon Sep 17 00:00:00 2001
From: Vasiliy Stelmachenok <ventureo@cachyos.org>
Date: Fri, 21 Mar 2025 14:04:59 +0300
Subject: [PATCH] winecfg: Add tweaks tab page
As of now, it currently allows you to:
- Enable ALSA driver for audio output
- Enable Wayland graphics driver
- Enable video decoding via FFmpeg (winedmo)
- Enable display mode emulation for X11
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
programs/winecfg/Makefile.in | 1 +
programs/winecfg/main.c | 12 +++-
programs/winecfg/resource.h | 8 +++
programs/winecfg/tweaks.c | 123 +++++++++++++++++++++++++++++++++++
programs/winecfg/winecfg.h | 1 +
programs/winecfg/winecfg.rc | 13 ++++
6 files changed, 157 insertions(+), 1 deletion(-)
create mode 100644 programs/winecfg/tweaks.c
diff --git a/programs/winecfg/Makefile.in b/programs/winecfg/Makefile.in
index 1105a99e177..a51505902d1 100644
--- a/programs/winecfg/Makefile.in
+++ b/programs/winecfg/Makefile.in
@@ -14,6 +14,7 @@ SOURCES = \
logo.svg \
main.c \
staging.c \
+ tweaks.c \
theme.c \
winecfg.c \
winecfg.man.in \
diff --git a/programs/winecfg/main.c b/programs/winecfg/main.c
index b733b11be5e..48739f44997 100644
--- a/programs/winecfg/main.c
+++ b/programs/winecfg/main.c
@@ -58,7 +58,7 @@ PropSheetCallback (HWND hWnd, UINT uMsg, LPARAM lParam)
return 0;
}
-#define NUM_PROPERTY_PAGES 9
+#define NUM_PROPERTY_PAGES 10
static INT_PTR
doPropertySheet (HINSTANCE hInstance, HWND hOwner)
@@ -149,6 +149,16 @@ doPropertySheet (HINSTANCE hInstance, HWND hOwner)
psp[pg].lParam = 0;
pg++;
+ psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
+ psp[pg].dwFlags = PSP_USETITLE;
+ psp[pg].hInstance = hInstance;
+ psp[pg].pszTemplate = MAKEINTRESOURCEW (IDD_TWEAKS);
+ psp[pg].pszIcon = NULL;
+ psp[pg].pfnDlgProc = TweaksDlgProc;
+ psp[pg].pszTitle = load_string (IDS_TAB_TWEAKS);
+ psp[pg].lParam = 0;
+ pg++;
+
psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
psp[pg].dwFlags = PSP_USETITLE;
psp[pg].hInstance = hInstance;
diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h
index 803a0fc150e..16851e7adb8 100644
--- a/programs/winecfg/resource.h
+++ b/programs/winecfg/resource.h
@@ -47,6 +47,7 @@
#define IDS_WINECFG_TITLE_APP 18 /* App specific title */
#define IDS_TAB_STAGING 19
#define IDS_TAB_INPUT 20
+#define IDS_TAB_TWEAKS 21
#define IDI_WINECFG 100
#define IDI_LOGO 102
#define IDD_ABOUTCFG 107
@@ -58,6 +59,7 @@
#define IDD_DESKTOP_INTEGRATION 115
#define IDD_STAGING 116
#define IDD_INPUT_CONFIG 117
+#define IDD_TWEAKS 118
#define IDC_WINVER 1012
#define IDC_DESKTOP_WIDTH 1023
#define IDC_DESKTOP_HEIGHT 1024
@@ -223,6 +225,12 @@
#define IDC_ENABLE_HIDEWINE 9004
#define IDC_ENABLE_GTK3 9005
+/* Tweaks tab */
+#define IDC_ENABLE_ALSA 10001
+#define IDC_ENABLE_WAYLAND 10002
+#define IDC_ENABLE_FSHACK 10003
+#define IDC_ENABLE_FFMPEG 10004
+
/* About tab */
#define IDC_ABT_OWNER 8432
#define IDC_ABT_ORG 8433
diff --git a/programs/winecfg/tweaks.c b/programs/winecfg/tweaks.c
new file mode 100644
index 00000000000..6e7e45d4205
--- /dev/null
+++ b/programs/winecfg/tweaks.c
@@ -0,0 +1,123 @@
+#define COBJMACROS
+
+#include <windows.h>
+
+#include "resource.h"
+#include "winecfg.h"
+
+/*
+ * ALSA
+ */
+static BOOL alsa_get(void)
+{
+ BOOL ret;
+ WCHAR *value = get_reg_key(config_key, keypath(L"Drivers"), L"Audio", NULL);
+ ret = (value && !wcsicmp(value, L"alsa"));
+ free(value);
+ return ret;
+}
+static void alsa_set(BOOL status)
+{
+ set_reg_key(config_key, keypath(L"Drivers"), L"Audio", status ? L"alsa" : NULL);
+}
+
+/*
+ * Wayland
+ */
+static BOOL wayland_get(void)
+{
+ BOOL ret;
+ WCHAR *value = get_reg_key(config_key, keypath(L"Drivers"), L"Graphics", NULL);
+ ret = (value && !wcsicmp(value, L"wayland"));
+ free(value);
+ return ret;
+}
+static void wayland_set(BOOL status)
+{
+ set_reg_key(config_key, keypath(L"Drivers"), L"Graphics", status ? L"wayland" : NULL);
+}
+
+/*
+ * FS Hack
+ */
+static BOOL fshack_get(void)
+{
+ BOOL ret;
+ WCHAR *value = get_reg_key(config_key, keypath(L"X11 Driver"), L"EmulateModeset", NULL);
+ ret = (value && !wcsicmp(value, L"Y"));
+ free(value);
+ return ret;
+}
+static void fshack_set(BOOL status)
+{
+ set_reg_key(config_key, keypath(L"X11 Driver"), L"EmulateModeset", status ? L"Y" : NULL);
+}
+
+/*
+ * FFmpeg
+ */
+static BOOL ffmpeg_get(void)
+{
+ BOOL ret;
+ WCHAR *value = get_reg_key(config_key, keypath(L"MediaFoundation"), L"DisableGstByteStreamHandler", NULL);
+ ret = (value && !wcsicmp(value, L"Y"));
+ free(value);
+ return ret;
+}
+static void ffmpeg_set(BOOL status)
+{
+ set_reg_key(config_key, keypath(L"MediaFoundation"), L"DisableGstByteStreamHandler", status ? L"Y" : NULL);
+}
+
+static void load_staging_settings(HWND dialog)
+{
+ CheckDlgButton(dialog, IDC_ENABLE_ALSA, alsa_get() ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(dialog, IDC_ENABLE_WAYLAND, wayland_get() ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(dialog, IDC_ENABLE_FSHACK, fshack_get() ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(dialog, IDC_ENABLE_FFMPEG, ffmpeg_get() ? BST_CHECKED : BST_UNCHECKED);
+}
+
+INT_PTR CALLBACK TweaksDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == PSN_SETACTIVE)
+ load_staging_settings(hDlg);
+ break;
+
+ case WM_SHOWWINDOW:
+ set_window_title(hDlg);
+ break;
+
+ case WM_DESTROY:
+ break;
+
+ case WM_COMMAND:
+ if (HIWORD(wParam) != BN_CLICKED) break;
+ switch (LOWORD(wParam))
+ {
+ case IDC_ENABLE_ALSA:
+ alsa_set(IsDlgButtonChecked(hDlg, IDC_ENABLE_ALSA) == BST_CHECKED);
+ SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_ENABLE_WAYLAND:
+ wayland_set(IsDlgButtonChecked(hDlg, IDC_ENABLE_WAYLAND) == BST_CHECKED);
+ SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_ENABLE_FSHACK:
+ fshack_set(IsDlgButtonChecked(hDlg, IDC_ENABLE_FSHACK) == BST_CHECKED);
+ SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_ENABLE_FFMPEG:
+ ffmpeg_set(IsDlgButtonChecked(hDlg, IDC_ENABLE_FFMPEG) == BST_CHECKED);
+ SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h
index b83234470c1..d5ed6cf9f5c 100644
--- a/programs/winecfg/winecfg.h
+++ b/programs/winecfg/winecfg.h
@@ -89,6 +89,7 @@ INT_PTR CALLBACK LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM l
INT_PTR CALLBACK AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK ThemeDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK StagingDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK TweaksDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc
index 4370d9b360c..aea7a3a5d07 100644
--- a/programs/winecfg/winecfg.rc
+++ b/programs/winecfg/winecfg.rc
@@ -39,6 +39,7 @@ BEGIN
IDS_TAB_DESKTOP_INTEGRATION "Desktop Integration"
IDS_TAB_AUDIO "Audio"
IDS_TAB_STAGING "Staging"
+ IDS_TAB_TWEAKS "Tweaks"
IDS_TAB_ABOUT "About"
IDS_TAB_INPUT "Input"
IDS_WINECFG_TITLE "Wine configuration"
@@ -337,6 +338,18 @@ BEGIN
CONTROL "Enable >K3 Theming",IDC_ENABLE_GTK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,100,230,8
END
+IDD_TWEAKS DIALOG 0, 0, 260, 220
+STYLE WS_CHILD | WS_DISABLED
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Tweaks",IDC_STATIC,8,4,244,210
+ LTEXT "The following settings are experimental and may break stuff!\nMake sure to reset them again in case of a problem.",IDC_STATIC,16,16,230,16
+ CONTROL "Enable &ALSA sound driver",IDC_ENABLE_ALSA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,40,230,8
+ CONTROL "Enable &Wayland graphics driver",IDC_ENABLE_WAYLAND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,55,230,8
+ CONTROL "Enable X11 display mode virtualization",IDC_ENABLE_FSHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,70,230,8
+ CONTROL "Enable video decoding via FFmpeg",IDC_ENABLE_FFMPEG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,85,230,8
+END
+
IDD_INPUT_CONFIG DIALOG 0, 0, 260, 220
STYLE WS_CHILD | WS_DISABLED
FONT 8, "MS Shell Dlg"
--
2.49.0
07070100B69342000081A4000003E8000003E80000000168AA560300000810000001030000000200000000000000000000004800000000patches/0001-HACK-ws2_32-Block-first-internet-connection-for-some.patchFrom d0eee8a7ec74f370df43f342a8b2977f99e7cb40 Mon Sep 17 00:00:00 2001
From: NelloKudo <marshnelloosu@gmail.com>
Date: Thu, 14 Aug 2025 14:18:26 +0200
Subject: [PATCH] HACK: ws2_32: Block first internet connection for some games
Fixes launch issues/high CPU usage, can be disabled in-case of
various issues with WINE_DISABLE_DISCONNECT=1.
---
dlls/ws2_32/socket.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index d4223e93bd1..3030d8df6bb 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1262,6 +1262,25 @@ int WINAPI closesocket( SOCKET s )
return 0;
}
+static BOOL is_mhy(void)
+{
+ static volatile char cache = -1;
+ BOOL ret = cache;
+ if (ret == -1)
+ {
+ const WCHAR *p, *name = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
+ if ((p = wcsrchr(name, '/')))
+ name = p + 1;
+ if ((p = wcsrchr(name, '\\')))
+ name = p + 1;
+ ret = (!wcsicmp(name, L"GenshinImpact.exe") ||
+ !wcsicmp(name, L"StarRail.exe") ||
+ !wcsicmp(name, L"YuanShen.exe") ||
+ !wcsicmp(name, L"ZenlessZoneZero.exe"));
+ cache = ret;
+ }
+ return ret;
+}
/***********************************************************************
* connect (ws2_32.4)
@@ -1272,6 +1291,18 @@ int WINAPI connect( SOCKET s, const struct sockaddr *addr, int len )
IO_STATUS_BLOCK io;
HANDLE sync_event;
NTSTATUS status;
+ static int count = 0;
+ const char* env = getenv("WINE_DISABLE_DISCONNECT");
+
+ // HACK: Block first connection for mhy games
+ // can be disabled with WINE_DISABLE_DISCONNECT=1
+ if (!count && !(env && atoi(env) == 1) && is_mhy())
+ {
+ FIXME("Toggle detected, disabling first connection..\n");
+ count = 1;
+ WSASetLastError(WSAECONNREFUSED);
+ return SOCKET_ERROR;
+ }
TRACE( "socket %#Ix, addr %s, len %d\n", s, debugstr_sockaddr(addr), len );
--
2.50.1
07070100B69343000081A4000003E8000003E80000000168AA560300000618000001030000000200000000000000000000003800000000patches/0002-wine.inf-Set-a-valid-Win10-ProductId.patchFrom b664a786b1b7a5b00e9dbc30c40d537a57fde145 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Fri, 7 Feb 2025 22:25:55 +0300
Subject: [PATCH 2/5] wine.inf: Set a valid Win10 ProductId
Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
---
loader/wine.inf.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index 04612cd2522..27df37619d0 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -369,7 +369,7 @@ HKCU,%CurrentVersion%\Run,,16
HKCU,%CurrentVersionNT%\Winlogon,,16
HKLM,%CurrentVersion%,"CommonFilesDir",,"%16427%"
HKLM,%CurrentVersion%,"FirstInstallDateTime",1,21,81,7c,23
-HKLM,%CurrentVersion%,"ProductId",,"12345-oem-0000001-54321"
+HKLM,%CurrentVersion%,"ProductId",,"00330-50000-00000-AAOEM"
HKLM,%CurrentVersion%,"ProgramFilesDir",,"%16422%"
HKLM,%CurrentVersion%,"ProgramFilesPath",0x20000,"%%ProgramFiles%%"
HKLM,%CurrentVersion%,"RegisteredOrganization",2,""
@@ -395,7 +395,7 @@ HKLM,%CurrentVersion%\Shell Extensions\Approved,,16
HKLM,%CurrentVersion%\Time Zones,"SymbolicLinkValue",0x60000,"\Registry\Machine\%CurrentVersionNT%\Time Zones"
HKLM,%CurrentVersion%\Uninstall,,16
HKLM,%CurrentVersionNT%,"InstallDate",0x10003,1273299354
-HKLM,%CurrentVersionNT%,"ProductId",,"12345-oem-0000001-54321"
+HKLM,%CurrentVersionNT%,"ProductId",,"00330-50000-00000-AAOEM"
HKLM,%CurrentVersionNT%,"RegisteredOrganization",2,""
HKLM,%CurrentVersionNT%,"RegisteredOwner",2,""
HKLM,%CurrentVersionNT%,"SystemRoot",,"%10%"
--
2.48.1
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!