Index: base/time/time_posix.cc |
diff --git a/base/time/time_posix.cc b/base/time/time_posix.cc |
index b5b8213846dbbd282b7aab63c681dc15f6a9ae33..dcbd83cd54e4fb7b769ded532b2ed9b5bf626f47 100644 |
--- a/base/time/time_posix.cc |
+++ b/base/time/time_posix.cc |
@@ -26,9 +26,19 @@ |
#include "base/os_compat_nacl.h" |
#endif |
+#if !defined(OS_MACOSX) |
+#include "base/lazy_instance.h" |
+#include "base/synchronization/lock.h" |
+#endif |
+ |
namespace { |
#if !defined(OS_MACOSX) |
+// This prevents a crash on traversing the environment global and looking up |
+// the 'TZ' variable in libc. See: crbug.com/390567. |
+base::LazyInstance<base::Lock>::Leaky |
+ g_sys_time_to_time_struct_lock = LAZY_INSTANCE_INITIALIZER; |
+ |
// Define a system-specific SysTime that wraps either to a time_t or |
// a time64_t depending on the host system, and associated convertion. |
// See crbug.com/162007 |
@@ -36,6 +46,7 @@ namespace { |
typedef time64_t SysTime; |
SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { |
+ base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); |
if (is_local) |
return mktime64(timestruct); |
else |
@@ -43,6 +54,7 @@ SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { |
} |
void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { |
+ base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); |
if (is_local) |
localtime64_r(&t, timestruct); |
else |
@@ -53,6 +65,7 @@ void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { |
typedef time_t SysTime; |
SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { |
+ base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); |
if (is_local) |
return mktime(timestruct); |
else |
@@ -60,6 +73,7 @@ SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { |
} |
void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { |
+ base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); |
if (is_local) |
localtime_r(&t, timestruct); |
else |