Loading services/oboeservice/AAudioService.cpp +14 −15 Original line number Diff line number Diff line Loading @@ -144,15 +144,14 @@ aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &req // If a close request is pending then close the stream bool AAudioService::releaseStream(const sp<AAudioServiceStreamBase> &serviceStream) { bool closed = false; if ((serviceStream->decrementServiceReferenceCount() == 0) && serviceStream->isCloseNeeded()) { // removeStreamByHandle() uses a lock so that if there are two simultaneous closes // decrementAndRemoveStreamByHandle() uses a lock so that if there are two simultaneous closes // then only one will get the pointer and do the close. sp<AAudioServiceStreamBase> foundStream = mStreamTracker.removeStreamByHandle(serviceStream->getHandle()); sp<AAudioServiceStreamBase> foundStream = mStreamTracker.decrementAndRemoveStreamByHandle( serviceStream->getHandle()); if (foundStream.get() != nullptr) { foundStream->close(); pid_t pid = foundStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, foundStream); } closed = true; } return closed; Loading @@ -175,14 +174,15 @@ aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { pid_t pid = serviceStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream); serviceStream->setCloseNeeded(true); serviceStream->markCloseNeeded(); (void) releaseStream(serviceStream); return AAUDIO_OK; } sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandle(streamHandle); sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandleAndIncrement( streamHandle); if (serviceStream.get() != nullptr) { // Only allow owner or the aaudio service to access the stream. const uid_t callingUserId = IPCThreadState::self()->getCallingUid(); Loading @@ -194,9 +194,9 @@ sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( if (!allowed) { ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d", callingUserId, streamHandle, ownerUserId); // We incremented the reference count so we must check if it needs to be closed. checkForPendingClose(serviceStream, AAUDIO_OK); serviceStream.clear(); } else { serviceStream->incrementServiceReferenceCount(); } } return serviceStream; Loading Loading @@ -328,12 +328,11 @@ aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) { ALOGD("%s(%d) called", __func__, portHandle); sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.findStreamByPortHandle(portHandle); mStreamTracker.findStreamByPortHandleAndIncrement(portHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle); return AAUDIO_ERROR_INVALID_HANDLE; } serviceStream->incrementServiceReferenceCount(); aaudio_result_t result = serviceStream->stop(); serviceStream->disconnect(); return checkForPendingClose(serviceStream, result); Loading services/oboeservice/AAudioServiceStreamBase.cpp +6 −5 Original line number Diff line number Diff line Loading @@ -414,12 +414,13 @@ void AAudioServiceStreamBase::onVolumeChanged(float volume) { sendServiceEvent(AAUDIO_SERVICE_EVENT_VOLUME, volume); } int32_t AAudioServiceStreamBase::incrementServiceReferenceCount() { std::lock_guard<std::mutex> lock(mCallingCountLock); int32_t AAudioServiceStreamBase::incrementServiceReferenceCount_l() { return ++mCallingCount; } int32_t AAudioServiceStreamBase::decrementServiceReferenceCount() { std::lock_guard<std::mutex> lock(mCallingCountLock); return --mCallingCount; int32_t AAudioServiceStreamBase::decrementServiceReferenceCount_l() { int32_t count = --mCallingCount; // Each call to increment should be balanced with one call to decrement. assert(count >= 0); return count; } services/oboeservice/AAudioServiceStreamBase.h +18 −6 Original line number Diff line number Diff line Loading @@ -205,22 +205,33 @@ public: /** * Atomically increment the number of active references to the stream by AAudioService. * * This is called under a global lock in AAudioStreamTracker. * * @return value after the increment */ int32_t incrementServiceReferenceCount(); int32_t incrementServiceReferenceCount_l(); /** * Atomically decrement the number of active references to the stream by AAudioService. * This should only be called after incrementServiceReferenceCount_l(). * * This is called under a global lock in AAudioStreamTracker. * * @return value after the decrement */ int32_t decrementServiceReferenceCount(); int32_t decrementServiceReferenceCount_l(); bool isCloseNeeded() const { return mCloseNeeded.load(); } void setCloseNeeded(bool needed) { mCloseNeeded.store(needed); /** * Mark this stream as needing to be closed. * Once marked for closing, it cannot be unmarked. */ void markCloseNeeded() { mCloseNeeded.store(true); } virtual const char *getTypeText() const { return "Base"; } Loading Loading @@ -290,8 +301,9 @@ private: aaudio_handle_t mHandle = -1; bool mFlowing = false; std::mutex mCallingCountLock; std::atomic<int32_t> mCallingCount{0}; // This is modified under a global lock in AAudioStreamTracker. int32_t mCallingCount = 0; std::atomic<bool> mCloseNeeded{false}; }; Loading services/oboeservice/AAudioStreamTracker.cpp +15 −8 Original line number Diff line number Diff line Loading @@ -30,34 +30,40 @@ using namespace android; using namespace aaudio; sp<AAudioServiceStreamBase> AAudioStreamTracker::removeStreamByHandle( sp<AAudioServiceStreamBase> AAudioStreamTracker::decrementAndRemoveStreamByHandle( aaudio_handle_t streamHandle) { std::lock_guard<std::mutex> lock(mHandleLock); sp<AAudioServiceStreamBase> serviceStream; auto it = mStreamsByHandle.find(streamHandle); if (it != mStreamsByHandle.end()) { serviceStream = it->second; sp<AAudioServiceStreamBase> tempStream = it->second; // Does the caller need to close the stream? // The reference count should never be negative. // But it is safer to check for <= 0 than == 0. if ((tempStream->decrementServiceReferenceCount_l() <= 0) && tempStream->isCloseNeeded()) { serviceStream = tempStream; // Only return stream if ready to be closed. mStreamsByHandle.erase(it); } } return serviceStream; } sp<AAudioServiceStreamBase> AAudioStreamTracker::getStreamByHandle( sp<AAudioServiceStreamBase> AAudioStreamTracker::getStreamByHandleAndIncrement( aaudio_handle_t streamHandle) { std::lock_guard<std::mutex> lock(mHandleLock); sp<AAudioServiceStreamBase> serviceStream; auto it = mStreamsByHandle.find(streamHandle); if (it != mStreamsByHandle.end()) { serviceStream = it->second; serviceStream->incrementServiceReferenceCount_l(); } return serviceStream; } // The port handle is only available when the stream is started. // So we have to iterate over all the streams. // Luckily this rarely happens. sp<AAudioServiceStreamBase> AAudioStreamTracker::findStreamByPortHandle( sp<AAudioServiceStreamBase> AAudioStreamTracker::findStreamByPortHandleAndIncrement( audio_port_handle_t portHandle) { std::lock_guard<std::mutex> lock(mHandleLock); sp<AAudioServiceStreamBase> serviceStream; Loading @@ -66,6 +72,7 @@ sp<AAudioServiceStreamBase> AAudioStreamTracker::findStreamByPortHandle( auto candidate = it->second; if (candidate->getPortHandle() == portHandle) { serviceStream = candidate; serviceStream->incrementServiceReferenceCount_l(); break; } it++; Loading @@ -86,7 +93,7 @@ aaudio_handle_t AAudioStreamTracker::bumpHandle(aaudio_handle_t handle) { aaudio_handle_t AAudioStreamTracker::addStreamForHandle(sp<AAudioServiceStreamBase> serviceStream) { std::lock_guard<std::mutex> lock(mHandleLock); aaudio_handle_t handle = mPreviousHandle.load(); aaudio_handle_t handle = mPreviousHandle; // Assign a unique handle. while (true) { handle = bumpHandle(handle); Loading @@ -98,7 +105,7 @@ aaudio_handle_t AAudioStreamTracker::addStreamForHandle(sp<AAudioServiceStreamBa break; } } mPreviousHandle.store(handle); mPreviousHandle = handle; return handle; } Loading services/oboeservice/AAudioStreamTracker.h +20 −8 Original line number Diff line number Diff line Loading @@ -32,25 +32,35 @@ class AAudioStreamTracker { public: /** * Remove the stream associated with the handle. * Find the stream associated with the handle. * Decrement its reference counter. If zero and the stream needs * to be closed then remove the stream and return a pointer to the stream. * Otherwise return null if it does not need to be closed. * * @param streamHandle * @return strong pointer to the stream if found or to nullptr * @return strong pointer to the stream if it needs to be closed, or nullptr */ android::sp<AAudioServiceStreamBase> removeStreamByHandle(aaudio_handle_t streamHandle); android::sp<AAudioServiceStreamBase> decrementAndRemoveStreamByHandle( aaudio_handle_t streamHandle); /** * Look up a stream based on the handle. * Increment its service reference count if found. * * @param streamHandle * @return strong pointer to the stream if found or to nullptr * @return strong pointer to the stream if found, or nullptr */ android::sp<aaudio::AAudioServiceStreamBase> getStreamByHandle(aaudio_handle_t streamHandle); android::sp<aaudio::AAudioServiceStreamBase> getStreamByHandleAndIncrement( aaudio_handle_t streamHandle); /** * Look up a stream based on the AudioPolicy portHandle. * Increment its service reference count if found. * * @param portHandle * @return strong pointer to the stream if found or to nullptr * @return strong pointer to the stream if found, or nullptr */ android::sp<aaudio::AAudioServiceStreamBase> findStreamByPortHandle( android::sp<aaudio::AAudioServiceStreamBase> findStreamByPortHandleAndIncrement( audio_port_handle_t portHandle); /** Loading @@ -71,7 +81,9 @@ private: // Track stream using a unique handle that wraps. Only use positive half. mutable std::mutex mHandleLock; std::atomic<aaudio_handle_t> mPreviousHandle{0}; // protected by mHandleLock aaudio_handle_t mPreviousHandle = 0; // protected by mHandleLock std::map<aaudio_handle_t, android::sp<aaudio::AAudioServiceStreamBase>> mStreamsByHandle; }; Loading Loading
services/oboeservice/AAudioService.cpp +14 −15 Original line number Diff line number Diff line Loading @@ -144,15 +144,14 @@ aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &req // If a close request is pending then close the stream bool AAudioService::releaseStream(const sp<AAudioServiceStreamBase> &serviceStream) { bool closed = false; if ((serviceStream->decrementServiceReferenceCount() == 0) && serviceStream->isCloseNeeded()) { // removeStreamByHandle() uses a lock so that if there are two simultaneous closes // decrementAndRemoveStreamByHandle() uses a lock so that if there are two simultaneous closes // then only one will get the pointer and do the close. sp<AAudioServiceStreamBase> foundStream = mStreamTracker.removeStreamByHandle(serviceStream->getHandle()); sp<AAudioServiceStreamBase> foundStream = mStreamTracker.decrementAndRemoveStreamByHandle( serviceStream->getHandle()); if (foundStream.get() != nullptr) { foundStream->close(); pid_t pid = foundStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, foundStream); } closed = true; } return closed; Loading @@ -175,14 +174,15 @@ aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { pid_t pid = serviceStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream); serviceStream->setCloseNeeded(true); serviceStream->markCloseNeeded(); (void) releaseStream(serviceStream); return AAUDIO_OK; } sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandle(streamHandle); sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandleAndIncrement( streamHandle); if (serviceStream.get() != nullptr) { // Only allow owner or the aaudio service to access the stream. const uid_t callingUserId = IPCThreadState::self()->getCallingUid(); Loading @@ -194,9 +194,9 @@ sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( if (!allowed) { ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d", callingUserId, streamHandle, ownerUserId); // We incremented the reference count so we must check if it needs to be closed. checkForPendingClose(serviceStream, AAUDIO_OK); serviceStream.clear(); } else { serviceStream->incrementServiceReferenceCount(); } } return serviceStream; Loading Loading @@ -328,12 +328,11 @@ aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) { ALOGD("%s(%d) called", __func__, portHandle); sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.findStreamByPortHandle(portHandle); mStreamTracker.findStreamByPortHandleAndIncrement(portHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle); return AAUDIO_ERROR_INVALID_HANDLE; } serviceStream->incrementServiceReferenceCount(); aaudio_result_t result = serviceStream->stop(); serviceStream->disconnect(); return checkForPendingClose(serviceStream, result); Loading
services/oboeservice/AAudioServiceStreamBase.cpp +6 −5 Original line number Diff line number Diff line Loading @@ -414,12 +414,13 @@ void AAudioServiceStreamBase::onVolumeChanged(float volume) { sendServiceEvent(AAUDIO_SERVICE_EVENT_VOLUME, volume); } int32_t AAudioServiceStreamBase::incrementServiceReferenceCount() { std::lock_guard<std::mutex> lock(mCallingCountLock); int32_t AAudioServiceStreamBase::incrementServiceReferenceCount_l() { return ++mCallingCount; } int32_t AAudioServiceStreamBase::decrementServiceReferenceCount() { std::lock_guard<std::mutex> lock(mCallingCountLock); return --mCallingCount; int32_t AAudioServiceStreamBase::decrementServiceReferenceCount_l() { int32_t count = --mCallingCount; // Each call to increment should be balanced with one call to decrement. assert(count >= 0); return count; }
services/oboeservice/AAudioServiceStreamBase.h +18 −6 Original line number Diff line number Diff line Loading @@ -205,22 +205,33 @@ public: /** * Atomically increment the number of active references to the stream by AAudioService. * * This is called under a global lock in AAudioStreamTracker. * * @return value after the increment */ int32_t incrementServiceReferenceCount(); int32_t incrementServiceReferenceCount_l(); /** * Atomically decrement the number of active references to the stream by AAudioService. * This should only be called after incrementServiceReferenceCount_l(). * * This is called under a global lock in AAudioStreamTracker. * * @return value after the decrement */ int32_t decrementServiceReferenceCount(); int32_t decrementServiceReferenceCount_l(); bool isCloseNeeded() const { return mCloseNeeded.load(); } void setCloseNeeded(bool needed) { mCloseNeeded.store(needed); /** * Mark this stream as needing to be closed. * Once marked for closing, it cannot be unmarked. */ void markCloseNeeded() { mCloseNeeded.store(true); } virtual const char *getTypeText() const { return "Base"; } Loading Loading @@ -290,8 +301,9 @@ private: aaudio_handle_t mHandle = -1; bool mFlowing = false; std::mutex mCallingCountLock; std::atomic<int32_t> mCallingCount{0}; // This is modified under a global lock in AAudioStreamTracker. int32_t mCallingCount = 0; std::atomic<bool> mCloseNeeded{false}; }; Loading
services/oboeservice/AAudioStreamTracker.cpp +15 −8 Original line number Diff line number Diff line Loading @@ -30,34 +30,40 @@ using namespace android; using namespace aaudio; sp<AAudioServiceStreamBase> AAudioStreamTracker::removeStreamByHandle( sp<AAudioServiceStreamBase> AAudioStreamTracker::decrementAndRemoveStreamByHandle( aaudio_handle_t streamHandle) { std::lock_guard<std::mutex> lock(mHandleLock); sp<AAudioServiceStreamBase> serviceStream; auto it = mStreamsByHandle.find(streamHandle); if (it != mStreamsByHandle.end()) { serviceStream = it->second; sp<AAudioServiceStreamBase> tempStream = it->second; // Does the caller need to close the stream? // The reference count should never be negative. // But it is safer to check for <= 0 than == 0. if ((tempStream->decrementServiceReferenceCount_l() <= 0) && tempStream->isCloseNeeded()) { serviceStream = tempStream; // Only return stream if ready to be closed. mStreamsByHandle.erase(it); } } return serviceStream; } sp<AAudioServiceStreamBase> AAudioStreamTracker::getStreamByHandle( sp<AAudioServiceStreamBase> AAudioStreamTracker::getStreamByHandleAndIncrement( aaudio_handle_t streamHandle) { std::lock_guard<std::mutex> lock(mHandleLock); sp<AAudioServiceStreamBase> serviceStream; auto it = mStreamsByHandle.find(streamHandle); if (it != mStreamsByHandle.end()) { serviceStream = it->second; serviceStream->incrementServiceReferenceCount_l(); } return serviceStream; } // The port handle is only available when the stream is started. // So we have to iterate over all the streams. // Luckily this rarely happens. sp<AAudioServiceStreamBase> AAudioStreamTracker::findStreamByPortHandle( sp<AAudioServiceStreamBase> AAudioStreamTracker::findStreamByPortHandleAndIncrement( audio_port_handle_t portHandle) { std::lock_guard<std::mutex> lock(mHandleLock); sp<AAudioServiceStreamBase> serviceStream; Loading @@ -66,6 +72,7 @@ sp<AAudioServiceStreamBase> AAudioStreamTracker::findStreamByPortHandle( auto candidate = it->second; if (candidate->getPortHandle() == portHandle) { serviceStream = candidate; serviceStream->incrementServiceReferenceCount_l(); break; } it++; Loading @@ -86,7 +93,7 @@ aaudio_handle_t AAudioStreamTracker::bumpHandle(aaudio_handle_t handle) { aaudio_handle_t AAudioStreamTracker::addStreamForHandle(sp<AAudioServiceStreamBase> serviceStream) { std::lock_guard<std::mutex> lock(mHandleLock); aaudio_handle_t handle = mPreviousHandle.load(); aaudio_handle_t handle = mPreviousHandle; // Assign a unique handle. while (true) { handle = bumpHandle(handle); Loading @@ -98,7 +105,7 @@ aaudio_handle_t AAudioStreamTracker::addStreamForHandle(sp<AAudioServiceStreamBa break; } } mPreviousHandle.store(handle); mPreviousHandle = handle; return handle; } Loading
services/oboeservice/AAudioStreamTracker.h +20 −8 Original line number Diff line number Diff line Loading @@ -32,25 +32,35 @@ class AAudioStreamTracker { public: /** * Remove the stream associated with the handle. * Find the stream associated with the handle. * Decrement its reference counter. If zero and the stream needs * to be closed then remove the stream and return a pointer to the stream. * Otherwise return null if it does not need to be closed. * * @param streamHandle * @return strong pointer to the stream if found or to nullptr * @return strong pointer to the stream if it needs to be closed, or nullptr */ android::sp<AAudioServiceStreamBase> removeStreamByHandle(aaudio_handle_t streamHandle); android::sp<AAudioServiceStreamBase> decrementAndRemoveStreamByHandle( aaudio_handle_t streamHandle); /** * Look up a stream based on the handle. * Increment its service reference count if found. * * @param streamHandle * @return strong pointer to the stream if found or to nullptr * @return strong pointer to the stream if found, or nullptr */ android::sp<aaudio::AAudioServiceStreamBase> getStreamByHandle(aaudio_handle_t streamHandle); android::sp<aaudio::AAudioServiceStreamBase> getStreamByHandleAndIncrement( aaudio_handle_t streamHandle); /** * Look up a stream based on the AudioPolicy portHandle. * Increment its service reference count if found. * * @param portHandle * @return strong pointer to the stream if found or to nullptr * @return strong pointer to the stream if found, or nullptr */ android::sp<aaudio::AAudioServiceStreamBase> findStreamByPortHandle( android::sp<aaudio::AAudioServiceStreamBase> findStreamByPortHandleAndIncrement( audio_port_handle_t portHandle); /** Loading @@ -71,7 +81,9 @@ private: // Track stream using a unique handle that wraps. Only use positive half. mutable std::mutex mHandleLock; std::atomic<aaudio_handle_t> mPreviousHandle{0}; // protected by mHandleLock aaudio_handle_t mPreviousHandle = 0; // protected by mHandleLock std::map<aaudio_handle_t, android::sp<aaudio::AAudioServiceStreamBase>> mStreamsByHandle; }; Loading