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

Side by Side Diff: webrtc/base/asyncinvoker.cc

Issue 2859443002: Revert of Relanding: Fixing crash that can occur if signal is modified while firing. (Closed)
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « webrtc/base/asyncinvoker.h ('k') | webrtc/base/sigslot.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/base/asyncinvoker.h" 11 #include "webrtc/base/asyncinvoker.h"
12 12
13 #include "webrtc/base/atomicops.h" 13 #include "webrtc/base/atomicops.h"
14 #include "webrtc/base/checks.h" 14 #include "webrtc/base/checks.h"
15 #include "webrtc/base/logging.h" 15 #include "webrtc/base/logging.h"
16 16
17 namespace rtc { 17 namespace rtc {
18 18
19 AsyncInvoker::AsyncInvoker() : invocation_complete_(false, false) {} 19 AsyncInvoker::AsyncInvoker() : invocation_complete_(false, false) {}
20 20
21 AsyncInvoker::~AsyncInvoker() { 21 AsyncInvoker::~AsyncInvoker() {
22 destroying_ = true; 22 destroying_ = true;
23 SignalInvokerDestroyed();
23 // Messages for this need to be cleared *before* our destructor is complete. 24 // Messages for this need to be cleared *before* our destructor is complete.
24 MessageQueueManager::Clear(this); 25 MessageQueueManager::Clear(this);
25 // And we need to wait for any invocations that are still in progress on 26 // And we need to wait for any invocations that are still in progress on
26 // other threads. 27 // other threads.
27 while (AtomicOps::AcquireLoad(&pending_invocations_)) { 28 while (AtomicOps::AcquireLoad(&pending_invocations_)) {
28 // If the destructor was called while AsyncInvoke was being called by 29 // If the destructor was called while AsyncInvoke was being called by
29 // another thread, WITHIN an AsyncInvoked functor, it may do another 30 // another thread, WITHIN an AsyncInvoked functor, it may do another
30 // Thread::Post even after we called MessageQueueManager::Clear(this). So 31 // Thread::Post even after we called MessageQueueManager::Clear(this). So
31 // we need to keep calling Clear to discard these posts. 32 // we need to keep calling Clear to discard these posts.
32 MessageQueueManager::Clear(this); 33 MessageQueueManager::Clear(this);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 119
119 NotifyingAsyncClosureBase::NotifyingAsyncClosureBase( 120 NotifyingAsyncClosureBase::NotifyingAsyncClosureBase(
120 AsyncInvoker* invoker, 121 AsyncInvoker* invoker,
121 const Location& callback_posted_from, 122 const Location& callback_posted_from,
122 Thread* calling_thread) 123 Thread* calling_thread)
123 : AsyncClosure(invoker), 124 : AsyncClosure(invoker),
124 callback_posted_from_(callback_posted_from), 125 callback_posted_from_(callback_posted_from),
125 calling_thread_(calling_thread) { 126 calling_thread_(calling_thread) {
126 calling_thread->SignalQueueDestroyed.connect( 127 calling_thread->SignalQueueDestroyed.connect(
127 this, &NotifyingAsyncClosureBase::CancelCallback); 128 this, &NotifyingAsyncClosureBase::CancelCallback);
128 // Note: We don't need to listen for the invoker being destroyed, because it 129 invoker->SignalInvokerDestroyed.connect(
129 // will wait for this closure to be destroyed (and pending_invocations_ to go 130 this, &NotifyingAsyncClosureBase::CancelCallback);
130 // to 0) before its destructor completes.
131 } 131 }
132 132
133 NotifyingAsyncClosureBase::~NotifyingAsyncClosureBase() { 133 NotifyingAsyncClosureBase::~NotifyingAsyncClosureBase() {
134 disconnect_all(); 134 disconnect_all();
135 } 135 }
136 136
137 void NotifyingAsyncClosureBase::TriggerCallback() { 137 void NotifyingAsyncClosureBase::TriggerCallback() {
138 CritScope cs(&crit_); 138 CritScope cs(&crit_);
139 if (!CallbackCanceled() && !callback_.empty()) { 139 if (!CallbackCanceled() && !callback_.empty()) {
140 invoker_->AsyncInvoke<void>(callback_posted_from_, calling_thread_, 140 invoker_->AsyncInvoke<void>(callback_posted_from_, calling_thread_,
141 callback_); 141 callback_);
142 } 142 }
143 } 143 }
144 144
145 void NotifyingAsyncClosureBase::CancelCallback() { 145 void NotifyingAsyncClosureBase::CancelCallback() {
146 // If the callback is triggering when this is called, block the 146 // If the callback is triggering when this is called, block the
147 // destructor of the dying object here by waiting until the callback 147 // destructor of the dying object here by waiting until the callback
148 // is done triggering. 148 // is done triggering.
149 CritScope cs(&crit_); 149 CritScope cs(&crit_);
150 // calling_thread_ == nullptr means do not trigger the callback. 150 // calling_thread_ == nullptr means do not trigger the callback.
151 calling_thread_ = nullptr; 151 calling_thread_ = nullptr;
152 } 152 }
153 153
154 } // namespace rtc 154 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/asyncinvoker.h ('k') | webrtc/base/sigslot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698