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:
@@ -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_;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user