| /* |
| * 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(); |
| } |