Execution module

DDS discovery datacentric memory execution serialization platform protocol transport portable system toolchain

Safe DDS provides a set of interfaces to allow the application to implement their own execution model. This allows for integrating Safe DDS into specific execution models such as leveraging the library within threaded environments.

Note

Safe DDS cannot be used in a threaded environment as it does not provide any kind of thread locking mechanism.

In order to use Safe DDS in a threaded environment, it must be assumed that all provided APIs are non thread safe, and application locking mechanisms shall be implemented to protect every concurrent API call.

The Safe DDS execution model is based on ISpinnable interface, which provides:

  • A non-blocking has_pending_work method that enables the entities to check if they have pending work to be done.

  • A blocking with timeout spin method that enables the entities to perform their internal tasks including transport operations.

By means of these two methods, the entities can be integrated into any kind of execution model, including blocking and non-blocking ones.

ISpinnable interface

API Reference

For more information about execution::ISpinnable interface, check API Reference execution::ISpinnable

In general, most of the entities in Safe DDS are ISpinnable and implement the interface methods.

has_pending_work

This method returns true if the entity has pending work to be done, and false otherwise. It takes no arguments and returns a bool.

get_next_work_timepoint

This method returns TimePoint with next work TimePoint of the spinnable entity.

spin

This method performs the entity internal tasks, including possible transport operations. This method takes as argument:

  • Timepoint as execution::Timepoint Timeout for the spin operation to be performed.

Default Execution Model

Safe DDS provides a default executor at the BasicExecutor class.

API Reference

For more information about execution::BasicExecutor interface, check API Reference execution::BasicExecutor

This executor can be instantiated using the create_default_executor member function of DomainParticipantFactory, and can be used as follows:

dds::DomainParticipantFactory factory{};

/****************************
* CREATE DDS ENTITIES HERE *
****************************/

// Retrieve the default executor from a DomainParticipantFactory.
execution::ISpinnable* executor = factory.create_default_executor();

if (nullptr == executor)
{
    std::cout << "Error creating default executor" << std::endl;
}

// 10 Hz loop
while (1)
{
    execution::TimePoint next_timepoint =
            get_platform().get_current_timepoint() + execution::TimePeriod::from_ms(100);

    // Spin the executor if there is pending work
    if (executor->has_pending_work())
    {
        executor->spin(next_timepoint);
    }

    // Sleep until next timepoint
    execution::TimePeriod sleep_time =
            next_timepoint - get_platform().get_current_timepoint();

    usleep(sleep_time.to_us());
}

Custom Execution Model

An example of a custom executor implementation can be found in the custom executor tutorial.