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: test8.c (DuplicateHandle)
8**
9** Purpose: Tests the PAL implementation of the DuplicateHandle function,
10** with a handle from GetCurrentThread. The test will create a thread
11** handle, get the current thread and its duplicate. Then get the
12** priorities of the threads, set the priority of one and the change
13** should be seen in the other.
14**
15**
16**===================================================================*/
17
18#include <palsuite.h>
19
20DWORD PALAPI CreateTestThread(LPVOID lpParam);
21
22int __cdecl main(int argc, char* argv[])
23{
24 HANDLE hThread;
25 HANDLE hCurrentThread;
26 HANDLE hDupThread;
27 DWORD dwThreadId = 0;
28 LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread;
29
30 int threadPriority;
31 int duplicatePriority;
32 int finalPriority;
33
34 /* Initialize the PAL.*/
35 if ((PAL_Initialize(argc, argv)) != 0)
36 {
37 return (FAIL);
38 }
39
40#if !HAVE_SCHED_OTHER_ASSIGNABLE
41 /* Defining thread priority for SCHED_OTHER is implementation defined.
42 Some platforms like NetBSD cannot reassign it as they are dynamic.
43 */
44 printf("paltest_duplicatehandle_test8 has been disabled on this platform\n");
45#else
46
47 /* Create a thread.*/
48 hThread = CreateThread(NULL, /* SD*/
49 (DWORD)0, /* initial stack size*/
50 lpStartAddress, /* thread function*/
51 NULL, /* thread argument*/
52 (DWORD)0, /* creation option*/
53 &dwThreadId); /* thread identifier*/
54 if (hThread == NULL)
55 {
56 Fail("ERROR:%u: Unable to create thread.\n",
57 GetLastError());
58 }
59
60 /*Get a psuedo handle to the current thread.*/
61 hCurrentThread = GetCurrentThread();
62
63 /* Duplicate the psuedo thread handle.*/
64 if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/
65 hCurrentThread, /* handle to duplicate*/
66 GetCurrentProcess(), /* target process handle*/
67 &hDupThread, /* duplicate handle*/
68 (DWORD)0, /* requested access*/
69 FALSE, /* handle inheritance*/
70 DUPLICATE_SAME_ACCESS))) /* optional actions*/
71 {
72 Trace("ERROR: %ld :Fail to create the duplicate handle"
73 " to hThread=0x%lx",
74 GetLastError(),
75 hThread);
76 CloseHandle(hThread);
77 Fail("");
78 }
79
80 /* Get the priority of the thread.*/
81 threadPriority = GetThreadPriority(hCurrentThread);
82 if(threadPriority != 0)
83 {
84 Trace("ERROR: Thread priority of hCurrentThread=0x%lx should be "
85 "set to normal THREAD_PRIORITY_NORMAL=%d\n",
86 hCurrentThread,
87 THREAD_PRIORITY_NORMAL);
88 CloseHandle(hThread);
89 CloseHandle(hDupThread);
90 Fail("");
91 }
92
93 /* Get the priority of the duplicated handle, and compare it to
94 * the priority of the original thread. Should be the same.*/
95 duplicatePriority = GetThreadPriority(hCurrentThread);
96 if(duplicatePriority != threadPriority)
97 {
98 Trace("ERROR: Expected priority of hCurrentThread=0x%lx and "
99 "hDupThread=0x%lx to be the same. Priorities:hThread="
100 "\"%d\":hDupThread=\"%d\"\n",
101 hCurrentThread,
102 hDupThread,
103 threadPriority,
104 duplicatePriority);
105 CloseHandle(hThread);
106 CloseHandle(hDupThread);
107 Fail("");
108 }
109
110 /* Set the priority of the original thread.*/
111 if(!SetThreadPriority (hCurrentThread,THREAD_PRIORITY_HIGHEST))
112 {
113 Trace("ERROR:%u: SetThreadPriority failed on hCurrentThread=0x%lx\n",
114 GetLastError(),
115 hCurrentThread);
116 CloseHandle(hThread);
117 CloseHandle(hDupThread);
118 Fail("");
119 }
120
121 /* Get the priority of the duplicate thread, and
122 * compare it to what the original was set to.*/
123 finalPriority = GetThreadPriority(hDupThread);
124 if (finalPriority != THREAD_PRIORITY_HIGHEST)
125 {
126 Trace("ERROR: Expected priority of hCurrentThread=0x%lw and "
127 "hDupThread=0x%lw to be set the same. Priorities:"
128 "hCurrentThread=\"%d\":hDupThread=\"%d\".\n",
129 hCurrentThread,
130 hDupThread,
131 threadPriority,
132 duplicatePriority);
133 CloseHandle(hThread);
134 CloseHandle(hDupThread);
135 Fail("");
136 }
137
138 /* Wait on the original thread.*/
139 if((WaitForSingleObject(hThread, 100)) != WAIT_OBJECT_0)
140 {
141 Trace("ERROR:%u: hCurrentThread=0x%lx is in a non-signalled "
142 "mode, yet created signalled.\n",
143 GetLastError(),
144 hThread);
145 CloseHandle(hThread);
146 CloseHandle(hDupThread);
147 Fail("");
148 }
149
150 /* Clean-up thread and Terminate the PAL.*/
151 CloseHandle(hThread);
152 CloseHandle(hDupThread);
153
154#endif
155
156 PAL_Terminate();
157 return PASS;
158}
159
160/*Thread testing function, only return '0'*/
161DWORD PALAPI CreateTestThread(LPVOID lpParam)
162{
163 return (DWORD)0;
164}
165