[dawn][native] Fixes TSAN race from GetCompilationInfo.
- The race happens when multiple threads Complete the
CompilationInfoEvent. The call to
OwnedCompilationMessages::GetCompilationInfo was writing
to the owned copy of CompilationInfo in both threads. Note
that in practice, the competing threads would have written
the same things.
- Adds an atomic bool to gate writing to the internal
CompilationInfo struct that should only ever be written
once.
- Updates some of the asserts to use the new bool to be
explicit.
Bug: 373845830
Change-Id: I3998a276bc210bc5bf5bccfe31c44b4e01de4472
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/211947
Reviewed-by: Shrek Shao <shrekshao@google.com>
Auto-Submit: Loko Kung <lokokung@google.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/dawn/native/CompilationMessages.cpp b/src/dawn/native/CompilationMessages.cpp
index 91c3b59..3fe0be5 100644
--- a/src/dawn/native/CompilationMessages.cpp
+++ b/src/dawn/native/CompilationMessages.cpp
@@ -83,11 +83,7 @@
return numberOfUTF16CodeUnits;
}
-OwnedCompilationMessages::OwnedCompilationMessages() {
- mCompilationInfo.nextInChain = 0;
- mCompilationInfo.messageCount = 0;
- mCompilationInfo.messages = nullptr;
-}
+OwnedCompilationMessages::OwnedCompilationMessages() = default;
OwnedCompilationMessages::~OwnedCompilationMessages() = default;
@@ -193,7 +189,7 @@
void OwnedCompilationMessages::AddMessage(const CompilationMessage& message) {
// Cannot add messages after GetCompilationInfo has been called.
- DAWN_ASSERT(mCompilationInfo.messages == nullptr);
+ DAWN_ASSERT(!mCompilationInfo->has_value());
DAWN_ASSERT(message.nextInChain == nullptr);
@@ -208,7 +204,7 @@
MaybeError OwnedCompilationMessages::AddMessages(const tint::diag::List& diagnostics) {
// Cannot add messages after GetCompilationInfo has been called.
- DAWN_ASSERT(mCompilationInfo.messages == nullptr);
+ DAWN_ASSERT(!mCompilationInfo->has_value());
for (const auto& diag : diagnostics) {
DAWN_TRY(AddMessage(diag));
@@ -221,17 +217,23 @@
void OwnedCompilationMessages::ClearMessages() {
// Cannot clear messages after GetCompilationInfo has been called.
- DAWN_ASSERT(mCompilationInfo.messages == nullptr);
+ DAWN_ASSERT(!mCompilationInfo->has_value());
mMessageStrings.clear();
mMessages.clear();
}
const CompilationInfo* OwnedCompilationMessages::GetCompilationInfo() {
- mCompilationInfo.messageCount = mMessages.size();
- mCompilationInfo.messages = mMessages.data();
+ return mCompilationInfo.Use([&](auto info) {
+ if (info->has_value()) {
+ return &info->value();
+ }
- return &mCompilationInfo;
+ (*info).emplace();
+ (*info)->messageCount = mMessages.size();
+ (*info)->messages = mMessages.data();
+ return &info->value();
+ });
}
const std::vector<std::string>& OwnedCompilationMessages::GetFormattedTintMessages() const {
diff --git a/src/dawn/native/CompilationMessages.h b/src/dawn/native/CompilationMessages.h
index 8a0280d..48d79d9 100644
--- a/src/dawn/native/CompilationMessages.h
+++ b/src/dawn/native/CompilationMessages.h
@@ -32,11 +32,11 @@
#include <string>
#include <vector>
+#include "dawn/common/MutexProtected.h"
+#include "dawn/common/NonCopyable.h"
#include "dawn/native/Error.h"
#include "dawn/native/dawn_platform.h"
-#include "dawn/common/NonCopyable.h"
-
namespace tint::diag {
class Diagnostic;
class List;
@@ -76,7 +76,7 @@
void AddMessage(const CompilationMessage& message);
void AddFormattedTintMessages(const tint::diag::List& diagnostics);
- CompilationInfo mCompilationInfo;
+ MutexProtected<std::optional<CompilationInfo>> mCompilationInfo = std::nullopt;
std::vector<std::unique_ptr<std::string>> mMessageStrings;
std::vector<CompilationMessage> mMessages;
std::vector<std::string> mFormattedTintMessages;