MediaPlayerService: fix access of mPlayer in client am: 502c2f4053 am: bd7db202c6 am: 03fa67202f am: 263d5a2a70 am: 0844e1a3e8 am: e0f4963584 am: 5cc9f8780c am: 93ae13644b am: 50280c1b44 am: 1a1bb632e7
am: d8192c9149
Change-Id: I25ed67aa5671f7484dc99d3d79e0ed33125117f6
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index bd16e91..6e689e6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -82,6 +82,9 @@
#include "HTTPBase.h"
#include "RemoteDisplay.h"
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleepUs = 20000;
+
namespace {
using android::media::Metadata;
using android::status_t;
@@ -405,12 +408,32 @@
snprintf(buffer, 255, " pid(%d), connId(%d), status(%d), looping(%s)\n",
mPid, mConnId, mStatus, mLoop?"true": "false");
result.append(buffer);
- write(fd, result.string(), result.size());
- if (mPlayer != NULL) {
- mPlayer->dump(fd, args);
+
+ sp<MediaPlayerBase> p;
+ sp<AudioOutput> audioOutput;
+ bool locked = false;
+ for (int i = 0; i < kDumpLockRetries; ++i) {
+ if (mLock.tryLock() == NO_ERROR) {
+ locked = true;
+ break;
+ }
+ usleep(kDumpLockSleepUs);
}
- if (mAudioOutput != 0) {
- mAudioOutput->dump(fd, args);
+
+ if (locked) {
+ p = mPlayer;
+ audioOutput = mAudioOutput;
+ mLock.unlock();
+ } else {
+ result.append(" lock is taken, no dump from player and audio output\n");
+ }
+ write(fd, result.string(), result.size());
+
+ if (p != NULL) {
+ p->dump(fd, args);
+ }
+ if (audioOutput != 0) {
+ audioOutput->dump(fd, args);
}
write(fd, "\n", 1);
return NO_ERROR;
@@ -590,7 +613,10 @@
MediaPlayerService::Client::~Client()
{
ALOGV("Client(%d) destructor pid = %d", mConnId, mPid);
- mAudioOutput.clear();
+ {
+ Mutex::Autolock l(mLock);
+ mAudioOutput.clear();
+ }
wp<Client> client(this);
disconnect();
mService->removeClient(client);
@@ -609,10 +635,9 @@
Mutex::Autolock l(mLock);
p = mPlayer;
mClient.clear();
+ mPlayer.clear();
}
- mPlayer.clear();
-
// clear the notification to prevent callbacks to dead client
// and reset the player. We assume the player will serialize
// access to itself if necessary.
@@ -633,7 +658,7 @@
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
// determine if we have the right player type
- sp<MediaPlayerBase> p = mPlayer;
+ sp<MediaPlayerBase> p = getPlayer();
if ((p != NULL) && (p->playerType() != playerType)) {
ALOGV("delete player");
p.clear();
@@ -721,6 +746,7 @@
}
if (mStatus == OK) {
+ Mutex::Autolock l(mLock);
mPlayer = p;
}
}