1 /*
2 * pthread_self.c
3 *
4 * Description:
5 * This translation unit implements miscellaneous thread functions.
6 *
7 * --------------------------------------------------------------------------
8 *
9 * Pthreads4w - POSIX Threads for Windows
10 * Copyright 1998 John E. Bossom
11 * Copyright 1999-2018, Pthreads4w contributors
12 *
13 * Homepage: https://sourceforge.net/projects/pthreads4w/
14 *
15 * The current list of contributors is contained
16 * in the file CONTRIBUTORS included with the source
17 * code distribution. The list can also be seen at the
18 * following World Wide Web location:
19 *
20 * https://sourceforge.net/p/pthreads4w/wiki/Contributors/
21 *
22 * Licensed under the Apache License, Version 2.0 (the "License");
23 * you may not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
25 *
26 * http://www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
33 */
34
35 #ifdef HAVE_CONFIG_H
36 # include <config.h>
37 #endif
38
39 #include "pthread.h"
40 #include "implement.h"
41
42 pthread_t
pthread_self(void)43 pthread_self (void)
44 /*
45 * ------------------------------------------------------
46 * DOCPUBLIC
47 * This function returns a reference to the current running
48 * thread.
49 *
50 * PARAMETERS
51 * N/A
52 *
53 *
54 * DESCRIPTION
55 * This function returns a reference to the current running
56 * thread.
57 *
58 * RESULTS
59 * pthread_t reference to the current thread
60 *
61 * ------------------------------------------------------
62 */
63 {
64 pthread_t self;
65 pthread_t nil = {NULL, 0};
66 __ptw32_thread_t * sp;
67
68 #if defined(_UWIN)
69 if (!__ptw32_selfThreadKey)
70 return nil;
71 #endif
72
73 sp = (__ptw32_thread_t *) pthread_getspecific (__ptw32_selfThreadKey);
74
75 if (sp != NULL)
76 {
77 self = sp->ptHandle;
78 }
79 else
80 {
81 int fail = __PTW32_FALSE;
82
83 /*
84 * Need to create an implicit 'self' for the currently
85 * executing thread.
86 */
87 self = __ptw32_new ();
88 sp = (__ptw32_thread_t *) self.p;
89
90 if (sp != NULL)
91 {
92 /*
93 * This is a non-POSIX thread which has chosen to call
94 * a POSIX threads function for some reason. We assume that
95 * it isn't joinable, but we do assume that it's
96 * (deferred) cancelable.
97 */
98 sp->implicit = 1;
99 sp->detachState = PTHREAD_CREATE_DETACHED;
100 sp->thread = GetCurrentThreadId ();
101
102 #if defined(NEED_DUPLICATEHANDLE)
103 /*
104 * DuplicateHandle does not exist on WinCE.
105 *
106 * NOTE:
107 * GetCurrentThread only returns a pseudo-handle
108 * which is only valid in the current thread context.
109 * Therefore, you should not pass the handle to
110 * other threads for whatever purpose.
111 */
112 sp->threadH = GetCurrentThread ();
113 #else
114 if (!DuplicateHandle (GetCurrentProcess (),
115 GetCurrentThread (),
116 GetCurrentProcess (),
117 &sp->threadH,
118 0, FALSE, DUPLICATE_SAME_ACCESS))
119 {
120 fail = __PTW32_TRUE;
121 }
122 #endif
123
124 if (!fail)
125 {
126
127 #if defined(HAVE_CPU_AFFINITY)
128
129 /*
130 * Get this threads CPU affinity by temporarily setting the threads
131 * affinity to that of the process to get the old thread affinity,
132 * then reset to the old affinity.
133 */
134 DWORD_PTR vThreadMask, vProcessMask, vSystemMask;
135 if (GetProcessAffinityMask(GetCurrentProcess(), &vProcessMask, &vSystemMask))
136 {
137 vThreadMask = SetThreadAffinityMask(sp->threadH, vProcessMask);
138 if (vThreadMask)
139 {
140 if (SetThreadAffinityMask(sp->threadH, vThreadMask))
141 {
142 sp->cpuset = (size_t) vThreadMask;
143 }
144 else fail = __PTW32_TRUE;
145 }
146 else fail = __PTW32_TRUE;
147 }
148 else fail = __PTW32_TRUE;
149
150 #endif
151
152 sp->sched_priority = GetThreadPriority (sp->threadH);
153 pthread_setspecific (__ptw32_selfThreadKey, (void *) sp);
154 }
155 }
156
157 if (fail)
158 {
159 /*
160 * Thread structs are never freed but are reused so if this
161 * continues to fail at least we don't leak memory.
162 */
163 __ptw32_threadReusePush (self);
164 /*
165 * As this is a win32 thread calling us and we have failed,
166 * return a value that makes sense to win32.
167 */
168 return nil;
169 }
170 else
171 {
172 /*
173 * This implicit POSIX thread is running (it called us).
174 * No other thread can reference us yet because all API calls
175 * passing a pthread_t should recognise an invalid thread id
176 * through the reuse counter inequality.
177 */
178 sp->state = PThreadStateRunning;
179 }
180 }
181
182 return (self);
183 }
184