Commit b927af88 authored by ulan@chromium.org's avatar ulan@chromium.org

Fix a race in initialization of timezone cache in platform-win32.

This allocates a timezone cache per isolate.

BUG=
R=jochen@chromium.org

Review URL: https://codereview.chromium.org/197023002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19943 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 17d040e2
...@@ -62,7 +62,7 @@ void DateCache::ResetDateCache() { ...@@ -62,7 +62,7 @@ void DateCache::ResetDateCache() {
after_ = &dst_[1]; after_ = &dst_[1];
local_offset_ms_ = kInvalidLocalOffsetInMs; local_offset_ms_ = kInvalidLocalOffsetInMs;
ymd_valid_ = false; ymd_valid_ = false;
OS::TimeZoneChanged(); OS::ClearTimezoneCache(tz_cache_);
} }
......
...@@ -62,11 +62,14 @@ class DateCache { ...@@ -62,11 +62,14 @@ class DateCache {
// It is an invariant of DateCache that cache stamp is non-negative. // It is an invariant of DateCache that cache stamp is non-negative.
static const int kInvalidStamp = -1; static const int kInvalidStamp = -1;
DateCache() : stamp_(0) { DateCache() : stamp_(0), tz_cache_(OS::CreateTimezoneCache()) {
ResetDateCache(); ResetDateCache();
} }
virtual ~DateCache() {} virtual ~DateCache() {
OS::DisposeTimezoneCache(tz_cache_);
tz_cache_ = NULL;
}
// Clears cached timezone information and increments the cache stamp. // Clears cached timezone information and increments the cache stamp.
...@@ -113,7 +116,7 @@ class DateCache { ...@@ -113,7 +116,7 @@ class DateCache {
if (time_ms < 0 || time_ms > kMaxEpochTimeInMs) { if (time_ms < 0 || time_ms > kMaxEpochTimeInMs) {
time_ms = EquivalentTime(time_ms); time_ms = EquivalentTime(time_ms);
} }
return OS::LocalTimezone(static_cast<double>(time_ms)); return OS::LocalTimezone(static_cast<double>(time_ms), tz_cache_);
} }
// ECMA 262 - 15.9.5.26 // ECMA 262 - 15.9.5.26
...@@ -182,11 +185,11 @@ class DateCache { ...@@ -182,11 +185,11 @@ class DateCache {
// These functions are virtual so that we can override them when testing. // These functions are virtual so that we can override them when testing.
virtual int GetDaylightSavingsOffsetFromOS(int64_t time_sec) { virtual int GetDaylightSavingsOffsetFromOS(int64_t time_sec) {
double time_ms = static_cast<double>(time_sec * 1000); double time_ms = static_cast<double>(time_sec * 1000);
return static_cast<int>(OS::DaylightSavingsOffset(time_ms)); return static_cast<int>(OS::DaylightSavingsOffset(time_ms, tz_cache_));
} }
virtual int GetLocalOffsetFromOS() { virtual int GetLocalOffsetFromOS() {
double offset = OS::LocalTimeOffset(); double offset = OS::LocalTimeOffset(tz_cache_);
ASSERT(offset < kInvalidLocalOffsetInMs); ASSERT(offset < kInvalidLocalOffsetInMs);
return static_cast<int>(offset); return static_cast<int>(offset);
} }
...@@ -253,6 +256,8 @@ class DateCache { ...@@ -253,6 +256,8 @@ class DateCache {
int ymd_year_; int ymd_year_;
int ymd_month_; int ymd_month_;
int ymd_day_; int ymd_day_;
TimezoneCache* tz_cache_;
}; };
} } // namespace v8::internal } } // namespace v8::internal
......
...@@ -51,7 +51,7 @@ namespace v8 { ...@@ -51,7 +51,7 @@ namespace v8 {
namespace internal { namespace internal {
const char* OS::LocalTimezone(double time) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -60,7 +60,7 @@ const char* OS::LocalTimezone(double time) { ...@@ -60,7 +60,7 @@ const char* OS::LocalTimezone(double time) {
} }
double OS::LocalTimeOffset() { double OS::LocalTimeOffset(TimezoneCache* cache) {
// On Cygwin, struct tm does not contain a tm_gmtoff field. // On Cygwin, struct tm does not contain a tm_gmtoff field.
time_t utc = time(NULL); time_t utc = time(NULL);
ASSERT(utc != -1); ASSERT(utc != -1);
......
...@@ -61,7 +61,7 @@ namespace v8 { ...@@ -61,7 +61,7 @@ namespace v8 {
namespace internal { namespace internal {
const char* OS::LocalTimezone(double time) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -70,7 +70,7 @@ const char* OS::LocalTimezone(double time) { ...@@ -70,7 +70,7 @@ const char* OS::LocalTimezone(double time) {
} }
double OS::LocalTimeOffset() { double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL); time_t tv = time(NULL);
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it. // tm_gmtoff includes any daylight savings offset, so subtract it.
......
...@@ -118,7 +118,7 @@ bool OS::ArmUsingHardFloat() { ...@@ -118,7 +118,7 @@ bool OS::ArmUsingHardFloat() {
#endif // def __arm__ #endif // def __arm__
const char* OS::LocalTimezone(double time) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -127,7 +127,7 @@ const char* OS::LocalTimezone(double time) { ...@@ -127,7 +127,7 @@ const char* OS::LocalTimezone(double time) {
} }
double OS::LocalTimeOffset() { double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL); time_t tv = time(NULL);
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it. // tm_gmtoff includes any daylight savings offset, so subtract it.
......
...@@ -182,7 +182,7 @@ void OS::SignalCodeMovingGC() { ...@@ -182,7 +182,7 @@ void OS::SignalCodeMovingGC() {
} }
const char* OS::LocalTimezone(double time) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -191,7 +191,7 @@ const char* OS::LocalTimezone(double time) { ...@@ -191,7 +191,7 @@ const char* OS::LocalTimezone(double time) {
} }
double OS::LocalTimeOffset() { double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL); time_t tv = time(NULL);
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it. // tm_gmtoff includes any daylight savings offset, so subtract it.
......
...@@ -59,7 +59,7 @@ namespace v8 { ...@@ -59,7 +59,7 @@ namespace v8 {
namespace internal { namespace internal {
const char* OS::LocalTimezone(double time) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -68,7 +68,7 @@ const char* OS::LocalTimezone(double time) { ...@@ -68,7 +68,7 @@ const char* OS::LocalTimezone(double time) {
} }
double OS::LocalTimeOffset() { double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL); time_t tv = time(NULL);
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it. // tm_gmtoff includes any daylight savings offset, so subtract it.
......
...@@ -354,7 +354,25 @@ double OS::TimeCurrentMillis() { ...@@ -354,7 +354,25 @@ double OS::TimeCurrentMillis() {
} }
double OS::DaylightSavingsOffset(double time) { class TimezoneCache {};
TimezoneCache* OS::CreateTimezoneCache() {
return NULL;
}
void OS::DisposeTimezoneCache(TimezoneCache* cache) {
ASSERT(cache == NULL);
}
void OS::ClearTimezoneCache(TimezoneCache* cache) {
ASSERT(cache == NULL);
}
double OS::DaylightSavingsOffset(double time, TimezoneCache*) {
if (std::isnan(time)) return nan_value(); if (std::isnan(time)) return nan_value();
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -363,9 +381,6 @@ double OS::DaylightSavingsOffset(double time) { ...@@ -363,9 +381,6 @@ double OS::DaylightSavingsOffset(double time) {
} }
void OS::TimeZoneChanged() {}
int OS::GetLastError() { int OS::GetLastError() {
return errno; return errno;
} }
......
...@@ -110,7 +110,7 @@ bool OS::ArmUsingHardFloat() { ...@@ -110,7 +110,7 @@ bool OS::ArmUsingHardFloat() {
#endif // __arm__ #endif // __arm__
const char* OS::LocalTimezone(double time) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -119,7 +119,7 @@ const char* OS::LocalTimezone(double time) { ...@@ -119,7 +119,7 @@ const char* OS::LocalTimezone(double time) {
} }
double OS::LocalTimeOffset() { double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL); time_t tv = time(NULL);
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it. // tm_gmtoff includes any daylight savings offset, so subtract it.
......
...@@ -80,7 +80,7 @@ namespace v8 { ...@@ -80,7 +80,7 @@ namespace v8 {
namespace internal { namespace internal {
const char* OS::LocalTimezone(double time) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
...@@ -89,7 +89,7 @@ const char* OS::LocalTimezone(double time) { ...@@ -89,7 +89,7 @@ const char* OS::LocalTimezone(double time) {
} }
double OS::LocalTimeOffset() { double OS::LocalTimeOffset(TimezoneCache* cache) {
tzset(); tzset();
return -static_cast<double>(timezone * msPerSecond); return -static_cast<double>(timezone * msPerSecond);
} }
......
This diff is collapsed.
...@@ -159,6 +159,9 @@ inline intptr_t InternalGetExistingThreadLocal(intptr_t index) { ...@@ -159,6 +159,9 @@ inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
#endif // V8_NO_FAST_TLS #endif // V8_NO_FAST_TLS
class TimezoneCache;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// OS // OS
// //
...@@ -182,18 +185,20 @@ class OS { ...@@ -182,18 +185,20 @@ class OS {
// 00:00:00 UTC, January 1, 1970. // 00:00:00 UTC, January 1, 1970.
static double TimeCurrentMillis(); static double TimeCurrentMillis();
static TimezoneCache* CreateTimezoneCache();
static void DisposeTimezoneCache(TimezoneCache* cache);
static void ClearTimezoneCache(TimezoneCache* cache);
// Returns a string identifying the current time zone. The // Returns a string identifying the current time zone. The
// timestamp is used for determining if DST is in effect. // timestamp is used for determining if DST is in effect.
static const char* LocalTimezone(double time); static const char* LocalTimezone(double time, TimezoneCache* cache);
// Returns the local time offset in milliseconds east of UTC without // Returns the local time offset in milliseconds east of UTC without
// taking daylight savings time into account. // taking daylight savings time into account.
static double LocalTimeOffset(); static double LocalTimeOffset(TimezoneCache* cache);
// Returns the daylight savings offset for the given time. // Returns the daylight savings offset for the given time.
static double DaylightSavingsOffset(double time); static double DaylightSavingsOffset(double time, TimezoneCache* cache);
static void TimeZoneChanged();
// Returns last OS error. // Returns last OS error.
static int GetLastError(); static int GetLastError();
......
...@@ -9583,8 +9583,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) { ...@@ -9583,8 +9583,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0); CONVERT_DOUBLE_ARG_CHECKED(x, 0);
int64_t time = isolate->date_cache()->EquivalentTime(static_cast<int64_t>(x)); const char* zone =
const char* zone = OS::LocalTimezone(static_cast<double>(time)); isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone)); return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment