OSDN Git Service

ffmpeg-extractor: Fix deadlock when stopping the reader thread
authorChristopher R. Palmer <crpalmer@gmail.com>
Mon, 31 Aug 2015 12:07:19 +0000 (08:07 -0400)
committerChristopher R. Palmer <crpalmer@gmail.com>
Mon, 31 Aug 2015 12:11:27 +0000 (08:11 -0400)
You cannot hold the lock used by the reader thread when trying
to join to the reader thread!

For example, if we start and then stop the reader thread
before it gets a chance to execute, one thread will be in
stopReaderThread calling pthread_thread_join (and holding mLock).
Then the reader thread will execute and immediately block on
mLock (it gets the lock immediately on startup).

Instead, release the lock while we wait for the thread to exit
and then reacquire the lock.

Change-Id: I9247ae48586c18f4eb7a4f74e188b9d4f88824e2

extractor/FFmpegExtractor.cpp

index df9044a..0b39032 100644 (file)
@@ -144,10 +144,10 @@ FFmpegExtractor::FFmpegExtractor(const sp<DataSource> &source, const sp<AMessage
 
 FFmpegExtractor::~FFmpegExtractor() {
     ALOGV("FFmpegExtractor::~FFmpegExtractor");
-    Mutex::Autolock autoLock(mLock);
     // stop reader here if no track!
     stopReaderThread();
 
+    Mutex::Autolock autoLock(mLock);
     deInitStreams();
 }
 
@@ -1028,8 +1028,11 @@ status_t FFmpegExtractor::startReaderThread() {
 void FFmpegExtractor::stopReaderThread() {
     ALOGV("Stopping reader thread");
 
+    mLock.lock();
+
     if (!mReaderThreadStarted) {
         ALOGD("Reader thread have been stopped");
+        mLock.unlock();
         return;
     }
 
@@ -1042,7 +1045,9 @@ void FFmpegExtractor::stopReaderThread() {
     if (mVideoStreamIdx >= 0)
         stream_component_close(mVideoStreamIdx);
 
+    mLock.unlock();
     pthread_join(mReaderThread, NULL);
+    mLock.lock();
 
     if (mFormatCtx) {
         avformat_close_input(&mFormatCtx);
@@ -1050,6 +1055,8 @@ void FFmpegExtractor::stopReaderThread() {
 
     mReaderThreadStarted = false;
     ALOGD("Reader thread stopped");
+
+    mLock.unlock();
 }
 
 // static