Use non recursive mutex in rtc::ThreadManager

ThreadManager, i.e. list of all thread is only used for debugging
purpose now, such uses do not enter the loop recursively

Bug: webrtc:11567
Change-Id: I7deb86e0245950c92fe27485285fd119baf6707a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/289461
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38986}
This commit is contained in:
Danil Chapovalov 2023-01-02 09:21:29 +00:00 committed by WebRTC LUCI CQ
parent e192b68958
commit c3c8934219
2 changed files with 6 additions and 40 deletions

View File

@ -37,7 +37,6 @@
#include "absl/cleanup/cleanup.h" #include "absl/cleanup/cleanup.h"
#include "api/sequence_checker.h" #include "api/sequence_checker.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/deprecated/recursive_critical_section.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/internal/default_socket_server.h" #include "rtc_base/internal/default_socket_server.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
@ -74,35 +73,10 @@ class ScopedAutoReleasePool {
#endif #endif
namespace rtc { namespace rtc {
namespace {
using ::webrtc::MutexLock; using ::webrtc::MutexLock;
using ::webrtc::TimeDelta; using ::webrtc::TimeDelta;
class RTC_SCOPED_LOCKABLE MarkProcessingCritScope {
public:
MarkProcessingCritScope(const RecursiveCriticalSection* cs,
size_t* processing) RTC_EXCLUSIVE_LOCK_FUNCTION(cs)
: cs_(cs), processing_(processing) {
cs_->Enter();
*processing_ += 1;
}
~MarkProcessingCritScope() RTC_UNLOCK_FUNCTION() {
*processing_ -= 1;
cs_->Leave();
}
MarkProcessingCritScope(const MarkProcessingCritScope&) = delete;
MarkProcessingCritScope& operator=(const MarkProcessingCritScope&) = delete;
private:
const RecursiveCriticalSection* const cs_;
size_t* processing_;
};
} // namespace
ThreadManager* ThreadManager::Instance() { ThreadManager* ThreadManager::Instance() {
static ThreadManager* const thread_manager = new ThreadManager(); static ThreadManager* const thread_manager = new ThreadManager();
return thread_manager; return thread_manager;
@ -118,9 +92,7 @@ void ThreadManager::Add(Thread* message_queue) {
return Instance()->AddInternal(message_queue); return Instance()->AddInternal(message_queue);
} }
void ThreadManager::AddInternal(Thread* message_queue) { void ThreadManager::AddInternal(Thread* message_queue) {
CritScope cs(&crit_); MutexLock cs(&crit_);
// Prevent changes while the list of message queues is processed.
RTC_DCHECK_EQ(processing_, 0);
message_queues_.push_back(message_queue); message_queues_.push_back(message_queue);
} }
@ -130,9 +102,7 @@ void ThreadManager::Remove(Thread* message_queue) {
} }
void ThreadManager::RemoveInternal(Thread* message_queue) { void ThreadManager::RemoveInternal(Thread* message_queue) {
{ {
CritScope cs(&crit_); MutexLock cs(&crit_);
// Prevent changes while the list of message queues is processed.
RTC_DCHECK_EQ(processing_, 0);
std::vector<Thread*>::iterator iter; std::vector<Thread*>::iterator iter;
iter = absl::c_find(message_queues_, message_queue); iter = absl::c_find(message_queues_, message_queue);
if (iter != message_queues_.end()) { if (iter != message_queues_.end()) {
@ -161,7 +131,7 @@ void ThreadManager::RegisterSendAndCheckForCycles(Thread* source,
RTC_DCHECK(source); RTC_DCHECK(source);
RTC_DCHECK(target); RTC_DCHECK(target);
CritScope cs(&crit_); MutexLock cs(&crit_);
std::deque<Thread*> all_targets({target}); std::deque<Thread*> all_targets({target});
// We check the pre-existing who-sends-to-who graph for any path from target // We check the pre-existing who-sends-to-who graph for any path from target
// to source. This loop is guaranteed to terminate because per the send graph // to source. This loop is guaranteed to terminate because per the send graph
@ -191,7 +161,7 @@ void ThreadManager::ProcessAllMessageQueuesInternal() {
std::atomic<int> queues_not_done(0); std::atomic<int> queues_not_done(0);
{ {
MarkProcessingCritScope cs(&crit_, &processing_); MutexLock cs(&crit_);
for (Thread* queue : message_queues_) { for (Thread* queue : message_queues_) {
if (!queue->IsProcessingMessagesForTesting()) { if (!queue->IsProcessingMessagesForTesting()) {
// If the queue is not processing messages, it can // If the queue is not processing messages, it can

View File

@ -34,7 +34,6 @@
#include "api/task_queue/task_queue_base.h" #include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/deprecated/recursive_critical_section.h"
#include "rtc_base/platform_thread_types.h" #include "rtc_base/platform_thread_types.h"
#include "rtc_base/socket_server.h" #include "rtc_base/socket_server.h"
#include "rtc_base/synchronization/mutex.h" #include "rtc_base/synchronization/mutex.h"
@ -140,11 +139,8 @@ class RTC_EXPORT ThreadManager {
// This list contains all live Threads. // This list contains all live Threads.
std::vector<Thread*> message_queues_ RTC_GUARDED_BY(crit_); std::vector<Thread*> message_queues_ RTC_GUARDED_BY(crit_);
// Methods that don't modify the list of message queues may be called in a webrtc::Mutex crit_;
// re-entrant fashion. "processing_" keeps track of the depth of re-entrant
// calls.
RecursiveCriticalSection crit_;
size_t processing_ RTC_GUARDED_BY(crit_) = 0;
#if RTC_DCHECK_IS_ON #if RTC_DCHECK_IS_ON
// Represents all thread seand actions by storing all send targets per thread. // Represents all thread seand actions by storing all send targets per thread.
// This is used by RegisterSendAndCheckForCycles. This graph has no cycles // This is used by RegisterSendAndCheckForCycles. This graph has no cycles