Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ea16e4b authored by Eric Laurent's avatar Eric Laurent
Browse files

audioflinger: fix race condition in SyncEvent callback

Now that the SyncEvent callback is implemented by the
RecordTrack instead of the RecordThread, there is a possibility
that the callback is called after the track deletion.

SyncEvent callback now uses a weak pointer instead of
a raw pointer as cookie. This allows the callback implementer to
acquire a strong reference on the object pointed to by the cookie.

Bug: 13114128.
Change-Id: Id61b8f06044ed1e52c6f7e7c666cdede68340de2
parent 56df9ff3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2094,7 +2094,7 @@ sp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_even
                                    int triggerSession,
                                    int listenerSession,
                                    sync_event_callback_t callBack,
                                    void *cookie)
                                    wp<RefBase> cookie)
{
    Mutex::Autolock _l(mLock);

+4 −4
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ public:
                  int triggerSession,
                  int listenerSession,
                  sync_event_callback_t callBack,
                  void *cookie)
                  wp<RefBase> cookie)
        : mType(type), mTriggerSession(triggerSession), mListenerSession(listenerSession),
          mCallback(callBack), mCookie(cookie)
        {}
@@ -266,14 +266,14 @@ public:
        AudioSystem::sync_event_t type() const { return mType; }
        int triggerSession() const { return mTriggerSession; }
        int listenerSession() const { return mListenerSession; }
        void *cookie() const { return mCookie; }
        wp<RefBase> cookie() const { return mCookie; }

    private:
          const AudioSystem::sync_event_t mType;
          const int mTriggerSession;
          const int mListenerSession;
          sync_event_callback_t mCallback;
          void * const mCookie;
          const wp<RefBase> mCookie;
          mutable Mutex mLock;
    };

@@ -281,7 +281,7 @@ public:
                                        int triggerSession,
                                        int listenerSession,
                                        sync_event_callback_t callBack,
                                        void *cookie);
                                        wp<RefBase> cookie);

private:
    class AudioHwDevice;    // fwd declaration for findSuitableHwDev_l
+5 −2
Original line number Diff line number Diff line
@@ -5095,10 +5095,13 @@ void AudioFlinger::RecordThread::syncStartEventCallback(const wp<SyncEvent>& eve
    sp<SyncEvent> strongEvent = event.promote();

    if (strongEvent != 0) {
        RecordTrack *recordTrack = (RecordTrack *)strongEvent->cookie();
        sp<RefBase> ptr = strongEvent->cookie().promote();
        if (ptr != 0) {
            RecordTrack *recordTrack = (RecordTrack *)ptr.get();
            recordTrack->handleSyncStartEvent(strongEvent);
        }
    }
}

bool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
    ALOGV("RecordThread::stop");