diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-09-18 02:55:00 -0400 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-09-18 02:55:00 -0400 |
commit | 2925b8c62a03381e5b3ff159847e8312ae9dfee5 (patch) | |
tree | 8897f49792ada5363176047cc10de96579a288d0 /libs | |
parent | 56af9e9f9cbc3626acf55558d581efd2de3caa03 (diff) | |
parent | b9481d8cf6f3ade96ed062dc3f601c777fe4430f (diff) | |
download | frameworks_base-2925b8c62a03381e5b3ff159847e8312ae9dfee5.zip frameworks_base-2925b8c62a03381e5b3ff159847e8312ae9dfee5.tar.gz frameworks_base-2925b8c62a03381e5b3ff159847e8312ae9dfee5.tar.bz2 |
Merge change 25496 into eclair
* changes:
Fix issue 2127371: Possible race condition in AudioFlinger::openRecord() when a Track is being destroyed.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/audioflinger/AudioFlinger.cpp | 20 | ||||
-rw-r--r-- | libs/audioflinger/AudioFlinger.h | 4 |
2 files changed, 18 insertions, 6 deletions
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp index add358b..e534447 100644 --- a/libs/audioflinger/AudioFlinger.cpp +++ b/libs/audioflinger/AudioFlinger.cpp @@ -307,6 +307,9 @@ sp<IAudioTrack> AudioFlinger::createTrack( if (lStatus == NO_ERROR) { trackHandle = new TrackHandle(track); } 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(); } @@ -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()); - Mutex::Autolock _l(mLock); + LOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid()); mClients.removeItem(pid); } @@ -2078,7 +2081,10 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase() } } mCblkMemory.clear(); // and free the shared memory - mClient.clear(); + if (mClient != NULL) { + Mutex::Autolock _l(mClient->audioFlinger()->mLock); + mClient.clear(); + } } 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 } +// Client destructor must be called with AudioFlinger::mLock held AudioFlinger::Client::~Client() { - mAudioFlinger->removeClient(mPid); + mAudioFlinger->removeClient_l(mPid); } const sp<MemoryDealer>& AudioFlinger::Client::heap() const @@ -2820,6 +2827,9 @@ sp<IAudioRecord> AudioFlinger::openRecord( format, channelCount, frameCount, flags); } 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(); lStatus = NO_MEMORY; goto Exit; diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h index 7a6641f..3699019 100644 --- a/libs/audioflinger/AudioFlinger.h +++ b/libs/audioflinger/AudioFlinger.h @@ -189,6 +189,8 @@ private: virtual ~Client(); const sp<MemoryDealer>& heap() const; pid_t pid() const { return mPid; } + sp<AudioFlinger> audioFlinger() { return mAudioFlinger; } + private: Client(const Client&); Client& operator = (const Client&); @@ -641,7 +643,7 @@ private: friend class PlaybackThread::Track; - void removeClient(pid_t pid); + void removeClient_l(pid_t pid); // record thread |