Stop policy timer before invoking session destructor
The CDM session was being destroyed before the policy timer was stopped and before the session was removed from a list of active sessions. This allowed race conditions, where the policy timer would try to evaluate policy for a closed session. This led to segfaults. b/11338324 Merge of https://widevine-internal-review.googlesource.com/#/c/8240/1 from the widevine cdm repo. Change-Id: Ib159ccfdb763a47da573f5c06c0793c2c63886c4
This commit is contained in:
@@ -114,7 +114,7 @@ class CdmEngine : public TimerHandler {
|
||||
|
||||
// timer related methods to drive policy decisions
|
||||
virtual void EnablePolicyTimer();
|
||||
virtual void DisablePolicyTimer();
|
||||
virtual void DisablePolicyTimer(bool force);
|
||||
virtual void OnTimerEvent();
|
||||
|
||||
virtual void OnKeyReleaseEvent(const CdmKeySetId& key_set_id);
|
||||
|
||||
@@ -29,6 +29,7 @@ CdmEngine::CdmEngine()
|
||||
CdmEngine::~CdmEngine() {
|
||||
CancelSessions();
|
||||
|
||||
DisablePolicyTimer(true);
|
||||
CdmSessionMap::iterator i(sessions_.begin());
|
||||
for (; i != sessions_.end(); ++i)
|
||||
delete i->second;
|
||||
@@ -98,9 +99,10 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) {
|
||||
return KEY_ERROR;
|
||||
}
|
||||
|
||||
delete iter->second;
|
||||
CdmSession* session = iter->second;
|
||||
sessions_.erase(session_id);
|
||||
DisablePolicyTimer();
|
||||
DisablePolicyTimer(false);
|
||||
delete session;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -295,7 +297,7 @@ CdmResponseType CdmEngine::CancelKeyRequest(const CdmSessionId& session_id) {
|
||||
}
|
||||
|
||||
// TODO(edwinwong, rfrias): unload keys here
|
||||
DisablePolicyTimer();
|
||||
DisablePolicyTimer(false);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -675,8 +677,8 @@ void CdmEngine::EnablePolicyTimer() {
|
||||
policy_timer_.Start(this, kCdmPolicyTimerDurationSeconds);
|
||||
}
|
||||
|
||||
void CdmEngine::DisablePolicyTimer() {
|
||||
if (sessions_.size() == 0 && policy_timer_.IsRunning())
|
||||
void CdmEngine::DisablePolicyTimer(bool force) {
|
||||
if ((sessions_.size() == 0 || force) && policy_timer_.IsRunning())
|
||||
policy_timer_.Stop();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user