f94936c549
If two threads concurrently trigger initialization of the lazily populated ObjectStore members, they have to coordinate. We ensure mutual exclusion by holding a writer lock, to ensure only one thread can perform the lazy initialization. Furthermore we use store-release/load-acquire for those ObjectStore fields to ensure that once an object is made available on ObjectStore all of it's initializing stores are visible at that point. We no longer make public setters for those fields, since they shouldn't be used (only the getters + lazy initialization should be used) Fixes https://github.com/dart-lang/sdk/issues/46611 TEST=Fixes TSAN races reported on iso-stres builder. Change-Id: Icaf54bb224e74baf1bfbb4a9bfc386ebfbd52755 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206782 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Tess Strickland <sstrickl@google.com>
50 lines
1.4 KiB
C++
50 lines
1.4 KiB
C++
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "platform/atomic.h"
|
|
|
|
#include "vm/cpu.h"
|
|
#include "vm/os.h"
|
|
#include "vm/version.h"
|
|
|
|
namespace dart {
|
|
|
|
// We use acquire-release semantics to ensure initializing stores to the string
|
|
// are visible when the string becomes visible.
|
|
static AcqRelAtomic<const char*> formatted_version = nullptr;
|
|
|
|
const char* Version::String() {
|
|
if (formatted_version.load() == nullptr) {
|
|
const char* os = OS::Name();
|
|
const char* arch = CPU::Id();
|
|
char* version_string =
|
|
OS::SCreate(nullptr, "%s on \"%s_%s\"", str_, os, arch);
|
|
const char* expect_old_is_null = nullptr;
|
|
if (!formatted_version.compare_exchange_strong(expect_old_is_null,
|
|
version_string)) {
|
|
free(version_string);
|
|
}
|
|
}
|
|
return formatted_version.load();
|
|
}
|
|
|
|
const char* Version::SnapshotString() {
|
|
return snapshot_hash_;
|
|
}
|
|
|
|
const char* Version::CommitString() {
|
|
return commit_;
|
|
}
|
|
|
|
const char* Version::SdkHash() {
|
|
return git_short_hash_;
|
|
}
|
|
|
|
const char* Version::snapshot_hash_ = "{{SNAPSHOT_HASH}}";
|
|
const char* Version::str_ = "{{VERSION_STR}} ({{CHANNEL}}) ({{COMMIT_TIME}})";
|
|
const char* Version::commit_ = "{{VERSION_STR}}";
|
|
const char* Version::git_short_hash_ = "{{GIT_HASH}}";
|
|
|
|
} // namespace dart
|