add guard conditions

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2018-07-13 08:47:29 +02:00
parent 414be4a569
commit 24f622b114
7 changed files with 249 additions and 2 deletions

View file

@ -30,3 +30,4 @@
68 src/dds_write.c
69 src/dds_report.c
70 src/dds_builtin.c
72 src/dds_guardcond.c

View file

@ -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

View file

@ -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.
*

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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 <assert.h>
#include <string.h>
#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;
}