[1/2] kernel32: Some tests for blocking initialization with InitOnceBeginInitialize() (try2)
Nikolay Sivov
nsivov at codeweavers.com
Tue Jul 24 04:49:37 CDT 2012
try2: fixed a test failure
-------------- next part --------------
>From df34b2bbdbba221fb2ffd826090a3edc723157f4 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue, 24 Jul 2012 13:39:12 +0400
Subject: [PATCH 1/2] Some tests for blocking initialization with InitOnceBeginInitialize()
---
dlls/kernel32/tests/sync.c | 64 ++++++++++++++++++++++++++++++++++---------
include/winbase.h | 5 +++-
include/winnt.h | 4 +++
3 files changed, 58 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
index 97139a9..2110711 100644
--- a/dlls/kernel32/tests/sync.c
+++ b/dlls/kernel32/tests/sync.c
@@ -39,6 +39,8 @@ static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFI
static BOOL (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL);
static VOID (WINAPI *pInitOnceInitialize)(PINIT_ONCE);
static BOOL (WINAPI *pInitOnceExecuteOnce)(PINIT_ONCE,PINIT_ONCE_FN,PVOID,LPVOID*);
+static BOOL (WINAPI *pInitOnceBeginInitialize)(PINIT_ONCE,DWORD,BOOL*,LPVOID*);
+static BOOL (WINAPI *pInitOnceComplete)(PINIT_ONCE,DWORD,LPVOID);
static void test_signalandwait(void)
{
@@ -1138,11 +1140,13 @@ static void test_WaitForMultipleObjects(void)
}
static BOOL g_initcallback_ret, g_initcallback_called;
+static void *g_initctxt;
BOOL CALLBACK initonce_callback(INIT_ONCE *initonce, void *parameter, void **ctxt)
{
g_initcallback_called = TRUE;
/* zero bit set means here that initialization is taking place - initialization locked */
+ ok(g_initctxt == *ctxt, "got wrong context value %p, expected %p\n", *ctxt, g_initctxt);
ok(initonce->Ptr == (void*)0x1, "got %p\n", initonce->Ptr);
ok(parameter == (void*)0xdeadbeef, "got wrong parameter\n");
return g_initcallback_ret;
@@ -1151,8 +1155,7 @@ BOOL CALLBACK initonce_callback(INIT_ONCE *initonce, void *parameter, void **ctx
static void test_initonce(void)
{
INIT_ONCE initonce;
- void *ctxt;
- BOOL ret;
+ BOOL ret, pending;
if (!pInitOnceInitialize || !pInitOnceExecuteOnce)
{
@@ -1160,48 +1163,79 @@ static void test_initonce(void)
return;
}
+ /* blocking initialization with callback */
initonce.Ptr = (void*)0xdeadbeef;
pInitOnceInitialize(&initonce);
ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
/* initialisation completed successfully */
g_initcallback_ret = TRUE;
- ctxt = NULL;
- ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &ctxt);
+ g_initctxt = NULL;
+ ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &g_initctxt);
ok(ret, "got wrong ret value %d\n", ret);
ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
- ok(ctxt == (void*)0x0, "got %p\n", ctxt);
+ ok(g_initctxt == (void*)0x0, "got %p\n", g_initctxt);
ok(g_initcallback_called, "got %d\n", g_initcallback_called);
/* so it's been called already so won't be called again */
- ctxt = NULL;
+ g_initctxt = NULL;
g_initcallback_called = FALSE;
- ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &ctxt);
+ ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &g_initctxt);
ok(ret, "got wrong ret value %d\n", ret);
ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
- ok(ctxt == (void*)0, "got %p\n", ctxt);
+ ok(g_initctxt == (void*)0, "got %p\n", g_initctxt);
ok(!g_initcallback_called, "got %d\n", g_initcallback_called);
pInitOnceInitialize(&initonce);
g_initcallback_called = FALSE;
/* 2 lower order bits should never be used, you'll get a crash in result */
- ctxt = (void*)0xFFFFFFF0;
- ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &ctxt);
+ g_initctxt = (void*)0xFFFFFFF0;
+ ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &g_initctxt);
ok(ret, "got wrong ret value %d\n", ret);
ok(initonce.Ptr == (void*)0xFFFFFFF2, "got %p\n", initonce.Ptr);
- ok(ctxt == (void*)0xFFFFFFF0, "got %p\n", ctxt);
+ ok(g_initctxt == (void*)0xFFFFFFF0, "got %p\n", g_initctxt);
ok(g_initcallback_called, "got %d\n", g_initcallback_called);
/* callback failed */
g_initcallback_ret = FALSE;
g_initcallback_called = FALSE;
- ctxt = NULL;
+ g_initctxt = NULL;
pInitOnceInitialize(&initonce);
- ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &ctxt);
+ ret = pInitOnceExecuteOnce(&initonce, &initonce_callback, (void*)0xdeadbeef, &g_initctxt);
ok(!ret, "got wrong ret value %d\n", ret);
ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
- ok(ctxt == NULL, "got %p\n", ctxt);
+ ok(g_initctxt == NULL, "got %p\n", g_initctxt);
ok(g_initcallback_called, "got %d\n", g_initcallback_called);
+
+ /* blocking initialzation without a callback */
+ pInitOnceInitialize(&initonce);
+ g_initctxt = NULL;
+ pending = FALSE;
+ ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
+ ok(ret, "got wrong ret value %d\n", ret);
+ ok(pending, "got %d\n", pending);
+ ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
+ ok(g_initctxt == NULL, "got %p\n", g_initctxt);
+ /* another attempt to begin initialization with block a single thread */
+
+ g_initctxt = NULL;
+ pending = 0xf;
+ ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
+ ok(!ret, "got wrong ret value %d\n", ret);
+ ok(pending == 0xf, "got %d\n", pending);
+ ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
+ ok(g_initctxt == NULL, "got %p\n", g_initctxt);
+
+ g_initctxt = (void*)0xdeadbee0;
+ ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, g_initctxt);
+ ok(!ret, "got wrong ret value %d\n", ret);
+ ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
+
+ /* once failed already */
+ g_initctxt = (void*)0xdeadbee0;
+ ret = pInitOnceComplete(&initonce, 0, g_initctxt);
+ ok(ret, "got wrong ret value %d\n", ret);
+ ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
}
START_TEST(sync)
@@ -1218,6 +1252,8 @@ START_TEST(sync)
pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification");
pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize");
pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce");
+ pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize");
+ pInitOnceComplete = (void *)GetProcAddress(hdll, "InitOnceComplete");
test_signalandwait();
test_mutex();
diff --git a/include/winbase.h b/include/winbase.h
index 0bc5755..a6ca4b6 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1320,7 +1320,10 @@ typedef struct _WIN32_STREAM_ID {
typedef RTL_RUN_ONCE INIT_ONCE;
typedef PRTL_RUN_ONCE PINIT_ONCE;
typedef PRTL_RUN_ONCE LPINIT_ONCE;
-#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
+#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
+#define INIT_ONCE_CHECK_ONLY RTL_RUN_ONCE_CHECK_ONLY
+#define INIT_ONCE_ASYNC RTL_RUN_ONCE_ASYNC
+#define INIT_ONCE_INIT_FAILED RTL_RUN_ONCE_INIT_FAILED
/* initialization callback prototype */
typedef BOOL (WINAPI *PINIT_ONCE_FN)(PINIT_ONCE,PVOID,PVOID*);
diff --git a/include/winnt.h b/include/winnt.h
index d65e2f6..121b83c 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5092,6 +5092,10 @@ typedef union _RTL_RUN_ONCE {
PVOID Ptr;
} RTL_RUN_ONCE, *PRTL_RUN_ONCE;
+#define RTL_RUN_ONCE_CHECK_ONLY 0x00000001
+#define RTL_RUN_ONCE_ASYNC 0x00000002
+#define RTL_RUN_ONCE_INIT_FAILED 0x00000004
+
NTSYSAPI VOID NTAPI RtlRunOnceInitialize(PRTL_RUN_ONCE);
#include <pshpack8.h>
--
1.5.6.5
More information about the wine-patches
mailing list