audio-io fixed crash at audio_in_read() of another thread. 78/97478/3 accepted/tizen/common/20161115.200735 accepted/tizen/common/20161122.192836 accepted/tizen/ivi/20161115.234320 accepted/tizen/ivi/20161122.235922 accepted/tizen/mobile/20161115.234119 accepted/tizen/mobile/20161122.235715 accepted/tizen/tv/20161115.234211 accepted/tizen/tv/20161122.235757 accepted/tizen/wearable/20161115.234243 accepted/tizen/wearable/20161122.235839 submit/tizen/20161115.062308 submit/tizen/20161122.044017
authorKimJeongYeon <jeongyeon.kim@samsung.com>
Mon, 14 Nov 2016 08:54:56 +0000 (17:54 +0900)
committerKimJeongYeon <jeongyeon.kim@samsung.com>
Tue, 15 Nov 2016 01:13:41 +0000 (10:13 +0900)
There are no syncronization between audio_in_read() and audio_in_unprepare().
Therefore, assert crash occurs possibly while use multiple reader thread.

Changes:
 * Add locking method at audio_in_read() and null check of mpPulseAudioClient.
 * Fixed syncronous-method of audio_out_write() too.
 * Miscellaneous typos are fixed.

[Version] 0.3.45
[Profile] Common
[Issue Type] Bug Fix

Signed-off-by: KimJeongYeon <jeongyeon.kim@samsung.com>
Change-Id: I18147b9e1e7bb5c16816250d65d2ff066f6383b7

packaging/capi-media-audio-io.spec
src/cpp/CAudioInput.cpp
src/cpp/CAudioOutput.cpp
src/cpp/CPulseAudioClient.cpp
src/cpp/cpp_audio_io.cpp
test/audio_io_test.c

index 30ee55e..7c36bf2 100644 (file)
@@ -1,6 +1,6 @@
 Name:           capi-media-audio-io
 Summary:        An Audio Input & Audio Output library in Tizen Native API
-Version:        0.3.44
+Version:        0.3.45
 Release:        0
 Group:          Multimedia/API
 License:        Apache-2.0
index c806f9f..919cecd 100644 (file)
@@ -250,7 +250,7 @@ void CAudioInput::prepare() throw(CAudioError) {
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [type:%d]", static_cast<int>(audioType));
         }
 
-        if (mpAudioSessionHandler->getId() < 0) {  //Did not registerSound()
+        if (mpAudioSessionHandler->getId() < 0) {  // Did not registerSound()
             // Check session to skip registration
             if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
                 // Register ASM Listener
@@ -446,9 +446,18 @@ size_t CAudioInput::read(void* buffer, size_t length) throw(CAudioError) {
     int ret = 0;
 
     try {
+        internalLock();
+
+        // If another thread did call unprepare, do not read
+        if (mpPulseAudioClient == NULL)
+            THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+
         // Block until read done
         ret = mpPulseAudioClient->read(buffer, length);
+
+        internalUnlock();
     } catch (CAudioError e) {
+        internalUnlock();
         throw e;
     }
 
index 2f70ed6..267ba95 100644 (file)
@@ -150,7 +150,7 @@ void CAudioOutput::prepare() throw(CAudioError) {
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [type:%d]", static_cast<int>(audioType));
         }
 
-        if (mpAudioSessionHandler->getId() < 0) {  //Did not registerSound()
+        if (mpAudioSessionHandler->getId() < 0) {  // Did not registerSound()
             if (isForceIgnore() == false) {
                 // Register ASM Listener
                 AUDIO_IO_LOGD("Register ASM Listener");
@@ -327,7 +327,7 @@ size_t CAudioOutput::write(const void* buffer, size_t length) throw(CAudioError)
         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are invalid - buffer:%p, length:%zu", buffer, length);
     }
 
-    /* When write() is called in PulseAudio callback, bypass a pcm data to PulseAudioClient (For Asynchronous) */
+    /* When write() is called in PulseAudio callback, bypass a pcm data to CPulseAudioClient (For Asynchronous) */
     if (mpPulseAudioClient->isInThread() == true) {
         int ret = mpPulseAudioClient->write(buffer, length);
         if (ret < 0) {
@@ -340,6 +340,10 @@ size_t CAudioOutput::write(const void* buffer, size_t length) throw(CAudioError)
         /* For synchronization */
         internalLock();
 
+        // If another thread did call unprepare, do not write
+        if (mpPulseAudioClient == NULL)
+            THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+
         // Sets synchronous flag
         __mIsUsedSyncWrite = true;
 
@@ -360,7 +364,7 @@ size_t CAudioOutput::write(const void* buffer, size_t length) throw(CAudioError)
             }
 
 #ifdef _AUDIO_IO_DEBUG_TIMING_
-            AUDIO_IO_LOGD("PulseAudioClient->write(buffer:%p, length:%d)", buffer, l);
+            AUDIO_IO_LOGD("CPulseAudioClient->write(buffer:%p, length:%d)", buffer, l);
 #endif
 
             int ret = mpPulseAudioClient->write(buffer, l);
index 74cd735..bfe72b2 100644 (file)
@@ -455,7 +455,7 @@ int CPulseAudioClient::read(void* buffer, size_t length) throw(CAudioError) {
 
             // Copy partial pcm data on out parameter
 #ifdef _AUDIO_IO_DEBUG_TIMING_
-            AUDIO_IO_LOGD("memcpy() that a peeked buffer[%], index[%d], length[%d] on out buffer", (const uint8_t*)(__mpSyncReadDataPtr) + __mSyncReadIndex, __mSyncReadIndex, l);
+            AUDIO_IO_LOGD("memcpy() that a peeked buffer[0x%x], index[%d], length[%d] on out buffer", (const uint8_t*)(__mpSyncReadDataPtr) + __mSyncReadIndex, __mSyncReadIndex, l);
 #endif
             memcpy(buffer, (const uint8_t*)__mpSyncReadDataPtr + __mSyncReadIndex, l);
 
index 55d1f7b..10ffe8a 100644 (file)
@@ -1284,10 +1284,10 @@ int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
         if (outputHandle == NULL) {
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
         }
-        size_t writen = outputHandle->write(buffer, static_cast<size_t>(length));
-        ret = static_cast<int>(writen);
+        size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
+        ret = static_cast<int>(written);
 #ifdef _AUDIO_IO_DEBUG_TIMING_
-        AUDIO_IO_LOGD("writen:%d", writen);
+        AUDIO_IO_LOGD("written:%d", written);
 #endif
     } catch (CAudioError e) {
         AUDIO_IO_LOGE("%s", e.getErrorMsg());
index 81043ce..ca89a73 100644 (file)
@@ -168,6 +168,7 @@ int audio_io_test(int length, int num, int ch)
 
                fclose(fp);
 
+               audio_in_unprepare(input);
                audio_in_destroy(input);
        }