mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
[dart vm] Add in call to time svc for UTC offset
Dart VM will now call the time service to get the UTC offset. Change-Id: Iec5f1a375d1fbc00c534eed10c8f1ba6b01e87a2 Reviewed-on: https://dart-review.googlesource.com/20824 Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
parent
22d3af523c
commit
fcc6836b88
2 changed files with 47 additions and 20 deletions
|
@ -75,6 +75,10 @@ template("build_libdart_vm") {
|
|||
# TODO(zra): When the platform-specific timeline code is moved out to
|
||||
# the embedder, this can go away.
|
||||
"//zircon/system/ulib/fbl",
|
||||
# TODO(US-399): Remove time_service specific code when it is no longer
|
||||
# necessary.
|
||||
"//garnet/public/lib/time_service/fidl",
|
||||
"//garnet/public/lib/app/cpp",
|
||||
]
|
||||
}
|
||||
public_configs = [ ":libdart_vm_config" ]
|
||||
|
|
|
@ -8,14 +8,20 @@
|
|||
#include "vm/os.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fdio/util.h>
|
||||
#include <zircon/process.h>
|
||||
#include <zircon/syscalls.h>
|
||||
#include <zircon/syscalls/object.h>
|
||||
#include <zircon/types.h>
|
||||
|
||||
#include "lib/app/cpp/environment_services.h"
|
||||
#include "lib/time_service/fidl/time_service.fidl.h"
|
||||
|
||||
#include "platform/assert.h"
|
||||
#include "vm/zone.h"
|
||||
|
||||
static constexpr char kTimeServiceName[] = "time_service::TimeService";
|
||||
|
||||
namespace dart {
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
@ -35,36 +41,53 @@ intptr_t OS::ProcessId() {
|
|||
return static_cast<intptr_t>(getpid());
|
||||
}
|
||||
|
||||
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
|
||||
time_t seconds = static_cast<time_t>(seconds_since_epoch);
|
||||
if (seconds != seconds_since_epoch) {
|
||||
return false;
|
||||
static zx_status_t GetTimeServicePtr(
|
||||
time_service::TimeServiceSyncPtr* time_svc) {
|
||||
zx::channel service_root = app::subtle::CreateStaticServiceRootHandle();
|
||||
zx::channel time_svc_channel = GetSynchronousProxy(time_svc).PassChannel();
|
||||
return fdio_service_connect_at(service_root.get(), kTimeServiceName,
|
||||
time_svc_channel.release());
|
||||
}
|
||||
|
||||
static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
|
||||
int32_t* local_offset,
|
||||
int32_t* dst_offset) {
|
||||
time_service::TimeServiceSyncPtr time_svc;
|
||||
zx_status_t status = GetTimeServicePtr(&time_svc);
|
||||
if (status == ZX_OK) {
|
||||
time_svc->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000, local_offset,
|
||||
dst_offset);
|
||||
*local_offset *= 60;
|
||||
*dst_offset *= 60;
|
||||
}
|
||||
struct tm* error_code = localtime_r(&seconds, tm_result);
|
||||
return error_code != NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
|
||||
tm decomposed;
|
||||
bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
|
||||
// If unsuccessful, return an empty string like V8 does.
|
||||
return (succeeded && (decomposed.tm_zone != NULL)) ? decomposed.tm_zone : "";
|
||||
time_service::TimeServiceSyncPtr time_svc;
|
||||
if (GetTimeServicePtr(&time_svc) == ZX_OK) {
|
||||
fidl::String res;
|
||||
time_svc->GetTimezoneId(&res);
|
||||
char* tz_name = Thread::Current()->zone()->Alloc<char>(res.size() + 1);
|
||||
memmove(tz_name, res.get().c_str(), res.size());
|
||||
tz_name[res.size()] = '\0';
|
||||
return tz_name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
|
||||
tm decomposed;
|
||||
bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
|
||||
// Even if the offset was 24 hours it would still easily fit into 32 bits.
|
||||
// If unsuccessful, return zero like V8 does.
|
||||
return succeeded ? static_cast<int>(decomposed.tm_gmtoff) : 0;
|
||||
int32_t local_offset, dst_offset;
|
||||
zx_status_t status = GetLocalAndDstOffsetInSeconds(
|
||||
seconds_since_epoch, &local_offset, &dst_offset);
|
||||
return status == ZX_OK ? local_offset + dst_offset : 0;
|
||||
}
|
||||
|
||||
int OS::GetLocalTimeZoneAdjustmentInSeconds() {
|
||||
// TODO(floitsch): avoid excessive calls to tzset?
|
||||
tzset();
|
||||
// Even if the offset was 24 hours it would still easily fit into 32 bits.
|
||||
// Note that Unix and Dart disagree on the sign.
|
||||
return static_cast<int>(-timezone);
|
||||
int32_t local_offset, dst_offset;
|
||||
zx_status_t status = GetLocalAndDstOffsetInSeconds(
|
||||
zx_time_get(ZX_CLOCK_UTC) / ZX_SEC(1), &local_offset, &dst_offset);
|
||||
return status == ZX_OK ? local_offset : 0;
|
||||
}
|
||||
|
||||
int64_t OS::GetCurrentTimeMillis() {
|
||||
|
|
Loading…
Reference in a new issue