eProsima / Micro-XRCE-DDS-Client

Micro XRCE-DDS Client repository. Looking for commercial support? Contact info@eprosima.com
Apache License 2.0
134 stars 84 forks source link

Run uxr_prepare_output_stream and uxr_run_session_time on two different task in FreeRTOS #310

Closed zhangyaothu closed 2 years ago

zhangyaothu commented 2 years ago

Hello, I want to run uxr_prepare_output_stream and uxr_run_session_time on two different task in FreeRTOS, which will make the application and the middleware seperate from each other.

But I find that uxr_run_time_timeout is blocked when acquring stream id lock. The lock is locked when uxr_prepare_output_stream but never unlocked.

I just commented the else branch and make it to unlock before return. I want to check if there are some errors I make or some suggestions to make it work.

uint16_t uxr_prepare_output_stream(
        uxrSession* session,
        uxrStreamId stream_id,
        uxrObjectId entity_id,
        ucdrBuffer* ub,
        uint32_t len)
{
    uint16_t rv = UXR_INVALID_REQUEST_ID;

    UXR_LOCK_STREAM_ID(session, stream_id);

    size_t payload_size = WRITE_DATA_PAYLOAD_SIZE + len;

    ub->error = !uxr_prepare_stream_to_write_submessage(session, stream_id, payload_size, ub, SUBMESSAGE_ID_WRITE_DATA,
                    FORMAT_DATA);
    if (!ub->error)
    {
        WRITE_DATA_Payload_Data payload;
        rv = uxr_init_base_object_request(&session->info, entity_id, &payload.base);
        (void) uxr_serialize_WRITE_DATA_Payload_Data(ub, &payload);

        OnFullBuffer on_full_buffer = ub->on_full_buffer;
        void* args = ub->args;
        ucdr_init_buffer(ub, ub->iterator, (size_t)(ub->final - ub->iterator));
        ucdr_set_on_full_buffer_callback(ub, on_full_buffer, args);

        UXR_PREPARE_SHARED_MEMORY(session, entity_id, ub, (uint16_t) len, rv);
    }
//    else
//    {
        UXR_UNLOCK_STREAM_ID(session, stream_id);
//    }

    return rv;
}
pablogs9 commented 2 years ago

When you use uxr_prepare_output_stream you are asking the library to prepare the internal buffer to serialize a certain amount of data.

That's why the stream is locked but never unlocked (when the request is successful) because the expected serialization of data by the user should be protected by the same lock. So: when you call uxr_prepare_output_stream and the return is successful (ret != UXR_INVALID_REQUEST_ID) you are in charge of unlocking the stream with UXR_UNLOCK_STREAM_ID(session, stream_id); after the serialization of the data.