Address deadlock

[ Merge of http://go/wvgerrit/51322 ]

This avoids taking the session_map_lock_ twice.

Bug: 80248149
Test: WV unit/integration tests, GtsMediaTestCases,
      2 days of netflix playback.

Change-Id: Iea1c7b7ba08d7d40c227d21c5abfce13c0a8b395
This commit is contained in:
Rahul Frias
2018-05-28 12:40:41 -07:00
parent 7d90a07c08
commit d401baa236

View File

@@ -1655,51 +1655,54 @@ void CdmEngine::OnTimerEvent() {
bool is_initial_usage_update = false;
bool is_usage_update_needed = false;
AutoLock lock(session_map_lock_);
CdmSessionList sessions;
session_map_.GetSessionList(sessions);
while (!sessions.empty()) {
is_initial_usage_update =
is_initial_usage_update || sessions.front()->is_initial_usage_update();
is_usage_update_needed =
is_usage_update_needed || sessions.front()->is_usage_update_needed();
sessions.front()->OnTimerEvent(usage_update_period_expired);
sessions.pop_front();
}
if (is_usage_update_needed &&
(usage_update_period_expired || is_initial_usage_update)) {
bool has_usage_been_updated = false;
// Session list may have changed. Rebuild.
{
AutoLock lock(session_map_lock_);
CdmSessionList sessions;
session_map_.GetSessionList(sessions);
for (CdmSessionList::iterator iter = sessions.begin();
iter != sessions.end(); ++iter) {
(*iter)->reset_usage_flags();
switch ((*iter)->get_usage_support_type()) {
case kUsageEntrySupport:
if ((*iter)->has_provider_session_token()) {
(*iter)->UpdateUsageEntryInformation();
}
break;
case kUsageTableSupport:
if (!has_usage_been_updated) {
// usage is updated for all sessions so this needs to be
// called only once per update usage information period
CdmResponseType status = (*iter)->UpdateUsageTableInformation();
if (NO_ERROR != status) {
LOGW("Update usage information failed: %d", status);
} else {
has_usage_been_updated = true;
while (!sessions.empty()) {
is_initial_usage_update =
is_initial_usage_update ||
sessions.front()->is_initial_usage_update();
is_usage_update_needed =
is_usage_update_needed || sessions.front()->is_usage_update_needed();
sessions.front()->OnTimerEvent(usage_update_period_expired);
sessions.pop_front();
}
if (is_usage_update_needed &&
(usage_update_period_expired || is_initial_usage_update)) {
bool has_usage_been_updated = false;
// Session list may have changed. Rebuild.
session_map_.GetSessionList(sessions);
for (CdmSessionList::iterator iter = sessions.begin();
iter != sessions.end(); ++iter) {
(*iter)->reset_usage_flags();
switch ((*iter)->get_usage_support_type()) {
case kUsageEntrySupport:
if ((*iter)->has_provider_session_token()) {
(*iter)->UpdateUsageEntryInformation();
}
}
break;
default:
// Ignore
break;
break;
case kUsageTableSupport:
if (!has_usage_been_updated) {
// usage is updated for all sessions so this needs to be
// called only once per update usage information period
CdmResponseType status = (*iter)->UpdateUsageTableInformation();
if (NO_ERROR != status) {
LOGW("Update usage information failed: %d", status);
} else {
has_usage_been_updated = true;
}
}
break;
default:
// Ignore
break;
}
}
}
}