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: test2.c
8**
9** Purpose: Test that lpThreadId is assigned the correct
10** threadId value and that lpThreadId can be NULL.
11**
12**
13**=========================================================*/
14
15#include <palsuite.h>
16
17#define NUM_TESTS 3
18
19HANDLE hThread[NUM_TESTS];
20DWORD dwThreadId[NUM_TESTS];
21volatile BOOL bResult[NUM_TESTS];
22volatile DWORD dwThreadId1[NUM_TESTS];
23
24DWORD PALAPI Thread( LPVOID lpParameter)
25{
26 dwThreadId1[(DWORD) lpParameter] = GetCurrentThreadId();
27 bResult[(DWORD) lpParameter] = TRUE;
28 return (DWORD) lpParameter;
29}
30
31struct testCase
32{
33 LPSECURITY_ATTRIBUTES lpThreadAttributes;
34 DWORD dwStackSize;
35 LPTHREAD_START_ROUTINE lpStartAddress;
36 DWORD dwCreationFlags;
37 LPDWORD lpThreadId;
38};
39
40struct testCase testCases[]=
41{
42 {NULL, 0, &Thread, 0, NULL},
43 {NULL, 0, &Thread, CREATE_SUSPENDED, NULL},
44 {NULL, 0, &Thread, 0, (LPDWORD) 1}
45};
46
47/*
48 * close handles
49 */
50BOOL cleanup(int index)
51{
52 int i;
53 BOOL bRet = TRUE;
54
55 for (i = 0; i < index; i++)
56 {
57 if (!CloseHandle(hThread[i]))
58 {
59 bRet = FALSE;
60 Trace("PALSUITE ERROR: CloseHandle(%p) call failed for index %d\n",
61 hThread[i], i);
62 }
63 }
64
65 return(bRet);
66}
67
68int __cdecl main(int argc, char **argv)
69{
70 SIZE_T i;
71 DWORD dwRetWFSO;
72 DWORD dwRetRT;
73 BOOL bRet = TRUE;
74
75 if(0 != (PAL_Initialize(argc, argv)))
76 {
77 return (FAIL);
78 }
79
80 /* set results array to FALSE */
81 for (i = 0; i < NUM_TESTS; i++)
82 {
83 bResult[i]=FALSE;
84 dwThreadId[i]=0;
85 }
86
87 for (i = 0; i < NUM_TESTS; i++)
88 {
89 if (NULL != testCases[i].lpThreadId)
90 {
91 testCases[i].lpThreadId = &dwThreadId[i];
92 }
93 /* pass the index as the thread argument */
94 hThread[i] = CreateThread( testCases[i].lpThreadAttributes,
95 testCases[i].dwStackSize,
96 testCases[i].lpStartAddress,
97 (LPVOID)i,
98 testCases[i].dwCreationFlags,
99 testCases[i].lpThreadId);
100 if (hThread[i] == NULL)
101 {
102 Trace("PALSUITE ERROR: CreateThread('%p' '%d' '%p' '%p' '%d' "
103 "'%p') call failed.\nGetLastError returned '%u'.\n",
104 testCases[i].lpThreadAttributes, testCases[i].dwStackSize,
105 testCases[i].lpStartAddress, (LPVOID)i,
106 testCases[i].dwCreationFlags,
107 testCases[i].lpThreadId, GetLastError());
108 cleanup(i - 1);
109 Fail("");
110 }
111
112 /* Resume suspended threads */
113 if (testCases[i].dwCreationFlags == CREATE_SUSPENDED)
114 {
115 dwRetRT = ResumeThread (hThread[i]);
116 if (dwRetRT != 1)
117 {
118 Trace ("PALSUITE ERROR: ResumeThread(%p) "
119 "call returned %d it should have returned %d.\n"
120 "GetLastError returned %u.\n", hThread[i], dwRetRT,
121 1, GetLastError());
122 cleanup(i);
123 Fail("");
124 }
125 }
126 }
127
128 /* cleanup */
129 for (i = 0; i < NUM_TESTS; i++)
130 {
131 dwRetWFSO = WaitForSingleObject(hThread[i], 10000);
132 if (dwRetWFSO != WAIT_OBJECT_0)
133 {
134 Trace ("PALSUITE ERROR: WaitForSingleObject('%p' '%d') "
135 "call returned %d instead of WAIT_OBJECT_0 ('%d').\n"
136 "GetLastError returned %u.\n", hThread[i], 10000,
137 dwRetWFSO, WAIT_OBJECT_0, GetLastError());
138 cleanup(i);
139 Fail("");
140 }
141 }
142 if(!cleanup(NUM_TESTS))
143 {
144 Fail("");
145 }
146
147 for (i = 0; i < NUM_TESTS; i++)
148 {
149 /*
150 * check to see that all threads were created and were passed
151 * the array index as an argument.
152 */
153 if (FALSE == bResult[i])
154 {
155 bRet = FALSE;
156 Trace("PALSUITE ERROR: result[%d]=%d. It should be %d\n", i,
157 FALSE, TRUE);
158 }
159 /*
160 * check to see that lpThreadId received the correct value.
161 */
162 if (0 != dwThreadId[i])
163 {
164 if (dwThreadId[i] != dwThreadId1[i])
165 {
166 bRet = FALSE;
167 Trace("PALSUITE ERROR: dwThreadId[%d]=%p and dwThreadId1[%d]"
168 "=%p\nThese values should be identical.\n", i,
169 dwThreadId[i], i, dwThreadId1[i]);
170 }
171 }
172 }
173 if (!bRet)
174 {
175 cleanup(NUM_TESTS);
176 Fail("");
177 }
178
179 PAL_Terminate();
180 return (PASS);
181}
182
183
184
185