diff --git a/rmw/include/rmw/event_callback_type.h b/rmw/include/rmw/event_callback_type.h new file mode 100644 index 00000000..8833b49f --- /dev/null +++ b/rmw/include/rmw/event_callback_type.h @@ -0,0 +1,52 @@ +// Copyright 2021 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMW__EVENT_CALLBACK_TYPE_H_ +#define RMW__EVENT_CALLBACK_TYPE_H_ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/// Common event callback type signature. +/** + * Event callbacks of this type can be called in various scenarios, e.g. + * data becomes available on a subscription, a QoS event has occurred, or + * something similar. + * + * The user_data argument is given by the user when registering the callback, + * and is given back to the callback each time so it can have associated, + * user-defined state. + * + * The number_of_events argument indicates the number of events since the + * callback was called. + * This is most often 1, but can be > 1 when events occur before the callback + * is registered. + * It should never be 0. + * + * \sa rmw_subscription_set_on_new_message_callback() + * \sa rmw_service_set_on_new_request_callback() + * \sa rmw_client_set_on_new_response_callback() + * \sa rmw_event_set_callback() + */ +typedef void (* rmw_event_callback_t)(const void * user_data, size_t number_of_events); + +#ifdef __cplusplus +} +#endif + +#endif // RMW__EVENT_CALLBACK_TYPE_H_ diff --git a/rmw/include/rmw/rmw.h b/rmw/include/rmw/rmw.h index bb224e2c..c98011e5 100644 --- a/rmw/include/rmw/rmw.h +++ b/rmw/include/rmw/rmw.h @@ -98,12 +98,14 @@ extern "C" #include "rosidl_runtime_c/service_type_support_struct.h" #include "rosidl_runtime_c/sequence_bound.h" +#include "rmw/event.h" #include "rmw/init.h" +#include "rmw/event_callback_type.h" #include "rmw/macros.h" +#include "rmw/message_sequence.h" #include "rmw/publisher_options.h" #include "rmw/qos_profiles.h" #include "rmw/subscription_options.h" -#include "rmw/message_sequence.h" #include "rmw/types.h" #include "rmw/visibility_control.h" @@ -2995,6 +2997,146 @@ RMW_WARN_UNUSED rmw_ret_t rmw_set_log_severity(rmw_log_severity_t severity); +/// Set the on new message callback function for the subscription. +/** + * This API sets the callback function to be called whenever the + * subscription is notified about a new message. + * + * This callback is called for each new message received by the subscription. + * If messages arrive before the callback is registered, the number_of_events + * argument given to the callback may be > 1. + * + * The callback may be called from a thread that the rmw implementation + * created, rather than a thread owned by the user, i.e. some thread other + * than user owned threads calling rmw functions such as rmw_wait() or + * rmw_publish(). + * + * This function is thread-safe. + * This is required of the rmw implementation because the callback may be called + * from any middleware thread, and this function could be called by the user + * at any time. + * + * \param[in] subscription The subscription on which to set the callback + * \param[in] callback The callback to be called when new messages arrive + * \param[in] user_data Given to the callback when called later, may be NULL + * \return `RMW_RET_OK` if successful, or + * \return `RMW_RET_INVALID_ARGUMENT` if `subscription` or `callback` is NULL, or + * \return `RMW_RET_UNSUPPORTED` if the API is not implemented in the dds implementation + */ +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_subscription_set_on_new_message_callback( + rmw_subscription_t * subscription, + rmw_event_callback_t callback, + const void * user_data); + +/// Set the on new request callback function for the service. +/** + * This API sets the callback function to be called whenever the + * service is notified about a new request. + * + * This callback is called for each new request received by the service. + * If requests arrive before the callback is registered, the number_of_events + * argument given to the callback may be > 1. + * + * The callback may be called from a thread that the rmw implementation + * created, rather than a thread owned by the user, i.e. some thread other + * than user owned threads calling rmw functions such as rmw_wait() or + * rmw_send_request(). + * + * This function is thread-safe. + * This is required of the rmw implementation because the callback may be called + * from any middleware thread, and this function could be called by the user + * at any time. + * + * \param[in] service The service on which to set the callback + * \param[in] callback The callback to be called when new requests arrive + * \param[in] user_data Given to the callback when called later, may be NULL + * \return `RMW_RET_OK` if callback was set to the listener, or + * \return `RMW_RET_INVALID_ARGUMENT` if `service` or `callback` is NULL, or + * \return `RMW_RET_UNSUPPORTED` if the API is not implemented in the dds implementation + */ +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_service_set_on_new_request_callback( + rmw_service_t * service, + rmw_event_callback_t callback, + const void * user_data); + +/// Set the on new response callback function for the client. +/** + * This API sets the callback function to be called whenever the + * client is notified about a new response. + * + * This callback is called for each new response received by the client. + * If responses arrive before the callback is registered, the number_of_events + * argument given to the callback may be > 1. + * + * The callback may be called from a thread that the rmw implementation + * created, rather than a thread owned by the user, i.e. some thread other + * than user owned threads calling rmw functions such as rmw_wait() or + * rmw_take_response(). + * + * This function is thread-safe. + * This is required of the rmw implementation because the callback may be called + * from any middleware thread, and this function could be called by the user + * at any time. + * + * \param[in] client The client on which to set the callback + * \param[in] callback The callback to be called when new responses arrive + * \param[in] user_data Given to the callback when called later, may be NULL + * \return `RMW_RET_OK` if callback was set to the listener, or + * \return `RMW_RET_INVALID_ARGUMENT` if `client` or `callback` is NULL, or + * \return `RMW_RET_UNSUPPORTED` if the API is not implemented in the dds implementation + */ +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_client_set_on_new_response_callback( + rmw_client_t * client, + rmw_event_callback_t callback, + const void * user_data); + +/// Set the callback function for the event. +/** + * This API sets the callback function to be called whenever the + * event is notified about a new instance of the event. + * + * For example, this could be called when incompatible QoS is detected, or + * a deadline is missed, or any other QoS event. + * + * This callback is called for each new event that occurs for this rmw_event_t + * instance. + * If events occur before the callback is registered, the number_of_events + * argument given to the callback may be > 1. + * + * The callback may be called from a thread that the rmw implementation + * created, rather than a thread owned by the user, i.e. some thread other + * than user owned threads calling rmw functions such as rmw_wait() or + * rmw_publish(). + * + * This function is thread-safe. + * This is required of the rmw implementation because the callback may be called + * from any middleware thread, and this function could be called by the user + * at any time. + * + * \param[in] event The event on which to set the callback + * \param[in] callback The callback to be called when new events occur + * \param[in] user_data Given to the callback when called later, may be NULL + * \return `RMW_RET_OK` if callback was set to the listener, or + * \return `RMW_RET_INVALID_ARGUMENT` if `event` or `callback` is NULL, or + * \return `RMW_RET_UNSUPPORTED` if the API is not implemented in the dds implementation + */ +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_event_set_callback( + rmw_event_t * event, + rmw_event_callback_t callback, + const void * user_data); + #ifdef __cplusplus } #endif