am 2925b8c6: Merge change 25496 into eclair

Merge commit '2925b8c62a03381e5b3ff159847e8312ae9dfee5' into eclair-plus-aosp

* commit '2925b8c62a03381e5b3ff159847e8312ae9dfee5':
  Fix issue 2127371: Possible race condition in AudioFlinger::openRecord() when a Track is being destroyed.
This commit is contained in:
Eric Laurent
2009-09-17 23:59:57 -07:00
committed by Android Git Automerger
2 changed files with 18 additions and 6 deletions

View File

@@ -307,6 +307,9 @@ sp<IAudioTrack> AudioFlinger::createTrack(
if (lStatus == NO_ERROR) { if (lStatus == NO_ERROR) {
trackHandle = new TrackHandle(track); trackHandle = new TrackHandle(track);
} else { } else {
// remove local strong reference to Client before deleting the Track so that the Client
// destructor is called by the TrackBase destructor with mLock held
client.clear();
track.clear(); track.clear();
} }
@@ -707,10 +710,10 @@ void AudioFlinger::audioConfigChanged_l(int event, const sp<ThreadBase>& thread,
} }
} }
void AudioFlinger::removeClient(pid_t pid) // removeClient_l() must be called with AudioFlinger::mLock held
void AudioFlinger::removeClient_l(pid_t pid)
{ {
LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid()); LOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
Mutex::Autolock _l(mLock);
mClients.removeItem(pid); mClients.removeItem(pid);
} }
@@ -2078,8 +2081,11 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase()
} }
} }
mCblkMemory.clear(); // and free the shared memory mCblkMemory.clear(); // and free the shared memory
if (mClient != NULL) {
Mutex::Autolock _l(mClient->audioFlinger()->mLock);
mClient.clear(); mClient.clear();
} }
}
void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer) void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{ {
@@ -2712,9 +2718,10 @@ AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
// 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
} }
// Client destructor must be called with AudioFlinger::mLock held
AudioFlinger::Client::~Client() AudioFlinger::Client::~Client()
{ {
mAudioFlinger->removeClient(mPid); mAudioFlinger->removeClient_l(mPid);
} }
const sp<MemoryDealer>& AudioFlinger::Client::heap() const const sp<MemoryDealer>& AudioFlinger::Client::heap() const
@@ -2820,6 +2827,9 @@ sp<IAudioRecord> AudioFlinger::openRecord(
format, channelCount, frameCount, flags); format, channelCount, frameCount, flags);
} }
if (recordTrack->getCblk() == NULL) { if (recordTrack->getCblk() == NULL) {
// remove local strong reference to Client before deleting the RecordTrack so that the Client
// destructor is called by the TrackBase destructor with mLock held
client.clear();
recordTrack.clear(); recordTrack.clear();
lStatus = NO_MEMORY; lStatus = NO_MEMORY;
goto Exit; goto Exit;

View File

@@ -189,6 +189,8 @@ private:
virtual ~Client(); virtual ~Client();
const sp<MemoryDealer>& heap() const; const sp<MemoryDealer>& heap() const;
pid_t pid() const { return mPid; } pid_t pid() const { return mPid; }
sp<AudioFlinger> audioFlinger() { return mAudioFlinger; }
private: private:
Client(const Client&); Client(const Client&);
Client& operator = (const Client&); Client& operator = (const Client&);
@@ -641,7 +643,7 @@ private:
friend class PlaybackThread::Track; friend class PlaybackThread::Track;
void removeClient(pid_t pid); void removeClient_l(pid_t pid);
// record thread // record thread