Remove ReturnTrace from DeregisterCallback().

Should fix deadlock on build bots. Before, TraceImpl called
TraceDispatcher::Print, while TraceDispatcher::Deregister called
TraceImpl through VideoEngine::SetTraceCallback. This violates locking
order as both take their own locks.

BUG=2421
R=stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2340005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4905 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org
2013-10-02 16:22:18 +00:00
parent 4887114af7
commit 9b5c807272

View File

@@ -31,8 +31,16 @@ class TraceDispatcher : public TraceCallback {
public: public:
TraceDispatcher() TraceDispatcher()
: crit_(CriticalSectionWrapper::CreateCriticalSection()), : crit_(CriticalSectionWrapper::CreateCriticalSection()),
initialized_(false),
filter_(kTraceNone) {} filter_(kTraceNone) {}
~TraceDispatcher() {
if (initialized_) {
Trace::ReturnTrace();
VideoEngine::SetTraceCallback(NULL);
}
}
virtual void Print(TraceLevel level, virtual void Print(TraceLevel level,
const char* message, const char* message,
int length) OVERRIDE { int length) OVERRIDE {
@@ -52,23 +60,18 @@ class TraceDispatcher : public TraceCallback {
CriticalSectionScoped lock(crit_.get()); CriticalSectionScoped lock(crit_.get());
callbacks_[call] = config; callbacks_[call] = config;
if ((filter_ | config->trace_filter) != filter_) { filter_ |= config->trace_filter;
if (filter_ == kTraceNone) { if (filter_ != kTraceNone && !initialized_) {
Trace::CreateTrace(); initialized_ = true;
VideoEngine::SetTraceCallback(this); Trace::CreateTrace();
} VideoEngine::SetTraceCallback(this);
filter_ |= config->trace_filter;
VideoEngine::SetTraceFilter(filter_);
} }
VideoEngine::SetTraceFilter(filter_);
} }
void DeregisterCallback(Call* call) { void DeregisterCallback(Call* call) {
CriticalSectionScoped lock(crit_.get()); CriticalSectionScoped lock(crit_.get());
callbacks_.erase(call); callbacks_.erase(call);
// Return early if there was no filter, this is required to prevent
// returning the Trace handle more than once.
if (filter_ == kTraceNone)
return;
filter_ = kTraceNone; filter_ = kTraceNone;
for (std::map<Call*, Call::Config*>::iterator it = callbacks_.begin(); for (std::map<Call*, Call::Config*>::iterator it = callbacks_.begin();
@@ -78,14 +81,11 @@ class TraceDispatcher : public TraceCallback {
} }
VideoEngine::SetTraceFilter(filter_); VideoEngine::SetTraceFilter(filter_);
if (filter_ == kTraceNone) {
VideoEngine::SetTraceCallback(NULL);
Trace::ReturnTrace();
}
} }
private: private:
scoped_ptr<CriticalSectionWrapper> crit_; scoped_ptr<CriticalSectionWrapper> crit_;
bool initialized_;
unsigned int filter_; unsigned int filter_;
std::map<Call*, Call::Config*> callbacks_; std::map<Call*, Call::Config*> callbacks_;
}; };