Execution module¶
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_workmethod that enables the entities to check if they have pending work to be done.A blocking with timeout
spinmethod 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::TimepointTimeout 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.