Skip to content

Instantly share code, notes, and snippets.

@101arrowz
Last active April 23, 2024 16:40
Show Gist options
  • Save 101arrowz/2f09a1331d32a7b22491770e183eb4ce to your computer and use it in GitHub Desktop.
Save 101arrowz/2f09a1331d32a7b22491770e183eb4ce to your computer and use it in GitHub Desktop.

Revisions

  1. 101arrowz revised this gist Apr 23, 2024. 1 changed file with 51 additions and 94 deletions.
    145 changes: 51 additions & 94 deletions msync-wine-9.0.patch
    Original file line number Diff line number Diff line change
    @@ -32,10 +32,10 @@ index 803d8079213..2e96eb2cf08 100644
    init_files();
    diff --git a/dlls/ntdll/unix/msync.c b/dlls/ntdll/unix/msync.c
    new file mode 100644
    index 00000000000..eb41b2fdd8b
    index 00000000000..8d63bf51c15
    --- /dev/null
    +++ b/dlls/ntdll/unix/msync.c
    @@ -0,0 +1,1719 @@
    @@ -0,0 +1,1662 @@
    +/*
    + * mach semaphore-based synchronization objects
    + *
    @@ -94,7 +94,6 @@ index 00000000000..eb41b2fdd8b
    +
    +#include "ntstatus.h"
    +#define WIN32_NO_STATUS
    +#define NONAMELESSUNION
    +#include "windef.h"
    +#include "winternl.h"
    +#include "wine/debug.h"
    @@ -1699,66 +1698,9 @@ index 00000000000..eb41b2fdd8b
    +
    + return msync_wait_objects( 1, &wait, TRUE, alertable, timeout );
    +}
    +iff --git a/dlls/ntdll/unix/msync.h b/dlls/ntdll/unix/msync.h
    +ew file mode 100644
    +ndex 00000000000..9d0538297d4
    +-- /dev/null
    +++ b/dlls/ntdll/unix/msync.h
    +@ -0,0 +1,50 @@
    +/*
    + * mach semaphore-based synchronization objects
    + *
    + * Copyright (C) 2018 Zebediah Figura
    + * Copyright (C) 2023 Marc-Aurel Zent
    + *
    + * 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
    + */
    +
    +extern int do_msync(void) DECLSPEC_HIDDEN;
    +extern void msync_init(void) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_close( HANDLE handle ) DECLSPEC_HIDDEN;
    +
    +extern NTSTATUS msync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_open_semaphore( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_query_semaphore( HANDLE handle, void *info, ULONG *ret_len ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_create_event( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN initial ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_open_event( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_set_event( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_reset_event( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_pulse_event( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_query_event( HANDLE handle, void *info, ULONG *ret_len ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_create_mutex( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr, BOOLEAN initial ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_open_mutex( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_release_mutex( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_query_mutex( HANDLE handle, void *info, ULONG *ret_len ) DECLSPEC_HIDDEN;
    +
    +extern NTSTATUS msync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
    + BOOLEAN alertable, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_signal_and_wait( HANDLE signal, HANDLE wait,
    + BOOLEAN alertable, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
    \ No newline at end of file
    diff --git a/dlls/ntdll/unix/msync.h b/dlls/ntdll/unix/msync.h
    new file mode 100644
    index 00000000000..eec066e04d1
    index 00000000000..9793b73c2d8
    --- /dev/null
    +++ b/dlls/ntdll/unix/msync.h
    @@ -0,0 +1,50 @@
    @@ -1783,35 +1725,35 @@ index 00000000000..eec066e04d1
    + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
    + */
    +
    +extern int do_msync(void) DECLSPEC_HIDDEN;
    +extern void msync_init(void) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_close( HANDLE handle ) DECLSPEC_HIDDEN;
    +extern int do_msync(void);
    +extern void msync_init(void);
    +extern NTSTATUS msync_close( HANDLE handle );
    +
    +extern NTSTATUS msync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev ) DECLSPEC_HIDDEN;
    + const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max);
    +extern NTSTATUS msync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev );
    +extern NTSTATUS msync_open_semaphore( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_query_semaphore( HANDLE handle, void *info, ULONG *ret_len ) DECLSPEC_HIDDEN;
    + const OBJECT_ATTRIBUTES *attr );
    +extern NTSTATUS msync_query_semaphore( HANDLE handle, void *info, ULONG *ret_len );
    +extern NTSTATUS msync_create_event( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN initial ) DECLSPEC_HIDDEN;
    + const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN initial );
    +extern NTSTATUS msync_open_event( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_set_event( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_reset_event( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_pulse_event( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_query_event( HANDLE handle, void *info, ULONG *ret_len ) DECLSPEC_HIDDEN;
    + const OBJECT_ATTRIBUTES *attr );
    +extern NTSTATUS msync_set_event( HANDLE handle, LONG *prev );
    +extern NTSTATUS msync_reset_event( HANDLE handle, LONG *prev );
    +extern NTSTATUS msync_pulse_event( HANDLE handle, LONG *prev );
    +extern NTSTATUS msync_query_event( HANDLE handle, void *info, ULONG *ret_len );
    +extern NTSTATUS msync_create_mutex( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr, BOOLEAN initial ) DECLSPEC_HIDDEN;
    + const OBJECT_ATTRIBUTES *attr, BOOLEAN initial );
    +extern NTSTATUS msync_open_mutex( HANDLE *handle, ACCESS_MASK access,
    + const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_release_mutex( HANDLE handle, LONG *prev ) DECLSPEC_HIDDEN;
    +extern NTSTATUS msync_query_mutex( HANDLE handle, void *info, ULONG *ret_len ) DECLSPEC_HIDDEN;
    + const OBJECT_ATTRIBUTES *attr );
    +extern NTSTATUS msync_release_mutex( HANDLE handle, LONG *prev );
    +extern NTSTATUS msync_query_mutex( HANDLE handle, void *info, ULONG *ret_len );
    +
    +extern NTSTATUS msync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
    + BOOLEAN alertable, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
    + BOOLEAN alertable, const LARGE_INTEGER *timeout );
    +extern NTSTATUS msync_signal_and_wait( HANDLE signal, HANDLE wait,
    + BOOLEAN alertable, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
    + BOOLEAN alertable, const LARGE_INTEGER *timeout );
    \ No newline at end of file
    diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
    index 53fcc61ccf3..a02666d5248 100644
    @@ -1836,7 +1778,7 @@ index 53fcc61ccf3..a02666d5248 100644
    {
    req->handle = wine_server_obj_handle( handle );
    diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
    index bfbcaf4a851..45baf7dd28f 100644
    index bfbcaf4a851..3c18e5f02ac 100644
    --- a/dlls/ntdll/unix/sync.c
    +++ b/dlls/ntdll/unix/sync.c
    @@ -63,6 +63,7 @@
    @@ -2015,12 +1957,13 @@ index bfbcaf4a851..45baf7dd28f 100644
    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 );
    @@ -1527,7 +1584,16 @@ NTSTATUS WINAPI NtYieldExecution(void)
    @@ -1527,7 +1584,17 @@ NTSTATUS WINAPI NtYieldExecution(void)
    NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeout )
    {
    /* if alertable, we need to query the server */
    - if (alertable) return server_wait( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, timeout );
    + if (alertable) {
    + if (alertable)
    + {
    + if (do_msync())
    + {
    + NTSTATUS ret = msync_wait_objects( 0, NULL, TRUE, TRUE, timeout );
    @@ -2275,7 +2218,7 @@ index 6933195e72d..6be3bc7da85 100644
    no_signal, /* signal */
    no_get_fd, /* get_fd */
    diff --git a/server/console.c b/server/console.c
    index b64283baf4a..ef94ab69f0d 100644
    index b64283baf4a..134726043cb 100644
    --- a/server/console.c
    +++ b/server/console.c
    @@ -41,6 +41,7 @@
    @@ -2409,6 +2352,15 @@ index b64283baf4a..ef94ab69f0d 100644
    }

    if (ioctl)
    @@ -1643,5 +1671,8 @@ DECL_HANDLER(get_next_console_request)
    set_error( STATUS_PENDING );
    }

    + if (do_msync() && list_empty( &server->queue ))
    + msync_clear_shm( server->msync_idx );
    +
    release_object( server );
    }
    diff --git a/server/debugger.c b/server/debugger.c
    index 48adb244b09..3bb42a0d059 100644
    --- a/server/debugger.c
    @@ -4233,7 +4185,7 @@ index 5d60e7fcda3..876e0225215 100644
    +@END
    \ No newline at end of file
    diff --git a/server/queue.c b/server/queue.c
    index cd913ae03e5..fad4988078d 100644
    index cd913ae03e5..064454ece0c 100644
    --- a/server/queue.c
    +++ b/server/queue.c
    @@ -42,6 +42,7 @@
    @@ -4295,17 +4247,22 @@ index cd913ae03e5..fad4988078d 100644
    thread->queue = queue;
    }
    if (new_input) release_object( new_input );
    @@ -599,6 +610,10 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
    @@ -599,11 +610,15 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
    {
    queue->wake_bits &= ~bits;
    queue->changed_bits &= ~bits;
    +
    + if (do_msync() && !is_signaled( queue ))
    + msync_clear( &queue->obj );
    +
    if (!(queue->wake_bits & (QS_KEY | QS_MOUSEBUTTON)))
    {
    if (queue->keystate_lock) unlock_input_keystate( queue->input );
    queue->keystate_lock = 0;
    }
    +
    + if (do_msync() && !is_signaled( queue ))
    + msync_clear( &queue->obj );
    }

    /* check if message is matched by the filter */
    @@ -1082,6 +1097,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 */
    @@ -4339,16 +4296,16 @@ index cd913ae03e5..fad4988078d 100644
    }

    static void msg_queue_destroy( struct object *obj )
    @@ -1191,6 +1220,9 @@ 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 );
    @@ -1181,6 +1210,9 @@ static void msg_queue_destroy( struct object *obj )
    release_object( queue->input );
    if (queue->hooks) release_object( queue->hooks );
    if (queue->fd) release_object( queue->fd );
    +
    + if (do_msync() && !is_signaled( queue ))
    + msync_clear( &queue->obj );
    }

    static void thread_input_dump( struct object *obj, int verbose )
    static void msg_queue_poll_event( struct fd *fd, int event )
    @@ -2559,6 +2591,9 @@ DECL_HANDLER(set_queue_mask)
    if (req->skip_wait) queue->wake_mask = queue->changed_mask = 0;
    else wake_up( &queue->obj, 0 );
  2. 101arrowz created this gist Apr 22, 2024.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Adapted from [https://github.com/marzent/wine-msync](https://github.com/marzent/wine-msync) to apply to Wine 9.0 without CrossOver.
    4,938 changes: 4,938 additions & 0 deletions msync-wine-9.0.patch
    4,938 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.