| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | |
| 5 | /*============================================================ |
| 6 | ** |
| 7 | ** Source: test1.c |
| 8 | ** |
| 9 | ** Purpose: Test for ExitThread. Create a thread and then call |
| 10 | ** exit thread within the threading function. Ensure that it exits |
| 11 | ** immediatly. |
| 12 | ** |
| 13 | ** |
| 14 | **=========================================================*/ |
| 15 | |
| 16 | #include <palsuite.h> |
| 17 | |
| 18 | DWORD dwExitThreadTestParameter = 0; |
| 19 | |
| 20 | DWORD PALAPI ExitThreadTestThread( LPVOID lpParameter) |
| 21 | { |
| 22 | DWORD dwRet = 0; |
| 23 | |
| 24 | /* Save parameter for test */ |
| 25 | dwExitThreadTestParameter = (DWORD)lpParameter; |
| 26 | |
| 27 | /* Call the ExitThread function */ |
| 28 | ExitThread(dwRet); |
| 29 | |
| 30 | /* If we didn't exit, get caught in this loop. But, the |
| 31 | program will exit. |
| 32 | */ |
| 33 | while (!dwRet) |
| 34 | { |
| 35 | Fail("ERROR: Entered an infinite loop because ExitThread " |
| 36 | "failed to exit from the thread. Forcing exit from " |
| 37 | "the test now." ); |
| 38 | } |
| 39 | |
| 40 | return dwRet; |
| 41 | } |
| 42 | |
| 43 | BOOL ExitThreadTest() |
| 44 | { |
| 45 | BOOL bRet = FALSE; |
| 46 | DWORD dwRet = 0; |
| 47 | |
| 48 | LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL; |
| 49 | DWORD dwStackSize = 0; |
| 50 | LPTHREAD_START_ROUTINE lpStartAddress = &ExitThreadTestThread; |
| 51 | LPVOID lpParameter = (LPVOID)lpStartAddress; |
| 52 | DWORD dwCreationFlags = 0; //run immediately |
| 53 | DWORD dwThreadId = 0; |
| 54 | |
| 55 | HANDLE hThread = 0; |
| 56 | |
| 57 | dwExitThreadTestParameter = 0; |
| 58 | |
| 59 | /* Create a Thread. We'll need this to test that we're able |
| 60 | to exit the thread. |
| 61 | */ |
| 62 | hThread = CreateThread( lpThreadAttributes, |
| 63 | dwStackSize, lpStartAddress, lpParameter, |
| 64 | dwCreationFlags, &dwThreadId ); |
| 65 | |
| 66 | if (hThread != INVALID_HANDLE_VALUE) |
| 67 | { |
| 68 | dwRet = WaitForSingleObject(hThread,INFINITE); |
| 69 | |
| 70 | if (dwRet != WAIT_OBJECT_0) |
| 71 | { |
| 72 | Trace("ExitThreadTest:WaitForSingleObject failed " |
| 73 | "(%x)\n" ,GetLastError()); |
| 74 | } |
| 75 | else |
| 76 | { |
| 77 | /* Check to ensure that the parameter set in the Thread |
| 78 | function is correct. |
| 79 | */ |
| 80 | if (dwExitThreadTestParameter != (DWORD)lpParameter) |
| 81 | { |
| 82 | Trace("ERROR: The paramater passed should have been " |
| 83 | "%d but turned up as %d." , |
| 84 | dwExitThreadTestParameter, lpParameter); |
| 85 | } |
| 86 | else |
| 87 | { |
| 88 | bRet = TRUE; |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | else |
| 93 | { |
| 94 | Trace("ExitThreadTest:CreateThread failed (%x)\n" ,GetLastError()); |
| 95 | } |
| 96 | |
| 97 | return bRet; |
| 98 | } |
| 99 | |
| 100 | int __cdecl main(int argc, char **argv) |
| 101 | { |
| 102 | if(0 != (PAL_Initialize(argc, argv))) |
| 103 | { |
| 104 | return ( FAIL ); |
| 105 | } |
| 106 | |
| 107 | if(!ExitThreadTest()) |
| 108 | { |
| 109 | Fail ("Test failed\n" ); |
| 110 | } |
| 111 | |
| 112 | PAL_Terminate(); |
| 113 | return ( PASS ); |
| 114 | } |
| 115 | |