Module: tools
Branch: master
Commit: c3e23ab6e1c1a2fac56d0795dc51fac21f6f4499
URL: https://source.winehq.org/git/tools.git/?a=commit;h=c3e23ab6e1c1a2fac56d079…
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Thu May 6 14:21:56 2021 +0200
winetest/build-patterns: Store an 'is wine' flag in the report structure.
This groups all the tag parsing aspects in one place and is useful to
check if a pattern contains Wine reports.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
winetest/build-patterns | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/winetest/build-patterns b/winetest/build-patterns
index a5f98f5..d16050d 100755
--- a/winetest/build-patterns
+++ b/winetest/build-patterns
@@ -322,12 +322,14 @@ foreach my $build (@sortedbuilds)
if (!$report)
{
my ($platform, $tag, $num) = split /_/, $reportdir;
+ my $is_wine = ($platform =~ /^(?:linux|mac|bsd|solaris|wine)$/);
$report = {
dir => $reportdir,
platform => $platform,
tag => $tag,
num => $num,
is_rerun => ($num ? 1 : 0),
+ is_wine => $is_wine,
};
$reports{$reportdir} = $report;
}
@@ -1028,7 +1030,7 @@ foreach my $report (values %reports)
}
# Windows and Wine have different failure modes so put them on separate
# pages.
- my $page = ($report->{platform} =~ /^(?:linux|mac|bsd|solaris|wine)$/) ? "wine" : "win";
+ my $page = $report->{is_wine} ? "wine" : "win";
$tbreports{$page}->{$report->{dir}} = 1;
}
Module: wine
Branch: master
Commit: f80ac265e5fbd1b4c0c0c346f0cc232385a8f868
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f80ac265e5fbd1b4c0c0c346…
Author: Arkadiusz Hiler <ahiler(a)codeweavers.com>
Date: Wed May 5 13:03:13 2021 +0300
ucrtbase: Add tests for _beginthread[ex]().
Signed-off-by: Arkadiusz Hiler <ahiler(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/ucrtbase/tests/Makefile.in | 7 +-
dlls/ucrtbase/tests/thread.c | 147 +++++++++++++++++++++++++++++++++++++
dlls/ucrtbase/tests/threaddll.c | 67 +++++++++++++++++
dlls/ucrtbase/tests/threaddll.h | 30 ++++++++
dlls/ucrtbase/tests/threaddll.spec | 3 +
5 files changed, 252 insertions(+), 2 deletions(-)
diff --git a/dlls/ucrtbase/tests/Makefile.in b/dlls/ucrtbase/tests/Makefile.in
index 259880a7d90..4df5684290c 100644
--- a/dlls/ucrtbase/tests/Makefile.in
+++ b/dlls/ucrtbase/tests/Makefile.in
@@ -2,9 +2,12 @@ TESTDLL = ucrtbase.dll
IMPORTS = ucrtbase
EXTRADEFS = -fno-builtin
-C_SRCS = \
+SOURCES = \
cpp.c \
misc.c \
printf.c \
scanf.c \
- string.c
+ string.c \
+ thread.c \
+ threaddll.c \
+ threaddll.spec
diff --git a/dlls/ucrtbase/tests/thread.c b/dlls/ucrtbase/tests/thread.c
new file mode 100644
index 00000000000..01f46029c06
--- /dev/null
+++ b/dlls/ucrtbase/tests/thread.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2021 Arkadiusz Hiler 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 <errno.h>
+#include <stdarg.h>
+#include <process.h>
+
+#include <windef.h>
+#include <winbase.h>
+#include "wine/test.h"
+
+#include "threaddll.h"
+
+enum beginthread_method
+{
+ use_beginthread,
+ use_beginthreadex
+};
+
+static char *get_thread_dll_path(void)
+{
+ static char path[MAX_PATH];
+ const char dll_name[] = "threaddll.dll";
+ DWORD written;
+ HANDLE file;
+ HRSRC res;
+ void *ptr;
+
+ GetTempPathA(ARRAY_SIZE(path), path);
+ strcat(path, dll_name);
+
+ file = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+ ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s: %u.\n",
+ debugstr_a(path), GetLastError());
+
+ res = FindResourceA(NULL, dll_name, "TESTDLL");
+ ok(!!res, "Failed to load resource: %u\n", GetLastError());
+ ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
+ WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written, NULL);
+ ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource\n");
+ CloseHandle(file);
+
+ return path;
+}
+
+static void set_thead_dll_detach_event(HANDLE dll, HANDLE event)
+{
+ void WINAPI (*_set_detach_event)(HANDLE event);
+ _set_detach_event = (void*) GetProcAddress(dll, "set_detach_event");
+ ok(_set_detach_event != NULL, "Failed to get set_detach_event: %u\n", GetLastError());
+ _set_detach_event(event);
+}
+
+static void test_thread_library_reference(char *thread_dll,
+ enum beginthread_method beginthread_method,
+ enum thread_exit_method exit_method)
+{
+ HANDLE detach_event;
+ HMODULE dll;
+ DWORD ret;
+ uintptr_t thread_handle;
+ struct threaddll_args args;
+
+ args.exit_method = exit_method;
+
+ detach_event = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ok(detach_event != NULL, "Failed to create an event: %u\n", GetLastError());
+ args.confirm_running = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ok(args.confirm_running != NULL, "Failed to create an event: %u\n", GetLastError());
+ args.past_free = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ok(args.past_free != NULL, "Failed to create an event: %u\n", GetLastError());
+
+ dll = LoadLibraryA(thread_dll);
+ ok(dll != NULL, "Failed to load the test dll: %u\n", GetLastError());
+
+ set_thead_dll_detach_event(dll, detach_event);
+
+ if (beginthread_method == use_beginthreadex)
+ {
+ _beginthreadex_start_routine_t proc = (void*) GetProcAddress(dll, "stdcall_thread_proc");
+ ok(proc != NULL, "Failed to get stdcall_thread_proc: %u\n", GetLastError());
+ thread_handle = _beginthreadex(NULL, 0, proc, &args, 0, NULL);
+ }
+ else
+ {
+ _beginthread_start_routine_t proc = (void*) GetProcAddress(dll, "cdecl_thread_proc");
+ ok(proc != NULL, "Failed to get stdcall_thread_proc: %u\n", GetLastError());
+ thread_handle = _beginthread(proc, 0, &args);
+ }
+
+ ok(thread_handle != -1 && thread_handle != 0, "Failed to begin thread: %u\n", errno);
+
+ ret = WaitForSingleObject(args.confirm_running, 200);
+ ok(ret == WAIT_OBJECT_0, "Event was not signaled, ret: %u, err: %u\n", ret, GetLastError());
+
+ ok(FreeLibrary(dll), "Failed to free the library: %u\n", GetLastError());
+
+ ret = WaitForSingleObject(detach_event, 0);
+ ok(ret == WAIT_TIMEOUT, "Thread detach happened unexpectedly signaling an event, ret: %d, err: %u\n", ret, GetLastError());
+
+ ok(SetEvent(args.past_free), "Failed to signal event: %d\n", GetLastError());
+
+ if (beginthread_method == use_beginthreadex)
+ {
+ ret = WaitForSingleObject((HANDLE)thread_handle, 200);
+ ok(ret == WAIT_OBJECT_0, "Thread has not exited, ret: %d, err: %u\n", ret, GetLastError());
+ }
+
+ ret = WaitForSingleObject(detach_event, 200);
+ ok(ret == WAIT_OBJECT_0, "Detach event was not signaled, ret: %d, err: %u\n", ret, GetLastError());
+
+ if (beginthread_method == use_beginthreadex)
+ CloseHandle((HANDLE)thread_handle);
+
+ CloseHandle(args.past_free);
+ CloseHandle(args.confirm_running);
+ CloseHandle(detach_event);
+}
+
+START_TEST(thread)
+{
+ BOOL ret;
+ char *thread_dll = get_thread_dll_path();
+
+ test_thread_library_reference(thread_dll, use_beginthread, thread_exit_return);
+ test_thread_library_reference(thread_dll, use_beginthread, thread_exit_endthread);
+ test_thread_library_reference(thread_dll, use_beginthreadex, thread_exit_return);
+ test_thread_library_reference(thread_dll, use_beginthreadex, thread_exit_endthreadex);
+
+ ret = DeleteFileA(thread_dll);
+ ok(ret, "Failed to remove the test dll, err: %u", GetLastError());
+}
diff --git a/dlls/ucrtbase/tests/threaddll.c b/dlls/ucrtbase/tests/threaddll.c
new file mode 100644
index 00000000000..72b8074054a
--- /dev/null
+++ b/dlls/ucrtbase/tests/threaddll.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2021 Arkadiusz Hiler 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 <windows.h>
+
+#include "threaddll.h"
+
+static HANDLE detach_event;
+
+void CDECL _endthread(void);
+void CDECL _endthreadex(unsigned int);
+
+void WINAPI set_detach_event(HANDLE event)
+{
+ detach_event = event;
+}
+
+static unsigned internal_thread_proc(void *param)
+{
+ struct threaddll_args *args = param;
+ SetEvent(args->confirm_running);
+ WaitForSingleObject(args->past_free, INFINITE);
+
+ if (args->exit_method == thread_exit_endthread)
+ _endthread();
+ else if (args->exit_method == thread_exit_endthreadex)
+ _endthreadex(0);
+
+ return 0;
+}
+
+unsigned WINAPI stdcall_thread_proc(void *param)
+{
+ return internal_thread_proc(param);
+}
+
+void CDECL cdecl_thread_proc(void *param)
+{
+ internal_thread_proc(param);
+}
+
+BOOL WINAPI DllMain(HINSTANCE instance_new, DWORD reason, LPVOID reserved)
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_DETACH:
+ if (detach_event) SetEvent(detach_event);
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/dlls/ucrtbase/tests/threaddll.h b/dlls/ucrtbase/tests/threaddll.h
new file mode 100644
index 00000000000..1d8d085798f
--- /dev/null
+++ b/dlls/ucrtbase/tests/threaddll.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 Arkadiusz Hiler 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
+ */
+
+enum thread_exit_method {
+ thread_exit_return,
+ thread_exit_endthread,
+ thread_exit_endthreadex
+};
+
+struct threaddll_args
+{
+ HANDLE confirm_running;
+ HANDLE past_free;
+ enum thread_exit_method exit_method;
+};
diff --git a/dlls/ucrtbase/tests/threaddll.spec b/dlls/ucrtbase/tests/threaddll.spec
new file mode 100644
index 00000000000..8422c096946
--- /dev/null
+++ b/dlls/ucrtbase/tests/threaddll.spec
@@ -0,0 +1,3 @@
+@ stdcall set_detach_event(ptr)
+@ stdcall stdcall_thread_proc(ptr)
+@ cdecl cdecl_thread_proc(ptr)