OSDN Git Service

Fix call to restoreTrack_l() without lock held
authorGlenn Kasten <gkasten@google.com>
Fri, 2 Nov 2012 20:05:14 +0000 (13:05 -0700)
committerGlenn Kasten <gkasten@google.com>
Thu, 8 Nov 2012 00:11:56 +0000 (16:11 -0800)
Also document lock order

Change-Id: I2c1f273a0a51fa79ee3dd766de8d23083e270051

include/media/AudioTrack.h
media/libmedia/AudioTrack.cpp

index 529f74e..1a19999 100644 (file)
@@ -481,6 +481,7 @@ protected:
             // body of AudioTrackThread::threadLoop()
             bool processAudioBuffer(const sp<AudioTrackThread>& thread);
 
+            // caller must hold lock on mLock for all _l methods
             status_t createTrack_l(audio_stream_type_t streamType,
                                  uint32_t sampleRate,
                                  audio_format_t format,
@@ -535,7 +536,13 @@ protected:
     audio_output_flags_t    mFlags;
     int                     mSessionId;
     int                     mAuxEffectId;
+
+    // When locking both mLock and mCblk->lock, must lock in this order to avoid deadlock:
+    //      1. mLock
+    //      2. mCblk->lock
+    // It is OK to lock only mCblk->lock.
     mutable Mutex           mLock;
+
     status_t                mRestoreStatus;
     bool                    mIsTimed;
     int                     mPreviousPriority;          // before start()
index 5348646..1f4f3d0 100644 (file)
@@ -1122,8 +1122,14 @@ TimedAudioTrack::TimedAudioTrack() {
 
 status_t TimedAudioTrack::allocateTimedBuffer(size_t size, sp<IMemory>* buffer)
 {
+    AutoMutex lock(mLock);
     status_t result = UNKNOWN_ERROR;
 
+    // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed
+    // while we are accessing the cblk
+    sp<IAudioTrack> audioTrack = mAudioTrack;
+    sp<IMemory> iMem = mCblkMemory;
+
     // If the track is not invalid already, try to allocate a buffer.  alloc
     // fails indicating that the server is dead, flag the track as invalid so
     // we can attempt to restore in just a bit.