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 | |