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: WFSOMutexTest.c |
8 | ** |
9 | ** Purpose: Test for WaitForSingleObjectTest. |
10 | ** Create Mutex Object |
11 | ** Create Two Threads, Each Threads does WFSO for the Mutex Object |
12 | ** Increments Counter |
13 | ** Releases Mutex |
14 | ** Test Passes if the above operations are successful |
15 | ** |
16 | ** |
17 | ** |
18 | **=========================================================*/ |
19 | |
20 | |
21 | |
22 | #include <palsuite.h> |
23 | |
24 | |
25 | #define NUMBER_OF_WORKER_THREADS 2 |
26 | |
27 | //Declaring Variables |
28 | HANDLE hMutex = NULL; |
29 | unsigned int globalcounter =0; |
30 | int testReturnCode = PASS; |
31 | |
32 | //Declaring Function Prototypes |
33 | DWORD PALAPI WFSOMutexTest(LPVOID params); |
34 | void incrementCounter(void); |
35 | |
36 | |
37 | |
38 | int __cdecl main(int argc, char **argv) |
39 | { |
40 | |
41 | //Declare local variables |
42 | int i =0; |
43 | |
44 | // 2 dimensional array to hold thread handles for each worker thread |
45 | HANDLE hThread[NUMBER_OF_WORKER_THREADS]; |
46 | DWORD dwThreadId=0; |
47 | int returnCode = 0; |
48 | |
49 | //Initialize PAL |
50 | if(0 != (PAL_Initialize(argc, argv))) |
51 | { |
52 | return ( FAIL ); |
53 | } |
54 | |
55 | //Create Mutex |
56 | hMutex = CreateMutex(NULL, // no security attributes |
57 | FALSE, // initially not owned |
58 | NULL); // name of mutex |
59 | |
60 | //Check for Mutex Creation |
61 | |
62 | if (hMutex == NULL) |
63 | { |
64 | Fail("Create Mutex Failed, GetLastError: %d\n" , GetLastError()); |
65 | } |
66 | |
67 | |
68 | //Spawn 2 worker threads |
69 | for (i=0;i<NUMBER_OF_WORKER_THREADS;i++) |
70 | { |
71 | //Create Thread |
72 | |
73 | hThread[i] = CreateThread( |
74 | NULL, |
75 | 0, |
76 | WFSOMutexTest, |
77 | NULL, |
78 | 0, |
79 | &dwThreadId); |
80 | |
81 | if ( NULL == hThread[i] ) |
82 | { |
83 | Fail ( "CreateThread() returned NULL. Failing test.\n" |
84 | "GetLastError returned %d\n" , GetLastError()); |
85 | } |
86 | |
87 | } |
88 | |
89 | /* Test running */ |
90 | returnCode = WaitForMultipleObjects( NUMBER_OF_WORKER_THREADS, hThread, TRUE, 5000); |
91 | if( WAIT_OBJECT_0 != returnCode ) |
92 | { |
93 | Trace("Wait for Object(s) returned %d, and GetLastError value is %d\n" , returnCode, GetLastError()); |
94 | testReturnCode = FAIL; |
95 | } |
96 | |
97 | //Close thread handles |
98 | for (i=0;i<NUMBER_OF_WORKER_THREADS;i++) |
99 | { |
100 | |
101 | if (0==CloseHandle(hThread[i])) |
102 | { |
103 | Trace("Could not Close thread handle\n" ); |
104 | Fail ( "GetLastError returned %d\n" , GetLastError()); |
105 | } |
106 | } |
107 | |
108 | //Close Mutex Handle |
109 | if (0==CloseHandle(hMutex)) |
110 | { |
111 | Trace("Could not close mutex handle\n" ); |
112 | Fail ( "GetLastError returned %d\n" , GetLastError()); |
113 | } |
114 | |
115 | |
116 | PAL_TerminateEx(testReturnCode); |
117 | return ( testReturnCode ); |
118 | |
119 | } |
120 | |
121 | |
122 | void incrementCounter(void) |
123 | { |
124 | if (INT_MAX == globalcounter) |
125 | { |
126 | globalcounter = 0; |
127 | } |
128 | |
129 | globalcounter++; |
130 | Trace("Global Counter Value: %d \n" , globalcounter); |
131 | } |
132 | |
133 | |
134 | DWORD PALAPI WFSOMutexTest(LPVOID params) |
135 | { |
136 | |
137 | DWORD dwWaitResult; |
138 | |
139 | // Request ownership of mutex. |
140 | |
141 | dwWaitResult = WaitForSingleObject( |
142 | hMutex, // handle to mutex |
143 | 5000L); // five-second time-out interval |
144 | |
145 | switch (dwWaitResult) |
146 | { |
147 | // The thread got mutex ownership. |
148 | case WAIT_OBJECT_0: |
149 | { |
150 | |
151 | incrementCounter(); |
152 | |
153 | //Release ownership of the mutex object. |
154 | if (! ReleaseMutex(hMutex)) |
155 | { |
156 | Fail ( "ReleaseMutex() returned NULL. Failing test.\n" |
157 | "GetLastError returned %d\n" , GetLastError()); |
158 | } |
159 | |
160 | break; |
161 | } |
162 | |
163 | // Cannot get mutex ownership due to time-out. |
164 | case WAIT_TIMEOUT: |
165 | { |
166 | Fail ( "Cannot get mutex ownership due to time-out. Failing test.\n" |
167 | "GetLastError returned %d\n" , GetLastError()); |
168 | return FALSE; |
169 | } |
170 | |
171 | // Got ownership of the abandoned mutex object. |
172 | case WAIT_ABANDONED: |
173 | { |
174 | Fail ( "Got ownership of the abandoned mutex object. Failing test.\n" |
175 | "GetLastError returned %d\n" , GetLastError()); |
176 | return FALSE; |
177 | } |
178 | } |
179 | |
180 | return 1; |
181 | } |
182 | |
183 | |
184 | |
185 | |