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

Commit 2037d809 authored by Harsh Bansal's avatar Harsh Bansal Committed by Gerrit - the friendly Code Review server
Browse files

hal:qaf: Fix to avoid hang while session close

-session close sometime hangs due to deadlock in qaf
-fix is done to avoid multiple lock while closing session

Change-Id: Ia4b89bf039e44a4e543d751a5f62cedec896d59e
parent f8c64ee3
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@ struct qaf_module {
    float vol_right;
    bool is_vol_set;
    qaf_stream_state stream_state[MAX_QAF_MODULE_IN];
    bool is_session_closing;
};

struct qaf {
@@ -1269,10 +1270,14 @@ static void notify_event_callback(audio_session_handle_t session_handle __unused
    struct audio_config config;
    audio_qaf_media_format_t *media_fmt = NULL;

    DEBUG_MSG_VV("Device 0x%X, Event = 0x%X, Bytes to write %d", device, event_id, size);
    if (qaf_mod->is_session_closing) {
        DEBUG_MSG("Dropping event as session is closing."
                "Device 0x%X, Event = 0x%X, Bytes to write %d", device, event_id, size);
        return;
    }

    DEBUG_MSG_VV("Device 0x%X, Event = 0x%X, Bytes to write %d", device, event_id, size);

    pthread_mutex_lock(&p_qaf->lock);

    /* Default config initialization. */
    config.sample_rate = config.offload_info.sample_rate = QAF_OUTPUT_SAMPLING_RATE;
@@ -1285,10 +1290,11 @@ static void notify_event_callback(audio_session_handle_t session_handle __unused
    if (event_id == AUDIO_SEC_FAIL_EVENT) {
        DEBUG_MSG("%s Security failed, closing session");
        qaf_session_close(qaf_mod);
        pthread_mutex_unlock(&p_qaf->lock);
        return;
    }

    pthread_mutex_lock(&p_qaf->lock);

    if (event_id == AUDIO_DATA_EVENT) {
        data_buffer_p = (int8_t*)buf;
        buffer_size = size;
@@ -1777,6 +1783,8 @@ static int qaf_session_close(struct qaf_module* qaf_mod)
{
    int j;

    DEBUG_MSG("Closing Session.");

    //Check if all streams are closed or not.
    for (j = 0; j < MAX_QAF_MODULE_IN; j++) {
        if (qaf_mod->stream_in[j] != NULL) {
@@ -1787,6 +1795,9 @@ static int qaf_session_close(struct qaf_module* qaf_mod)
        return 0; //Some stream is already active, Can not close session.
    }

    qaf_mod->is_session_closing = true;
    pthread_mutex_lock(&p_qaf->lock);

    if (qaf_mod->session_handle != NULL && qaf_mod->qaf_audio_session_close) {
#ifdef AUDIO_EXTN_IP_HDLR_ENABLED
        if (qaf_mod == &p_qaf->qaf_mod[MS12]) {
@@ -1810,6 +1821,8 @@ static int qaf_session_close(struct qaf_module* qaf_mod)
    }
    qaf_mod->new_out_format_index = 0;

    pthread_mutex_unlock(&p_qaf->lock);
    qaf_mod->is_session_closing = false;
    DEBUG_MSG("Session Closed.");

    return 0;
@@ -1843,11 +1856,11 @@ static int qaf_stream_close(struct stream_out *out)
    }
    unlock_output_stream(out);

    pthread_mutex_unlock(&p_qaf->lock);

    //If all streams are closed then close the session.
    qaf_session_close(qaf_mod);

    pthread_mutex_unlock(&p_qaf->lock);

    DEBUG_MSG();
    return ret;
}