summaryrefslogtreecommitdiffstats
path: root/libcxx/src
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2019-05-22 03:45:49 +0000
committerEric Fiselier <eric@efcs.ca>2019-05-22 03:45:49 +0000
commitf8d2d87fbbdf1c59c9ddad45cfc6064ac0c2cf18 (patch)
tree676531bb89b34f00d36937725417340bea3504ed /libcxx/src
parentb727b0483c864a3d82dce4c4da913cfe968aed4e (diff)
downloadbcm5719-llvm-f8d2d87fbbdf1c59c9ddad45cfc6064ac0c2cf18.tar.gz
bcm5719-llvm-f8d2d87fbbdf1c59c9ddad45cfc6064ac0c2cf18.zip
Speculative fix for std stream destruction order on Windows.
The MSVC CRT uses TLS storage to implement per-thread locales. This storage gets freed during program termination, and if we attempt to do any io operations (like flushing the std streams) after this occurs the program may abort. This patch is a speculative fix for that issue. The fix tries forcing the initialization of the locale TLS before initializing the std streams. This should mean that the TLS is freed after we destroy the streams. llvm-svn: 361348
Diffstat (limited to 'libcxx/src')
-rw-r--r--libcxx/src/iostream.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index 9b8d1fa444a..0a5d6e8d226 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "__std_stream"
+#include "__locale"
#include "string"
#include "new"
@@ -78,8 +79,28 @@ __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_t
_LIBCPP_HIDDEN ios_base::Init __start_std_streams;
+// On Windows the TLS storage for locales needs to be initialized before we create
+// the standard streams, otherwise it may not be alive during program termination
+// when we flush the streams.
+static void force_locale_initialization() {
+#if defined(_LIBCPP_MSVCRT_LIKE)
+ static bool once = []() {
+ auto loc = newlocale(LC_ALL_MASK, "C", 0);
+ {
+ __libcpp_locale_guard g(loc); // forces initialization of locale TLS
+ ((void)g);
+ }
+ freelocale(loc);
+ return true;
+ }();
+ ((void)once);
+#endif
+}
+
ios_base::Init::Init()
{
+ force_locale_initialization();
+
#ifndef _LIBCPP_HAS_NO_STDIN
istream* cin_ptr = ::new(cin) istream(::new(__cin) __stdinbuf <char>(stdin, &mb_cin));
wistream* wcin_ptr = ::new(wcin) wistream(::new(__wcin) __stdinbuf <wchar_t>(stdin, &mb_wcin));
OpenPOWER on IntegriCloud