Protect sessions from concurrent access.

Locks in earlier releases controlled access to sessions and the list
of sessions for each CdmEngine instance. This guarded against
concurrent access between session management (OpenSession,
CloseSession, etc), periodic timer calls and calls to Decrypt.

The list of sessions and locking was moved to a separate class
CdmSessionMap. This left open the possibility that a session
might be destructed, while being called to decrypt or invoked through the
timer. An attempt was made to add per-session locks in b/73781703
but this was found insufficient.

Per-session locks will be introduced in a future changelist, but for
now the coarser locks will be reintroduced.

Bug: 73781703
Bug: 79158083
Bug: 79262108
Bug: 79436509

Test: WV unit/integration tests, GTS GtsMediaTestCases tests and
      24 hours of continuous Netflix playback.

Change-Id: I30a3ede340192370dfe5c92c01b1c76df16b7123
This commit is contained in:
Rahul Frias
2018-05-13 21:14:26 -07:00
parent dcab2b1355
commit e8c3a4afac
4 changed files with 35 additions and 12 deletions

View File

@@ -330,6 +330,17 @@ class CdmEngine {
// Protect release_key_sets_ from non-thread-safe operations.
Lock release_key_sets_lock_;
// TODO(rfrias): Replace with two sets of locks, one to protect
// the CdmSessionMap and a per-session lock to control access to
// session usage/destruction.
// Locks the session map |session_map_| and session usage/destruction
// between session management calls (OpenSession, CloseSession, etc),
// periodic timer calls (OnTimerEvent), and calls to Decrypt.
// The layer above the CDM implementation is expected to handle thread
// synchronization to make sure other functions that access sessions do not
// occur simultaneously with OpenSession or CloseSession.
Lock session_map_lock_;
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngine);
};

View File

@@ -10,7 +10,6 @@
#include <string>
#include "cdm_session.h"
#include "lock.h"
#include "shared_ptr.h"
#include "wv_cdm_types.h"
@@ -18,11 +17,18 @@ namespace wvcdm {
typedef std::list<shared_ptr<CdmSession> > CdmSessionList;
// TODO(rfrias): Concurrency protection for this class has moved to CdmEngine.
// Add it back when locks to control access to session usage and destruction
// are introduced.
class CdmSessionMap {
public:
CdmSessionMap() {}
virtual ~CdmSessionMap();
// Use |Terminate| rather than relying on the destructor to release
// resources, as it can be protected by locks.
void Terminate();
void Add(const std::string& id, CdmSession* session);
bool CloseSession(const std::string& id);
@@ -43,7 +49,6 @@ class CdmSessionMap {
bool FindSessionNoLock(const CdmSessionId& session_id,
shared_ptr<CdmSession>* session);
Lock lock_;
CdmIdToSessionMap sessions_;
CORE_DISALLOW_COPY_AND_ASSIGN(CdmSessionMap);