Add mutex lock for protecting observer member variable 46/252946/3
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 3 Feb 2021 08:24:33 +0000 (17:24 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Thu, 4 Feb 2021 04:41:12 +0000 (13:41 +0900)
Change-Id: I10bc01dc248fea90086240a62eeff70bf66f46bc

plugins/wakeup-manager/inc/wakeup_audio_manager.h
plugins/wakeup-manager/src/wakeup_audio_manager.cpp

index 7f870ae93ff7e68bbf4d04c23e9aeb643fa34144..2c8ac6631aaedcd6804c92bf40f59e55adc289e0 100644 (file)
@@ -66,6 +66,9 @@ public:
 
        void sound_focus_changed();
 
+       /* NOTE : The observer that is being passed to this subscribe() function
+        * must not be deleted before the call to CAudioManager::deinitialize(),
+        * since the observer's callback can be called even after unsubscribe() */
        void subscribe(IAudioEventObserver *observer);
        void unsubscribe(IAudioEventObserver *observer);
 
index 65f691cc9fb20aabfa5da13d359d9b5bff7e3c2d..744bb6074c39b2b15f2956d95017835bc86f7a67 100644 (file)
@@ -116,6 +116,7 @@ void CAudioManager::sound_focus_changed()
 
 void CAudioManager::subscribe(IAudioEventObserver *observer)
 {
+       lock_guard<mutex> lock(mMutex);
        if (observer) {
                mObservers.push_back(observer);
        }
@@ -123,6 +124,7 @@ void CAudioManager::subscribe(IAudioEventObserver *observer)
 
 void CAudioManager::unsubscribe(IAudioEventObserver *observer)
 {
+       lock_guard<mutex> lock(mMutex);
        auto iter = find(mObservers.begin(), mObservers.end(), observer);
        if (iter != mObservers.end()) {
                mObservers.erase(iter);
@@ -240,6 +242,7 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time)
                                lock.lock();
                                end = mAudioData.end();
                                auto begin = mAudioData.begin();
+                               vector<IAudioEventObserver*> observers = mObservers;
                                lock.unlock();
                                if (iter == end) {
                                        lead = begin;
@@ -256,7 +259,7 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time)
                                if (g_speech_pcm_wait_count < cnt) {
                                        unsigned char final_buffer[2] = {'\0', };
                                        MWR_LOGE("[ERROR] Wrong request, there's no pcm data");
-                                       for (const auto& observer : mObservers) {
+                                       for (const auto& observer : observers) {
                                                if (observer) {
                                                        if (!observer->on_streaming_audio_data(
                                                                MAS_SPEECH_STREAMING_EVENT_FAIL, NULL, 0)) {
@@ -282,11 +285,12 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time)
 
                lock.lock();
                end = mAudioData.end();
+               vector<IAudioEventObserver*> observers = mObservers;
 
                if (lead != end) {
                        iter = lead;
                        mas_speech_data& speech_data = iter->data;
-                       for (const auto& observer : mObservers) {
+                       for (const auto& observer : observers) {
                                if (observer) {
                                        if (!observer->on_streaming_audio_data(
                                                speech_data.event, speech_data.buffer, speech_data.len)) {
@@ -308,7 +312,10 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time)
 
        if (true != finish_event_sent) {
                unsigned char final_buffer[2] = {'\0', };
-               for (const auto& observer : mObservers) {
+               lock.lock();
+               vector<IAudioEventObserver*> observers = mObservers;
+               lock.unlock();
+               for (const auto& observer : observers) {
                        if (observer) {
                                MWR_LOGI("No FINISH event sent yet, adding to finalize streaming session");
                                if (!observer->on_streaming_audio_data(
@@ -391,7 +398,11 @@ void CAudioManager::clear_audio_data()
 
 void CAudioManager::notify_audio_data_recording(long time, void* data, int len)
 {
-       for (const auto& observer : mObservers) {
+       unique_lock<mutex> lock(mMutex, defer_lock);
+       lock.lock();
+       vector<IAudioEventObserver*> observers = mObservers;
+       lock.unlock();
+       for (const auto& observer : observers) {
                if (observer) {
                        if (!observer->on_recording_audio_data(time, data, len)) {
                                LOGE("[Recorder WARNING] One of the observer returned false");