Sebastian Lackner : ntdll/tests: Add tests for threadpool timer merging.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jul 3 09:02:35 CDT 2015
Module: wine
Branch: master
Commit: 9f71015a994a18656b2c0093bd3f525e959460d3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9f71015a994a18656b2c0093bd3f525e959460d3
Author: Sebastian Lackner <sebastian at fds-team.de>
Date: Fri Jul 3 01:59:02 2015 +0200
ntdll/tests: Add tests for threadpool timer merging.
---
dlls/ntdll/tests/threadpool.c | 117 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c
index 460e85e..0671202 100644
--- a/dlls/ntdll/tests/threadpool.c
+++ b/dlls/ntdll/tests/threadpool.c
@@ -790,6 +790,122 @@ static void test_tp_timer(void)
CloseHandle(semaphore);
}
+struct window_length_info
+{
+ HANDLE semaphore;
+ DWORD ticks;
+};
+
+static void CALLBACK window_length_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_TIMER *timer)
+{
+ struct window_length_info *info = userdata;
+ trace("Running window length callback\n");
+ info->ticks = GetTickCount();
+ ReleaseSemaphore(info->semaphore, 1, NULL);
+}
+
+static void test_tp_window_length(void)
+{
+ struct window_length_info info1, info2;
+ TP_CALLBACK_ENVIRON environment;
+ TP_TIMER *timer1, *timer2;
+ LARGE_INTEGER when;
+ HANDLE semaphore;
+ NTSTATUS status;
+ TP_POOL *pool;
+ DWORD result;
+
+ semaphore = CreateSemaphoreA(NULL, 0, 2, NULL);
+ ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
+
+ /* 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");
+
+ /* allocate two identical timers */
+ memset(&environment, 0, sizeof(environment));
+ environment.Version = 1;
+ environment.Pool = pool;
+
+ timer1 = NULL;
+ info1.semaphore = semaphore;
+ status = pTpAllocTimer(&timer1, window_length_cb, &info1, &environment);
+ ok(!status, "TpAllocTimer failed with status %x\n", status);
+ ok(timer1 != NULL, "expected timer1 != NULL\n");
+
+ timer2 = NULL;
+ info2.semaphore = semaphore;
+ status = pTpAllocTimer(&timer2, window_length_cb, &info2, &environment);
+ ok(!status, "TpAllocTimer failed with status %x\n", status);
+ ok(timer2 != NULL, "expected timer2 != NULL\n");
+
+ /* choose parameters so that timers are not merged */
+ info1.ticks = 0;
+ info2.ticks = 0;
+
+ NtQuerySystemTime( &when );
+ when.QuadPart += (ULONGLONG)250 * 10000;
+ pTpSetTimer(timer2, &when, 0, 0);
+ Sleep(50);
+ when.QuadPart -= (ULONGLONG)150 * 10000;
+ pTpSetTimer(timer1, &when, 0, 75);
+
+ result = WaitForSingleObject(semaphore, 1000);
+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
+ result = WaitForSingleObject(semaphore, 1000);
+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
+ ok(info1.ticks != 0 && info2.ticks != 0, "expected that ticks are nonzero\n");
+ ok(info2.ticks >= info1.ticks + 75 || broken(info2.ticks < info1.ticks + 75) /* Win 2008 */,
+ "expected that timers are not merged\n");
+
+ /* timers will be merged */
+ info1.ticks = 0;
+ info2.ticks = 0;
+
+ NtQuerySystemTime( &when );
+ when.QuadPart += (ULONGLONG)250 * 10000;
+ pTpSetTimer(timer2, &when, 0, 0);
+ Sleep(50);
+ when.QuadPart -= (ULONGLONG)150 * 10000;
+ pTpSetTimer(timer1, &when, 0, 200);
+
+ result = WaitForSingleObject(semaphore, 1000);
+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
+ result = WaitForSingleObject(semaphore, 1000);
+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
+ ok(info1.ticks != 0 && info2.ticks != 0, "expected that ticks are nonzero\n");
+ ok(info2.ticks >= info1.ticks - 50 && info2.ticks <= info1.ticks + 50,
+ "expected that timers are merged\n");
+
+ /* on Windows the timers also get merged in this case */
+ info1.ticks = 0;
+ info2.ticks = 0;
+
+ NtQuerySystemTime( &when );
+ when.QuadPart += (ULONGLONG)100 * 10000;
+ pTpSetTimer(timer1, &when, 0, 200);
+ Sleep(50);
+ when.QuadPart += (ULONGLONG)150 * 10000;
+ pTpSetTimer(timer2, &when, 0, 0);
+
+ result = WaitForSingleObject(semaphore, 1000);
+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
+ result = WaitForSingleObject(semaphore, 1000);
+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
+ ok(info1.ticks != 0 && info2.ticks != 0, "expected that ticks are nonzero\n");
+ todo_wine
+ ok(info2.ticks >= info1.ticks - 50 && info2.ticks <= info1.ticks + 50,
+ "expected that timers are merged\n");
+
+ /* cleanup */
+ pTpReleaseTimer(timer1);
+ pTpReleaseTimer(timer2);
+ pTpReleasePool(pool);
+ CloseHandle(semaphore);
+}
+
START_TEST(threadpool)
{
if (!init_threadpool())
@@ -802,4 +918,5 @@ START_TEST(threadpool)
test_tp_instance();
test_tp_disassociate();
test_tp_timer();
+ test_tp_window_length();
}
More information about the wine-cvs
mailing list