From: Sebastian Lackner Subject: ntdll/tests: Add tests for TpSimpleTryPost function. (try 2) Message-Id: <54F50BF3.4010404@fds-team.de> Date: Tue, 03 Mar 2015 02:18:43 +0100 Uses a semaphore instead of the busy-looping. The Sleep at the end was also removed, but there is a high risk of race-conditions in the threading implementation of Wine, which can lead to wrong exit codes from time to time (of course only after the Tp* functions are implemented). The race-condition is fixed with http://source.winehq.org/patches/data/109498. --- dlls/ntdll/tests/Makefile.in | 1 + dlls/ntdll/tests/threadpool.c | 127 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 dlls/ntdll/tests/threadpool.c From dd356288cfea711a8e14bb1dad6de142f48b499b Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 24 Feb 2015 05:42:03 +0100 Subject: ntdll/tests: Add tests for TpSimpleTryPost function. --- dlls/ntdll/tests/Makefile.in | 1 + dlls/ntdll/tests/threadpool.c | 127 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 dlls/ntdll/tests/threadpool.c diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in index 81b4466..fc352dd 100644 --- a/dlls/ntdll/tests/Makefile.in +++ b/dlls/ntdll/tests/Makefile.in @@ -21,4 +21,5 @@ C_SRCS = \ rtlbitmap.c \ rtlstr.c \ string.c \ + threadpool.c \ time.c diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c new file mode 100644 index 0000000..2e31b34 --- /dev/null +++ b/dlls/ntdll/tests/threadpool.c @@ -0,0 +1,127 @@ +/* + * Unit test suite for thread pool functions + * + * Copyright 2015 Sebastian Lackner + * + * 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 "ntdll_test.h" + +static HMODULE hntdll = 0; +static NTSTATUS (WINAPI *pTpAllocPool)(TP_POOL **,PVOID); +static VOID (WINAPI *pTpReleasePool)(TP_POOL *); +static NTSTATUS (WINAPI *pTpSimpleTryPost)(PTP_SIMPLE_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); + +#define NTDLL_GET_PROC(func) \ + do \ + { \ + p ## func = (void *)GetProcAddress(hntdll, #func); \ + if (!p ## func) trace("Failed to get address for %s\n", #func); \ + } \ + while (0) + +static BOOL init_threadpool(void) +{ + hntdll = GetModuleHandleA("ntdll"); + if (!hntdll) + { + win_skip("Could not load ntdll\n"); + return FALSE; + } + + NTDLL_GET_PROC(TpAllocPool); + NTDLL_GET_PROC(TpReleasePool); + NTDLL_GET_PROC(TpSimpleTryPost); + + if (!pTpAllocPool) + { + skip("Threadpool functions not supported, skipping tests\n"); + return FALSE; + } + + return TRUE; +} + +#undef NTDLL_GET_PROC + + +static void CALLBACK simple_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) +{ + HANDLE semaphore = userdata; + trace("Running simple callback\n"); + ReleaseSemaphore(semaphore, 1, NULL); +} + +static void test_tp_simple(void) +{ + TP_CALLBACK_ENVIRON environment; + HANDLE semaphore; + NTSTATUS status; + TP_POOL *pool; + DWORD result; + + semaphore = CreateSemaphoreA(NULL, 0, 1, NULL); + ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + + /* post the callback using the default threadpool */ + memset(&environment, 0, sizeof(environment)); + environment.Version = 1; + environment.Pool = NULL; + status = pTpSimpleTryPost(simple_cb, semaphore, &environment); + ok(!status, "TpSimpleTryPost failed with status %x\n", status); + result = WaitForSingleObject(semaphore, 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + + /* allocate new threadpool */ + pool = NULL; + status = pTpAllocPool(&pool, NULL); + ok(!status, "TpAllocPool failed with status %x\n", status); + ok(pool != NULL, "expected pool != NULL\n"); + + /* post the callback using the new threadpool */ + memset(&environment, 0, sizeof(environment)); + environment.Version = 1; + environment.Pool = pool; + status = pTpSimpleTryPost(simple_cb, semaphore, &environment); + ok(!status, "TpSimpleTryPost failed with status %x\n", status); + result = WaitForSingleObject(semaphore, 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + + /* test with invalid version number */ + memset(&environment, 0, sizeof(environment)); + environment.Version = 9999; + environment.Pool = pool; + status = pTpSimpleTryPost(simple_cb, semaphore, &environment); + ok(status == STATUS_INVALID_PARAMETER || broken(!status) /* Vista/2008 */, + "TpSimpleTryPost unexpectedly returned status %x\n", status); + if (!status) + { + result = WaitForSingleObject(semaphore, 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + } + + /* cleanup */ + pTpReleasePool(pool); + CloseHandle(semaphore); +} + +START_TEST(threadpool) +{ + if (!init_threadpool()) + return; + + test_tp_simple(); +} -- 2.3.0