Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: nspr/pr/src/md/windows/w95thred.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nspr/pr/src/md/windows/w95sock.c ('k') | nspr/pr/src/md/windows/win32_errors.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "primpl.h"
7 #include <process.h> /* for _beginthreadex() */
8
9 #if defined(_MSC_VER) && _MSC_VER <= 1200
10 /*
11 * VC++ 6.0 doesn't have DWORD_PTR.
12 */
13
14 typedef DWORD DWORD_PTR;
15 #endif /* _MSC_VER <= 1200 */
16
17 /* --- globals ------------------------------------------------ */
18 #ifdef _PR_USE_STATIC_TLS
19 __declspec(thread) struct PRThread *_pr_thread_last_run;
20 __declspec(thread) struct PRThread *_pr_currentThread;
21 __declspec(thread) struct _PRCPU *_pr_currentCPU;
22 #else
23 DWORD _pr_currentThreadIndex;
24 DWORD _pr_lastThreadIndex;
25 DWORD _pr_currentCPUIndex;
26 #endif
27 int _pr_intsOff = 0;
28 _PRInterruptTable _pr_interruptTable[] = { { 0 } };
29
30 void
31 _PR_MD_EARLY_INIT()
32 {
33 #ifndef _PR_USE_STATIC_TLS
34 _pr_currentThreadIndex = TlsAlloc();
35 _pr_lastThreadIndex = TlsAlloc();
36 _pr_currentCPUIndex = TlsAlloc();
37 #endif
38 }
39
40 void _PR_MD_CLEANUP_BEFORE_EXIT(void)
41 {
42 _PR_NT_FreeSids();
43
44 _PR_MD_CleanupSockets();
45
46 WSACleanup();
47
48 #ifndef _PR_USE_STATIC_TLS
49 TlsFree(_pr_currentThreadIndex);
50 TlsFree(_pr_lastThreadIndex);
51 TlsFree(_pr_currentCPUIndex);
52 #endif
53 }
54
55 PRStatus
56 _PR_MD_INIT_THREAD(PRThread *thread)
57 {
58 if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
59 /*
60 ** Warning:
61 ** --------
62 ** NSPR requires a real handle to every thread.
63 ** GetCurrentThread() returns a pseudo-handle which
64 ** is not suitable for some thread operations (e.g.,
65 ** suspending). Therefore, get a real handle from
66 ** the pseudo handle via DuplicateHandle(...)
67 */
68 BOOL ok = DuplicateHandle(
69 GetCurrentProcess(), /* Process of source handle */
70 GetCurrentThread(), /* Pseudo Handle to dup */
71 GetCurrentProcess(), /* Process of handle */
72 &(thread->md.handle), /* resulting handle */
73 0L, /* access flags */
74 FALSE, /* Inheritable */
75 DUPLICATE_SAME_ACCESS); /* Options */
76 if (!ok) {
77 return PR_FAILURE;
78 }
79 thread->id = GetCurrentThreadId();
80 thread->md.id = thread->id;
81 }
82
83 /* Create the blocking IO semaphore */
84 thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL);
85 if (thread->md.blocked_sema == NULL)
86 return PR_FAILURE;
87 else
88 return PR_SUCCESS;
89 }
90
91 static unsigned __stdcall
92 pr_root(void *arg)
93 {
94 PRThread *thread = (PRThread *)arg;
95 thread->md.start(thread);
96 return 0;
97 }
98
99 PRStatus
100 _PR_MD_CREATE_THREAD(PRThread *thread,
101 void (*start)(void *),
102 PRThreadPriority priority,
103 PRThreadScope scope,
104 PRThreadState state,
105 PRUint32 stackSize)
106 {
107
108 thread->md.start = start;
109 thread->md.handle = (HANDLE) _beginthreadex(
110 NULL,
111 thread->stack->stackSize,
112 pr_root,
113 (void *)thread,
114 CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
115 &(thread->id));
116 if(!thread->md.handle) {
117 return PR_FAILURE;
118 }
119
120 thread->md.id = thread->id;
121 /*
122 * On windows, a thread is created with a thread priority of
123 * THREAD_PRIORITY_NORMAL.
124 */
125 if (priority != PR_PRIORITY_NORMAL) {
126 _PR_MD_SET_PRIORITY(&(thread->md), priority);
127 }
128
129 /* Activate the thread */
130 if ( ResumeThread( thread->md.handle ) != -1)
131 return PR_SUCCESS;
132
133 return PR_FAILURE;
134 }
135
136 void
137 _PR_MD_YIELD(void)
138 {
139 /* Can NT really yield at all? */
140 Sleep(0);
141 }
142
143 void
144 _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
145 {
146 int nativePri;
147 BOOL rv;
148
149 if (newPri < PR_PRIORITY_FIRST) {
150 newPri = PR_PRIORITY_FIRST;
151 } else if (newPri > PR_PRIORITY_LAST) {
152 newPri = PR_PRIORITY_LAST;
153 }
154 switch (newPri) {
155 case PR_PRIORITY_LOW:
156 nativePri = THREAD_PRIORITY_BELOW_NORMAL;
157 break;
158 case PR_PRIORITY_NORMAL:
159 nativePri = THREAD_PRIORITY_NORMAL;
160 break;
161 case PR_PRIORITY_HIGH:
162 nativePri = THREAD_PRIORITY_ABOVE_NORMAL;
163 break;
164 case PR_PRIORITY_URGENT:
165 nativePri = THREAD_PRIORITY_HIGHEST;
166 }
167 rv = SetThreadPriority(thread->handle, nativePri);
168 PR_ASSERT(rv);
169 if (!rv) {
170 PR_LOG(_pr_thread_lm, PR_LOG_MIN,
171 ("PR_SetThreadPriority: can't set thread priority\n"));
172 }
173 return;
174 }
175
176 const DWORD MS_VC_EXCEPTION = 0x406D1388;
177
178 #pragma pack(push,8)
179 typedef struct tagTHREADNAME_INFO
180 {
181 DWORD dwType; // Must be 0x1000.
182 LPCSTR szName; // Pointer to name (in user addr space).
183 DWORD dwThreadID; // Thread ID (-1=caller thread).
184 DWORD dwFlags; // Reserved for future use, must be zero.
185 } THREADNAME_INFO;
186 #pragma pack(pop)
187
188 void
189 _PR_MD_SET_CURRENT_THREAD_NAME(const char *name)
190 {
191 #ifdef _MSC_VER
192 THREADNAME_INFO info;
193
194 if (!IsDebuggerPresent())
195 return;
196
197 info.dwType = 0x1000;
198 info.szName = (char*) name;
199 info.dwThreadID = -1;
200 info.dwFlags = 0;
201
202 __try {
203 RaiseException(MS_VC_EXCEPTION,
204 0,
205 sizeof(info) / sizeof(ULONG_PTR),
206 (ULONG_PTR*)&info);
207 } __except(EXCEPTION_CONTINUE_EXECUTION) {
208 }
209 #endif
210 }
211
212 void
213 _PR_MD_CLEAN_THREAD(PRThread *thread)
214 {
215 BOOL rv;
216
217 if (thread->md.blocked_sema) {
218 rv = CloseHandle(thread->md.blocked_sema);
219 PR_ASSERT(rv);
220 thread->md.blocked_sema = 0;
221 }
222
223 if (thread->md.handle) {
224 rv = CloseHandle(thread->md.handle);
225 PR_ASSERT(rv);
226 thread->md.handle = 0;
227 }
228 }
229
230 void
231 _PR_MD_EXIT_THREAD(PRThread *thread)
232 {
233 _PR_MD_CLEAN_THREAD(thread);
234 _PR_MD_SET_CURRENT_THREAD(NULL);
235 }
236
237
238 void
239 _PR_MD_EXIT(PRIntn status)
240 {
241 _exit(status);
242 }
243
244 PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
245 {
246 #ifdef WINCE
247 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
248 return -1;
249 #else
250 DWORD_PTR rv;
251
252 rv = SetThreadAffinityMask(thread->md.handle, mask);
253
254 return rv?0:-1;
255 #endif
256 }
257
258 PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
259 {
260 #ifdef WINCE
261 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
262 return -1;
263 #else
264 BOOL rv;
265 DWORD_PTR process_mask;
266 DWORD_PTR system_mask;
267
268 rv = GetProcessAffinityMask(GetCurrentProcess(),
269 &process_mask, &system_mask);
270 if (rv)
271 *mask = (PRUint32)process_mask;
272
273 return rv?0:-1;
274 #endif
275 }
276
277 void
278 _PR_MD_SUSPEND_CPU(_PRCPU *cpu)
279 {
280 _PR_MD_SUSPEND_THREAD(cpu->thread);
281 }
282
283 void
284 _PR_MD_RESUME_CPU(_PRCPU *cpu)
285 {
286 _PR_MD_RESUME_THREAD(cpu->thread);
287 }
288
289 void
290 _PR_MD_SUSPEND_THREAD(PRThread *thread)
291 {
292 if (_PR_IS_NATIVE_THREAD(thread)) {
293 DWORD previousSuspendCount;
294 /* XXXMB - SuspendThread() is not a blocking call; how do we
295 * know when the thread is *REALLY* suspended?
296 */
297 previousSuspendCount = SuspendThread(thread->md.handle);
298 PR_ASSERT(previousSuspendCount == 0);
299 }
300 }
301
302 void
303 _PR_MD_RESUME_THREAD(PRThread *thread)
304 {
305 if (_PR_IS_NATIVE_THREAD(thread)) {
306 DWORD previousSuspendCount;
307 previousSuspendCount = ResumeThread(thread->md.handle);
308 PR_ASSERT(previousSuspendCount == 1);
309 }
310 }
311
312 PRThread*
313 _MD_CURRENT_THREAD(void)
314 {
315 PRThread *thread;
316
317 thread = _MD_GET_ATTACHED_THREAD();
318
319 if (NULL == thread) {
320 thread = _PRI_AttachThread(
321 PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
322 }
323 PR_ASSERT(thread != NULL);
324 return thread;
325 }
326
327 #ifdef NSPR_STATIC
328
329 // The following code is from Chromium src/base/thread_local_storage_win.cc,
330 // r11329.
331
332 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
333 //
334 // Redistribution and use in source and binary forms, with or without
335 // modification, are permitted provided that the following conditions are
336 // met:
337 //
338 // * Redistributions of source code must retain the above copyright
339 // notice, this list of conditions and the following disclaimer.
340 // * Redistributions in binary form must reproduce the above
341 // copyright notice, this list of conditions and the following disclaimer
342 // in the documentation and/or other materials provided with the
343 // distribution.
344 // * Neither the name of Google Inc. nor the names of its
345 // contributors may be used to endorse or promote products derived from
346 // this software without specific prior written permission.
347 //
348 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
349 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
350 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
351 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
352 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
353 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
354 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
355 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
356 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
357 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
358 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
359
360 // Thread Termination Callbacks.
361 // Windows doesn't support a per-thread destructor with its
362 // TLS primitives. So, we build it manually by inserting a
363 // function to be called on each thread's exit.
364 // This magic is from http://www.codeproject.com/threads/tls.asp
365 // and it works for VC++ 7.0 and later.
366
367 // Force a reference to _tls_used to make the linker create the TLS directory
368 // if it's not already there. (e.g. if __declspec(thread) is not used).
369 // Force a reference to p_thread_callback_nspr to prevent whole program
370 // optimization from discarding the variable.
371 #ifdef _WIN64
372
373 #pragma comment(linker, "/INCLUDE:_tls_used")
374 #pragma comment(linker, "/INCLUDE:p_thread_callback_nspr")
375
376 #else // _WIN64
377
378 #pragma comment(linker, "/INCLUDE:__tls_used")
379 #pragma comment(linker, "/INCLUDE:_p_thread_callback_nspr")
380
381 #endif // _WIN64
382
383 // Static callback function to call with each thread termination.
384 static void NTAPI PR_OnThreadExit(PVOID module, DWORD reason, PVOID reserved)
385 {
386 PRThread *me;
387
388 switch (reason) {
389 case DLL_PROCESS_ATTACH:
390 break;
391 case DLL_THREAD_ATTACH:
392 break;
393 case DLL_THREAD_DETACH:
394 if (_pr_initialized) {
395 me = _MD_GET_ATTACHED_THREAD();
396 if ((me != NULL) && (me->flags & _PR_ATTACHED))
397 _PRI_DetachThread();
398 }
399 break;
400 case DLL_PROCESS_DETACH:
401 break;
402 }
403 }
404
405 // .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
406 // called automatically by the OS loader code (not the CRT) when the module is
407 // loaded and on thread creation. They are NOT called if the module has been
408 // loaded by a LoadLibrary() call. It must have implicitly been loaded at
409 // process startup.
410 // By implicitly loaded, I mean that it is directly referenced by the main EXE
411 // or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being
412 // implicitly loaded.
413 //
414 // See VC\crt\src\tlssup.c for reference.
415
416 // The linker must not discard p_thread_callback_nspr. (We force a reference
417 // to this variable with a linker /INCLUDE:symbol pragma to ensure that.) If
418 // this variable is discarded, the PR_OnThreadExit function will never be
419 // called.
420 #ifdef _WIN64
421
422 // .CRT section is merged with .rdata on x64 so it must be constant data.
423 #pragma const_seg(".CRT$XLB")
424 // When defining a const variable, it must have external linkage to be sure the
425 // linker doesn't discard it.
426 extern const PIMAGE_TLS_CALLBACK p_thread_callback_nspr;
427 const PIMAGE_TLS_CALLBACK p_thread_callback_nspr = PR_OnThreadExit;
428
429 // Reset the default section.
430 #pragma const_seg()
431
432 #else // _WIN64
433
434 #pragma data_seg(".CRT$XLB")
435 PIMAGE_TLS_CALLBACK p_thread_callback_nspr = PR_OnThreadExit;
436
437 // Reset the default section.
438 #pragma data_seg()
439
440 #endif // _WIN64
441
442 #endif // NSPR_STATIC
OLDNEW
« no previous file with comments | « nspr/pr/src/md/windows/w95sock.c ('k') | nspr/pr/src/md/windows/win32_errors.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698