summaryrefslogtreecommitdiff
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/jni/soundpool/StreamManager.cpp18
-rw-r--r--media/jni/soundpool/StreamManager.h10
2 files changed, 22 insertions, 6 deletions
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index 8b84bf3eb8d8..49c2b39f8904 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -43,6 +43,14 @@ static constexpr bool kPlayOnCallingThread = true;
// Amount of time for a StreamManager thread to wait before closing.
static constexpr int64_t kWaitTimeBeforeCloseNs = 9 * NANOS_PER_SECOND;
+// Debug flag:
+// kForceLockStreamManagerStop is set to true to force lock the StreamManager
+// worker thread during stop. This limits concurrency of Stream processing.
+// Normally we lock the StreamManager worker thread during stop ONLY
+// for SoundPools configured with a single Stream.
+//
+static constexpr bool kForceLockStreamManagerStop = false;
+
////////////
StreamMap::StreamMap(int32_t streams) {
@@ -103,6 +111,7 @@ StreamManager::StreamManager(
: StreamMap(streams)
, mAttributes(*attributes)
, mOpPackageName(std::move(opPackageName))
+ , mLockStreamManagerStop(streams == 1 || kForceLockStreamManagerStop)
{
ALOGV("%s(%d, %zu, ...)", __func__, streams, threads);
forEach([this](Stream *stream) {
@@ -113,7 +122,8 @@ StreamManager::StreamManager(
});
mThreadPool = std::make_unique<ThreadPool>(
- std::min(threads, (size_t)std::thread::hardware_concurrency()),
+ std::min((size_t)streams, // do not make more threads than streams to play
+ std::min(threads, (size_t)std::thread::hardware_concurrency())),
"SoundPool_");
}
@@ -375,12 +385,12 @@ void StreamManager::run(int32_t id)
}
mRestartStreams.erase(it);
mProcessingStreams.emplace(stream);
- lock.unlock();
+ if (!mLockStreamManagerStop) lock.unlock();
stream->stop();
ALOGV("%s(%d) stopping streamID:%d", __func__, id, stream->getStreamID());
if (Stream* nextStream = stream->playPairStream()) {
ALOGV("%s(%d) starting streamID:%d", __func__, id, nextStream->getStreamID());
- lock.lock();
+ if (!mLockStreamManagerStop) lock.lock();
if (nextStream->getStopTimeNs() > 0) {
// the next stream was stopped before we can move it to the active queue.
ALOGV("%s(%d) stopping started streamID:%d",
@@ -390,7 +400,7 @@ void StreamManager::run(int32_t id)
addToActiveQueue_l(nextStream);
}
} else {
- lock.lock();
+ if (!mLockStreamManagerStop) lock.lock();
mAvailableStreams.insert(stream);
}
mProcessingStreams.erase(stream);
diff --git a/media/jni/soundpool/StreamManager.h b/media/jni/soundpool/StreamManager.h
index 81ac69eb4358..85b468cd2cbc 100644
--- a/media/jni/soundpool/StreamManager.h
+++ b/media/jni/soundpool/StreamManager.h
@@ -437,6 +437,14 @@ private:
void sanityCheckQueue_l() const REQUIRES(mStreamManagerLock);
const audio_attributes_t mAttributes;
+ const std::string mOpPackageName;
+
+ // For legacy compatibility, we lock the stream manager on stop when
+ // there is only one stream. This allows a play to be called immediately
+ // after stopping, otherwise it is possible that the play might be discarded
+ // (returns 0) because that stream may be in the worker thread call to stop.
+ const bool mLockStreamManagerStop;
+
std::unique_ptr<ThreadPool> mThreadPool; // locked internally
// mStreamManagerLock is used to lock access for transitions between the
@@ -477,8 +485,6 @@ private:
// The paired stream may be active or restarting.
// No particular order.
std::unordered_set<Stream*> mProcessingStreams GUARDED_BY(mStreamManagerLock);
-
- const std::string mOpPackageName;
};
} // namespace android::soundpool