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: CriticalSectionFunctions/test5/test5.c
8**
9** Purpose: Attempt to delete a critical section owned by another
10** thread.
11**
12**
13**===================================================================*/
14#include <palsuite.h>
15
16/*
17 * Tokens 0 and 1 are events. Token 2 is the thread.
18 */
19#define NUM_TOKENS 3
20
21HANDLE hToken[NUM_TOKENS];
22CRITICAL_SECTION CriticalSection;
23
24BOOL CleanupHelper (HANDLE *hArray, DWORD dwIndex)
25{
26 BOOL bCHRet;
27
28 bCHRet = CloseHandle(hArray[dwIndex]);
29 if (!bCHRet)
30 {
31 Trace("PALSUITE ERROR: Unable to execute CloseHandle(%p) during "
32 "clean up.\nGetLastError returned '%u'.\n", hArray[dwIndex],
33 GetLastError());
34 }
35
36 return (bCHRet);
37}
38
39BOOL Cleanup(HANDLE *hArray, DWORD dwIndex)
40{
41 BOOL bCRet;
42 BOOL bCHRet = FALSE;
43
44 while (--dwIndex > 0)
45 {
46 bCHRet = CleanupHelper(&hArray[0], dwIndex);
47 }
48
49 bCRet = CloseHandle(hArray[0]);
50 if (!bCRet)
51 {
52 Trace("PALSUITE ERROR: Unable to execute CloseHandle(%p) during "
53 "clean up.\nGetLastError returned '%u'.\n", hArray[dwIndex],
54 GetLastError());
55 }
56
57 return (bCRet&&bCHRet);
58}
59
60DWORD PALAPI Thread(LPVOID lpParam)
61{
62 DWORD dwTRet;
63
64 EnterCriticalSection(&CriticalSection);
65
66 /* signal thread 0 */
67 if (0 == SetEvent(hToken[0]))
68 {
69 Trace("PALSUITE ERROR: Unable to execute SetEvent(%p) during "
70 "clean up.\nGetLastError returned '%u'.\n", hToken[0],
71 GetLastError());
72 LeaveCriticalSection(&CriticalSection);
73 Cleanup (&hToken[0], NUM_TOKENS);
74 DeleteCriticalSection(&CriticalSection);
75 Fail("");
76 }
77
78 /* wait to be signaled */
79 dwTRet = WaitForSingleObject(hToken[1], 10000);
80 if (WAIT_OBJECT_0 != dwTRet)
81
82 {
83 Trace("PALSUITE ERROR: WaitForSingleObject(%p,%d) should have "
84 "returned\nWAIT_OBJECT_0 ('%d'), instead it returned "
85 "('%d').\nGetLastError returned '%u'.\n",
86 hToken[1], 10000, WAIT_OBJECT_0, dwTRet, GetLastError());
87 LeaveCriticalSection(&CriticalSection);
88 Cleanup (&hToken[0], NUM_TOKENS);
89 DeleteCriticalSection(&CriticalSection);
90 Fail("");
91 }
92
93 LeaveCriticalSection(&CriticalSection);
94 return 0;
95}
96
97int __cdecl main(int argc, char **argv)
98{
99 DWORD dwThreadId;
100 DWORD dwMRet;
101
102 if ((PAL_Initialize(argc,argv)) != 0)
103 {
104 return(FAIL);
105 }
106
107 /* thread 0 event */
108 hToken[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
109 if (NULL == hToken[0])
110 {
111 Fail("PALSUITE ERROR: CreateEvent call #0 failed. GetLastError "
112 "returned %u.\n", GetLastError());
113 }
114
115 /* thread 1 event */
116 hToken[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
117 if (NULL == hToken[1])
118 {
119 Trace("PALSUITE ERROR: CreateEvent call #1 failed. GetLastError "
120 "returned %u.\n", GetLastError());
121 Cleanup(&hToken[0], (NUM_TOKENS - 2));
122 Fail("");
123 }
124
125 InitializeCriticalSection(&CriticalSection);
126
127 hToken[2] = CreateThread(NULL,
128 0,
129 &Thread,
130 (LPVOID) NULL,
131 0,
132 &dwThreadId);
133 if (hToken[2] == NULL)
134 {
135 Trace("PALSUITE ERROR: CreateThread call #0 failed. GetLastError "
136 "returned %u.\n", GetLastError());
137 Cleanup(&hToken[0], (NUM_TOKENS - 1));
138 DeleteCriticalSection(&CriticalSection);
139 Fail("");
140 }
141
142 /* wait for thread 0 to be signaled */
143 dwMRet = WaitForSingleObject(hToken[0], 10000);
144 if (WAIT_OBJECT_0 != dwMRet)
145 {
146 Trace("PALSUITE ERROR: WaitForSingleObject(%p,%d) should have "
147 "returned\nWAIT_OBJECT_0 ('%d'), instead it returned "
148 "('%d').\nGetLastError returned '%u'.\n", hToken[0], 10000,
149 WAIT_OBJECT_0, dwMRet, GetLastError());
150 Cleanup(&hToken[0], NUM_TOKENS);
151 Fail("");
152 }
153
154 /*
155 * Attempt to do delete CriticalSection object owned by other thread
156 */
157 DeleteCriticalSection(&CriticalSection);
158
159 /* signal thread 1 */
160 if (0 == SetEvent(hToken[1]))
161 {
162 Trace("PALSUITE ERROR: Unable to execute SetEvent(%p) call.\n"
163 "GetLastError returned '%u'.\n", hToken[1],
164 GetLastError());
165 Cleanup(&hToken[0], NUM_TOKENS);
166 Fail("");
167 }
168
169 dwMRet = WaitForSingleObject(hToken[2], 10000);
170 if (WAIT_OBJECT_0 != dwMRet)
171 {
172 Trace("PALSUITE ERROR: WaitForSingleObject(%p, %d) call "
173 "returned an unexpected value '%d'.\nGetLastError returned "
174 "%u.\n", hToken[2], 10000, dwMRet, GetLastError());
175 Cleanup(&hToken[0], NUM_TOKENS);
176 Fail("");
177 }
178
179 if (!Cleanup(&hToken[0], NUM_TOKENS))
180 {
181 Fail("");
182 }
183
184 PAL_Terminate();
185
186 return (PASS);
187}
188