Cleanup Thread::BlockingCall
Remove integration with socket server of the current thread Network thread that uses PhysicalSocketServer shouldn't be allowed to do blocking calls Other threads that use NullSocketServer do not need to process any messages while blocking Bug: webrtc:14856 Change-Id: I56865b86e0992e60376ecefe163ff6b23911edca Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291527 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39225}
This commit is contained in:
parent
815522782a
commit
2ded55e0df
@ -736,13 +736,10 @@ void Thread::BlockingCall(rtc::FunctionView<void()> functor) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertBlockingIsAllowedOnCurrentThread();
|
|
||||||
|
|
||||||
Thread* current_thread = Thread::Current();
|
|
||||||
|
|
||||||
#if RTC_DCHECK_IS_ON
|
#if RTC_DCHECK_IS_ON
|
||||||
if (current_thread) {
|
if (Thread* current_thread = Thread::Current()) {
|
||||||
RTC_DCHECK_RUN_ON(current_thread);
|
RTC_DCHECK_RUN_ON(current_thread);
|
||||||
|
RTC_DCHECK(current_thread->blocking_calls_allowed_);
|
||||||
current_thread->blocking_call_count_++;
|
current_thread->blocking_call_count_++;
|
||||||
RTC_DCHECK(current_thread->IsInvokeToThreadAllowed(this));
|
RTC_DCHECK(current_thread->IsInvokeToThreadAllowed(this));
|
||||||
ThreadManager::Instance()->RegisterSendAndCheckForCycles(current_thread,
|
ThreadManager::Instance()->RegisterSendAndCheckForCycles(current_thread,
|
||||||
@ -750,54 +747,10 @@ void Thread::BlockingCall(rtc::FunctionView<void()> functor) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Perhaps down the line we can get rid of this workaround and always require
|
Event done;
|
||||||
// current_thread to be valid when BlockingCall() is called.
|
absl::Cleanup cleanup = [&done] { done.Set(); };
|
||||||
std::unique_ptr<rtc::Event> done_event;
|
|
||||||
if (!current_thread)
|
|
||||||
done_event.reset(new rtc::Event());
|
|
||||||
|
|
||||||
bool ready = false;
|
|
||||||
absl::Cleanup cleanup = [this, &ready, current_thread,
|
|
||||||
done = done_event.get()] {
|
|
||||||
if (current_thread) {
|
|
||||||
{
|
|
||||||
MutexLock lock(&mutex_);
|
|
||||||
ready = true;
|
|
||||||
}
|
|
||||||
current_thread->socketserver()->WakeUp();
|
|
||||||
} else {
|
|
||||||
done->Set();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
PostTask([functor, cleanup = std::move(cleanup)] { functor(); });
|
PostTask([functor, cleanup = std::move(cleanup)] { functor(); });
|
||||||
if (current_thread) {
|
done.Wait(Event::kForever);
|
||||||
bool waited = false;
|
|
||||||
mutex_.Lock();
|
|
||||||
while (!ready) {
|
|
||||||
mutex_.Unlock();
|
|
||||||
current_thread->socketserver()->Wait(SocketServer::kForever, false);
|
|
||||||
waited = true;
|
|
||||||
mutex_.Lock();
|
|
||||||
}
|
|
||||||
mutex_.Unlock();
|
|
||||||
|
|
||||||
// Our Wait loop above may have consumed some WakeUp events for this
|
|
||||||
// Thread, that weren't relevant to this Send. Losing these WakeUps can
|
|
||||||
// cause problems for some SocketServers.
|
|
||||||
//
|
|
||||||
// Concrete example:
|
|
||||||
// Win32SocketServer on thread A calls Send on thread B. While processing
|
|
||||||
// the message, thread B Posts a message to A. We consume the wakeup for
|
|
||||||
// that Post while waiting for the Send to complete, which means that when
|
|
||||||
// we exit this loop, we need to issue another WakeUp, or else the Posted
|
|
||||||
// message won't be processed in a timely manner.
|
|
||||||
|
|
||||||
if (waited) {
|
|
||||||
current_thread->socketserver()->WakeUp();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
done_event->Wait(rtc::Event::kForever);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by the ThreadManager when being set as the current thread.
|
// Called by the ThreadManager when being set as the current thread.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user