add guard conditions
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
		
							parent
							
								
									414be4a569
								
							
						
					
					
						commit
						24f622b114
					
				
					 7 changed files with 249 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -30,3 +30,4 @@
 | 
			
		|||
68  src/dds_write.c
 | 
			
		||||
69  src/dds_report.c
 | 
			
		||||
70  src/dds_builtin.c
 | 
			
		||||
72  src/dds_guardcond.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										21
									
								
								src/core/ddsc/src/dds__guardcond.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/core/ddsc/src/dds__guardcond.h
									
										
									
									
									
										Normal 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
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										138
									
								
								src/core/ddsc/src/dds_guardcond.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/core/ddsc/src/dds_guardcond.c
									
										
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue