OLD | NEW |
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 /* ***** BEGIN LICENSE BLOCK ***** | 2 /* ***** BEGIN LICENSE BLOCK ***** |
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
4 * | 4 * |
5 * The contents of this file are subject to the Mozilla Public License Version | 5 * The contents of this file are subject to the Mozilla Public License Version |
6 * 1.1 (the "License"); you may not use this file except in compliance with | 6 * 1.1 (the "License"); you may not use this file except in compliance with |
7 * the License. You may obtain a copy of the License at | 7 * the License. You may obtain a copy of the License at |
8 * http://www.mozilla.org/MPL/ | 8 * http://www.mozilla.org/MPL/ |
9 * | 9 * |
10 * Software distributed under the License is distributed on an "AS IS" basis, | 10 * Software distributed under the License is distributed on an "AS IS" basis, |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 | 302 |
303 PRThread* | 303 PRThread* |
304 _MD_CURRENT_THREAD(void) | 304 _MD_CURRENT_THREAD(void) |
305 { | 305 { |
306 PRThread *thread; | 306 PRThread *thread; |
307 | 307 |
308 thread = _MD_GET_ATTACHED_THREAD(); | 308 thread = _MD_GET_ATTACHED_THREAD(); |
309 | 309 |
310 if (NULL == thread) { | 310 if (NULL == thread) { |
311 thread = _PRI_AttachThread( | 311 thread = _PRI_AttachThread( |
312 PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, NULL, 0); | 312 PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); |
313 } | 313 } |
314 PR_ASSERT(thread != NULL); | 314 PR_ASSERT(thread != NULL); |
315 return thread; | 315 return thread; |
316 } | 316 } |
317 | 317 |
318 // The following code is from Chromium src/base/thread_local_storage_win.cc, | 318 // The following code is from Chromium src/base/thread_local_storage_win.cc, |
319 // r11329. | 319 // r11329. |
320 | 320 |
321 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 321 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
322 // | 322 // |
(...skipping 23 matching lines...) Expand all Loading... |
346 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 346 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
347 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 347 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
348 | 348 |
349 // Thread Termination Callbacks. | 349 // Thread Termination Callbacks. |
350 // Windows doesn't support a per-thread destructor with its | 350 // Windows doesn't support a per-thread destructor with its |
351 // TLS primitives. So, we build it manually by inserting a | 351 // TLS primitives. So, we build it manually by inserting a |
352 // function to be called on each thread's exit. | 352 // function to be called on each thread's exit. |
353 // This magic is from http://www.codeproject.com/threads/tls.asp | 353 // This magic is from http://www.codeproject.com/threads/tls.asp |
354 // and it works for VC++ 7.0 and later. | 354 // and it works for VC++ 7.0 and later. |
355 | 355 |
| 356 // Force a reference to _tls_used to make the linker create the TLS directory |
| 357 // if it's not already there. (e.g. if __declspec(thread) is not used). |
| 358 // Force a reference to p_thread_callback_nspr to prevent whole program |
| 359 // optimization from discarding the variable. |
356 #ifdef _WIN64 | 360 #ifdef _WIN64 |
357 | 361 |
358 // This makes the linker create the TLS directory if it's not already | |
359 // there. (e.g. if __declspec(thread) is not used). | |
360 #pragma comment(linker, "/INCLUDE:_tls_used") | 362 #pragma comment(linker, "/INCLUDE:_tls_used") |
| 363 #pragma comment(linker, "/INCLUDE:p_thread_callback_nspr") |
361 | 364 |
362 #else // _WIN64 | 365 #else // _WIN64 |
363 | 366 |
364 // This makes the linker create the TLS directory if it's not already | |
365 // there. (e.g. if __declspec(thread) is not used). | |
366 #pragma comment(linker, "/INCLUDE:__tls_used") | 367 #pragma comment(linker, "/INCLUDE:__tls_used") |
| 368 #pragma comment(linker, "/INCLUDE:_p_thread_callback_nspr") |
367 | 369 |
368 #endif // _WIN64 | 370 #endif // _WIN64 |
369 | 371 |
370 // Static callback function to call with each thread termination. | 372 // Static callback function to call with each thread termination. |
371 static void NTAPI PR_OnThreadExit(PVOID module, DWORD reason, PVOID reserved) | 373 static void NTAPI PR_OnThreadExit(PVOID module, DWORD reason, PVOID reserved) |
372 { | 374 { |
373 PRThread *me; | 375 PRThread *me; |
374 | 376 |
375 switch (reason) { | 377 switch (reason) { |
376 case DLL_PROCESS_ATTACH: | 378 case DLL_PROCESS_ATTACH: |
(...skipping 15 matching lines...) Expand all Loading... |
392 // .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are | 394 // .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are |
393 // called automatically by the OS loader code (not the CRT) when the module is | 395 // called automatically by the OS loader code (not the CRT) when the module is |
394 // loaded and on thread creation. They are NOT called if the module has been | 396 // loaded and on thread creation. They are NOT called if the module has been |
395 // loaded by a LoadLibrary() call. It must have implicitly been loaded at | 397 // loaded by a LoadLibrary() call. It must have implicitly been loaded at |
396 // process startup. | 398 // process startup. |
397 // By implicitly loaded, I mean that it is directly referenced by the main EXE | 399 // By implicitly loaded, I mean that it is directly referenced by the main EXE |
398 // or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being | 400 // or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being |
399 // implicitly loaded. | 401 // implicitly loaded. |
400 // | 402 // |
401 // See VC\crt\src\tlssup.c for reference. | 403 // See VC\crt\src\tlssup.c for reference. |
| 404 |
| 405 // The linker must not discard p_thread_callback_nspr. (We force a reference |
| 406 // to this variable with a linker /INCLUDE:symbol pragma to ensure that.) If |
| 407 // this variable is discarded, the PR_OnThreadExit function will never be |
| 408 // called. |
402 #ifdef _WIN64 | 409 #ifdef _WIN64 |
403 | 410 |
404 // .CRT section is merged with .rdata on x64 so it must be constant data. | 411 // .CRT section is merged with .rdata on x64 so it must be constant data. |
405 #pragma const_seg(".CRT$XLB") | 412 #pragma const_seg(".CRT$XLB") |
406 // When defining a const variable, it must have external linkage to be sure the | 413 // When defining a const variable, it must have external linkage to be sure the |
407 // linker doesn't discard it. If this value is discarded, the PR_OnThreadExit | 414 // linker doesn't discard it. |
408 // function will never be called. | 415 extern const PIMAGE_TLS_CALLBACK p_thread_callback_nspr; |
409 extern const PIMAGE_TLS_CALLBACK p_thread_callback; | 416 const PIMAGE_TLS_CALLBACK p_thread_callback_nspr = PR_OnThreadExit; |
410 const PIMAGE_TLS_CALLBACK p_thread_callback = PR_OnThreadExit; | |
411 | 417 |
412 // Reset the default section. | 418 // Reset the default section. |
413 #pragma const_seg() | 419 #pragma const_seg() |
414 | 420 |
415 #else // _WIN64 | 421 #else // _WIN64 |
416 | 422 |
417 #pragma data_seg(".CRT$XLB") | 423 #pragma data_seg(".CRT$XLB") |
418 PIMAGE_TLS_CALLBACK p_thread_callback = PR_OnThreadExit; | 424 PIMAGE_TLS_CALLBACK p_thread_callback_nspr = PR_OnThreadExit; |
419 | 425 |
420 // Reset the default section. | 426 // Reset the default section. |
421 #pragma data_seg() | 427 #pragma data_seg() |
422 | 428 |
423 #endif // _WIN64 | 429 #endif // _WIN64 |
OLD | NEW |