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

Commit 4e5f2088 authored by Andy Hung's avatar Andy Hung Committed by Jessica Wagantall
Browse files

DO NOT MERGE SoundPool: add lock for findSample access from SoundPoolThread

Sample decoding still occurs in SoundPoolThread
without holding the SoundPool lock.
Ticket: CYNGNOS-1404

Bug: 25781119
Change-Id: I11fde005aa9cf5438e0390a0d2dfe0ec1dd282e8
parent 5f08570f
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -187,6 +187,7 @@ public:


    // called from SoundPoolThread
    // called from SoundPoolThread
    void sampleLoaded(int sampleID);
    void sampleLoaded(int sampleID);
    sp<Sample> findSample(int sampleID);


    // called from AudioTrack thread
    // called from AudioTrack thread
    void done_l(SoundChannel* channel);
    void done_l(SoundChannel* channel);
@@ -198,8 +199,7 @@ public:
private:
private:
    SoundPool() {} // no default constructor
    SoundPool() {} // no default constructor
    bool startThreads();
    bool startThreads();
    void doLoad(sp<Sample>& sample);
    sp<Sample> findSample_l(int sampleID);
    sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); }
    SoundChannel* findChannel (int channelID);
    SoundChannel* findChannel (int channelID);
    SoundChannel* findNextChannel (int channelID);
    SoundChannel* findNextChannel (int channelID);
    SoundChannel* allocateChannel_l(int priority);
    SoundChannel* allocateChannel_l(int priority);
+42 −19
Original line number Original line Diff line number Diff line
@@ -183,6 +183,17 @@ bool SoundPool::startThreads()
    return mDecodeThread != NULL;
    return mDecodeThread != NULL;
}
}


sp<Sample> SoundPool::findSample(int sampleID)
{
    Mutex::Autolock lock(&mLock);
    return findSample_l(sampleID);
}

sp<Sample> SoundPool::findSample_l(int sampleID)
{
    return mSamples.valueFor(sampleID);
}

SoundChannel* SoundPool::findChannel(int channelID)
SoundChannel* SoundPool::findChannel(int channelID)
{
{
    for (int i = 0; i < mMaxChannels; ++i) {
    for (int i = 0; i < mMaxChannels; ++i) {
@@ -206,29 +217,42 @@ SoundChannel* SoundPool::findNextChannel(int channelID)
int SoundPool::load(const char* path, int priority __unused)
int SoundPool::load(const char* path, int priority __unused)
{
{
    ALOGV("load: path=%s, priority=%d", path, priority);
    ALOGV("load: path=%s, priority=%d", path, priority);
    int sampleID;
    {
        Mutex::Autolock lock(&mLock);
        Mutex::Autolock lock(&mLock);
    sp<Sample> sample = new Sample(++mNextSampleID, path);
        sampleID = ++mNextSampleID;
    mSamples.add(sample->sampleID(), sample);
        sp<Sample> sample = new Sample(sampleID, path);
    doLoad(sample);
        mSamples.add(sampleID, sample);
    return sample->sampleID();
        sample->startLoad();
    }
    // mDecodeThread->loadSample() must be called outside of mLock.
    // mDecodeThread->loadSample() may block on mDecodeThread message queue space;
    // the message queue emptying may block on SoundPool::findSample().
    //
    // It theoretically possible that sample loads might decode out-of-order.
    mDecodeThread->loadSample(sampleID);
    return sampleID;
}
}


int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused)
int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused)
{
{
    ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d",
    ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d",
            fd, offset, length, priority);
            fd, offset, length, priority);
    Mutex::Autolock lock(&mLock);
    int sampleID;
    sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length);
    mSamples.add(sample->sampleID(), sample);
    doLoad(sample);
    return sample->sampleID();
}

void SoundPool::doLoad(sp<Sample>& sample)
    {
    {
    ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID());
        Mutex::Autolock lock(&mLock);
        sampleID = ++mNextSampleID;
        sp<Sample> sample = new Sample(sampleID, fd, offset, length);
        mSamples.add(sampleID, sample);
        sample->startLoad();
        sample->startLoad();
    mDecodeThread->loadSample(sample->sampleID());
    }
    // mDecodeThread->loadSample() must be called outside of mLock.
    // mDecodeThread->loadSample() may block on mDecodeThread message queue space;
    // the message queue emptying may block on SoundPool::findSample().
    //
    // It theoretically possible that sample loads might decode out-of-order.
    mDecodeThread->loadSample(sampleID);
    return sampleID;
}
}


bool SoundPool::unload(int sampleID)
bool SoundPool::unload(int sampleID)
@@ -243,7 +267,6 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
{
{
    ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
    ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
            sampleID, leftVolume, rightVolume, priority, loop, rate);
            sampleID, leftVolume, rightVolume, priority, loop, rate);
    sp<Sample> sample;
    SoundChannel* channel;
    SoundChannel* channel;
    int channelID;
    int channelID;


@@ -253,7 +276,7 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
        return 0;
        return 0;
    }
    }
    // is sample ready?
    // is sample ready?
    sample = findSample(sampleID);
    sp<Sample> sample(findSample_l(sampleID));
    if ((sample == 0) || (sample->state() != Sample::READY)) {
    if ((sample == 0) || (sample->state() != Sample::READY)) {
        ALOGW("  sample %d not READY", sampleID);
        ALOGW("  sample %d not READY", sampleID);
        return 0;
        return 0;