| --- pr/include/prtypes.h Tue Nov 12 04:52:34 2013 |
| +++ pr/include/prtypes.h Tue Nov 26 11:22:56 2013 |
| @@ -48,7 +48,23 @@ |
| ** |
| ** |
| ***********************************************************************/ |
| -#if defined(WIN32) |
| +#if defined(NSPR_STATIC) |
| + |
| +#define PR_EXPORT(__type) extern __type |
| +#define PR_EXPORT_DATA(__type) extern __type |
| +#define PR_IMPORT(__type) extern __type |
| +#define PR_IMPORT_DATA(__type) extern __type |
| + |
| +#define PR_EXTERN(__type) extern __type |
| +#define PR_IMPLEMENT(__type) __type |
| +#define PR_EXTERN_DATA(__type) extern __type |
| +#define PR_IMPLEMENT_DATA(__type) __type |
| + |
| +#define PR_CALLBACK |
| +#define PR_CALLBACK_DECL |
| +#define PR_STATIC_CALLBACK(__x) static __x |
| + |
| +#elif defined(WIN32) |
| |
| #define PR_EXPORT(__type) extern __declspec(dllexport) __type |
| #define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type |
| --- pr/src/md/windows/w95dllmain.c Tue Nov 12 04:52:34 2013 |
| +++ pr/src/md/windows/w95dllmain.c Mon Mar 03 06:37:08 2014 |
| @@ -3,6 +3,7 @@ |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| +#ifndef NSPR_STATIC /* See the end of w95thred.c. */ |
| /* |
| * The DLL entry point (DllMain) for NSPR. |
| * |
| @@ -37,3 +38,5 @@ |
| } |
| return TRUE; |
| } |
| + |
| +#endif |
| --- pr/src/md/windows/w95thred.c Tue Nov 12 04:52:34 2013 |
| +++ pr/src/md/windows/w95thred.c Tue Nov 26 11:22:56 2013 |
| @@ -318,3 +318,120 @@ |
| PR_ASSERT(thread != NULL); |
| return thread; |
| } |
| + |
| +#ifdef NSPR_STATIC |
| + |
| +// The following code is from Chromium src/base/thread_local_storage_win.cc, |
| +// r11329. |
| + |
| +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| +// |
| +// Redistribution and use in source and binary forms, with or without |
| +// modification, are permitted provided that the following conditions are |
| +// met: |
| +// |
| +// * Redistributions of source code must retain the above copyright |
| +// notice, this list of conditions and the following disclaimer. |
| +// * Redistributions in binary form must reproduce the above |
| +// copyright notice, this list of conditions and the following disclaimer |
| +// in the documentation and/or other materials provided with the |
| +// distribution. |
| +// * Neither the name of Google Inc. nor the names of its |
| +// contributors may be used to endorse or promote products derived from |
| +// this software without specific prior written permission. |
| +// |
| +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| + |
| +// Thread Termination Callbacks. |
| +// Windows doesn't support a per-thread destructor with its |
| +// TLS primitives. So, we build it manually by inserting a |
| +// function to be called on each thread's exit. |
| +// This magic is from http://www.codeproject.com/threads/tls.asp |
| +// and it works for VC++ 7.0 and later. |
| + |
| +// Force a reference to _tls_used to make the linker create the TLS directory |
| +// if it's not already there. (e.g. if __declspec(thread) is not used). |
| +// Force a reference to p_thread_callback_nspr to prevent whole program |
| +// optimization from discarding the variable. |
| +#ifdef _WIN64 |
| + |
| +#pragma comment(linker, "/INCLUDE:_tls_used") |
| +#pragma comment(linker, "/INCLUDE:p_thread_callback_nspr") |
| + |
| +#else // _WIN64 |
| + |
| +#pragma comment(linker, "/INCLUDE:__tls_used") |
| +#pragma comment(linker, "/INCLUDE:_p_thread_callback_nspr") |
| + |
| +#endif // _WIN64 |
| + |
| +// Static callback function to call with each thread termination. |
| +static void NTAPI PR_OnThreadExit(PVOID module, DWORD reason, PVOID reserved) |
| +{ |
| +PRThread *me; |
| + |
| + switch (reason) { |
| + case DLL_PROCESS_ATTACH: |
| + break; |
| + case DLL_THREAD_ATTACH: |
| + break; |
| + case DLL_THREAD_DETACH: |
| + if (_pr_initialized) { |
| + me = _MD_GET_ATTACHED_THREAD(); |
| + if ((me != NULL) && (me->flags & _PR_ATTACHED)) |
| + _PRI_DetachThread(); |
| + } |
| + break; |
| + case DLL_PROCESS_DETACH: |
| + break; |
| + } |
| +} |
| + |
| +// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are |
| +// called automatically by the OS loader code (not the CRT) when the module is |
| +// loaded and on thread creation. They are NOT called if the module has been |
| +// loaded by a LoadLibrary() call. It must have implicitly been loaded at |
| +// process startup. |
| +// By implicitly loaded, I mean that it is directly referenced by the main EXE |
| +// or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being |
| +// implicitly loaded. |
| +// |
| +// See VC\crt\src\tlssup.c for reference. |
| + |
| +// The linker must not discard p_thread_callback_nspr. (We force a reference |
| +// to this variable with a linker /INCLUDE:symbol pragma to ensure that.) If |
| +// this variable is discarded, the PR_OnThreadExit function will never be |
| +// called. |
| +#ifdef _WIN64 |
| + |
| +// .CRT section is merged with .rdata on x64 so it must be constant data. |
| +#pragma const_seg(".CRT$XLB") |
| +// When defining a const variable, it must have external linkage to be sure the |
| +// linker doesn't discard it. |
| +extern const PIMAGE_TLS_CALLBACK p_thread_callback_nspr; |
| +const PIMAGE_TLS_CALLBACK p_thread_callback_nspr = PR_OnThreadExit; |
| + |
| +// Reset the default section. |
| +#pragma const_seg() |
| + |
| +#else // _WIN64 |
| + |
| +#pragma data_seg(".CRT$XLB") |
| +PIMAGE_TLS_CALLBACK p_thread_callback_nspr = PR_OnThreadExit; |
| + |
| +// Reset the default section. |
| +#pragma data_seg() |
| + |
| +#endif // _WIN64 |
| + |
| +#endif // NSPR_STATIC |