Notes:
- One test VM doesn't have sound output, that's why I added the check for SAR availability.
--
v2: mfmediaengine: Add support for inserting audio effects.
mfmediaengine/tests: Add tests for audio effects.
https://gitlab.winehq.org/wine/wine/-/merge_requests/3311
Today, NtContinue() on ARM64 does not restore X16 and X17 from the
context.
This is because the values for X16 and X17 are overwritten when the
current thread returns to the "user mode" (PE side) via
__wine_syscall_dispatcher, which in turn uses them as scratch registers
for restoring SP and PC respectively.
We cannot avoid using scratch registers when restoring SP and PC. This
is because ARMv8 does not have an unprivileged (EL0) instruction that
loads SP and PC from memory or non-GPR architectural state.
Fix this by making ARM64 __wine_syscall_dispatcher perform a full
context restore via raise(SIGUSR2) when NtContinue() is used.
Since raising a signal is quite expensive, it should be done only when
necessary. To achieve this, split the ARM64 syscall dispatcher's
returning behaviour into a fast path (that does not involve signals) and
a slow path (that involves signals):
- If CONTEXT_INTEGER is not set, the dispatcher takes the fast path:
the X16 and X17 registers are clobbered as usual.
- If X16 == PC and X17 == SP, the dispatcher also takes the fast path:
it can safely use X16 and X17 without corrupting the register values,
since those two registers already have the desired values.
This fast path is used in call_user_apc_dispatcher(),
call_user_exception_dispatcher(), and call_init_thunk().
- Otherwise, the dispatcher takes the slow path: it raises SIGUSR2 and
does full context restore in the signal handler.
--
v2: ntdll: Fix restoring X16 and X17 in ARM64 syscall dispatcher.
https://gitlab.winehq.org/wine/wine/-/merge_requests/3341
Today, NtContinue() on ARM64 does not restore X16 and X17 from the
context.
This is because X16 and X17 are used as scratch registers for restoring
SP and PC respectively in __wine_syscall_dispatcher. Scratch registers
are required because ARMv8 does not have an unprivileged (EL0)
instruction that loads SP and PC from memory or non-GPR architectural
state.
Fix this by making ARM64 __wine_syscall_dispatcher perform a full
context restore via raise(SIGUSR2) when NtContinue() is used.
Since raising a signal is quite expensive, it should be done only when
necessary. To achieve this, split the ARM64 syscall dispatcher's
returning behaviour into a fast path (that does not involve signals) and
a slow path (that involves signals):
- If CONTEXT_INTEGER is not set, the dispatcher takes the fast path:
the X16 and X17 registers are clobbered as usual.
- If X16 == PC and X17 == SP, the dispatcher also takes the fast path:
it can safely use X16 and X17 without corrupting the register values,
since those two registers already have the desired values.
This fast path is used in call_user_apc_dispatcher(),
call_user_exception_dispatcher(), and call_init_thunk().
- Otherwise, the dispatcher takes the slow path: it raises SIGUSR2 and
does full context restore in the signal handler.
Fixes: 88e336214db94318b6657d641919fcce6be4a328
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/3341
SafeSEH is not applicable to architectures other than i386.
This fixes compiling with the clang ARM assembler, which cannot parse
".def @feat.00" since "@" is parsed as the start of a line comment.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/3340
It turns out that Windows have a special behaviour WRT cancelling asyncs for terminating thread (or already terminated thread when socket handle is closed) when there is no more open handles in the process for the socket (while there might be handles to it in another processes).
We currently have a logic on cancelling async in server/async.c:cancel_terminating_thread_asyncs() called before thread termination. It has a special case ("async->completion && async->data.apc_context && !async->event") when async is not canceled (covered by the tests). It turns out that on Windows, if there are no more handles to the socket in the async's process, async is cancelled even in this case.
Then, if thread is terminated while there are open handles in the same process, but those handles are closed after that, it turns out the asyncs should be canceled the same way, even if there are handles for the socket in another process.
Why this is important (and, actually, makes some sense to me), is that it is very easy to duplicate all the open handles to the child process. Just e. g., Qt doesn't seem to have any way to create a process through QtProcess without inheriting handles. Programs might expect that once they close socket handle the async operations will be aborted and they receive completions on port. But that doesn't happen if they didn't use an event for overlapped operation and happened to create any child process with inherited handles after creating the socket. Windows behaviour looks to me as a workaround for this.
Besides the present test, I also tested the same with AcceptEx and IOCTL_AFD_RECV which behaves the same. Just to note, closing the handle before thread termination when there are no other open handles is quite a different case. In its heart it behaves *somewhat* similar on Windows and Wine but not quite, hitting various issues. But that looks unrelated to the special case concerned in this patchset.
Fixes Battle.net hanging on exit during "update and restart" (not to confuse with update itself not finishing which is an unrelated issue related to file DACLs).
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/3329
--
v4: sapi/tests: Use SHDeleteKeyA instead of RegDeleteTreeA in token tests.
sapi/tests: Fix ISpObjectToken::CreateInstance E_ACCESSDENIED error.
sapi/tests: Fix intermittent duration test failure in mmaudio.
https://gitlab.winehq.org/wine/wine/-/merge_requests/3336