Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: webrtc/base/asyncinvoker.cc

Issue 2885143006: Fixing potential AsyncInvoker deadlock that occurs for "reentrant" invocations. (Closed)
Patch Set: Addressing TSan race warning Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/base/asyncinvoker.h ('k') | webrtc/base/asyncinvoker-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/base/asyncinvoker.cc
diff --git a/webrtc/base/asyncinvoker.cc b/webrtc/base/asyncinvoker.cc
index bfd13172f70329598dc9393d41eb660f8877e8f7..d2583091ccdcfca9d8140b9db0f3b7c4c411ece3 100644
--- a/webrtc/base/asyncinvoker.cc
+++ b/webrtc/base/asyncinvoker.cc
@@ -19,7 +19,7 @@ namespace rtc {
AsyncInvoker::AsyncInvoker() : invocation_complete_(false, false) {}
AsyncInvoker::~AsyncInvoker() {
- destroying_ = true;
+ AtomicOps::Increment(&destroying_);
// Messages for this need to be cleared *before* our destructor is complete.
MessageQueueManager::Clear(this);
// And we need to wait for any invocations that are still in progress on
@@ -44,7 +44,8 @@ void AsyncInvoker::OnMessage(Message* msg) {
}
void AsyncInvoker::Flush(Thread* thread, uint32_t id /*= MQID_ANY*/) {
- if (destroying_) return;
+ if (AtomicOps::AcquireLoad(&destroying_))
+ return;
// Run this on |thread| to reduce the number of context switches.
if (Thread::Current() != thread) {
@@ -65,11 +66,10 @@ void AsyncInvoker::DoInvoke(const Location& posted_from,
Thread* thread,
std::unique_ptr<AsyncClosure> closure,
uint32_t id) {
- if (destroying_) {
+ if (AtomicOps::AcquireLoad(&destroying_)) {
LOG(LS_WARNING) << "Tried to invoke while destroying the invoker.";
return;
}
- AtomicOps::Increment(&pending_invocations_);
thread->Post(posted_from, this, id,
new ScopedMessageData<AsyncClosure>(std::move(closure)));
}
@@ -79,11 +79,10 @@ void AsyncInvoker::DoInvokeDelayed(const Location& posted_from,
std::unique_ptr<AsyncClosure> closure,
uint32_t delay_ms,
uint32_t id) {
- if (destroying_) {
+ if (AtomicOps::AcquireLoad(&destroying_)) {
LOG(LS_WARNING) << "Tried to invoke while destroying the invoker.";
return;
}
- AtomicOps::Increment(&pending_invocations_);
thread->PostDelayed(posted_from, delay_ms, this, id,
new ScopedMessageData<AsyncClosure>(std::move(closure)));
}
@@ -111,6 +110,10 @@ void GuardedAsyncInvoker::ThreadDestroyed() {
thread_ = nullptr;
}
+AsyncClosure::AsyncClosure(AsyncInvoker* invoker) : invoker_(invoker) {
+ AtomicOps::Increment(&invoker_->pending_invocations_);
+}
+
AsyncClosure::~AsyncClosure() {
AtomicOps::Decrement(&invoker_->pending_invocations_);
invoker_->invocation_complete_.Set();
« no previous file with comments | « webrtc/base/asyncinvoker.h ('k') | webrtc/base/asyncinvoker-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698