Always initialize Trace in Call TraceDispatcher.

Prevents violation of lock order occuring previously when
RegisterCallback called SetTraceCallback while holding its lock, which
called Print back (which acquires the lock).

BUG=
R=andrew@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5433 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org 2014-01-27 09:11:10 +00:00
parent 37c2976511
commit c98882dcd3

View File

@ -91,21 +91,22 @@ class Call : public webrtc::Call, public PacketReceiver {
class TraceDispatcher : public TraceCallback { class TraceDispatcher : public TraceCallback {
public: public:
TraceDispatcher() TraceDispatcher()
: crit_(CriticalSectionWrapper::CreateCriticalSection()), : lock_(CriticalSectionWrapper::CreateCriticalSection()),
initialized_(false), filter_(kTraceNone) {
filter_(kTraceNone) {} Trace::CreateTrace();
VideoEngine::SetTraceCallback(this);
VideoEngine::SetTraceFilter(kTraceNone);
}
~TraceDispatcher() { ~TraceDispatcher() {
if (initialized_) {
Trace::ReturnTrace(); Trace::ReturnTrace();
VideoEngine::SetTraceCallback(NULL); 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 {
CriticalSectionScoped lock(crit_.get()); CriticalSectionScoped crit(lock_.get());
for (std::map<Call*, Call::Config*>::iterator it = callbacks_.begin(); for (std::map<Call*, Call::Config*>::iterator it = callbacks_.begin();
it != callbacks_.end(); it != callbacks_.end();
++it) { ++it) {
@ -118,20 +119,15 @@ class TraceDispatcher : public TraceCallback {
if (config->trace_callback == NULL) if (config->trace_callback == NULL)
return; return;
CriticalSectionScoped lock(crit_.get()); CriticalSectionScoped crit(lock_.get());
callbacks_[call] = config; callbacks_[call] = config;
filter_ |= config->trace_filter; filter_ |= config->trace_filter;
if (filter_ != kTraceNone && !initialized_) {
initialized_ = true;
Trace::CreateTrace();
VideoEngine::SetTraceCallback(this);
}
VideoEngine::SetTraceFilter(filter_); VideoEngine::SetTraceFilter(filter_);
} }
void DeregisterCallback(Call* call) { void DeregisterCallback(Call* call) {
CriticalSectionScoped lock(crit_.get()); CriticalSectionScoped crit(lock_.get());
callbacks_.erase(call); callbacks_.erase(call);
filter_ = kTraceNone; filter_ = kTraceNone;
@ -145,8 +141,7 @@ class TraceDispatcher : public TraceCallback {
} }
private: private:
scoped_ptr<CriticalSectionWrapper> crit_; scoped_ptr<CriticalSectionWrapper> lock_;
bool initialized_;
unsigned int filter_; unsigned int filter_;
std::map<Call*, Call::Config*> callbacks_; std::map<Call*, Call::Config*> callbacks_;
}; };