Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EventsExecutor #286

Merged
merged 10 commits into from
Feb 24, 2022
52 changes: 52 additions & 0 deletions rmw/include/rmw/event_callback_type.h
Original file line number Diff line number Diff line change
@@ -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 <stddef.h>

#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_
144 changes: 143 additions & 1 deletion rmw/include/rmw/rmw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
wjwwood marked this conversation as resolved.
Show resolved Hide resolved
#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"

Expand Down Expand Up @@ -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
Expand Down