[PATCH 1/5] kernel32/tests: Add some HEAP_NO_SERIALIZE flag / LFH locking tests.

Rémi Bernon rbernon at codeweavers.com
Thu Apr 28 05:31:45 CDT 2022


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/kernel32/tests/heap.c | 202 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 201 insertions(+), 1 deletion(-)

diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index fded1c69f1e..28cbee6ea83 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -88,18 +88,76 @@ struct heap
 };
 
 
+struct heap_thread_params
+{
+    HANDLE ready_event;
+    HANDLE start_event;
+    BOOL done;
+
+    HANDLE heap;
+    DWORD flags;
+    BOOL lock;
+};
+
+DWORD WINAPI heap_thread_proc( void *arg )
+{
+    struct heap_thread_params *params = arg;
+    void *ptr;
+    DWORD res;
+    BOOL ret;
+
+    SetEvent( params->ready_event );
+
+    while (!(res = WaitForSingleObject( params->start_event, INFINITE )) && !params->done)
+    {
+        if (params->lock)
+        {
+            ret = HeapLock( params->heap );
+            ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+        }
+
+        ptr = HeapAlloc( params->heap, params->flags, 0 );
+        ok( !!ptr, "HeapAlloc failed, error %lu\n", GetLastError() );
+        ret = HeapFree( params->heap, params->flags, ptr );
+        ok( ret, "HeapFree failed, error %lu\n", GetLastError() );
+
+        if (params->lock)
+        {
+            ret = HeapUnlock( params->heap );
+            ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+        }
+
+        SetEvent( params->ready_event );
+    }
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+
+    return 0;
+}
+
+
 static void test_HeapCreate(void)
 {
     static const BYTE buffer[512] = {0};
     SIZE_T alloc_size = 0x8000 * sizeof(void *), size, i;
+    struct heap_thread_params thread_params = {0};
     PROCESS_HEAP_ENTRY entry, entries[256];
-    HANDLE heap, heap1, heaps[8];
+    HANDLE heap, heap1, heaps[8], thread;
     BYTE *ptr, *ptr1, *ptrs[128];
     DWORD heap_count, count;
     ULONG compat_info;
     UINT_PTR align;
+    DWORD res;
     BOOL ret;
 
+    thread_params.ready_event = CreateEventW( NULL, FALSE, FALSE, NULL );
+    ok( !!thread_params.ready_event, "CreateEventW failed, error %lu\n", GetLastError() );
+    thread_params.start_event = CreateEventW( NULL, FALSE, FALSE, NULL );
+    ok( !!thread_params.start_event, "CreateEventW failed, error %lu\n", GetLastError() );
+    thread = CreateThread( NULL, 0, heap_thread_proc, &thread_params, 0, NULL );
+    ok( !!thread, "CreateThread failed, error %lu\n", GetLastError() );
+    res = WaitForSingleObject( thread_params.ready_event, INFINITE );
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+
     heap_count = GetProcessHeaps( 0, NULL );
     ok( heap_count <= 6, "GetProcessHeaps returned %lu\n", heap_count );
 
@@ -879,6 +937,148 @@ static void test_HeapCreate(void)
 
     ret = HeapDestroy( heap );
     ok( ret, "HeapDestroy failed, error %lu\n", GetLastError() );
+
+
+    /* check HEAP_NO_SERIALIZE HeapCreate flag effect */
+
+    heap = HeapCreate( HEAP_NO_SERIALIZE, 0, 0 );
+    ok( !!heap, "HeapCreate failed, error %lu\n", GetLastError() );
+    ok( !((ULONG_PTR)heap & 0xffff), "wrong heap alignment\n" );
+
+    ret = HeapLock( heap );
+    ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+    thread_params.heap = heap;
+    thread_params.lock = TRUE;
+    thread_params.flags = 0;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    todo_wine
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    ret = HeapUnlock( heap );
+    ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+    if (res) WaitForSingleObject( thread_params.ready_event, 100 );
+
+    ret = HeapLock( heap );
+    ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+    thread_params.heap = heap;
+    thread_params.lock = FALSE;
+    thread_params.flags = 0;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    ret = HeapUnlock( heap );
+    ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+
+    ret = HeapDestroy( heap );
+    ok( ret, "HeapDestroy failed, error %lu\n", GetLastError() );
+
+
+    /* check HEAP_NO_SERIALIZE HeapAlloc / HeapFree flag effect */
+
+    heap = HeapCreate( 0, 0, 0 );
+    ok( !!heap, "HeapCreate failed, error %lu\n", GetLastError() );
+    ok( !((ULONG_PTR)heap & 0xffff), "wrong heap alignment\n" );
+
+    ret = HeapLock( heap );
+    ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+    thread_params.heap = heap;
+    thread_params.lock = TRUE;
+    thread_params.flags = 0;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( res == WAIT_TIMEOUT, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    ret = HeapUnlock( heap );
+    ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+
+    ret = HeapLock( heap );
+    ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+    thread_params.heap = heap;
+    thread_params.lock = FALSE;
+    thread_params.flags = 0;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( res == WAIT_TIMEOUT, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    ret = HeapUnlock( heap );
+    ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+
+    ret = HeapLock( heap );
+    ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+    thread_params.heap = heap;
+    thread_params.lock = FALSE;
+    thread_params.flags = HEAP_NO_SERIALIZE;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    ret = HeapUnlock( heap );
+    ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+
+    ret = HeapDestroy( heap );
+    ok( ret, "HeapDestroy failed, error %lu\n", GetLastError() );
+
+
+    /* check LFH heap locking */
+
+    heap = HeapCreate( 0, 0, 0 );
+    ok( !!heap, "HeapCreate failed, error %lu\n", GetLastError() );
+    ok( !((ULONG_PTR)heap & 0xffff), "wrong heap alignment\n" );
+
+    ret = pHeapQueryInformation( heap, HeapCompatibilityInformation, &compat_info, sizeof(compat_info), &size );
+    ok( ret, "HeapQueryInformation failed, error %lu\n", GetLastError() );
+    ok( compat_info == 0, "got HeapCompatibilityInformation %lu\n", compat_info );
+
+    for (i = 0; i < 0x12; i++) ptrs[i] = pHeapAlloc( heap, 0, 0 );
+    for (i = 0; i < 0x12; i++) HeapFree( heap, 0, ptrs[i] );
+
+    ret = pHeapQueryInformation( heap, HeapCompatibilityInformation, &compat_info, sizeof(compat_info), &size );
+    ok( ret, "HeapQueryInformation failed, error %lu\n", GetLastError() );
+    todo_wine
+    ok( compat_info == 2, "got HeapCompatibilityInformation %lu\n", compat_info );
+
+    /* locking is serialized */
+
+    ret = HeapLock( heap );
+    ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+    thread_params.heap = heap;
+    thread_params.lock = TRUE;
+    thread_params.flags = 0;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( res == WAIT_TIMEOUT, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    ret = HeapUnlock( heap );
+    ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+
+    /* but allocation is not */
+
+    ret = HeapLock( heap );
+    ok( ret, "HeapLock failed, error %lu\n", GetLastError() );
+    thread_params.heap = heap;
+    thread_params.lock = FALSE;
+    thread_params.flags = 0;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread_params.ready_event, 100 );
+    todo_wine
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    ret = HeapUnlock( heap );
+    ok( ret, "HeapUnlock failed, error %lu\n", GetLastError() );
+    if (res) res = WaitForSingleObject( thread_params.ready_event, 100 );
+
+    ret = HeapDestroy( heap );
+    ok( ret, "HeapDestroy failed, error %lu\n", GetLastError() );
+
+
+    thread_params.done = TRUE;
+    SetEvent( thread_params.start_event );
+    res = WaitForSingleObject( thread, INFINITE );
+    ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
+    CloseHandle( thread_params.start_event );
+    CloseHandle( thread_params.ready_event );
+    CloseHandle( thread );
 }
 
 
-- 
2.35.1




More information about the wine-devel mailing list