Skip to content

Commit 0474810

Browse files
xt0032rusandi34
authored andcommitted
DO NOT MERGE SoundPool: add lock for findSample access from SoundPoolThread
Sample decoding still occurs in SoundPoolThread without holding the SoundPool lock. Bug: 25781119 Change-Id: I11fde005aa9cf5438e0390a0d2dfe0ec1dd282e8 (cherry picked from commit 3d6a714)
1 parent f6172fa commit 0474810

File tree

2 files changed

+44
-21
lines changed

2 files changed

+44
-21
lines changed

include/media/SoundPool.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ class SoundPool {
188188

189189
// called from SoundPoolThread
190190
void sampleLoaded(int sampleID);
191+
sp<Sample> findSample(int sampleID);
191192

192193
// called from AudioTrack thread
193194
void done_l(SoundChannel* channel);
@@ -199,8 +200,7 @@ class SoundPool {
199200
private:
200201
SoundPool() {} // no default constructor
201202
bool startThreads();
202-
void doLoad(sp<Sample>& sample);
203-
sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); }
203+
sp<Sample> findSample_l(int sampleID);
204204
SoundChannel* findChannel (int channelID);
205205
SoundChannel* findNextChannel (int channelID);
206206
SoundChannel* allocateChannel_l(int priority);

media/libmedia/SoundPool.cpp

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,17 @@ bool SoundPool::startThreads()
179179
return mDecodeThread != NULL;
180180
}
181181

182+
sp<Sample> SoundPool::findSample(int sampleID)
183+
{
184+
Mutex::Autolock lock(&mLock);
185+
return findSample_l(sampleID);
186+
}
187+
188+
sp<Sample> SoundPool::findSample_l(int sampleID)
189+
{
190+
return mSamples.valueFor(sampleID);
191+
}
192+
182193
SoundChannel* SoundPool::findChannel(int channelID)
183194
{
184195
for (int i = 0; i < mMaxChannels; ++i) {
@@ -202,29 +213,42 @@ SoundChannel* SoundPool::findNextChannel(int channelID)
202213
int SoundPool::load(const char* path, int priority)
203214
{
204215
ALOGV("load: path=%s, priority=%d", path, priority);
205-
Mutex::Autolock lock(&mLock);
206-
sp<Sample> sample = new Sample(++mNextSampleID, path);
207-
mSamples.add(sample->sampleID(), sample);
208-
doLoad(sample);
209-
return sample->sampleID();
216+
int sampleID;
217+
{
218+
Mutex::Autolock lock(&mLock);
219+
sampleID = ++mNextSampleID;
220+
sp<Sample> sample = new Sample(sampleID, path);
221+
mSamples.add(sampleID, sample);
222+
sample->startLoad();
223+
}
224+
// mDecodeThread->loadSample() must be called outside of mLock.
225+
// mDecodeThread->loadSample() may block on mDecodeThread message queue space;
226+
// the message queue emptying may block on SoundPool::findSample().
227+
//
228+
// It theoretically possible that sample loads might decode out-of-order.
229+
mDecodeThread->loadSample(sampleID);
230+
return sampleID;
210231
}
211232

212233
int SoundPool::load(int fd, int64_t offset, int64_t length, int priority)
213234
{
214235
ALOGV("load: fd=%d, offset=%lld, length=%lld, priority=%d",
215236
fd, offset, length, priority);
216-
Mutex::Autolock lock(&mLock);
217-
sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length);
218-
mSamples.add(sample->sampleID(), sample);
219-
doLoad(sample);
220-
return sample->sampleID();
221-
}
222-
223-
void SoundPool::doLoad(sp<Sample>& sample)
224-
{
225-
ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID());
226-
sample->startLoad();
227-
mDecodeThread->loadSample(sample->sampleID());
237+
int sampleID;
238+
{
239+
Mutex::Autolock lock(&mLock);
240+
sampleID = ++mNextSampleID;
241+
sp<Sample> sample = new Sample(sampleID, fd, offset, length);
242+
mSamples.add(sampleID, sample);
243+
sample->startLoad();
244+
}
245+
// mDecodeThread->loadSample() must be called outside of mLock.
246+
// mDecodeThread->loadSample() may block on mDecodeThread message queue space;
247+
// the message queue emptying may block on SoundPool::findSample().
248+
//
249+
// It theoretically possible that sample loads might decode out-of-order.
250+
mDecodeThread->loadSample(sampleID);
251+
return sampleID;
228252
}
229253

230254
bool SoundPool::unload(int sampleID)
@@ -239,7 +263,6 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
239263
{
240264
ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
241265
sampleID, leftVolume, rightVolume, priority, loop, rate);
242-
sp<Sample> sample;
243266
SoundChannel* channel;
244267
int channelID;
245268

@@ -249,7 +272,7 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
249272
return 0;
250273
}
251274
// is sample ready?
252-
sample = findSample(sampleID);
275+
sp<Sample> sample(findSample_l(sampleID));
253276
if ((sample == 0) || (sample->state() != Sample::READY)) {
254277
ALOGW(" sample %d not READY", sampleID);
255278
return 0;

0 commit comments

Comments
 (0)