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

Commit 3d201944 authored by Phil Burk's avatar Phil Burk
Browse files

aaudio: pass strong pointers into threads

The AAudio service has several threads that are used
to handle routing changes (disconnects), and also the
timestamp generating thread.

In this CL we pass a strong pointer to the owning object into
the thread in order to prevent the object from being deleted
while the thread is running.

Bug: 179331032
Bug: 184774807
Test: atest CtsNativeMediaAAudioTestCases
Test: Run OboeTester "TEST DISCONNECTS" test.
Change-Id: I894f5c38fdf111257dea2bee9561c13608da52aa
parent 87e35b9b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -38,6 +38,10 @@
using namespace android;  // TODO just import names needed
using namespace aaudio;   // TODO just import names needed

AAudioServiceEndpoint::~AAudioServiceEndpoint() {
    ALOGD("%s() called", __func__);
}

std::string AAudioServiceEndpoint::dump() const NO_THREAD_SAFETY_ANALYSIS {
    std::stringstream result;

+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ class AAudioServiceEndpoint
        , public AAudioStreamParameters {
public:

    virtual ~AAudioServiceEndpoint() = default;
    virtual ~AAudioServiceEndpoint();

    virtual std::string dump() const;

+9 −6
Original line number Diff line number Diff line
@@ -51,8 +51,6 @@ AAudioServiceEndpointMMAP::AAudioServiceEndpointMMAP(AAudioService &audioService
        : mMmapStream(nullptr)
        , mAAudioService(audioService) {}

AAudioServiceEndpointMMAP::~AAudioServiceEndpointMMAP() {}

std::string AAudioServiceEndpointMMAP::dump() const {
    std::stringstream result;

@@ -357,7 +355,10 @@ void AAudioServiceEndpointMMAP::handleTearDownAsync(audio_port_handle_t portHand
// This is called by AudioFlinger when it wants to destroy a stream.
void AAudioServiceEndpointMMAP::onTearDown(audio_port_handle_t portHandle) {
    ALOGD("%s(portHandle = %d) called", __func__, portHandle);
    std::thread asyncTask(&AAudioServiceEndpointMMAP::handleTearDownAsync, this, portHandle);
    android::sp<AAudioServiceEndpointMMAP> holdEndpoint(this);
    std::thread asyncTask([holdEndpoint, portHandle]() {
        holdEndpoint->handleTearDownAsync(portHandle);
    });
    asyncTask.detach();
}

@@ -378,9 +379,11 @@ void AAudioServiceEndpointMMAP::onRoutingChanged(audio_port_handle_t portHandle)
    ALOGD("%s() called with dev %d, old = %d", __func__, deviceId, getDeviceId());
    if (getDeviceId() != deviceId) {
        if (getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
            std::thread asyncTask([this, deviceId]() {
                disconnectRegisteredStreams();
                setDeviceId(deviceId);
            android::sp<AAudioServiceEndpointMMAP> holdEndpoint(this);
            std::thread asyncTask([holdEndpoint, deviceId]() {
                ALOGD("onRoutingChanged() asyncTask launched");
                holdEndpoint->disconnectRegisteredStreams();
                holdEndpoint->setDeviceId(deviceId);
            });
            asyncTask.detach();
        } else {
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ class AAudioServiceEndpointMMAP
public:
    explicit AAudioServiceEndpointMMAP(android::AAudioService &audioService);

    virtual ~AAudioServiceEndpointMMAP();
    virtual ~AAudioServiceEndpointMMAP() = default;

    std::string dump() const override;

+12 −1
Original line number Diff line number Diff line
@@ -261,8 +261,14 @@ aaudio_result_t AAudioServiceStreamBase::start() {
    sendServiceEvent(AAUDIO_SERVICE_EVENT_STARTED);
    setState(AAUDIO_STREAM_STATE_STARTED);
    mThreadEnabled.store(true);
    // Make sure this object does not get deleted before the run() method
    // can protect it by making a strong pointer.
    incStrong(nullptr); // See run() method.
    result = mTimestampThread.start(this);
    if (result != AAUDIO_OK) goto error;
    if (result != AAUDIO_OK) {
        decStrong(nullptr); // run() can't do it so we have to do it here.
        goto error;
    }

    return result;

@@ -403,7 +409,12 @@ aaudio_result_t AAudioServiceStreamBase::flush() {
__attribute__((no_sanitize("integer")))
void AAudioServiceStreamBase::run() {
    ALOGD("%s() %s entering >>>>>>>>>>>>>> TIMESTAMPS", __func__, getTypeText());
    // Hold onto the ref counted stream until the end.
    android::sp<AAudioServiceStreamBase> holdStream(this);
    TimestampScheduler timestampScheduler;
    // Balance the incStrong from when the thread was launched.
    holdStream->decStrong(nullptr);

    timestampScheduler.setBurstPeriod(mFramesPerBurst, getSampleRate());
    timestampScheduler.start(AudioClock::getNanoseconds());
    int64_t nextTime = timestampScheduler.nextAbsoluteTime();