From 24f622b114095ad0cb8f3aac16922c1404b9c67a Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 13 Jul 2018 08:47:29 +0200 Subject: [PATCH] add guard conditions Signed-off-by: Erik Boasson --- src/core/ddsc/.fileids | 1 + src/core/ddsc/CMakeLists.txt | 2 + src/core/ddsc/include/ddsc/dds.h | 77 +++++++++++ src/core/ddsc/include/ddsc/dds_public_impl.h | 5 +- src/core/ddsc/src/dds__guardcond.h | 21 +++ src/core/ddsc/src/dds__types.h | 7 + src/core/ddsc/src/dds_guardcond.c | 138 +++++++++++++++++++ 7 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 src/core/ddsc/src/dds__guardcond.h create mode 100644 src/core/ddsc/src/dds_guardcond.c diff --git a/src/core/ddsc/.fileids b/src/core/ddsc/.fileids index 93578df..fad8ca9 100644 --- a/src/core/ddsc/.fileids +++ b/src/core/ddsc/.fileids @@ -30,3 +30,4 @@ 68 src/dds_write.c 69 src/dds_report.c 70 src/dds_builtin.c +72 src/dds_guardcond.c diff --git a/src/core/ddsc/CMakeLists.txt b/src/core/ddsc/CMakeLists.txt index 8b96b05..e53f2d2 100644 --- a/src/core/ddsc/CMakeLists.txt +++ b/src/core/ddsc/CMakeLists.txt @@ -38,6 +38,7 @@ PREPEND(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds_waitset.c dds_log.c dds_readcond.c + dds_guardcond.c dds_subscriber.c dds_write.c ) @@ -68,6 +69,7 @@ PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds__qos.h dds__querycond.h dds__readcond.h + dds__guardcond.h dds__reader.h dds__report.h dds__rhc.h diff --git a/src/core/ddsc/include/ddsc/dds.h b/src/core/ddsc/include/ddsc/dds.h index 47e3977..ce5c6d6 100644 --- a/src/core/ddsc/include/ddsc/dds.h +++ b/src/core/ddsc/include/ddsc/dds.h @@ -1821,6 +1821,83 @@ dds_create_querycondition( _In_ uint32_t mask, _In_ dds_querycondition_filter_fn filter); +/** + * @brief Creates a guardcondition. + * + * Waitsets allow waiting for an event on some of any set of entities. + * This means that the guardcondition can be used to wake up a waitset when + * data is in the reader history with states that matches the given mask. + * + * @returns A valid condition handle or an error code. + * + * @retval >0 + * A valid condition handle + * @retval DDS_RETCODE_ERROR + * An internal error has occurred. + * @retval DDS_RETCODE_ILLEGAL_OPERATION + * The operation is invoked on an inappropriate object. + * @retval DDS_RETCODE_ALREADY_DELETED + * The entity has already been deleted. + */ +_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT) +DDS_EXPORT _Must_inspect_result_ dds_entity_t +dds_create_guardcondition( + _In_ dds_entity_t participant); + +/** + * @brief Sets the trigger status of a guardcondition. + * + * @retval DDS_RETCODE_OK + * Operation successful + * @retval DDS_RETCODE_ERROR + * An internal error has occurred. + * @retval DDS_RETCODE_ILLEGAL_OPERATION + * The operation is invoked on an inappropriate object. + * @retval DDS_RETCODE_ALREADY_DELETED + * The entity has already been deleted. + */ +_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) +DDS_EXPORT dds_return_t +dds_set_guardcondition( + _In_ dds_entity_t guardcond, + _In_ bool triggered); + +/** + * @brief Reads the trigger status of a guardcondition. + * + * @retval DDS_RETCODE_OK + * Operation successful + * @retval DDS_RETCODE_ERROR + * An internal error has occurred. + * @retval DDS_RETCODE_ILLEGAL_OPERATION + * The operation is invoked on an inappropriate object. + * @retval DDS_RETCODE_ALREADY_DELETED + * The entity has already been deleted. + */ +_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) +DDS_EXPORT dds_return_t +dds_read_guardcondition( + _In_ dds_entity_t guardcond, + _Out_ bool *triggered); + +/** + * @brief Reads and resets the trigger status of a guardcondition. + * + * @retval DDS_RETCODE_OK + * Operation successful + * @retval DDS_RETCODE_ERROR + * An internal error has occurred. + * @retval DDS_RETCODE_ILLEGAL_OPERATION + * The operation is invoked on an inappropriate object. + * @retval DDS_RETCODE_ALREADY_DELETED + * The entity has already been deleted. + */ +_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) +DDS_EXPORT dds_return_t +dds_take_guardcondition( + _In_ dds_entity_t guardcond, + _Out_ bool *triggered); + /** * @brief Waitset attachment argument. * diff --git a/src/core/ddsc/include/ddsc/dds_public_impl.h b/src/core/ddsc/include/ddsc/dds_public_impl.h index 784d002..d0170c7 100644 --- a/src/core/ddsc/include/ddsc/dds_public_impl.h +++ b/src/core/ddsc/include/ddsc/dds_public_impl.h @@ -109,8 +109,9 @@ typedef enum dds_entity_kind DDS_KIND_PUBLISHER = 0x06000000, DDS_KIND_COND_READ = 0x07000000, DDS_KIND_COND_QUERY = 0x08000000, - DDS_KIND_WAITSET = 0x09000000, - DDS_KIND_INTERNAL = 0x0A000000, + DDS_KIND_COND_GUARD = 0x09000000, + DDS_KIND_WAITSET = 0x0A000000, + DDS_KIND_INTERNAL = 0x0B000000, } dds_entity_kind_t; diff --git a/src/core/ddsc/src/dds__guardcond.h b/src/core/ddsc/src/dds__guardcond.h new file mode 100644 index 0000000..6497f70 --- /dev/null +++ b/src/core/ddsc/src/dds__guardcond.h @@ -0,0 +1,21 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#ifndef _DDS_GUARDCOND_H_ +#define _DDS_GUARDCOND_H_ + +#include "dds__entity.h" + +_Must_inspect_result_ dds_guardcond* +dds_create_guardcond( + _In_ dds_participant *pp); + +#endif diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index 8b289f6..d345f32 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -36,6 +36,7 @@ struct dds_subscriber; struct dds_topic; struct dds_readcond; struct dds_guardcond; +struct dds_statuscond; struct sertopic; struct rhc; @@ -227,6 +228,12 @@ typedef struct dds_readcond } dds_readcond; +typedef struct dds_guardcond +{ + dds_entity m_entity; +} +dds_guardcond; + typedef struct dds_attachment { dds_entity *entity; diff --git a/src/core/ddsc/src/dds_guardcond.c b/src/core/ddsc/src/dds_guardcond.c new file mode 100644 index 0000000..32d2f52 --- /dev/null +++ b/src/core/ddsc/src/dds_guardcond.c @@ -0,0 +1,138 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include +#include "dds__reader.h" +#include "dds__guardcond.h" +#include "dds__entity.h" +#include "dds__err.h" +#include "ddsi/q_ephash.h" +#include "ddsi/q_entity.h" +#include "ddsi/q_thread.h" +#include "dds__report.h" + +_Must_inspect_result_ dds_guardcond* +dds_create_guardcond( + _In_ dds_participant *pp) +{ + dds_guardcond * gcond = dds_alloc(sizeof(*gcond)); + gcond->m_entity.m_hdl = dds_entity_init(&gcond->m_entity, (dds_entity*)pp, DDS_KIND_COND_GUARD, NULL, NULL, 0); + return gcond; +} + +_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT) +_Must_inspect_result_ dds_entity_t +dds_create_guardcondition( + _In_ dds_entity_t participant) +{ + dds_entity_t hdl; + dds_entity * pp; + dds__retcode_t rc; + + DDS_REPORT_STACK(); + rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &pp); + if (rc == DDS_RETCODE_OK) { + dds_guardcond *cond = dds_create_guardcond((dds_participant *)pp); + assert(cond); + hdl = cond->m_entity.m_hdl; + dds_entity_unlock(pp); + } else { + hdl = DDS_ERRNO(rc, "Error occurred on locking reader"); + } + DDS_REPORT_FLUSH(hdl <= 0); + return hdl; +} + +_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) ) +dds_return_t +dds_set_guardcondition( + _In_ dds_entity_t condition, + _In_ bool triggered) +{ + dds_return_t ret; + dds_guardcond *gcond; + dds__retcode_t rc; + + DDS_REPORT_STACK(); + rc = dds_entity_lock(condition, DDS_KIND_COND_GUARD, (dds_entity**)&gcond); + if (rc == DDS_RETCODE_OK) { + if (triggered) { + dds_entity_status_set(gcond, DDS_WAITSET_TRIGGER_STATUS); + dds_entity_status_signal(&gcond->m_entity); + } else { + dds_entity_status_reset(gcond, DDS_WAITSET_TRIGGER_STATUS); + } + dds_entity_unlock(&gcond->m_entity); + ret = DDS_RETCODE_OK; + } else { + ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_GUARD), "Argument condition is not valid"); + } + DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK); + return ret; +} + +_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) ) +dds_return_t +dds_read_guardcondition( + _In_ dds_entity_t condition, + _Out_ bool *triggered) +{ + dds_return_t ret; + dds_guardcond *gcond; + dds__retcode_t rc; + + DDS_REPORT_STACK(); + if (triggered != NULL) { + *triggered = false; + rc = dds_entity_lock(condition, DDS_KIND_COND_GUARD, (dds_entity**)&gcond); + if (rc == DDS_RETCODE_OK) { + *triggered = dds_entity_status_match(gcond, DDS_WAITSET_TRIGGER_STATUS); + dds_entity_unlock((dds_entity*)gcond); + ret = DDS_RETCODE_OK; + } else { + ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_GUARD), "Argument condition is not valid"); + } + } else { + ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument triggered is NULL"); + } + DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK); + return ret; +} + +_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) ) +dds_return_t +dds_take_guardcondition( + _In_ dds_entity_t condition, + _Out_ bool *triggered) +{ + dds_return_t ret; + dds_guardcond *gcond; + dds__retcode_t rc; + + DDS_REPORT_STACK(); + if (triggered != NULL) { + *triggered = false; + rc = dds_entity_lock(condition, DDS_KIND_COND_GUARD, (dds_entity**)&gcond); + if (rc == DDS_RETCODE_OK) { + *triggered = dds_entity_status_match(gcond, DDS_WAITSET_TRIGGER_STATUS); + dds_entity_status_reset(gcond, DDS_WAITSET_TRIGGER_STATUS); + dds_entity_unlock((dds_entity*)gcond); + ret = DDS_RETCODE_OK; + } else { + ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_GUARD), "Argument condition is not valid"); + } + } else { + ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument triggered is NULL"); + } + DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK); + return ret; +}