Merge pull request #93 from eboasson/entity-rework

Performance improvements by reworking listeners/status flags (and some odds and ends)
This commit is contained in:
eboasson 2019-01-17 18:57:36 +01:00 committed by GitHub
commit ed5f89b143
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 2173 additions and 2477 deletions

View file

@ -98,6 +98,38 @@ elseif(${CMAKE_C_COMPILER_ID} STREQUAL "MSVC")
add_definitions(/W3)
endif()
# I don't know how to enable warnings properly so that it ends up in Xcode projects as well
if(${CMAKE_GENERATOR} STREQUAL "Xcode")
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_EMPTY_BODY YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SHADOW YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_BOOL_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_CONSTANT_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_ENUM_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_FLOAT_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_INT_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_NON_LITERAL_NULL_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_IMPLICIT_SIGN_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_INFINITE_RECURSION YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_RETURN_TYPE YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_MISSING_PARENTHESES YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_NEWLINE YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_ASSIGN_ENUM YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SIGN_COMPARE YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_STRICT_PROTOTYPES YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_COMMA YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNINITIALIZED_AUTOS YES_AGGRESSIVE)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_FUNCTION YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_LABEL YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES)
endif()
# Make it easy to enable one of Clang's/gcc's analyzers, and default to using
# the address sanitizer for ordinary debug builds; gcc is giving some grief on
# Travis, so don't enable it for gcc by default

View file

@ -81,31 +81,47 @@ extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION;
/** @name Communication Status definitions
@{**/
/** Another topic exists with the same name but with different characteristics. */
#define DDS_INCONSISTENT_TOPIC_STATUS 1u
typedef enum dds_status_id {
DDS_INCONSISTENT_TOPIC_STATUS_ID,
DDS_OFFERED_DEADLINE_MISSED_STATUS_ID,
DDS_REQUESTED_DEADLINE_MISSED_STATUS_ID,
DDS_OFFERED_INCOMPATIBLE_QOS_STATUS_ID,
DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS_ID,
DDS_SAMPLE_LOST_STATUS_ID,
DDS_SAMPLE_REJECTED_STATUS_ID,
DDS_DATA_ON_READERS_STATUS_ID,
DDS_DATA_AVAILABLE_STATUS_ID,
DDS_LIVELINESS_LOST_STATUS_ID,
DDS_LIVELINESS_CHANGED_STATUS_ID,
DDS_PUBLICATION_MATCHED_STATUS_ID,
DDS_SUBSCRIPTION_MATCHED_STATUS_ID
}
dds_status_id_t;
#define DDS_INCONSISTENT_TOPIC_STATUS (1u << DDS_INCONSISTENT_TOPIC_STATUS_ID)
/** The deadline that the writer has committed through its deadline QoS policy was not respected for a specific instance. */
#define DDS_OFFERED_DEADLINE_MISSED_STATUS 2u
#define DDS_OFFERED_DEADLINE_MISSED_STATUS (1u << DDS_OFFERED_DEADLINE_MISSED_STATUS_ID)
/** The deadline that the reader was expecting through its deadline QoS policy was not respected for a specific instance. */
#define DDS_REQUESTED_DEADLINE_MISSED_STATUS 4u
#define DDS_REQUESTED_DEADLINE_MISSED_STATUS (1u << DDS_REQUESTED_DEADLINE_MISSED_STATUS_ID)
/** A QoS policy setting was incompatible with what was requested. */
#define DDS_OFFERED_INCOMPATIBLE_QOS_STATUS 32u
#define DDS_OFFERED_INCOMPATIBLE_QOS_STATUS (1u << DDS_OFFERED_INCOMPATIBLE_QOS_STATUS_ID)
/** A QoS policy setting was incompatible with what is offered. */
#define DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS 64u
#define DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS (1u << DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS_ID)
/** A sample has been lost (never received). */
#define DDS_SAMPLE_LOST_STATUS 128u
#define DDS_SAMPLE_LOST_STATUS (1u << DDS_SAMPLE_LOST_STATUS_ID)
/** A (received) sample has been rejected. */
#define DDS_SAMPLE_REJECTED_STATUS 256u
#define DDS_SAMPLE_REJECTED_STATUS (1u << DDS_SAMPLE_REJECTED_STATUS_ID)
/** New information is available. */
#define DDS_DATA_ON_READERS_STATUS 512u
#define DDS_DATA_ON_READERS_STATUS (1u << DDS_DATA_ON_READERS_STATUS_ID)
/** New information is available. */
#define DDS_DATA_AVAILABLE_STATUS 1024u
#define DDS_DATA_AVAILABLE_STATUS (1u << DDS_DATA_AVAILABLE_STATUS_ID)
/** The liveliness that the DDS_DataWriter has committed through its liveliness QoS policy was not respected; thus readers will consider the writer as no longer "alive". */
#define DDS_LIVELINESS_LOST_STATUS 2048u
#define DDS_LIVELINESS_LOST_STATUS (1u << DDS_LIVELINESS_LOST_STATUS_ID)
/** The liveliness of one or more writers, that were writing instances read through the readers has changed. Some writers have become "alive" or "not alive". */
#define DDS_LIVELINESS_CHANGED_STATUS 4096u
#define DDS_LIVELINESS_CHANGED_STATUS (1u << DDS_LIVELINESS_CHANGED_STATUS_ID)
/** The writer has found a reader that matches the topic and has a compatible QoS. */
#define DDS_PUBLICATION_MATCHED_STATUS 8192u
#define DDS_PUBLICATION_MATCHED_STATUS (1u << DDS_PUBLICATION_MATCHED_STATUS_ID)
/** The reader has found a writer that matches the topic and has a compatible QoS. */
#define DDS_SUBSCRIPTION_MATCHED_STATUS 16384u
#define DDS_SUBSCRIPTION_MATCHED_STATUS (1u << DDS_SUBSCRIPTION_MATCHED_STATUS_ID)
/** @}*/
/** Read state for a data value */
@ -685,7 +701,7 @@ dds_set_qos(
*/
/* TODO: Link to (generic) Listener and status information. */
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)
DDS_EXPORT _Check_return_ dds_return_t
DDS_EXPORT dds_return_t
dds_get_listener(
_In_ dds_entity_t entity,
_Out_ dds_listener_t * listener);
@ -744,7 +760,7 @@ dds_get_listener(
*/
/* TODO: Link to (generic) Listener and status information. */
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)
DDS_EXPORT _Check_return_ dds_return_t
DDS_EXPORT dds_return_t
dds_set_listener(
_In_ dds_entity_t entity,
_In_opt_ const dds_listener_t * listener);

View file

@ -44,16 +44,9 @@ typedef void (*dds_on_requested_incompatible_qos_fn) (dds_entity_t reader, const
typedef void (*dds_on_publication_matched_fn) (dds_entity_t writer, const dds_publication_matched_status_t status, void* arg);
typedef void (*dds_on_subscription_matched_fn) (dds_entity_t reader, const dds_subscription_matched_status_t status, void* arg);
#if 0
/* TODO: Why use (*dds_on_any_fn) (); and DDS_LUNSET? Why not just set the callbacks to NULL? */
typedef void (*dds_on_any_fn) (); /**< Empty parameter list on purpose; should be assignable without cast to all of the above. @todo check with an actual compiler; I'm a sloppy compiler */
#define DDS_LUNSET ((dds_on_any_fn)1) /**< Callback indicating a callback isn't set */
#else
#define DDS_LUNSET (NULL)
#endif
struct c_listener;
typedef struct c_listener dds_listener_t;
#define DDS_LUNSET 0
struct dds_listener;
typedef struct dds_listener dds_listener_t;
/**
* @brief Allocate memory and initializes to default values (::DDS_LUNSET) of a listener
@ -104,7 +97,6 @@ DDS_DEPRECATED_EXPORT void dds_listener_copy (_Out_ dds_listener_t * __restrict
DDS_EXPORT void dds_merge_listener (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src);
DDS_DEPRECATED_EXPORT void dds_listener_merge (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src);
/************************************************************************************************
* Setters
************************************************************************************************/

View file

@ -76,11 +76,11 @@ DDS_EXPORT double dds_stream_read_double (dds_stream_t * is);
DDS_EXPORT char * dds_stream_read_string (dds_stream_t * is);
DDS_EXPORT void dds_stream_read_buffer (dds_stream_t * is, uint8_t * buffer, uint32_t len);
#define dds_stream_read_char(s) ((char) dds_stream_read_uint8 (s))
#define dds_stream_read_int8(s) ((int8_t) dds_stream_read_uint8 (s))
#define dds_stream_read_int16(s) ((int16_t) dds_stream_read_uint16 (s))
#define dds_stream_read_int32(s) ((int32_t) dds_stream_read_uint32 (s))
#define dds_stream_read_int64(s) ((int64_t) dds_stream_read_uint64 (s))
inline char dds_stream_read_char (dds_stream_t *is) { return (char) dds_stream_read_uint8 (is); }
inline int8_t dds_stream_read_int8 (dds_stream_t *is) { return (int8_t) dds_stream_read_uint8 (is); }
inline int16_t dds_stream_read_int16 (dds_stream_t *is) { return (int16_t) dds_stream_read_uint16 (is); }
inline int32_t dds_stream_read_int32 (dds_stream_t *is) { return (int32_t) dds_stream_read_uint32 (is); }
inline int64_t dds_stream_read_int64 (dds_stream_t *is) { return (int64_t) dds_stream_read_uint64 (is); }
DDS_EXPORT void dds_stream_write_bool (dds_stream_t * os, bool val);
DDS_EXPORT void dds_stream_write_uint8 (dds_stream_t * os, uint8_t val);
@ -94,11 +94,11 @@ DDS_EXPORT void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, const
DDS_EXPORT void *dds_stream_address (dds_stream_t * s);
DDS_EXPORT void *dds_stream_alignto (dds_stream_t * s, uint32_t a);
#define dds_stream_write_char(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v)))
#define dds_stream_write_int8(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v)))
#define dds_stream_write_int16(s,v) (dds_stream_write_uint16 ((s), (uint16_t)(v)))
#define dds_stream_write_int32(s,v) (dds_stream_write_uint32 ((s), (uint32_t)(v)))
#define dds_stream_write_int64(s,v) (dds_stream_write_uint64 ((s), (uint64_t)(v)))
inline void dds_stream_write_char (dds_stream_t * os, char val) { dds_stream_write_uint8 (os, (uint8_t) val); }
inline void dds_stream_write_int8 (dds_stream_t * os, int8_t val) { dds_stream_write_uint8 (os, (uint8_t) val); }
inline void dds_stream_write_int16 (dds_stream_t * os, int16_t val) { dds_stream_write_uint16 (os, (uint16_t) val); }
inline void dds_stream_write_int32 (dds_stream_t * os, int32_t val) { dds_stream_write_uint32 (os, (uint32_t) val); }
inline void dds_stream_write_int64 (dds_stream_t * os, int64_t val) { dds_stream_write_uint64 (os, (uint64_t) val); }
#if defined (__cplusplus)
}

View file

@ -37,25 +37,50 @@ void
dds_entity_add_ref_nolock(
_In_ dds_entity *e);
_Check_return_ dds__retcode_t
dds_entity_listener_propagation(
_Inout_opt_ dds_entity *e,
_In_ dds_entity *src,
_In_ uint32_t status,
_In_opt_ void *metrics,
_In_ bool propagate);
#define DEFINE_ENTITY_LOCK_UNLOCK(qualifier_, type_, kind_) \
qualifier_ dds__retcode_t type_##_lock (dds_entity_t hdl, type_ **x) \
{ \
dds__retcode_t rc; \
dds_entity *e; \
if ((rc = dds_entity_lock (hdl, kind_, &e)) != DDS_RETCODE_OK) \
return rc; \
*x = (type_ *) e; \
return DDS_RETCODE_OK; \
} \
\
qualifier_ void type_##_unlock (type_ *x) \
{ \
dds_entity_unlock (&x->m_entity); \
}
#define DECL_ENTITY_LOCK_UNLOCK(qualifier_, type_) \
qualifier_ dds__retcode_t type_##_lock (dds_entity_t hdl, type_ **x); \
qualifier_ void type_##_unlock (type_ *x);
#define dds_entity_is_enabled(e, k) (((dds_entity*)e)->m_flags & DDS_ENTITY_ENABLED)
inline bool dds_entity_is_enabled (const dds_entity *e) {
return (e->m_flags & DDS_ENTITY_ENABLED) != 0;
}
#define dds_entity_status_set(e, t) (((dds_entity*)e)->m_trigger |= (((dds_entity*)e)->m_status_enable & t))
#define dds_entity_status_reset(e,t) (((dds_entity*)e)->m_trigger &= ~t)
#define dds_entity_status_match(e,t) (((dds_entity*)e)->m_trigger & t)
void dds_entity_status_set (dds_entity *e, uint32_t t);
/* The mutex needs to be unlocked when calling this because the entity can be called
* within the signal callback from other contexts. That shouldn't deadlock. */
void
dds_entity_status_signal(
_In_ dds_entity *e);
inline void dds_entity_status_reset (dds_entity *e, uint32_t t) {
e->m_trigger &= ~t;
}
inline bool dds_entity_status_match (const dds_entity *e, uint32_t t) {
return (e->m_trigger & t) != 0;
}
inline dds_entity_kind_t dds_entity_kind (const dds_entity *e) {
return (dds_entity_kind_t) (e->m_hdl & DDS_ENTITY_KIND_MASK);
}
inline dds_entity_kind_t dds_entity_kind_from_handle (dds_entity_t hdl) {
return (hdl > 0) ? (dds_entity_kind_t) (hdl & DDS_ENTITY_KIND_MASK) : DDS_KIND_DONTCARE;
}
void dds_entity_status_signal (dds_entity *e);
void dds_entity_invoke_listener (const dds_entity *entity, enum dds_status_id which, const void *vst);
_Check_return_ dds__retcode_t
dds_valid_hdl(
@ -74,8 +99,6 @@ void
dds_entity_unlock(
_Inout_ dds_entity *e);
#define dds_entity_kind(hdl) ((hdl > 0) ? (hdl & DDS_ENTITY_KIND_MASK) : 0)
_Check_return_ dds__retcode_t
dds_entity_observer_register_nl(
_In_ dds_entity* observed,

View file

@ -18,4 +18,6 @@ _Must_inspect_result_ dds_guardcond*
dds_create_guardcond(
_In_ dds_participant *pp);
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_guardcond, DDS_KIND_COND_GUARD)
#endif

View file

@ -19,11 +19,8 @@
extern "C" {
#endif
/*
* Listener API (internal & external) are present in
* dds__types.h
* ddsc/dds_public_listener.h
*/
void dds_override_inherited_listener (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src);
void dds_inherit_listener (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src);
#if defined (__cplusplus)
}

View file

@ -12,10 +12,13 @@
#ifndef _DDS_PPANT_H_
#define _DDS_PPANT_H_
#include "dds__entity.h"
#if defined (__cplusplus)
extern "C" {
#endif
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_participant, DDS_KIND_PARTICIPANT)
#if defined (__cplusplus)
}

View file

@ -13,6 +13,7 @@
#define _DDS_READER_H_
#include "dds__types.h"
#include "dds__entity.h"
#if defined (__cplusplus)
extern "C" {
@ -22,6 +23,8 @@ struct status_cb_data;
void dds_reader_status_cb (void *entity, const struct status_cb_data * data);
void dds_reader_data_available_cb (struct dds_reader *entity);
/*
dds_reader_lock_samples: Returns number of samples in read cache and locks the
reader cache to make sure that the samples content doesn't change.
@ -40,8 +43,7 @@ struct nn_rsample_info;
struct nn_rdata;
DDS_EXPORT void dds_reader_ddsi2direct (dds_entity_t entity, void (*cb) (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, void *arg), void *cbarg);
#define dds_reader_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_READER, (dds_entity**)obj)
#define dds_reader_unlock(obj) dds_entity_unlock((dds_entity*)obj);
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_reader, DDS_KIND_READER)
#if defined (__cplusplus)
}

View file

@ -13,13 +13,13 @@
#define _DDS_TOPIC_H_
#include "dds__types.h"
#include "dds__entity.h"
#if defined (__cplusplus)
extern "C" {
#endif
#define dds_topic_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_TOPIC, (dds_entity**)obj)
#define dds_topic_unlock(obj) dds_entity_unlock((dds_entity*)obj);
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_topic, DDS_KIND_TOPIC)
extern struct ddsi_sertopic * dds_topic_lookup (dds_domain * domain, const char * name);
extern void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic * st);

View file

@ -59,22 +59,35 @@ typedef bool (*dds_querycondition_filter_with_ctx_fn) (const void * sample, cons
/* The listener struct. */
typedef struct c_listener {
struct dds_listener {
uint32_t inherited;
dds_on_inconsistent_topic_fn on_inconsistent_topic;
void *on_inconsistent_topic_arg;
dds_on_liveliness_lost_fn on_liveliness_lost;
void *on_liveliness_lost_arg;
dds_on_offered_deadline_missed_fn on_offered_deadline_missed;
void *on_offered_deadline_missed_arg;
dds_on_offered_incompatible_qos_fn on_offered_incompatible_qos;
void *on_offered_incompatible_qos_arg;
dds_on_data_on_readers_fn on_data_on_readers;
void *on_data_on_readers_arg;
dds_on_sample_lost_fn on_sample_lost;
void *on_sample_lost_arg;
dds_on_data_available_fn on_data_available;
void *on_data_available_arg;
dds_on_sample_rejected_fn on_sample_rejected;
void *on_sample_rejected_arg;
dds_on_liveliness_changed_fn on_liveliness_changed;
void *on_liveliness_changed_arg;
dds_on_requested_deadline_missed_fn on_requested_deadline_missed;
void *on_requested_deadline_missed_arg;
dds_on_requested_incompatible_qos_fn on_requested_incompatible_qos;
void *on_requested_incompatible_qos_arg;
dds_on_publication_matched_fn on_publication_matched;
void *on_publication_matched_arg;
dds_on_subscription_matched_fn on_subscription_matched;
void *arg;
} c_listener_t;
void *on_subscription_matched_arg;
};
/* Entity flag values */
@ -98,7 +111,6 @@ typedef struct dds_entity_deriver {
dds_return_t (*delete)(struct dds_entity *e);
dds_return_t (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled);
dds_return_t (*validate_status)(uint32_t mask);
dds_return_t (*propagate_status)(struct dds_entity *e, uint32_t mask, bool set);
dds_return_t (*get_instance_hdl)(struct dds_entity *e, dds_instance_handle_t *i);
}
dds_entity_deriver;
@ -126,15 +138,18 @@ typedef struct dds_entity
dds_qos_t * m_qos;
dds_domainid_t m_domainid;
nn_guid_t m_guid;
uint32_t m_status_enable;
uint32_t m_flags;
uint32_t m_cb_count;
os_mutex m_mutex;
os_cond m_cond;
c_listener_t m_listener;
uint32_t m_trigger;
os_mutex m_observers_lock;
os_cond m_observers_cond;
dds_listener_t m_listener;
uint32_t m_trigger;
uint32_t m_status_enable;
uint32_t m_cb_count;
dds_entity_observer *m_observers;
struct ut_handlelink *m_hdllink;
}
dds_entity;

View file

@ -18,8 +18,7 @@
extern "C" {
#endif
#define dds_writer_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_WRITER, (dds_entity**)obj)
#define dds_writer_unlock(obj) dds_entity_unlock((dds_entity*)obj);
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_writer, DDS_KIND_WRITER)
#if defined (__cplusplus)
}

View file

@ -148,19 +148,17 @@ dds_entity_t dds__get_builtin_subscriber (dds_entity_t e)
dds_return_t ret;
dds_entity_t pp;
dds_participant *p;
dds_entity *part_entity;
if ((pp = dds_get_participant (e)) <= 0)
return pp;
if ((ret = dds_entity_lock (pp, DDS_KIND_PARTICIPANT, &part_entity)) < 0)
if ((ret = dds_participant_lock (pp, &p)) != DDS_RETCODE_OK)
return ret;
p = (dds_participant *) part_entity;
if (p->m_builtin_subscriber <= 0) {
p->m_builtin_subscriber = dds__create_builtin_subscriber (part_entity);
p->m_builtin_subscriber = dds__create_builtin_subscriber (&p->m_entity);
}
sub = p->m_builtin_subscriber;
dds_entity_unlock(part_entity);
dds_participant_unlock(p);
return sub;
}

View file

@ -27,7 +27,7 @@ dds_begin_coherent(
{
dds_return_t ret;
switch(dds_entity_kind(entity)) {
switch(dds_entity_kind_from_handle(entity)) {
case DDS_KIND_READER:
case DDS_KIND_WRITER:
/* Invoking on a writer/reader behaves as if invoked on
@ -58,7 +58,7 @@ dds_end_coherent(
{
dds_return_t ret;
switch(dds_entity_kind(entity)) {
switch(dds_entity_kind_from_handle(entity)) {
case DDS_KIND_READER:
case DDS_KIND_WRITER:
/* Invoking on a writer/reader behaves as if invoked on

View file

@ -27,7 +27,7 @@ const ut_avlTreedef_t dds_domaintree_def = UT_AVL_TREEDEF_INITIALIZER
dds_domain * dds_domain_find_locked (dds_domainid_t id)
{
return (dds_domain*) ut_avlLookup (&dds_domaintree_def, &dds_global.m_domains, &id);
return ut_avlLookup (&dds_domaintree_def, &dds_global.m_domains, &id);
}
dds_domain * dds_domain_create (dds_domainid_t id)

File diff suppressed because it is too large Load diff

View file

@ -13,127 +13,89 @@
#include <string.h>
#include "dds__reader.h"
#include "dds__guardcond.h"
#include "dds__entity.h"
#include "dds__participant.h"
#include "dds__err.h"
#include "ddsi/q_ephash.h"
#include "ddsi/q_entity.h"
#include "ddsi/q_thread.h"
_Must_inspect_result_ dds_guardcond*
dds_create_guardcond(
_In_ dds_participant *pp)
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_guardcond)
dds_entity_t dds_create_guardcondition (dds_entity_t participant)
{
dds_participant *pp;
dds__retcode_t rc;
if ((rc = dds_participant_lock (participant, &pp)) != DDS_RETCODE_OK)
return DDS_ERRNO (rc);
else
{
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;
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 {
DDS_ERROR("Error occurred on locking reader\n");
hdl = DDS_ERRNO(rc);
}
dds_entity_t hdl = dds_entity_init (&gcond->m_entity, &pp->m_entity, DDS_KIND_COND_GUARD, NULL, NULL, 0);
dds_participant_unlock (pp);
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 dds_set_guardcondition (dds_entity_t condition, bool triggered)
{
dds_return_t ret;
dds_guardcond *gcond;
dds__retcode_t rc;
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 {
DDS_ERROR("Argument condition is not valid\n");
ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_GUARD));
}
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)
if ((rc = dds_guardcond_lock (condition, &gcond)) != DDS_RETCODE_OK)
return DDS_ERRNO (dds_valid_hdl (condition, DDS_KIND_COND_GUARD));
else
{
os_mutexLock (&gcond->m_entity.m_observers_lock);
if (triggered)
dds_entity_status_set (&gcond->m_entity, DDS_WAITSET_TRIGGER_STATUS);
else
dds_entity_status_reset (&gcond->m_entity, DDS_WAITSET_TRIGGER_STATUS);
os_mutexUnlock (&gcond->m_entity.m_observers_lock);
dds_guardcond_unlock (gcond);
return DDS_RETCODE_OK;
}
}
dds_return_t dds_read_guardcondition (dds_entity_t condition, bool *triggered)
{
dds_return_t ret;
dds_guardcond *gcond;
dds__retcode_t rc;
if (triggered != NULL) {
if (triggered == NULL)
return DDS_ERRNO (DDS_RETCODE_BAD_PARAMETER);
*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 {
DDS_ERROR("Argument condition is not valid\n");
ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_GUARD));
}
} else {
DDS_ERROR("Argument triggered is NULL\n");
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
}
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)
if ((rc = dds_guardcond_lock (condition, &gcond)) != DDS_RETCODE_OK)
return DDS_ERRNO (dds_valid_hdl (condition, DDS_KIND_COND_GUARD));
else
{
os_mutexLock (&gcond->m_entity.m_observers_lock);
*triggered = dds_entity_status_match (&gcond->m_entity, DDS_WAITSET_TRIGGER_STATUS);
os_mutexUnlock (&gcond->m_entity.m_observers_lock);
dds_guardcond_unlock (gcond);
return DDS_RETCODE_OK;
}
}
dds_return_t dds_take_guardcondition (dds_entity_t condition, bool *triggered)
{
dds_return_t ret;
dds_guardcond *gcond;
dds__retcode_t rc;
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 {
DDS_ERROR("Argument condition is not valid\n");
ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_GUARD));
}
} else {
DDS_ERROR("Argument triggered is NULL\n");
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
}
if (triggered == NULL)
return DDS_ERRNO (DDS_RETCODE_BAD_PARAMETER);
return ret;
*triggered = false;
if ((rc = dds_guardcond_lock (condition, &gcond)) != DDS_RETCODE_OK)
return DDS_ERRNO (dds_valid_hdl (condition, DDS_KIND_COND_GUARD));
else
{
os_mutexLock (&gcond->m_entity.m_observers_lock);
*triggered = dds_entity_status_match (&gcond->m_entity, DDS_WAITSET_TRIGGER_STATUS);
dds_entity_status_reset (&gcond->m_entity, DDS_WAITSET_TRIGGER_STATUS);
os_mutexUnlock (&gcond->m_entity.m_observers_lock);
dds_guardcond_unlock (gcond);
return DDS_RETCODE_OK;
}
}

View file

@ -81,19 +81,20 @@ dds_instance_remove(
}
}
static const dds_topic*
dds_instance_info(
_In_ dds_entity *e)
static const dds_topic *dds_instance_info (dds_entity *e)
{
const dds_topic *topic = NULL;
assert (e);
assert ((dds_entity_kind(e->m_hdl) == DDS_KIND_READER) || (dds_entity_kind(e->m_hdl) == DDS_KIND_WRITER));
if (dds_entity_kind(e->m_hdl) == DDS_KIND_READER) {
const dds_topic *topic;
switch (dds_entity_kind (e))
{
case DDS_KIND_READER:
topic = ((dds_reader*) e)->m_topic;
} else {
break;
case DDS_KIND_WRITER:
topic = ((dds_writer*) e)->m_topic;
break;
default:
assert (0);
topic = NULL;
}
return topic;
}
@ -127,7 +128,7 @@ dds_register_instance(
struct thread_state1 * const thr = lookup_thread_state();
const bool asleep = !vtime_awake_p(thr->vtime);
struct ddsi_tkmap_instance * inst;
dds_entity *wr;
dds_writer *wr;
dds_return_t ret;
dds__retcode_t rc;
@ -141,7 +142,7 @@ dds_register_instance(
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
goto err;
}
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr);
rc = dds_writer_lock(writer, &wr);
if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n");
ret = DDS_ERRNO(rc);
@ -150,7 +151,7 @@ dds_register_instance(
if (asleep) {
thread_state_awake(thr);
}
inst = dds_instance_find (((dds_writer*) wr)->m_topic, data, true);
inst = dds_instance_find (wr->m_topic, data, true);
if(inst != NULL){
*handle = inst->m_iid;
ret = DDS_RETCODE_OK;
@ -161,7 +162,7 @@ dds_register_instance(
if (asleep) {
thread_state_asleep(thr);
}
dds_entity_unlock(wr);
dds_writer_unlock(wr);
err:
return ret;
}
@ -197,8 +198,7 @@ dds_unregister_instance_ts(
dds__retcode_t rc;
bool autodispose = true;
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
void * sample = (void*) data;
dds_entity *wr;
dds_writer *wr;
if (data == NULL){
DDS_ERROR("Argument data is NULL\n");
@ -210,28 +210,28 @@ dds_unregister_instance_ts(
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
goto err;
}
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr);
rc = dds_writer_lock(writer, &wr);
if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n");
ret = DDS_ERRNO(rc);
goto err;
}
if (wr->m_qos) {
dds_qget_writer_data_lifecycle (wr->m_qos, &autodispose);
if (wr->m_entity.m_qos) {
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
}
if (asleep) {
thread_state_awake(thr);
}
if (autodispose) {
dds_instance_remove (((dds_writer*) wr)->m_topic, data, DDS_HANDLE_NIL);
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
action |= DDS_WR_DISPOSE_BIT;
}
ret = dds_write_impl ((dds_writer*)wr, sample, timestamp, action);
ret = dds_write_impl (wr, data, timestamp, action);
if (asleep) {
thread_state_asleep(thr);
}
dds_entity_unlock(wr);
dds_writer_unlock(wr);
err:
return ret;
}
@ -249,21 +249,21 @@ dds_unregister_instance_ih_ts(
dds__retcode_t rc;
bool autodispose = true;
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
dds_entity *wr;
dds_writer *wr;
struct ddsi_tkmap_instance *tk;
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr);
rc = dds_writer_lock(writer, &wr);
if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n");
ret = DDS_ERRNO(rc);
goto err;
}
if (wr->m_qos) {
dds_qget_writer_data_lifecycle (wr->m_qos, &autodispose);
if (wr->m_entity.m_qos) {
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
}
if (autodispose) {
dds_instance_remove (((dds_writer*) wr)->m_topic, NULL, handle);
dds_instance_remove (wr->m_topic, NULL, handle);
action |= DDS_WR_DISPOSE_BIT;
}
@ -272,11 +272,11 @@ dds_unregister_instance_ih_ts(
}
tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
if (tk) {
struct ddsi_sertopic *tp = ((dds_writer*) wr)->m_topic->m_stopic;
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk);
ret = dds_write_impl ((dds_writer*)wr, sample, timestamp, action);
ret = dds_write_impl (wr, sample, timestamp, action);
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
} else {
DDS_ERROR("No instance related with the provided handle is found\n");
@ -285,7 +285,7 @@ dds_unregister_instance_ih_ts(
if (asleep) {
thread_state_asleep(thr);
}
dds_entity_unlock(wr);
dds_writer_unlock(wr);
err:
return ret;
}
@ -392,7 +392,7 @@ dds_dispose_ih_ts(
thread_state_awake(thr);
}
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) != NULL) {
struct ddsi_sertopic *tp = ((dds_writer*) wr)->m_topic->m_stopic;
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk);

View file

@ -13,161 +13,198 @@
#include "ddsc/dds.h"
#include "dds__listener.h"
_Ret_notnull_
dds_listener_t*
dds_create_listener(_In_opt_ void* arg)
dds_listener_t *dds_create_listener (void* arg)
{
c_listener_t *l = dds_alloc(sizeof(*l));
dds_listener_t *l = dds_alloc (sizeof (*l));
dds_reset_listener (l);
l->arg = arg;
l->on_inconsistent_topic_arg = arg;
l->on_liveliness_lost_arg = arg;
l->on_offered_deadline_missed_arg = arg;
l->on_offered_incompatible_qos_arg = arg;
l->on_data_on_readers_arg = arg;
l->on_sample_lost_arg = arg;
l->on_data_available_arg = arg;
l->on_sample_rejected_arg = arg;
l->on_liveliness_changed_arg = arg;
l->on_requested_deadline_missed_arg = arg;
l->on_requested_incompatible_qos_arg = arg;
l->on_publication_matched_arg = arg;
l->on_subscription_matched_arg = arg;
return l;
}
_Ret_notnull_
dds_listener_t*
dds_listener_create(_In_opt_ void* arg)
dds_listener_t *dds_listener_create (void* arg)
{
return dds_create_listener (arg);
}
void
dds_delete_listener(_In_ _Post_invalid_ dds_listener_t * __restrict listener)
void dds_delete_listener (dds_listener_t * __restrict listener)
{
if (listener) {
dds_free (listener);
}
}
void
dds_listener_delete(_In_ _Post_invalid_ dds_listener_t * __restrict listener)
void dds_listener_delete (dds_listener_t * __restrict listener)
{
dds_delete_listener (listener);
}
void
dds_reset_listener(_Out_ dds_listener_t * __restrict listener)
void dds_reset_listener (dds_listener_t * __restrict listener)
{
if (listener) {
c_listener_t *l = listener;
l->on_data_available = DDS_LUNSET;
l->on_data_on_readers = DDS_LUNSET;
l->on_inconsistent_topic = DDS_LUNSET;
l->on_liveliness_changed = DDS_LUNSET;
l->on_liveliness_lost = DDS_LUNSET;
l->on_offered_deadline_missed = DDS_LUNSET;
l->on_offered_incompatible_qos = DDS_LUNSET;
l->on_publication_matched = DDS_LUNSET;
l->on_requested_deadline_missed = DDS_LUNSET;
l->on_requested_incompatible_qos = DDS_LUNSET;
l->on_sample_lost = DDS_LUNSET;
l->on_sample_rejected = DDS_LUNSET;
l->on_subscription_matched = DDS_LUNSET;
} else {
DDS_ERROR("Argument listener is NULL\n");
if (listener)
{
dds_listener_t * const l = listener;
l->inherited = 0;
l->on_data_available = 0;
l->on_data_on_readers = 0;
l->on_inconsistent_topic = 0;
l->on_liveliness_changed = 0;
l->on_liveliness_lost = 0;
l->on_offered_deadline_missed = 0;
l->on_offered_incompatible_qos = 0;
l->on_publication_matched = 0;
l->on_requested_deadline_missed = 0;
l->on_requested_incompatible_qos = 0;
l->on_sample_lost = 0;
l->on_sample_rejected = 0;
l->on_subscription_matched = 0;
}
}
void
dds_listener_reset(_Out_ dds_listener_t * __restrict listener)
void dds_listener_reset (dds_listener_t * __restrict listener)
{
dds_reset_listener (listener);
}
void
dds_copy_listener(_Out_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
void dds_copy_listener (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
{
const c_listener_t *srcl = src;
c_listener_t *dstl = dst;
if(!src){
DDS_ERROR("Argument source(src) is NULL\n");
return ;
}
if(!dst){
DDS_ERROR("Argument destination(dst) is NULL\n");
return ;
}
dstl->on_data_available = srcl->on_data_available;
dstl->on_data_on_readers = srcl->on_data_on_readers;
dstl->on_inconsistent_topic = srcl->on_inconsistent_topic;
dstl->on_liveliness_changed = srcl->on_liveliness_changed;
dstl->on_liveliness_lost = srcl->on_liveliness_lost;
dstl->on_offered_deadline_missed = srcl->on_offered_deadline_missed;
dstl->on_offered_incompatible_qos = srcl->on_offered_incompatible_qos;
dstl->on_publication_matched = srcl->on_publication_matched;
dstl->on_requested_deadline_missed = srcl->on_requested_deadline_missed;
dstl->on_requested_incompatible_qos = srcl->on_requested_incompatible_qos;
dstl->on_sample_lost = srcl->on_sample_lost;
dstl->on_sample_rejected = srcl->on_sample_rejected;
dstl->on_subscription_matched = srcl->on_subscription_matched;
dstl->arg = srcl->arg;
if (dst && src)
*dst = *src;
}
void
dds_listener_copy(_Out_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
void dds_listener_copy(dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
{
dds_copy_listener (dst, src);
}
void
dds_merge_listener (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
static bool dds_combine_listener_merge (uint32_t inherited, void (*dst)(void), void (*src)(void))
{
const c_listener_t *srcl = src;
c_listener_t *dstl = dst;
(void)inherited;
(void)src;
return dst == 0;
}
if(!src){
DDS_ERROR("Argument source(src) is NULL\n");
return ;
static bool dds_combine_listener_override_inherited (uint32_t inherited, void (*dst)(void), void (*src)(void))
{
(void)dst;
(void)src;
return inherited;
}
if(!dst){
DDS_ERROR("Argument destination(dst) is NULL\n");
return ;
static void dds_combine_listener (bool (*op) (uint32_t inherited, void (*)(void), void (*)(void)), dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
{
if (op (dst->inherited & DDS_DATA_AVAILABLE_STATUS, (void (*)(void)) dst->on_data_available, (void (*)(void)) src->on_data_available))
{
dst->inherited |= DDS_DATA_AVAILABLE_STATUS;
dst->on_data_available = src->on_data_available;
dst->on_data_available_arg = src->on_data_available_arg;
}
if (dstl->on_data_available == DDS_LUNSET) {
dstl->on_data_available = srcl->on_data_available;
if (op (dst->inherited & DDS_DATA_ON_READERS_STATUS, (void (*)(void)) dst->on_data_on_readers, (void (*)(void)) src->on_data_on_readers))
{
dst->inherited |= DDS_DATA_ON_READERS_STATUS;
dst->on_data_on_readers = src->on_data_on_readers;
dst->on_data_on_readers_arg = src->on_data_on_readers_arg;
}
if (dstl->on_data_on_readers == DDS_LUNSET) {
dstl->on_data_on_readers = srcl->on_data_on_readers;
if (op (dst->inherited & DDS_INCONSISTENT_TOPIC_STATUS, (void (*)(void)) dst->on_inconsistent_topic, (void (*)(void)) src->on_inconsistent_topic))
{
dst->inherited |= DDS_INCONSISTENT_TOPIC_STATUS;
dst->on_inconsistent_topic = src->on_inconsistent_topic;
dst->on_inconsistent_topic_arg = src->on_inconsistent_topic_arg;
}
if (dstl->on_inconsistent_topic == DDS_LUNSET) {
dstl->on_inconsistent_topic = srcl->on_inconsistent_topic;
if (op (dst->inherited & DDS_LIVELINESS_CHANGED_STATUS, (void (*)(void)) dst->on_liveliness_changed, (void (*)(void)) src->on_liveliness_changed))
{
dst->inherited |= DDS_LIVELINESS_CHANGED_STATUS;
dst->on_liveliness_changed = src->on_liveliness_changed;
dst->on_liveliness_changed_arg = src->on_liveliness_changed_arg;
}
if (dstl->on_liveliness_changed == DDS_LUNSET) {
dstl->on_liveliness_changed = srcl->on_liveliness_changed;
if (op (dst->inherited & DDS_LIVELINESS_LOST_STATUS, (void (*)(void)) dst->on_liveliness_lost, (void (*)(void)) src->on_liveliness_lost))
{
dst->inherited |= DDS_LIVELINESS_LOST_STATUS;
dst->on_liveliness_lost = src->on_liveliness_lost;
dst->on_liveliness_lost_arg = src->on_liveliness_lost_arg;
}
if (dstl->on_liveliness_lost == DDS_LUNSET) {
dstl->on_liveliness_lost = srcl->on_liveliness_lost;
if (op (dst->inherited & DDS_OFFERED_DEADLINE_MISSED_STATUS, (void (*)(void)) dst->on_offered_deadline_missed, (void (*)(void)) src->on_offered_deadline_missed))
{
dst->inherited |= DDS_OFFERED_DEADLINE_MISSED_STATUS;
dst->on_offered_deadline_missed = src->on_offered_deadline_missed;
dst->on_offered_deadline_missed_arg = src->on_offered_deadline_missed_arg;
}
if (dstl->on_offered_deadline_missed == DDS_LUNSET) {
dstl->on_offered_deadline_missed = srcl->on_offered_deadline_missed;
if (op (dst->inherited & DDS_OFFERED_INCOMPATIBLE_QOS_STATUS, (void (*)(void)) dst->on_offered_incompatible_qos, (void (*)(void)) src->on_offered_incompatible_qos))
{
dst->inherited |= DDS_OFFERED_INCOMPATIBLE_QOS_STATUS;
dst->on_offered_incompatible_qos = src->on_offered_incompatible_qos;
dst->on_offered_incompatible_qos_arg = src->on_offered_incompatible_qos_arg;
}
if (dstl->on_offered_incompatible_qos == DDS_LUNSET) {
dstl->on_offered_incompatible_qos = srcl->on_offered_incompatible_qos;
if (op (dst->inherited & DDS_PUBLICATION_MATCHED_STATUS, (void (*)(void)) dst->on_publication_matched, (void (*)(void)) src->on_publication_matched))
{
dst->inherited |= DDS_PUBLICATION_MATCHED_STATUS;
dst->on_publication_matched = src->on_publication_matched;
dst->on_publication_matched_arg = src->on_publication_matched_arg;
}
if (dstl->on_publication_matched == DDS_LUNSET) {
dstl->on_publication_matched = srcl->on_publication_matched;
if (op (dst->inherited & DDS_REQUESTED_DEADLINE_MISSED_STATUS, (void (*)(void)) dst->on_requested_deadline_missed, (void (*)(void)) src->on_requested_deadline_missed))
{
dst->inherited |= DDS_REQUESTED_DEADLINE_MISSED_STATUS;
dst->on_requested_deadline_missed = src->on_requested_deadline_missed;
dst->on_requested_deadline_missed_arg = src->on_requested_deadline_missed_arg;
}
if (dstl->on_requested_deadline_missed == DDS_LUNSET) {
dstl->on_requested_deadline_missed = srcl->on_requested_deadline_missed;
if (op (dst->inherited & DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS, (void (*)(void)) dst->on_requested_incompatible_qos, (void (*)(void)) src->on_requested_incompatible_qos))
{
dst->inherited |= DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS;
dst->on_requested_incompatible_qos = src->on_requested_incompatible_qos;
dst->on_requested_incompatible_qos_arg = src->on_requested_incompatible_qos_arg;
}
if (dstl->on_requested_incompatible_qos == DDS_LUNSET) {
dstl->on_requested_incompatible_qos = srcl->on_requested_incompatible_qos;
if (op (dst->inherited & DDS_SAMPLE_LOST_STATUS, (void (*)(void)) dst->on_sample_lost, (void (*)(void)) src->on_sample_lost))
{
dst->inherited |= DDS_SAMPLE_LOST_STATUS;
dst->on_sample_lost = src->on_sample_lost;
dst->on_sample_lost_arg = src->on_sample_lost_arg;
}
if (dstl->on_sample_lost == DDS_LUNSET) {
dstl->on_sample_lost = srcl->on_sample_lost;
if (op (dst->inherited & DDS_SAMPLE_REJECTED_STATUS, (void (*)(void)) dst->on_sample_rejected, (void (*)(void)) src->on_sample_rejected))
{
dst->inherited |= DDS_SAMPLE_REJECTED_STATUS;
dst->on_sample_rejected = src->on_sample_rejected;
dst->on_sample_rejected_arg = src->on_sample_rejected_arg;
}
if (dstl->on_sample_rejected == DDS_LUNSET) {
dstl->on_sample_rejected = srcl->on_sample_rejected;
}
if (dstl->on_subscription_matched == DDS_LUNSET) {
dstl->on_subscription_matched = srcl->on_subscription_matched;
if (op (dst->inherited & DDS_SUBSCRIPTION_MATCHED_STATUS, (void (*)(void)) dst->on_subscription_matched, (void (*)(void)) src->on_subscription_matched))
{
dst->inherited |= DDS_SUBSCRIPTION_MATCHED_STATUS;
dst->on_subscription_matched = src->on_subscription_matched;
dst->on_subscription_matched_arg = src->on_subscription_matched_arg;
}
}
void
dds_listener_merge (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
void dds_override_inherited_listener (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
{
if (dst && src)
dds_combine_listener (dds_combine_listener_override_inherited, dst, src);
}
void dds_inherit_listener (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
{
if (dst && src)
dds_combine_listener (dds_combine_listener_merge, dst, src);
}
void dds_merge_listener (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
{
if (dst && src)
{
uint32_t inherited = dst->inherited;
dds_combine_listener (dds_combine_listener_merge, dst, src);
dst->inherited = inherited;
}
}
void dds_listener_merge (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
{
dds_merge_listener(dst, src);
}
@ -180,7 +217,7 @@ void
dds_lset_data_available (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_available_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_data_available = callback;
listener->on_data_available = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -190,7 +227,7 @@ void
dds_lset_data_on_readers (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_on_readers_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_data_on_readers = callback;
listener->on_data_on_readers = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -200,7 +237,7 @@ void
dds_lset_inconsistent_topic (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_inconsistent_topic_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_inconsistent_topic = callback;
listener->on_inconsistent_topic = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -210,7 +247,7 @@ void
dds_lset_liveliness_changed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_changed_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_liveliness_changed = callback;
listener->on_liveliness_changed = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -220,7 +257,7 @@ void
dds_lset_liveliness_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_lost_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_liveliness_lost = callback;
listener->on_liveliness_lost = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -230,7 +267,7 @@ void
dds_lset_offered_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_deadline_missed_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_offered_deadline_missed = callback;
listener->on_offered_deadline_missed = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -240,7 +277,7 @@ void
dds_lset_offered_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_incompatible_qos_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_offered_incompatible_qos = callback;
listener->on_offered_incompatible_qos = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -250,7 +287,7 @@ void
dds_lset_publication_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_publication_matched_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_publication_matched = callback;
listener->on_publication_matched = callback;
} else {
DDS_ERROR("Argument listener is NULL");
}
@ -260,7 +297,7 @@ void
dds_lset_requested_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_deadline_missed_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_requested_deadline_missed = callback;
listener->on_requested_deadline_missed = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -270,7 +307,7 @@ void
dds_lset_requested_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_incompatible_qos_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_requested_incompatible_qos = callback;
listener->on_requested_incompatible_qos = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -280,7 +317,7 @@ void
dds_lset_sample_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_lost_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_sample_lost = callback;
listener->on_sample_lost = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -290,7 +327,7 @@ void
dds_lset_sample_rejected (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_rejected_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_sample_rejected = callback;
listener->on_sample_rejected = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -300,7 +337,7 @@ void
dds_lset_subscription_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_subscription_matched_fn callback)
{
if (listener) {
((c_listener_t*)listener)->on_subscription_matched = callback;
listener->on_subscription_matched = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
@ -321,7 +358,7 @@ dds_lget_data_available (_In_ const dds_listener_t * __restrict listener, _Outpt
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_data_available;
*callback = listener->on_data_available;
}
void
@ -335,7 +372,7 @@ dds_lget_data_on_readers (_In_ const dds_listener_t * __restrict listener, _Outp
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_data_on_readers;
*callback = listener->on_data_on_readers;
}
void dds_lget_inconsistent_topic (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_inconsistent_topic_fn *callback)
@ -348,7 +385,7 @@ void dds_lget_inconsistent_topic (_In_ const dds_listener_t * __restrict listene
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_inconsistent_topic;
*callback = listener->on_inconsistent_topic;
}
void
@ -362,7 +399,7 @@ dds_lget_liveliness_changed (_In_ const dds_listener_t * __restrict listener, _O
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_liveliness_changed;
*callback = listener->on_liveliness_changed;
}
void
@ -376,7 +413,7 @@ dds_lget_liveliness_lost (_In_ const dds_listener_t * __restrict listener, _Outp
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_liveliness_lost;
*callback = listener->on_liveliness_lost;
}
void
@ -390,7 +427,7 @@ dds_lget_offered_deadline_missed (_In_ const dds_listener_t * __restrict listene
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_offered_deadline_missed;
*callback = listener->on_offered_deadline_missed;
}
void
@ -404,7 +441,7 @@ dds_lget_offered_incompatible_qos (_In_ const dds_listener_t * __restrict listen
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_offered_incompatible_qos;
*callback = listener->on_offered_incompatible_qos;
}
void
@ -418,7 +455,7 @@ dds_lget_publication_matched (_In_ const dds_listener_t * __restrict listener, _
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_publication_matched;
*callback = listener->on_publication_matched;
}
void
@ -432,7 +469,7 @@ dds_lget_requested_deadline_missed (_In_ const dds_listener_t * __restrict liste
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_requested_deadline_missed;
*callback = listener->on_requested_deadline_missed;
}
void
@ -446,7 +483,7 @@ dds_lget_requested_incompatible_qos (_In_ const dds_listener_t * __restrict list
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_requested_incompatible_qos;
*callback = listener->on_requested_incompatible_qos;
}
void
@ -460,7 +497,7 @@ dds_lget_sample_lost (_In_ const dds_listener_t *__restrict listener, _Outptr_re
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_sample_lost;
*callback = listener->on_sample_lost;
}
void
@ -474,7 +511,7 @@ dds_lget_sample_rejected (_In_ const dds_listener_t *__restrict listener, _Outp
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_sample_rejected;
*callback = listener->on_sample_rejected;
}
void
@ -488,5 +525,5 @@ dds_lget_subscription_matched (_In_ const dds_listener_t * __restrict listener,
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = ((c_listener_t*)listener)->on_subscription_matched;
*callback = listener->on_subscription_matched;
}

View file

@ -20,6 +20,8 @@
#include "dds__err.h"
#include "dds__builtin.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_participant)
#define DDS_PARTICIPANT_STATUS_MASK 0u
/* List of created participants */
@ -51,7 +53,7 @@ dds_participant_delete(
assert(e);
assert(thr);
assert(dds_entity_kind(e->m_hdl) == DDS_KIND_PARTICIPANT);
assert(dds_entity_kind_from_handle(e->m_hdl) == DDS_KIND_PARTICIPANT);
if (asleep) {
thread_state_awake(thr);

View file

@ -149,7 +149,7 @@ dds_suspend(
{
dds_return_t ret;
if(dds_entity_kind(publisher) != DDS_KIND_PUBLISHER) {
if(dds_entity_kind_from_handle(publisher) != DDS_KIND_PUBLISHER) {
DDS_ERROR("Provided entity is not a publisher kind\n");
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
goto err;
@ -169,7 +169,7 @@ dds_resume(
{
dds_return_t ret = DDS_RETCODE_OK;
if(dds_entity_kind(publisher) != DDS_KIND_PUBLISHER) {
if(dds_entity_kind_from_handle(publisher) != DDS_KIND_PUBLISHER) {
DDS_ERROR("Provided entity is not a publisher kind\n");
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
goto err;
@ -194,7 +194,7 @@ dds_wait_for_acks(
/* TODO: CHAM-125 Currently unsupported. */
OS_UNUSED_ARG(timeout);
switch(dds_entity_kind(publisher_or_writer)) {
switch(dds_entity_kind_from_handle(publisher_or_writer)) {
case DDS_KIND_WRITER:
DDS_ERROR("Wait for acknowledgments on a writer is not being supported yet\n");
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED);

View file

@ -21,59 +21,53 @@
#include "ddsi/q_entity.h"
#include "ddsi/ddsi_sertopic.h"
static _Check_return_ dds__retcode_t
dds_read_lock(
_In_ dds_entity_t hdl,
_Out_ dds_reader **reader,
_Out_ dds_readcond **condition,
_In_ bool only_reader)
static dds__retcode_t dds_read_lock (dds_entity_t hdl, dds_reader **reader, dds_readcond **condition, bool only_reader)
{
dds__retcode_t rc;
dds_entity *entity, *parent_entity;
if ((rc = dds_entity_lock (hdl, DDS_KIND_DONTCARE, &entity)) != DDS_RETCODE_OK)
{
dds__retcode_t rc = hdl;
assert(reader);
assert(condition);
*reader = NULL;
*condition = NULL;
rc = dds_entity_lock(hdl, DDS_KIND_READER, (dds_entity**)reader);
if (rc == DDS_RETCODE_ILLEGAL_OPERATION) {
if (!only_reader) {
if ((dds_entity_kind(hdl) == DDS_KIND_COND_READ ) || (dds_entity_kind(hdl) == DDS_KIND_COND_QUERY) ){
rc = dds_entity_lock(hdl, DDS_KIND_DONTCARE, (dds_entity**)condition);
if (rc == DDS_RETCODE_OK) {
dds_entity *parent = ((dds_entity*)*condition)->m_parent;
assert(parent);
rc = dds_entity_lock(parent->m_hdl, DDS_KIND_READER, (dds_entity**)reader);
if (rc != DDS_RETCODE_OK) {
dds_entity_unlock((dds_entity*)*condition);
DDS_ERROR("Failed to lock condition reader\n");
}
} else {
DDS_ERROR("Failed to lock condition\n");
}
} else {
DDS_ERROR("Given entity is not a reader nor a condition\n");
}
} else {
DDS_ERROR("Given entity is not a reader\n");
}
} else if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Failed to lock reader\n");
}
return rc;
}
static void
dds_read_unlock(
_In_ dds_reader *reader,
_In_ dds_readcond *condition)
else if (dds_entity_kind (entity) == DDS_KIND_READER)
{
assert(reader);
dds_entity_unlock((dds_entity*)reader);
if (condition) {
dds_entity_unlock((dds_entity*)condition);
*reader = (dds_reader *) entity;
*condition = NULL;
return DDS_RETCODE_OK;
}
else if (only_reader)
{
dds_entity_unlock (entity);
DDS_ERROR ("Given entity is not a reader\n");
return DDS_RETCODE_ILLEGAL_OPERATION;
}
else if (dds_entity_kind (entity) != DDS_KIND_COND_READ && dds_entity_kind (entity) != DDS_KIND_COND_QUERY)
{
dds_entity_unlock (entity);
DDS_ERROR ("Given entity is a reader nor a condition\n");
return DDS_RETCODE_ILLEGAL_OPERATION;
}
else if ((rc = dds_entity_lock (entity->m_parent->m_hdl, DDS_KIND_READER, &parent_entity)) != DDS_RETCODE_OK)
{
dds_entity_unlock (entity);
DDS_ERROR ("Failed to lock condition's reader\n");
return rc;
}
else
{
*reader = (dds_reader *) parent_entity;
*condition = (dds_readcond *) entity;
return DDS_RETCODE_OK;
}
}
static void dds_read_unlock (dds_reader *reader, dds_readcond *condition)
{
dds_entity_unlock (&reader->m_entity);
if (condition)
dds_entity_unlock (&condition->m_entity);
}
/*
dds_read_impl: Core read/take function. Usually maxs is size of buf and si
into which samples/status are written, when set to zero is special case
@ -172,10 +166,10 @@ dds_read_impl(
ret = (dds_return_t)dds_rhc_read(rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
}
/* read/take resets data available status */
dds_entity_status_reset(rd, DDS_DATA_AVAILABLE_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
/* reset DATA_ON_READERS status on subscriber after successful read/take */
if (dds_entity_kind(((dds_entity*)rd)->m_parent->m_hdl) == DDS_KIND_SUBSCRIBER) {
dds_entity_status_reset(((dds_entity*)rd)->m_parent, DDS_DATA_ON_READERS_STATUS);
if (dds_entity_kind_from_handle(rd->m_entity.m_parent->m_hdl) == DDS_KIND_SUBSCRIBER) {
dds_entity_status_reset(rd->m_entity.m_parent, DDS_DATA_ON_READERS_STATUS);
}
dds_read_unlock(rd, cond);
@ -227,13 +221,13 @@ dds_readcdr_impl(
);
/* read/take resets data available status */
dds_entity_status_reset(rd, DDS_DATA_AVAILABLE_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
/* reset DATA_ON_READERS status on subscriber after successful read/take */
if (dds_entity_kind(((dds_entity*)rd)->m_parent->m_hdl) == DDS_KIND_SUBSCRIBER)
if (dds_entity_kind_from_handle(rd->m_entity.m_parent->m_hdl) == DDS_KIND_SUBSCRIBER)
{
dds_entity_status_reset(((dds_entity*)rd)->m_parent, DDS_DATA_ON_READERS_STATUS);
dds_entity_status_reset(rd->m_entity.m_parent, DDS_DATA_ON_READERS_STATUS);
}
dds_read_unlock(rd, cond);
} else {

View file

@ -41,7 +41,7 @@ dds_create_readcond(
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
cond->m_rd_guid = ((dds_entity*)rd)->m_guid;
cond->m_rd_guid = rd->m_entity.m_guid;
dds_rhc_add_readcondition (cond);
return cond;
}
@ -70,17 +70,13 @@ dds_create_readcondition(
return hdl;
}
_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY) )
dds_entity_t
dds_get_datareader(
_In_ dds_entity_t condition)
dds_entity_t dds_get_datareader (dds_entity_t condition)
{
dds_entity_t hdl;
if (dds_entity_kind(condition) == DDS_KIND_COND_READ) {
if (dds_entity_kind_from_handle(condition) == DDS_KIND_COND_READ) {
hdl = dds_get_parent(condition);
} else if (dds_entity_kind(condition) == DDS_KIND_COND_QUERY) {
} else if (dds_entity_kind_from_handle(condition) == DDS_KIND_COND_QUERY) {
hdl = dds_get_parent(condition);
} else {
DDS_ERROR("Argument condition is not valid\n");
@ -90,39 +86,26 @@ dds_get_datareader(
return hdl;
}
_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY) )
_Check_return_ dds_return_t
dds_get_mask(
_In_ dds_entity_t condition,
_Out_ uint32_t *mask)
dds_return_t dds_get_mask (dds_entity_t condition, uint32_t *mask)
{
dds_return_t ret;
dds_readcond *cond;
dds_entity *entity;
dds__retcode_t rc;
if (mask != NULL) {
*mask = 0;
if ((dds_entity_kind(condition) == DDS_KIND_COND_READ ) ||
(dds_entity_kind(condition) == DDS_KIND_COND_QUERY) ){
rc = dds_entity_lock(condition, DDS_KIND_DONTCARE, (dds_entity**)&cond);
if (rc == DDS_RETCODE_OK) {
*mask = (cond->m_sample_states | cond->m_view_states | cond->m_instance_states);
dds_entity_unlock((dds_entity*)cond);
ret = DDS_RETCODE_OK;
} else{
DDS_ERROR("Error occurred on locking condition\n");
ret = DDS_ERRNO(rc);
}
} else {
DDS_ERROR("Argument condition is not valid\n");
ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_READ));
}
} else {
DDS_ERROR("Argument mask is NULL\n");
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
}
if (mask == NULL)
return DDS_ERRNO (DDS_RETCODE_BAD_PARAMETER);
return ret;
if ((rc = dds_entity_lock (condition, DDS_KIND_DONTCARE, &entity)) != DDS_RETCODE_OK)
return DDS_ERRNO (rc);
else if (dds_entity_kind (entity) != DDS_KIND_COND_READ && dds_entity_kind (entity) != DDS_KIND_COND_QUERY)
{
dds_entity_unlock (entity);
return DDS_ERRNO (dds_valid_hdl (condition, DDS_KIND_COND_READ));
}
else
{
dds_readcond *cond = (dds_readcond *) entity;
*mask = (cond->m_sample_states | cond->m_view_states | cond->m_instance_states);
dds_entity_unlock (entity);
return DDS_RETCODE_OK;
}
}

View file

@ -19,6 +19,7 @@
#include "dds__init.h"
#include "dds__rhc.h"
#include "dds__err.h"
#include "dds__topic.h"
#include "ddsi/q_entity.h"
#include "ddsi/q_thread.h"
#include "dds__builtin.h"
@ -27,6 +28,7 @@
#include "os/os.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_reader)
#define DDS_READER_STATUS_MASK \
DDS_SAMPLE_REJECTED_STATUS |\
@ -160,180 +162,196 @@ dds_reader_status_validate(
DDS_RETCODE_OK;
}
void
dds_reader_status_cb(
void *entity,
const status_cb_data_t *data)
void dds_reader_data_available_cb (struct dds_reader *rd)
{
dds_reader *rd;
dds__retcode_t rc;
void *metrics = NULL;
/* DATA_AVAILABLE is special in two ways: firstly, it should first try
DATA_ON_READERS on the line of ancestors, and if not consumed set the
status on the subscriber; secondly it is the only one for which
overhead really matters. Otherwise, it is pretty much like
dds_reader_status_cb. */
struct dds_listener const * const lst = &rd->m_entity.m_listener;
dds_entity * const sub = rd->m_entity.m_parent;
os_mutexLock (&rd->m_entity.m_observers_lock);
while (rd->m_entity.m_cb_count > 0)
os_condWait (&rd->m_entity.m_observers_cond, &rd->m_entity.m_observers_lock);
rd->m_entity.m_cb_count++;
if (lst->on_data_on_readers)
{
os_mutexUnlock (&rd->m_entity.m_observers_lock);
os_mutexLock (&sub->m_observers_lock);
while (sub->m_cb_count > 0)
os_condWait (&sub->m_observers_cond, &sub->m_observers_lock);
sub->m_cb_count++;
os_mutexUnlock (&sub->m_observers_lock);
lst->on_data_on_readers (sub->m_hdl, lst->on_data_on_readers_arg);
os_mutexLock (&rd->m_entity.m_observers_lock);
os_mutexLock (&sub->m_observers_lock);
sub->m_cb_count--;
os_condBroadcast (&sub->m_observers_cond);
os_mutexUnlock (&sub->m_observers_lock);
}
else if (rd->m_entity.m_listener.on_data_available)
{
os_mutexUnlock (&rd->m_entity.m_observers_lock);
lst->on_data_available (rd->m_entity.m_hdl, lst->on_data_available_arg);
os_mutexLock (&rd->m_entity.m_observers_lock);
}
else
{
dds_entity_status_set (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
os_mutexLock (&sub->m_observers_lock);
dds_entity_status_set (sub, DDS_DATA_ON_READERS_STATUS);
os_mutexUnlock (&sub->m_observers_lock);
}
rd->m_entity.m_cb_count--;
os_condBroadcast (&rd->m_entity.m_observers_cond);
os_mutexUnlock (&rd->m_entity.m_observers_lock);
}
void dds_reader_status_cb (void *ventity, const status_cb_data_t *data)
{
struct dds_entity * const entity = ventity;
/* When data is NULL, it means that the DDSI reader is deleted. */
if (data == NULL) {
if (data == NULL)
{
/* Release the initial claim that was done during the create. This
* will indicate that further API deletion is now possible. */
ut_handle_release(((dds_entity*)entity)->m_hdl, ((dds_entity*)entity)->m_hdllink);
ut_handle_release (entity->m_hdl, entity->m_hdllink);
return;
}
if (dds_reader_lock(((dds_entity*)entity)->m_hdl, &rd) != DDS_RETCODE_OK) {
return;
}
assert(rd == entity);
struct dds_listener const * const lst = &entity->m_listener;
enum dds_status_id status_id = (enum dds_status_id) data->raw_status_id;
bool invoke = false;
void *vst = NULL;
int32_t *reset[2] = { NULL, NULL };
/* Reset the status for possible Listener call.
* When a listener is not called, the status will be set (again). */
dds_entity_status_reset(entity, data->status);
/* DATA_AVAILABLE is handled by dds_reader_data_available_cb */
assert (status_id != DDS_DATA_AVAILABLE_STATUS_ID);
/* Serialize listener invocations -- it is somewhat sad to do this,
but then it may also be unreasonable to expect the application to
handle concurrent invocations of a single listener. The benefit
here is that it means the counters and "change" counters
can safely be incremented and/or reset while releasing
m_observers_lock for the duration of the listener call itself,
and that similarly the listener function and argument pointers
are stable */
os_mutexLock (&entity->m_observers_lock);
while (entity->m_cb_count > 0)
os_condWait (&entity->m_observers_cond, &entity->m_observers_lock);
entity->m_cb_count++;
/* Update status metrics. */
switch (data->status) {
case DDS_REQUESTED_DEADLINE_MISSED_STATUS: {
rd->m_requested_deadline_missed_status.total_count++;
rd->m_requested_deadline_missed_status.total_count_change++;
rd->m_requested_deadline_missed_status.last_instance_handle = data->handle;
metrics = (void*)&(rd->m_requested_deadline_missed_status);
dds_reader * const rd = (dds_reader *) entity;
switch (status_id) {
case DDS_REQUESTED_DEADLINE_MISSED_STATUS_ID: {
struct dds_requested_deadline_missed_status * const st = vst = &rd->m_requested_deadline_missed_status;
st->last_instance_handle = data->handle;
st->total_count++;
st->total_count_change++;
invoke = (lst->on_requested_deadline_missed != 0);
reset[0] = &st->total_count_change;
break;
}
case DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS: {
rd->m_requested_incompatible_qos_status.total_count++;
rd->m_requested_incompatible_qos_status.total_count_change++;
rd->m_requested_incompatible_qos_status.last_policy_id = data->extra;
metrics = (void*)&(rd->m_requested_incompatible_qos_status);
case DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS_ID: {
struct dds_requested_incompatible_qos_status * const st = vst = &rd->m_requested_incompatible_qos_status;
st->total_count++;
st->total_count_change++;
st->last_policy_id = data->extra;
invoke = (lst->on_requested_incompatible_qos != 0);
reset[0] = &st->total_count_change;
break;
}
case DDS_SAMPLE_LOST_STATUS: {
rd->m_sample_lost_status.total_count++;
rd->m_sample_lost_status.total_count_change++;
metrics = (void*)&(rd->m_sample_lost_status);
case DDS_SAMPLE_LOST_STATUS_ID: {
struct dds_sample_lost_status * const st = vst = &rd->m_sample_lost_status;
st->total_count++;
st->total_count_change++;
invoke = (lst->on_sample_lost != 0);
reset[0] = &st->total_count_change;
break;
}
case DDS_SAMPLE_REJECTED_STATUS: {
rd->m_sample_rejected_status.total_count++;
rd->m_sample_rejected_status.total_count_change++;
rd->m_sample_rejected_status.last_reason = data->extra;
rd->m_sample_rejected_status.last_instance_handle = data->handle;
metrics = (void*)&(rd->m_sample_rejected_status);
case DDS_SAMPLE_REJECTED_STATUS_ID: {
struct dds_sample_rejected_status * const st = vst = &rd->m_sample_rejected_status;
st->total_count++;
st->total_count_change++;
st->last_reason = data->extra;
st->last_instance_handle = data->handle;
invoke = (lst->on_sample_rejected != 0);
reset[0] = &st->total_count_change;
break;
}
case DDS_DATA_AVAILABLE_STATUS: {
metrics = NULL;
break;
}
case DDS_LIVELINESS_CHANGED_STATUS: {
case DDS_LIVELINESS_CHANGED_STATUS_ID: {
struct dds_liveliness_changed_status * const st = vst = &rd->m_liveliness_changed_status;
if (data->add) {
rd->m_liveliness_changed_status.alive_count++;
rd->m_liveliness_changed_status.alive_count_change++;
if (rd->m_liveliness_changed_status.not_alive_count > 0) {
rd->m_liveliness_changed_status.not_alive_count--;
st->alive_count++;
st->alive_count_change++;
if (st->not_alive_count > 0) {
st->not_alive_count--;
}
} else {
rd->m_liveliness_changed_status.alive_count--;
rd->m_liveliness_changed_status.not_alive_count++;
rd->m_liveliness_changed_status.not_alive_count_change++;
st->alive_count--;
st->not_alive_count++;
st->not_alive_count_change++;
}
rd->m_liveliness_changed_status.last_publication_handle = data->handle;
metrics = (void*)&(rd->m_liveliness_changed_status);
st->last_publication_handle = data->handle;
invoke = (lst->on_liveliness_changed != 0);
reset[0] = &st->alive_count_change;
reset[1] = &st->not_alive_count_change;
break;
}
case DDS_SUBSCRIPTION_MATCHED_STATUS: {
case DDS_SUBSCRIPTION_MATCHED_STATUS_ID: {
struct dds_subscription_matched_status * const st = vst = &rd->m_subscription_matched_status;
if (data->add) {
rd->m_subscription_matched_status.total_count++;
rd->m_subscription_matched_status.total_count_change++;
rd->m_subscription_matched_status.current_count++;
rd->m_subscription_matched_status.current_count_change++;
st->total_count++;
st->total_count_change++;
st->current_count++;
st->current_count_change++;
} else {
rd->m_subscription_matched_status.current_count--;
rd->m_subscription_matched_status.current_count_change--;
st->current_count--;
st->current_count_change--;
}
rd->m_subscription_matched_status.last_publication_handle = data->handle;
metrics = (void*)&(rd->m_subscription_matched_status);
st->last_publication_handle = data->handle;
invoke = (lst->on_subscription_matched != 0);
reset[0] = &st->total_count_change;
reset[1] = &st->current_count_change;
break;
}
default: assert (0);
case DDS_DATA_ON_READERS_STATUS_ID:
case DDS_DATA_AVAILABLE_STATUS_ID:
case DDS_INCONSISTENT_TOPIC_STATUS_ID:
case DDS_LIVELINESS_LOST_STATUS_ID:
case DDS_PUBLICATION_MATCHED_STATUS_ID:
case DDS_OFFERED_DEADLINE_MISSED_STATUS_ID:
case DDS_OFFERED_INCOMPATIBLE_QOS_STATUS_ID:
assert (0);
}
/* The reader needs to be unlocked when propagating the (possible) listener
* call because the application should be able to call this reader within
* the callback function. */
dds_reader_unlock(rd);
/* DATA_AVAILABLE is handled differently to normal status changes. */
if (data->status == DDS_DATA_AVAILABLE_STATUS) {
dds_entity *parent = rd->m_entity.m_parent;
/* First, try to ship it off to its parent(s) DDS_DATA_ON_READERS_STATUS. */
rc = dds_entity_listener_propagation(parent, parent, DDS_DATA_ON_READERS_STATUS, NULL, true);
if (rc == DDS_RETCODE_NO_DATA) {
/* No parent was interested (NO_DATA == NO_CALL).
* What about myself with DDS_DATA_AVAILABLE_STATUS? */
rc = dds_entity_listener_propagation(entity, entity, DDS_DATA_AVAILABLE_STATUS, NULL, false);
if (invoke)
{
os_mutexUnlock (&entity->m_observers_lock);
dds_entity_invoke_listener(entity, status_id, vst);
os_mutexLock (&entity->m_observers_lock);
*reset[0] = 0;
if (reset[1])
*reset[1] = 0;
}
else
{
dds_entity_status_set (entity, 1u << status_id);
}
if ( rc == DDS_RETCODE_NO_DATA ) {
/* Nobody was interested (NO_DATA == NO_CALL). Set the status on the subscriber. */
dds_entity_status_set(parent, DDS_DATA_ON_READERS_STATUS);
/* Notify possible interested observers of the subscriber. */
dds_entity_status_signal(parent);
}
} else {
/* Is anybody interested within the entity hierarchy through listeners? */
rc = dds_entity_listener_propagation(entity, entity, data->status, metrics, true);
}
if (rc == DDS_RETCODE_OK) {
/* Event was eaten by a listener. */
if (dds_reader_lock(((dds_entity*)entity)->m_hdl, &rd) == DDS_RETCODE_OK) {
assert(rd == entity);
/* Reset the change counts of the metrics. */
switch (data->status) {
case DDS_REQUESTED_DEADLINE_MISSED_STATUS: {
rd->m_requested_deadline_missed_status.total_count_change = 0;
break;
}
case DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS: {
rd->m_requested_incompatible_qos_status.total_count_change = 0;
break;
}
case DDS_SAMPLE_LOST_STATUS: {
rd->m_sample_lost_status.total_count_change = 0;
break;
}
case DDS_SAMPLE_REJECTED_STATUS: {
rd->m_sample_rejected_status.total_count_change = 0;
break;
}
case DDS_DATA_AVAILABLE_STATUS: {
/* Nothing to reset. */;
break;
}
case DDS_LIVELINESS_CHANGED_STATUS: {
rd->m_liveliness_changed_status.alive_count_change = 0;
rd->m_liveliness_changed_status.not_alive_count_change = 0;
break;
}
case DDS_SUBSCRIPTION_MATCHED_STATUS: {
rd->m_subscription_matched_status.total_count_change = 0;
rd->m_subscription_matched_status.current_count_change = 0;
break;
}
default: assert (0);
}
dds_reader_unlock(rd);
} else {
/* There's a deletion or closing going on. */
}
} else if (rc == DDS_RETCODE_NO_DATA) {
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status, consider successful. */
dds_entity_status_set(entity, data->status);
/* Notify possible interested observers. */
dds_entity_status_signal(entity);
} else if (rc == DDS_RETCODE_ALREADY_DELETED) {
/* An entity up the hierarchy is being deleted, consider successful. */
} else {
/* Something went wrong up the hierarchy. */
}
entity->m_cb_count--;
os_condBroadcast (&entity->m_observers_cond);
os_mutexUnlock (&entity->m_observers_lock);
}
_Pre_satisfies_(((participant_or_subscriber & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER ) ||\
@ -353,16 +371,16 @@ dds_create_reader(
dds_entity_t subscriber;
dds_reader * rd;
struct rhc * rhc;
dds_entity * tp;
dds_topic * tp;
dds_entity_t reader;
dds_entity_t t;
struct thread_state1 * const thr = lookup_thread_state ();
const bool asleep = !vtime_awake_p (thr->vtime);
dds_return_t ret = DDS_RETCODE_OK;
if (dds_entity_kind(topic) != DDS_KIND_INTERNAL) {
if (dds_entity_kind_from_handle(topic) != DDS_KIND_INTERNAL) {
/* Try claiming a participant. If that's not working, then it could be a subscriber. */
if (dds_entity_kind(participant_or_subscriber) == DDS_KIND_PARTICIPANT) {
if (dds_entity_kind_from_handle(participant_or_subscriber) == DDS_KIND_PARTICIPANT) {
subscriber = dds_create_subscriber(participant_or_subscriber, qos, NULL);
} else {
subscriber = participant_or_subscriber;
@ -381,19 +399,19 @@ dds_create_reader(
}
if ((subscriber != participant_or_subscriber) &&
(dds_entity_kind(topic) != DDS_KIND_INTERNAL)) {
(dds_entity_kind_from_handle(topic) != DDS_KIND_INTERNAL)) {
/* Delete implicit subscriber if reader creation fails */
sub->m_flags |= DDS_ENTITY_IMPLICIT;
}
rc = dds_entity_lock(t, DDS_KIND_TOPIC, &tp);
rc = dds_topic_lock(t, &tp);
if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking topic\n");
reader = DDS_ERRNO(rc);
goto err_tp_lock;
}
assert (((dds_topic*)tp)->m_stopic);
assert (sub->m_domain == tp->m_domain);
assert (tp->m_stopic);
assert (sub->m_domain == tp->m_entity.m_domain);
/* Merge qos from topic and subscriber */
rqos = dds_create_qos ();
@ -407,8 +425,8 @@ dds_create_reader(
dds_merge_qos (rqos, sub->m_qos);
}
if (tp->m_qos) {
dds_merge_qos (rqos, tp->m_qos);
if (tp->m_entity.m_qos) {
dds_merge_qos (rqos, tp->m_entity.m_qos);
/* reset the following qos policies if set during topic qos merge as they aren't applicable for reader */
rqos->present &= ~(QP_DURABILITY_SERVICE | QP_TRANSPORT_PRIORITY | QP_LIFESPAN);
@ -423,7 +441,7 @@ dds_create_reader(
}
/* Additional checks required for built-in topics */
if (dds_entity_kind(topic) == DDS_KIND_INTERNAL && !dds__validate_builtin_reader_qos(topic, qos)) {
if (dds_entity_kind_from_handle(topic) == DDS_KIND_INTERNAL && !dds__validate_builtin_reader_qos(topic, qos)) {
dds_delete_qos(rqos);
DDS_ERROR("Invalid QoS specified for built-in topic reader");
reader = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY);
@ -434,9 +452,9 @@ dds_create_reader(
rd = dds_alloc (sizeof (*rd));
reader = dds_entity_init (&rd->m_entity, sub, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK);
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
rd->m_topic = (dds_topic*)tp;
rhc = dds_rhc_new (rd, ((dds_topic*)tp)->m_stopic);
dds_entity_add_ref_nolock (tp);
rd->m_topic = tp;
rhc = dds_rhc_new (rd, tp->m_stopic);
dds_entity_add_ref_nolock (&tp->m_entity);
rd->m_entity.m_deriver.close = dds_reader_close;
rd->m_entity.m_deriver.delete = dds_reader_delete;
rd->m_entity.m_deriver.set_qos = dds_reader_qos_set;
@ -449,16 +467,16 @@ dds_create_reader(
assert(0);
}
os_mutexUnlock(&tp->m_mutex);
os_mutexUnlock(&tp->m_entity.m_mutex);
os_mutexUnlock(&sub->m_mutex);
if (asleep) {
thread_state_awake (thr);
}
rd->m_rd = new_reader(&rd->m_entity.m_guid, NULL, &sub->m_participant->m_guid, ((dds_topic*)tp)->m_stopic,
rd->m_rd = new_reader(&rd->m_entity.m_guid, NULL, &sub->m_participant->m_guid, tp->m_stopic,
rqos, rhc, dds_reader_status_cb, rd);
os_mutexLock(&sub->m_mutex);
os_mutexLock(&tp->m_mutex);
os_mutexLock(&tp->m_entity.m_mutex);
assert (rd->m_rd);
if (asleep) {
thread_state_asleep (thr);
@ -468,10 +486,10 @@ dds_create_reader(
if (dds_global.m_dur_reader && (rd->m_entity.m_qos->durability.kind > NN_TRANSIENT_LOCAL_DURABILITY_QOS)) {
(dds_global.m_dur_reader) (rd, rhc);
}
dds_entity_unlock(tp);
dds_topic_unlock(tp);
dds_entity_unlock(sub);
if (dds_entity_kind(topic) == DDS_KIND_INTERNAL) {
if (dds_entity_kind_from_handle(topic) == DDS_KIND_INTERNAL) {
/* If topic is builtin, then the topic entity is local and should
* be deleted because the application won't. */
dds_delete(t);
@ -480,14 +498,14 @@ dds_create_reader(
return reader;
err_bad_qos:
dds_entity_unlock(tp);
dds_topic_unlock(tp);
err_tp_lock:
dds_entity_unlock(sub);
if((sub->m_flags & DDS_ENTITY_IMPLICIT) != 0){
(void)dds_delete(subscriber);
}
err_sub_lock:
if (dds_entity_kind(topic) == DDS_KIND_INTERNAL) {
if (dds_entity_kind_from_handle(topic) == DDS_KIND_INTERNAL) {
/* If topic is builtin, then the topic entity is local and should
* be deleted because the application won't. */
dds_delete(t);
@ -495,11 +513,7 @@ err_sub_lock:
return reader;
}
void
dds_reader_ddsi2direct(
dds_entity_t entity,
ddsi2direct_directread_cb_t cb,
void *cbarg)
void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb, void *cbarg)
{
dds_reader *dds_rd;
@ -540,72 +554,57 @@ dds_reader_ddsi2direct(
os_mutexLock (&rd->e.lock);
}
os_mutexUnlock (&rd->e.lock);
ut_handle_release(entity, ((dds_entity*)rd)->m_hdllink);
ut_handle_release(entity, dds_rd->m_entity.m_hdllink);
}
}
uint32_t
dds_reader_lock_samples(
dds_entity_t reader)
uint32_t dds_reader_lock_samples (dds_entity_t reader)
{
uint32_t ret = 0;
dds_reader *rd;
if (dds_reader_lock(reader, &rd) == DDS_RETCODE_OK) {
ret = dds_rhc_lock_samples(rd->m_rd->rhc);
uint32_t n;
if (dds_reader_lock (reader, &rd) != DDS_RETCODE_OK)
return 0;
n = dds_rhc_lock_samples (rd->m_rd->rhc);
dds_reader_unlock (rd);
} else {
ret = 0;
}
return ret;
return n;
}
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
int
dds_reader_wait_for_historical_data(
dds_entity_t reader,
dds_duration_t max_wait)
int dds_reader_wait_for_historical_data (dds_entity_t reader, dds_duration_t max_wait)
{
dds_reader *rd;
int ret;
dds_reader *rd;
assert (reader);
ret = dds_reader_lock(reader, &rd);
if (ret == DDS_RETCODE_OK) {
if (((dds_entity*)rd)->m_qos->durability.kind > NN_TRANSIENT_LOCAL_DURABILITY_QOS) {
if ((ret = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK)
return DDS_ERRNO (ret);
switch (rd->m_entity.m_qos->durability.kind)
{
case DDS_DURABILITY_VOLATILE:
ret = DDS_RETCODE_OK;
break;
case DDS_DURABILITY_TRANSIENT_LOCAL:
break;
case DDS_DURABILITY_TRANSIENT:
case DDS_DURABILITY_PERSISTENT:
ret = (dds_global.m_dur_wait) (rd, max_wait);
} else {
DDS_ERROR("Can not wait for historical data on a reader with volatile durability\n");
ret = DDS_ERRNO(DDS_RETCODE_ERROR);
break;
}
dds_reader_unlock(rd);
} else {
DDS_ERROR("Error occurred on locking reader\n");
ret = DDS_ERRNO(ret);
}
return ret;
}
_Pre_satisfies_(((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) || \
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY) )
dds_entity_t
dds_get_subscriber(
_In_ dds_entity_t entity)
dds_entity_t dds_get_subscriber (dds_entity_t entity)
{
dds_entity_t hdl;
if (dds_entity_kind(entity) == DDS_KIND_READER) {
if (dds_entity_kind_from_handle (entity) == DDS_KIND_READER)
hdl = dds_get_parent (entity);
} else if (dds_entity_kind(entity) == DDS_KIND_COND_READ || dds_entity_kind(entity) == DDS_KIND_COND_QUERY) {
else if (dds_entity_kind_from_handle (entity) == DDS_KIND_COND_READ || dds_entity_kind_from_handle (entity) == DDS_KIND_COND_QUERY)
{
hdl = dds_get_parent (entity);
if(hdl > 0){
if (hdl > 0)
hdl = dds_get_subscriber (hdl);
} else {
DDS_ERROR ("Reader of this condition is already deleted\n");
}
} else {
else
{
DDS_ERROR ("Provided entity is not a reader nor a condition\n");
hdl = DDS_ERRNO (dds_valid_hdl (entity, DDS_KIND_READER));
}
@ -633,10 +632,10 @@ dds_get_subscription_matched_status (
if (status) {
*status = rd->m_subscription_matched_status;
}
if (((dds_entity*)rd)->m_status_enable & DDS_SUBSCRIPTION_MATCHED_STATUS) {
if (rd->m_entity.m_status_enable & DDS_SUBSCRIPTION_MATCHED_STATUS) {
rd->m_subscription_matched_status.total_count_change = 0;
rd->m_subscription_matched_status.current_count_change = 0;
dds_entity_status_reset(rd, DDS_SUBSCRIPTION_MATCHED_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_SUBSCRIPTION_MATCHED_STATUS);
}
dds_reader_unlock(rd);
fail:
@ -663,10 +662,10 @@ dds_get_liveliness_changed_status (
if (status) {
*status = rd->m_liveliness_changed_status;
}
if (((dds_entity*)rd)->m_status_enable & DDS_LIVELINESS_CHANGED_STATUS) {
if (rd->m_entity.m_status_enable & DDS_LIVELINESS_CHANGED_STATUS) {
rd->m_liveliness_changed_status.alive_count_change = 0;
rd->m_liveliness_changed_status.not_alive_count_change = 0;
dds_entity_status_reset(rd, DDS_LIVELINESS_CHANGED_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_LIVELINESS_CHANGED_STATUS);
}
dds_reader_unlock(rd);
fail:
@ -692,10 +691,10 @@ dds_return_t dds_get_sample_rejected_status (
if (status) {
*status = rd->m_sample_rejected_status;
}
if (((dds_entity*)rd)->m_status_enable & DDS_SAMPLE_REJECTED_STATUS) {
if (rd->m_entity.m_status_enable & DDS_SAMPLE_REJECTED_STATUS) {
rd->m_sample_rejected_status.total_count_change = 0;
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
dds_entity_status_reset(rd, DDS_SAMPLE_REJECTED_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_SAMPLE_REJECTED_STATUS);
}
dds_reader_unlock(rd);
fail:
@ -721,9 +720,9 @@ dds_return_t dds_get_sample_lost_status (
if (status) {
*status = rd->m_sample_lost_status;
}
if (((dds_entity*)rd)->m_status_enable & DDS_SAMPLE_LOST_STATUS) {
if (rd->m_entity.m_status_enable & DDS_SAMPLE_LOST_STATUS) {
rd->m_sample_lost_status.total_count_change = 0;
dds_entity_status_reset(rd, DDS_SAMPLE_LOST_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_SAMPLE_LOST_STATUS);
}
dds_reader_unlock(rd);
fail:
@ -749,9 +748,9 @@ dds_return_t dds_get_requested_deadline_missed_status (
if (status) {
*status = rd->m_requested_deadline_missed_status;
}
if (((dds_entity*)rd)->m_status_enable & DDS_REQUESTED_DEADLINE_MISSED_STATUS) {
if (rd->m_entity.m_status_enable & DDS_REQUESTED_DEADLINE_MISSED_STATUS) {
rd->m_requested_deadline_missed_status.total_count_change = 0;
dds_entity_status_reset(rd, DDS_REQUESTED_DEADLINE_MISSED_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_REQUESTED_DEADLINE_MISSED_STATUS);
}
dds_reader_unlock(rd);
fail:
@ -777,9 +776,9 @@ dds_return_t dds_get_requested_incompatible_qos_status (
if (status) {
*status = rd->m_requested_incompatible_qos_status;
}
if (((dds_entity*)rd)->m_status_enable & DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS) {
if (rd->m_entity.m_status_enable & DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS) {
rd->m_requested_incompatible_qos_status.total_count_change = 0;
dds_entity_status_reset(rd, DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS);
dds_entity_status_reset(&rd->m_entity, DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS);
}
dds_reader_unlock(rd);
fail:

View file

@ -146,8 +146,6 @@
"signal_conditions" after releasing the RHC lock.
*/
static const status_cb_data_t dds_rhc_data_avail_cb_data = { DDS_DATA_AVAILABLE_STATUS, 0, 0, true };
/* FIXME: tkmap should perhaps retain data with timestamp set to invalid
An invalid timestamp is (logically) unordered with respect to valid
timestamps, and that would mean BY_SOURCE order could be respected
@ -310,13 +308,40 @@ struct trigger_info
bool has_changed;
};
#define QMASK_OF_SAMPLE(s) ((s)->isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE)
#define QMASK_OF_INVSAMPLE(i) ((i)->inv_isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE)
#define INST_NSAMPLES(i) ((i)->nvsamples + (i)->inv_exists)
#define INST_NREAD(i) ((i)->nvread + (unsigned)((i)->inv_exists & (i)->inv_isread))
#define INST_IS_EMPTY(i) (INST_NSAMPLES (i) == 0)
#define INST_HAS_READ(i) (INST_NREAD (i) > 0)
#define INST_HAS_UNREAD(i) (INST_NREAD (i) < INST_NSAMPLES (i))
static unsigned qmask_of_sample (const struct rhc_sample *s)
{
return s->isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE;
}
static unsigned qmask_of_invsample (const struct rhc_instance *i)
{
return i->inv_isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE;
}
static uint32_t inst_nsamples (const struct rhc_instance *i)
{
return i->nvsamples + i->inv_exists;
}
static uint32_t inst_nread (const struct rhc_instance *i)
{
return i->nvread + (uint32_t) (i->inv_exists & i->inv_isread);
}
static bool inst_is_empty (const struct rhc_instance *i)
{
return inst_nsamples (i) == 0;
}
static bool inst_has_read (const struct rhc_instance *i)
{
return inst_nread (i) > 0;
}
static bool inst_has_unread (const struct rhc_instance *i)
{
return inst_nread (i) < inst_nsamples (i);
}
static unsigned qmask_of_inst (const struct rhc_instance *inst);
static bool update_conditions_locked (struct rhc *rhc, const struct trigger_info *pre, const struct trigger_info *post, const struct ddsi_serdata *sample);
@ -363,7 +388,7 @@ static void add_inst_to_nonempty_list (_Inout_ struct rhc *rhc, _Inout_ struct r
static void remove_inst_from_nonempty_list (struct rhc *rhc, struct rhc_instance *inst)
{
assert (INST_IS_EMPTY (inst));
assert (inst_is_empty (inst));
#ifndef NDEBUG
{
const struct rhc_instance *x = rhc->nonempty_instances;
@ -488,7 +513,7 @@ static void free_instance (void *vnode, void *varg)
struct rhc *rhc = varg;
struct rhc_instance *inst = vnode;
struct rhc_sample *s = inst->latest;
const bool was_empty = INST_IS_EMPTY (inst);
const bool was_empty = inst_is_empty (inst);
if (s)
{
do {
@ -559,8 +584,8 @@ static void init_trigger_info_nonmatch (struct trigger_info *info)
static void get_trigger_info (struct trigger_info *info, struct rhc_instance *inst, bool pre)
{
info->qminst = qmask_of_inst (inst);
info->has_read = INST_HAS_READ (inst);
info->has_not_read = INST_HAS_UNREAD (inst);
info->has_read = inst_has_read (inst);
info->has_not_read = inst_has_unread (inst);
/* reset instance has_changed before adding/overwriting a sample */
if (pre)
{
@ -619,7 +644,7 @@ static bool add_sample
if (rhc->reader && rhc->max_samples != DDS_LENGTH_UNLIMITED && rhc->n_vsamples >= (uint32_t) rhc->max_samples)
{
cb_data->status = DDS_SAMPLE_REJECTED_STATUS;
cb_data->raw_status_id = (int) DDS_SAMPLE_REJECTED_STATUS_ID;
cb_data->extra = DDS_REJECTED_BY_SAMPLES_LIMIT;
cb_data->handle = inst->iid;
cb_data->add = true;
@ -630,7 +655,7 @@ static bool add_sample
if (rhc->reader && rhc->max_samples_per_instance != DDS_LENGTH_UNLIMITED && inst->nvsamples >= (uint32_t) rhc->max_samples_per_instance)
{
cb_data->status = DDS_SAMPLE_REJECTED_STATUS;
cb_data->raw_status_id = (int) DDS_SAMPLE_REJECTED_STATUS_ID;
cb_data->extra = DDS_REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT;
cb_data->handle = inst->iid;
cb_data->add = true;
@ -749,7 +774,7 @@ static void update_inst
static void drop_instance_noupdate_no_writers (struct rhc *rhc, struct rhc_instance *inst)
{
int ret;
assert (INST_IS_EMPTY (inst));
assert (inst_is_empty (inst));
rhc->n_instances--;
@ -799,7 +824,7 @@ static void dds_rhc_register (struct rhc *rhc, struct rhc_instance *inst, uint64
inst->no_writers_gen++;
DDS_TRACE("new1");
if (!INST_IS_EMPTY (inst) && !inst->isdisposed)
if (!inst_is_empty (inst) && !inst->isdisposed)
rhc->n_not_alive_no_writers--;
}
else if (inst_wr_iid == 0 && inst->wrcount == 1)
@ -876,7 +901,7 @@ static void dds_rhc_register (struct rhc *rhc, struct rhc_instance *inst, uint64
static void account_for_empty_to_nonempty_transition (struct rhc *rhc, struct rhc_instance *inst)
{
assert (INST_NSAMPLES (inst) == 1);
assert (inst_nsamples (inst) == 1);
add_inst_to_nonempty_list (rhc, inst);
rhc->n_new += inst->isnew;
if (inst->isdisposed)
@ -953,7 +978,7 @@ static int rhc_unregister_updateinst
}
else
{
if (!INST_IS_EMPTY (inst))
if (!inst_is_empty (inst))
{
/* Instance still has content - do not drop until application
takes the last sample. Set the invalid sample if the latest
@ -985,7 +1010,7 @@ static int rhc_unregister_updateinst
{
/* Add invalid samples for transition to no-writers */
DDS_TRACE(",#0,empty,nowriters");
assert (INST_IS_EMPTY (inst));
assert (inst_is_empty (inst));
inst_set_invsample (rhc, inst);
update_inst (rhc, inst, pwr_info, false, tstamp);
account_for_empty_to_nonempty_transition (rhc, inst);
@ -1083,7 +1108,7 @@ static rhc_store_result_t rhc_store_new_instance
if (rhc->reader && rhc->max_instances != DDS_LENGTH_UNLIMITED && rhc->n_instances >= (uint32_t) rhc->max_instances)
{
cb_data->status = DDS_SAMPLE_REJECTED_STATUS;
cb_data->raw_status_id = (int) DDS_SAMPLE_REJECTED_STATUS_ID;
cb_data->extra = DDS_REJECTED_BY_INSTANCES_LIMIT;
cb_data->handle = tk->m_iid;
cb_data->add = true;
@ -1152,7 +1177,7 @@ bool dds_rhc_store
dummy_instance.iid = tk->m_iid;
stored = RHC_FILTERED;
cb_data.status = 0;
cb_data.raw_status_id = -1;
os_mutexLock (&rhc->lock);
@ -1204,7 +1229,7 @@ bool dds_rhc_store
}
/* notify sample lost */
cb_data.status = DDS_SAMPLE_LOST_STATUS;
cb_data.raw_status_id = (int) DDS_SAMPLE_LOST_STATUS_ID;
cb_data.extra = 0;
cb_data.handle = 0;
cb_data.add = true;
@ -1228,7 +1253,7 @@ bool dds_rhc_store
const int not_alive = inst->wrcount == 0 || inst->isdisposed;
const bool old_isdisposed = inst->isdisposed;
const bool old_isnew = inst->isnew;
const bool was_empty = INST_IS_EMPTY (inst);
const bool was_empty = inst_is_empty (inst);
int inst_became_disposed = 0;
/* Not just an unregister, so a write and/or a dispose (possibly
@ -1314,7 +1339,7 @@ bool dds_rhc_store
}
else
{
assert (INST_IS_EMPTY (inst) == was_empty);
assert (inst_is_empty (inst) == was_empty);
}
}
@ -1362,14 +1387,14 @@ bool dds_rhc_store
if (rhc->reader && (rhc->reader->m_entity.m_status_enable & DDS_DATA_AVAILABLE_STATUS))
{
os_atomic_inc32 (&rhc->n_cbs);
dds_reader_status_cb (&rhc->reader->m_entity, &dds_rhc_data_avail_cb_data);
dds_reader_data_available_cb (rhc->reader);
os_atomic_dec32 (&rhc->n_cbs);
}
}
if (rhc->reader && trigger_waitsets)
{
dds_entity_status_signal((dds_entity*)(rhc->reader));
dds_entity_status_signal(&rhc->reader->m_entity);
}
return delivered;
@ -1386,7 +1411,7 @@ error_or_nochange:
/* Make any reader status callback */
if (cb_data.status && rhc->reader && rhc->reader->m_entity.m_status_enable)
if (cb_data.raw_status_id >= 0 && rhc->reader && rhc->reader->m_entity.m_status_enable)
{
os_atomic_inc32 (&rhc->n_cbs);
dds_reader_status_cb (&rhc->reader->m_entity, &cb_data);
@ -1447,7 +1472,7 @@ void dds_rhc_unregister_wr
}
else
{
const bool was_empty = INST_IS_EMPTY (inst);
const bool was_empty = inst_is_empty (inst);
inst_set_invsample (rhc, inst);
if (was_empty)
account_for_empty_to_nonempty_transition (rhc, inst);
@ -1476,7 +1501,7 @@ void dds_rhc_unregister_wr
if (trigger_waitsets)
{
dds_entity_status_signal((dds_entity*)(rhc->reader));
dds_entity_status_signal(&rhc->reader->m_entity);
}
}
@ -1663,11 +1688,11 @@ static int dds_rhc_read_w_qminv
{
if (handle == DDS_HANDLE_NIL || inst->iid == handle)
{
if (!INST_IS_EMPTY (inst) && (qmask_of_inst (inst) & qminv) == 0)
if (!inst_is_empty (inst) && (qmask_of_inst (inst) & qminv) == 0)
{
/* samples present & instance, view state matches */
struct trigger_info pre, post;
const unsigned nread = INST_NREAD (inst);
const unsigned nread = inst_nread (inst);
const uint32_t n_first = n;
get_trigger_info (&pre, inst, true);
@ -1676,13 +1701,13 @@ static int dds_rhc_read_w_qminv
struct rhc_sample *sample = inst->latest->next, * const end1 = sample;
do
{
if ((QMASK_OF_SAMPLE (sample) & qminv) == 0)
if ((qmask_of_sample (sample) & qminv) == 0)
{
/* sample state matches too */
set_sample_info (info_seq + n, inst, sample);
ddsi_serdata_to_sample (sample->sample, values[n], 0, 0);
if (cond == NULL
|| (dds_entity_kind(cond->m_entity.m_hdl) != DDS_KIND_COND_QUERY)
|| (dds_entity_kind_from_handle(cond->m_entity.m_hdl) != DDS_KIND_COND_QUERY)
|| (cond->m_query.m_filter != NULL && cond->m_query.m_filter(values[n])))
{
if (!sample->isread)
@ -1709,7 +1734,7 @@ static int dds_rhc_read_w_qminv
while (sample != end1);
}
if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0)
if (inst->inv_exists && n < max_samples && (qmask_of_invsample (inst) & qminv) == 0)
{
set_sample_info_invsample (info_seq + n, inst);
ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0);
@ -1726,7 +1751,7 @@ static int dds_rhc_read_w_qminv
inst->isnew = 0;
rhc->n_new--;
}
if (nread != INST_NREAD (inst))
if (nread != inst_nread (inst))
{
get_trigger_info (&post, inst, false);
if (update_conditions_locked (rhc, &pre, &post, NULL))
@ -1754,7 +1779,7 @@ static int dds_rhc_read_w_qminv
if (trigger_waitsets)
{
dds_entity_status_signal((dds_entity*)(rhc->reader));
dds_entity_status_signal(&rhc->reader->m_entity);
}
assert (n <= INT_MAX);
@ -1792,7 +1817,7 @@ static int dds_rhc_take_w_qminv
iid = inst->iid;
if (handle == DDS_HANDLE_NIL || iid == handle)
{
if (!INST_IS_EMPTY (inst) && (qmask_of_inst (inst) & qminv) == 0)
if (!inst_is_empty (inst) && (qmask_of_inst (inst) & qminv) == 0)
{
struct trigger_info pre, post;
unsigned nvsamples = inst->nvsamples;
@ -1807,7 +1832,7 @@ static int dds_rhc_take_w_qminv
{
struct rhc_sample * const sample1 = sample->next;
if ((QMASK_OF_SAMPLE (sample) & qminv) != 0)
if ((qmask_of_sample (sample) & qminv) != 0)
{
psample = sample;
}
@ -1816,7 +1841,7 @@ static int dds_rhc_take_w_qminv
set_sample_info (info_seq + n, inst, sample);
ddsi_serdata_to_sample (sample->sample, values[n], 0, 0);
if (cond == NULL
|| (dds_entity_kind(cond->m_entity.m_hdl) != DDS_KIND_COND_QUERY)
|| (dds_entity_kind_from_handle(cond->m_entity.m_hdl) != DDS_KIND_COND_QUERY)
|| ( cond->m_query.m_filter != NULL && cond->m_query.m_filter(values[n])))
{
rhc->n_vsamples--;
@ -1855,7 +1880,7 @@ static int dds_rhc_take_w_qminv
}
}
if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0)
if (inst->inv_exists && n < max_samples && (qmask_of_invsample (inst) & qminv) == 0)
{
set_sample_info_invsample (info_seq + n, inst);
ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0);
@ -1880,7 +1905,7 @@ static int dds_rhc_take_w_qminv
}
}
if (INST_IS_EMPTY (inst))
if (inst_is_empty (inst))
{
remove_inst_from_nonempty_list (rhc, inst);
@ -1918,7 +1943,7 @@ static int dds_rhc_take_w_qminv
if (trigger_waitsets)
{
dds_entity_status_signal((dds_entity*)(rhc->reader));
dds_entity_status_signal(&rhc->reader->m_entity);
}
assert (n <= INT_MAX);
@ -1957,7 +1982,7 @@ static int dds_rhc_takecdr_w_qminv
iid = inst->iid;
if (handle == DDS_HANDLE_NIL || iid == handle)
{
if (!INST_IS_EMPTY (inst) && (qmask_of_inst (inst) & qminv) == 0)
if (!inst_is_empty (inst) && (qmask_of_inst (inst) & qminv) == 0)
{
struct trigger_info pre, post;
unsigned nvsamples = inst->nvsamples;
@ -1972,7 +1997,7 @@ static int dds_rhc_takecdr_w_qminv
{
struct rhc_sample * const sample1 = sample->next;
if ((QMASK_OF_SAMPLE (sample) & qminv) != 0)
if ((qmask_of_sample (sample) & qminv) != 0)
{
psample = sample;
}
@ -2006,7 +2031,7 @@ static int dds_rhc_takecdr_w_qminv
}
}
if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0)
if (inst->inv_exists && n < max_samples && (qmask_of_invsample (inst) & qminv) == 0)
{
set_sample_info_invsample (info_seq + n, inst);
values[n] = ddsi_serdata_ref(inst->tk->m_sample);
@ -2031,7 +2056,7 @@ static int dds_rhc_takecdr_w_qminv
}
}
if (INST_IS_EMPTY (inst))
if (inst_is_empty (inst))
{
remove_inst_from_nonempty_list (rhc, inst);
@ -2069,7 +2094,7 @@ static int dds_rhc_takecdr_w_qminv
if (trigger_waitsets)
{
dds_entity_status_signal((dds_entity*)(rhc->reader));
dds_entity_status_signal(&rhc->reader->m_entity);
}
assert (n <= INT_MAX);
@ -2086,15 +2111,15 @@ static uint32_t rhc_get_cond_trigger (struct rhc_instance * const inst, const dd
switch (c->m_sample_states)
{
case DDS_SST_READ:
m = m && INST_HAS_READ (inst);
m = m && inst_has_read (inst);
break;
case DDS_SST_NOT_READ:
m = m && INST_HAS_UNREAD (inst);
m = m && inst_has_unread (inst);
break;
case DDS_SST_READ | DDS_SST_NOT_READ:
case 0:
/* note: we get here only if inst not empty, so this is a no-op */
m = m && !INST_IS_EMPTY (inst);
m = m && !inst_is_empty (inst);
break;
default:
DDS_FATAL("update_readconditions: sample_states invalid: %x\n", c->m_sample_states);
@ -2118,11 +2143,11 @@ void dds_rhc_add_readcondition (dds_readcond * cond)
os_mutexLock (&rhc->lock);
for (inst = ut_hhIterFirst (rhc->instances, &iter); inst; inst = ut_hhIterNext (&iter))
{
if (dds_entity_kind(cond->m_entity.m_hdl) == DDS_KIND_COND_READ)
if (dds_entity_kind_from_handle(cond->m_entity.m_hdl) == DDS_KIND_COND_READ)
{
((dds_entity*)cond)->m_trigger += rhc_get_cond_trigger (inst, cond);
if (((dds_entity*)cond)->m_trigger) {
dds_entity_status_signal((dds_entity*)cond);
cond->m_entity.m_trigger += rhc_get_cond_trigger (inst, cond);
if (cond->m_entity.m_trigger) {
dds_entity_status_signal(&cond->m_entity);
}
}
}
@ -2225,7 +2250,7 @@ static bool update_conditions_locked
}
else if (m_pre < m_post)
{
if (sample && tmp == NULL && (dds_entity_kind(iter->m_entity.m_hdl) == DDS_KIND_COND_QUERY))
if (sample && tmp == NULL && (dds_entity_kind_from_handle(iter->m_entity.m_hdl) == DDS_KIND_COND_QUERY))
{
tmp = ddsi_sertopic_alloc_sample (rhc->topic);
ddsi_serdata_to_sample (sample, tmp, NULL, NULL);
@ -2233,7 +2258,7 @@ static bool update_conditions_locked
if
(
(sample == NULL)
|| (dds_entity_kind(iter->m_entity.m_hdl) != DDS_KIND_COND_QUERY)
|| (dds_entity_kind_from_handle(iter->m_entity.m_hdl) != DDS_KIND_COND_QUERY)
|| (iter->m_query.m_filter != NULL && iter->m_query.m_filter (tmp))
)
{
@ -2335,7 +2360,7 @@ static int rhc_check_counts_locked (struct rhc *rhc, bool check_conds)
for (inst = ut_hhIterFirst (rhc->instances, &iter); inst; inst = ut_hhIterNext (&iter))
{
n_instances++;
if (!INST_IS_EMPTY (inst))
if (!inst_is_empty (inst))
{
/* samples present (or an invalid sample is) */
unsigned n_vsamples_in_instance = 0, n_read_vsamples_in_instance = 0;
@ -2387,7 +2412,7 @@ static int rhc_check_counts_locked (struct rhc *rhc, bool check_conds)
dds_readcond * rciter = rhc->conds;
for (i = 0; i < (rhc->nconds < CHECK_MAX_CONDS ? rhc->nconds : CHECK_MAX_CONDS); i++)
{
if (dds_entity_kind(rciter->m_entity.m_hdl) == DDS_KIND_COND_READ)
if (dds_entity_kind_from_handle(rciter->m_entity.m_hdl) == DDS_KIND_COND_READ)
{
cond_match_count[i] += rhc_get_cond_trigger (inst, rciter);
}
@ -2412,7 +2437,7 @@ static int rhc_check_counts_locked (struct rhc *rhc, bool check_conds)
dds_readcond * rciter = rhc->conds;
for (i = 0; i < (rhc->nconds < CHECK_MAX_CONDS ? rhc->nconds : CHECK_MAX_CONDS); i++)
{
if (dds_entity_kind(rciter->m_entity.m_hdl) == DDS_KIND_COND_READ)
if (dds_entity_kind_from_handle(rciter->m_entity.m_hdl) == DDS_KIND_COND_READ)
{
assert (cond_match_count[i] == rciter->m_entity.m_trigger);
}
@ -2433,7 +2458,7 @@ static int rhc_check_counts_locked (struct rhc *rhc, bool check_conds)
inst = rhc->nonempty_instances;
n_nonempty_instances = 0;
do {
assert (!INST_IS_EMPTY (inst));
assert (!inst_is_empty (inst));
assert (prev->next == inst);
assert (inst->prev == prev);
prev = inst;

View file

@ -40,10 +40,8 @@ static const char * stream_op_type[11] =
const uint32_t dds_op_size[5] = { 0, 1u, 2u, 4u, 8u };
static void dds_stream_write
(dds_stream_t * os, const char * data, const uint32_t * ops);
static void dds_stream_read
(dds_stream_t * is, char * data, const uint32_t * ops);
static void dds_stream_write (dds_stream_t * os, const char * data, const uint32_t * ops);
static void dds_stream_read (dds_stream_t * is, char * data, const uint32_t * ops);
#define DDS_SWAP16(v) \
((uint16_t)(((v) >> 8) | ((v) << 8)))
@ -258,6 +256,12 @@ uint64_t dds_stream_read_uint64 (dds_stream_t * is)
return val;
}
extern inline char dds_stream_read_char (dds_stream_t *is);
extern inline int8_t dds_stream_read_int8 (dds_stream_t *is);
extern inline int16_t dds_stream_read_int16 (dds_stream_t *is);
extern inline int32_t dds_stream_read_int32 (dds_stream_t *is);
extern inline int64_t dds_stream_read_int64 (dds_stream_t *is);
float dds_stream_read_float (dds_stream_t * is)
{
float val = 0.0;
@ -417,6 +421,12 @@ void dds_stream_write_uint64 (dds_stream_t * os, uint64_t val)
DDS_OS_PUT8 (os, val, uint64_t);
}
extern inline void dds_stream_write_char (dds_stream_t * os, char val);
extern inline void dds_stream_write_int8 (dds_stream_t * os, int8_t val);
extern inline void dds_stream_write_int16 (dds_stream_t * os, int16_t val);
extern inline void dds_stream_write_int32 (dds_stream_t * os, int32_t val);
extern inline void dds_stream_write_int64 (dds_stream_t * os, int64_t val);
void dds_stream_write_float (dds_stream_t * os, float val)
{
union { float f; uint32_t u; } u;

View file

@ -97,28 +97,6 @@ dds_subscriber_status_validate(
return ret;
}
/*
Set boolean on readers that indicates state of DATA_ON_READERS
status on parent subscriber
*/
static dds_return_t
dds_subscriber_status_propagate(
dds_entity *sub,
uint32_t mask,
bool set)
{
if (mask & DDS_DATA_ON_READERS_STATUS) {
dds_entity *iter = sub->m_children;
while (iter) {
os_mutexLock (&iter->m_mutex);
((dds_reader*) iter)->m_data_on_readers = set;
os_mutexUnlock (&iter->m_mutex);
iter = iter->m_next;
}
}
return DDS_RETCODE_OK;
}
_Requires_exclusive_lock_held_(participant)
_Check_return_ dds_entity_t
dds__create_subscriber_l(
@ -149,7 +127,6 @@ dds__create_subscriber_l(
subscriber = dds_entity_init(&sub->m_entity, participant, DDS_KIND_SUBSCRIBER, new_qos, listener, DDS_SUBSCRIBER_STATUS_MASK);
sub->m_entity.m_deriver.set_qos = dds_subscriber_qos_set;
sub->m_entity.m_deriver.validate_status = dds_subscriber_status_validate;
sub->m_entity.m_deriver.propagate_status = dds_subscriber_status_propagate;
sub->m_entity.m_deriver.get_instance_hdl = dds_subscriber_instance_hdl;
return subscriber;

View file

@ -26,6 +26,8 @@
#include "os/os_atomics.h"
#include "ddsi/ddsi_iid.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_topic)
#define DDS_TOPIC_STATUS_MASK \
DDS_INCONSISTENT_TOPIC_STATUS
@ -90,55 +92,29 @@ dds_topic_status_validate(
status (only defined status on a topic).
*/
static void
dds_topic_status_cb(
struct dds_topic *cb_t)
static void dds_topic_status_cb (struct dds_topic *tp)
{
dds_topic *topic;
dds__retcode_t rc;
struct dds_listener const * const lst = &tp->m_entity.m_listener;
if (dds_topic_lock(((dds_entity*)cb_t)->m_hdl, &topic) != DDS_RETCODE_OK) {
return;
os_mutexLock (&tp->m_entity.m_observers_lock);
while (tp->m_entity.m_cb_count > 0)
os_condWait (&tp->m_entity.m_observers_cond, &tp->m_entity.m_observers_lock);
tp->m_entity.m_cb_count++;
tp->m_inconsistent_topic_status.total_count++;
tp->m_inconsistent_topic_status.total_count_change++;
if (lst->on_inconsistent_topic)
{
os_mutexUnlock (&tp->m_entity.m_observers_lock);
dds_entity_invoke_listener(&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS_ID, &tp->m_inconsistent_topic_status);
os_mutexLock (&tp->m_entity.m_observers_lock);
tp->m_inconsistent_topic_status.total_count_change = 0;
}
assert(topic == cb_t);
/* Reset the status for possible Listener call.
* When a listener is not called, the status will be set (again). */
/* Update status metrics. */
topic->m_inconsistent_topic_status.total_count++;
topic->m_inconsistent_topic_status.total_count_change++;
/* The topic needs to be unlocked when propagating the (possible) listener
* call because the application should be able to call this topic within
* the callback function. */
dds_topic_unlock(topic);
/* Is anybody interested within the entity hierarchy through listeners? */
rc = dds_entity_listener_propagation((dds_entity*)topic,
(dds_entity*)topic,
DDS_INCONSISTENT_TOPIC_STATUS,
(void*)&(topic->m_inconsistent_topic_status),
true);
if (rc == DDS_RETCODE_OK) {
/* Event was eaten by a listener. */
if (dds_topic_lock(((dds_entity*)cb_t)->m_hdl, &topic) == DDS_RETCODE_OK) {
/* Reset the change counts of the metrics. */
topic->m_inconsistent_topic_status.total_count_change = 0;
dds_topic_unlock(topic);
}
} else if (rc == DDS_RETCODE_NO_DATA) {
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status; consider it successful. */
dds_entity_status_set((dds_entity*)topic, DDS_INCONSISTENT_TOPIC_STATUS);
/* Notify possible interested observers. */
dds_entity_status_signal((dds_entity*)topic);
} else if (rc == DDS_RETCODE_ALREADY_DELETED) {
/* An entity up the hierarchy is being deleted; consider it successful. */
} else {
/* Something went wrong up the hierarchy. */
}
dds_entity_status_set(&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
tp->m_entity.m_cb_count--;
os_condBroadcast (&tp->m_entity.m_observers_cond);
os_mutexUnlock (&tp->m_entity.m_observers_lock);
}
struct ddsi_sertopic *
@ -184,7 +160,7 @@ dds_topic_free(
assert (st);
os_mutexLock (&dds_global.m_mutex);
domain = (dds_domain*) ut_avlLookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
domain = ut_avlLookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
if (domain != NULL) {
ut_avlDelete (&dds_topictree_def, &domain->m_topics, st);
}
@ -715,9 +691,9 @@ dds_get_inconsistent_topic_status(
if (status) {
*status = t->m_inconsistent_topic_status;
}
if (((dds_entity*)t)->m_status_enable & DDS_INCONSISTENT_TOPIC_STATUS) {
if (t->m_entity.m_status_enable & DDS_INCONSISTENT_TOPIC_STATUS) {
t->m_inconsistent_topic_status.total_count_change = 0;
dds_entity_status_reset(t, DDS_INCONSISTENT_TOPIC_STATUS);
dds_entity_status_reset(&t->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
}
dds_topic_unlock(t);
fail:

View file

@ -17,10 +17,7 @@
#include "dds__rhc.h"
#include "dds__err.h"
#define dds_waitset_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_WAITSET, (dds_entity**)obj)
#define dds_waitset_unlock(obj) dds_entity_unlock((dds_entity*)obj);
DEFINE_ENTITY_LOCK_UNLOCK(static, dds_waitset, DDS_KIND_WAITSET)
static void
dds_waitset_swap(
@ -41,20 +38,6 @@ dds_waitset_swap(
*dst = idx;
}
static void
dds_waitset_signal_entity(
_In_ dds_waitset *ws)
{
dds_entity *e = (dds_entity*)ws;
/* When signaling any observers of us through the entity,
* we need to be unlocked. We still have claimed the related
* handle, so possible deletions will be delayed until we
* release it. */
os_mutexUnlock(&(e->m_mutex));
dds_entity_status_signal(e);
os_mutexLock(&(e->m_mutex));
}
static dds_return_t
dds_waitset_wait_impl(
_In_ dds_entity_t waitset,
@ -214,8 +197,8 @@ dds_waitset_close(
{
dds_waitset *ws = (dds_waitset*)e;
dds_waitset_close_list(&(ws->observed), e->m_hdl);
dds_waitset_close_list(&(ws->triggered), e->m_hdl);
dds_waitset_close_list(&ws->observed, e->m_hdl);
dds_waitset_close_list(&ws->triggered, e->m_hdl);
/* Trigger waitset to wake up. */
os_condBroadcast(&e->m_cond);
@ -368,7 +351,7 @@ dds_waitset_attach(
e = NULL;
}
} else {
e = (dds_entity*)ws;
e = &ws->m_entity;
}
/* This will fail if given entity is already attached (or deleted). */
@ -421,7 +404,7 @@ dds_waitset_detach(
if (rc == DDS_RETCODE_OK) {
/* Possibly fails when entity was not attached. */
if (waitset == entity) {
rc = dds_entity_observer_unregister_nl((dds_entity*)ws, waitset);
rc = dds_entity_observer_unregister_nl(&ws->m_entity, waitset);
} else {
rc = dds_entity_observer_unregister(entity, waitset);
}
@ -477,33 +460,25 @@ dds_waitset_wait(
return ret;
}
_Pre_satisfies_((waitset & DDS_ENTITY_KIND_MASK) == DDS_KIND_WAITSET)
dds_return_t
dds_waitset_set_trigger(
_In_ dds_entity_t waitset,
_In_ bool trigger)
dds_return_t dds_waitset_set_trigger (dds_entity_t waitset, bool trigger)
{
dds_waitset *ws;
dds__retcode_t rc;
dds_return_t ret = DDS_RETCODE_OK;
/* Locking the waitset here will delay a possible deletion until it is
* unlocked. Even when the related mutex is unlocked when we want to send
* a signal. */
rc = dds_waitset_lock(waitset, &ws);
if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking waitset\n");
ret = DDS_ERRNO(rc);
goto fail;
}
if (trigger) {
dds_entity_status_set(ws, DDS_WAITSET_TRIGGER_STATUS);
} else {
dds_entity_status_reset(ws, DDS_WAITSET_TRIGGER_STATUS);
}
dds_waitset_signal_entity(ws);
if ((rc = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
return DDS_ERRNO (rc);
os_mutexUnlock (&ws->m_entity.m_mutex);
os_mutexLock (&ws->m_entity.m_observers_lock);
if (trigger)
dds_entity_status_set (&ws->m_entity, DDS_WAITSET_TRIGGER_STATUS);
else
dds_entity_status_reset (&ws->m_entity, DDS_WAITSET_TRIGGER_STATUS);
os_mutexUnlock (&ws->m_entity.m_observers_lock);
os_mutexLock (&ws->m_entity.m_mutex);
dds_waitset_unlock (ws);
fail:
return ret;
return DDS_RETCODE_OK;
}

View file

@ -20,10 +20,13 @@
#include "dds__qos.h"
#include "dds__err.h"
#include "dds__init.h"
#include "dds__topic.h"
#include "ddsi/ddsi_tkmap.h"
#include "dds__whc.h"
#include "ddsc/ddsc_project.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_writer)
#define DDS_WRITER_STATUS_MASK \
DDS_LIVELINESS_LOST_STATUS |\
DDS_OFFERED_DEADLINE_MISSED_STATUS |\
@ -62,123 +65,110 @@ dds_writer_status_validate(
then status conditions is not triggered.
*/
static void
dds_writer_status_cb(
void *entity,
const status_cb_data_t *data)
static void dds_writer_status_cb (void *ventity, const status_cb_data_t *data)
{
dds_writer *wr;
dds__retcode_t rc;
void *metrics = NULL;
struct dds_entity * const entity = ventity;
/* When data is NULL, it means that the writer is deleted. */
if (data == NULL) {
if (data == NULL)
{
/* Release the initial claim that was done during the create. This
* will indicate that further API deletion is now possible. */
ut_handle_release(((dds_entity*)entity)->m_hdl, ((dds_entity*)entity)->m_hdllink);
ut_handle_release (entity->m_hdl, entity->m_hdllink);
return;
}
if (dds_writer_lock(((dds_entity*)entity)->m_hdl, &wr) != DDS_RETCODE_OK) {
/* There's a deletion or closing going on. */
return;
}
assert(wr == entity);
struct dds_listener const * const lst = &entity->m_listener;
enum dds_status_id status_id = (enum dds_status_id) data->raw_status_id;
bool invoke = false;
void *vst = NULL;
int32_t *reset[2] = { NULL, NULL };
os_mutexLock (&entity->m_observers_lock);
while (entity->m_cb_count > 0)
os_condWait (&entity->m_observers_cond, &entity->m_observers_lock);
entity->m_cb_count++;
/* Reset the status for possible Listener call.
* When a listener is not called, the status will be set (again). */
dds_entity_status_reset(entity, data->status);
dds_entity_status_reset (entity, 1u << status_id);
/* Update status metrics. */
switch (data->status) {
case DDS_OFFERED_DEADLINE_MISSED_STATUS: {
wr->m_offered_deadline_missed_status.total_count++;
wr->m_offered_deadline_missed_status.total_count_change++;
wr->m_offered_deadline_missed_status.last_instance_handle = data->handle;
metrics = (void*)&(wr->m_offered_deadline_missed_status);
dds_writer * const wr = (dds_writer *) entity;
switch (status_id)
{
case DDS_OFFERED_DEADLINE_MISSED_STATUS_ID: {
struct dds_offered_deadline_missed_status * const st = vst = &wr->m_offered_deadline_missed_status;
st->total_count++;
st->total_count_change++;
st->last_instance_handle = data->handle;
invoke = (lst->on_offered_deadline_missed != 0);
reset[0] = &st->total_count_change;
break;
}
case DDS_LIVELINESS_LOST_STATUS: {
wr->m_liveliness_lost_status.total_count++;
wr->m_liveliness_lost_status.total_count_change++;
metrics = (void*)&(wr->m_liveliness_lost_status);
case DDS_LIVELINESS_LOST_STATUS_ID: {
struct dds_liveliness_lost_status * const st = vst = &wr->m_liveliness_lost_status;
st->total_count++;
st->total_count_change++;
invoke = (lst->on_liveliness_lost != 0);
reset[0] = &st->total_count_change;
break;
}
case DDS_OFFERED_INCOMPATIBLE_QOS_STATUS: {
wr->m_offered_incompatible_qos_status.total_count++;
wr->m_offered_incompatible_qos_status.total_count_change++;
wr->m_offered_incompatible_qos_status.last_policy_id = data->extra;
metrics = (void*)&(wr->m_offered_incompatible_qos_status);
case DDS_OFFERED_INCOMPATIBLE_QOS_STATUS_ID: {
struct dds_offered_incompatible_qos_status * const st = vst = &wr->m_offered_incompatible_qos_status;
st->total_count++;
st->total_count_change++;
st->last_policy_id = data->extra;
invoke = (lst->on_offered_incompatible_qos != 0);
reset[0] = &st->total_count_change;
break;
}
case DDS_PUBLICATION_MATCHED_STATUS: {
case DDS_PUBLICATION_MATCHED_STATUS_ID: {
struct dds_publication_matched_status * const st = vst = &wr->m_publication_matched_status;
if (data->add) {
wr->m_publication_matched_status.total_count++;
wr->m_publication_matched_status.total_count_change++;
wr->m_publication_matched_status.current_count++;
wr->m_publication_matched_status.current_count_change++;
st->total_count++;
st->total_count_change++;
st->current_count++;
st->current_count_change++;
} else {
wr->m_publication_matched_status.current_count--;
wr->m_publication_matched_status.current_count_change--;
st->current_count--;
st->current_count_change--;
}
wr->m_publication_matched_status.last_subscription_handle = data->handle;
metrics = (void*)&(wr->m_publication_matched_status);
invoke = (lst->on_publication_matched != 0);
reset[0] = &st->total_count_change;
reset[1] = &st->current_count_change;
break;
}
default: assert (0);
case DDS_DATA_AVAILABLE_STATUS_ID:
case DDS_INCONSISTENT_TOPIC_STATUS_ID:
case DDS_SAMPLE_LOST_STATUS_ID:
case DDS_DATA_ON_READERS_STATUS_ID:
case DDS_SAMPLE_REJECTED_STATUS_ID:
case DDS_LIVELINESS_CHANGED_STATUS_ID:
case DDS_SUBSCRIPTION_MATCHED_STATUS_ID:
case DDS_REQUESTED_DEADLINE_MISSED_STATUS_ID:
case DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS_ID:
assert (0);
}
/* The writer needs to be unlocked when propagating the (possible) listener
* call because the application should be able to call this writer within
* the callback function. */
dds_writer_unlock(wr);
if (invoke)
{
os_mutexUnlock (&entity->m_observers_lock);
dds_entity_invoke_listener(entity, status_id, vst);
os_mutexLock (&entity->m_observers_lock);
*reset[0] = 0;
if (reset[1])
*reset[1] = 0;
}
else
{
dds_entity_status_set (entity, 1u << status_id);
}
/* Is anybody interested within the entity hierarchy through listeners? */
rc = dds_entity_listener_propagation(entity, entity, data->status, metrics, true);
if (rc == DDS_RETCODE_OK) {
/* Event was eaten by a listener. */
if (dds_writer_lock(((dds_entity*)entity)->m_hdl, &wr) == DDS_RETCODE_OK) {
assert(wr == entity);
/* Reset the status. */
dds_entity_status_reset(entity, data->status);
/* Reset the change counts of the metrics. */
switch (data->status) {
case DDS_OFFERED_DEADLINE_MISSED_STATUS: {
wr->m_offered_deadline_missed_status.total_count_change = 0;
break;
}
case DDS_LIVELINESS_LOST_STATUS: {
wr->m_liveliness_lost_status.total_count_change = 0;
break;
}
case DDS_OFFERED_INCOMPATIBLE_QOS_STATUS: {
wr->m_offered_incompatible_qos_status.total_count_change = 0;
break;
}
case DDS_PUBLICATION_MATCHED_STATUS: {
wr->m_publication_matched_status.total_count_change = 0;
wr->m_publication_matched_status.current_count_change = 0;
break;
}
default: assert (0);
}
dds_writer_unlock(wr);
} else {
/* There's a deletion or closing going on. */
}
} else if (rc == DDS_RETCODE_NO_DATA) {
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status; consider it successful. */
dds_entity_status_set(entity, data->status);
/* Notify possible interested observers. */
dds_entity_status_signal(entity);
} else if (rc == DDS_RETCODE_ALREADY_DELETED) {
/* An entity up the hierarchy is being deleted; consider it successful. */
} else {
/* Something went wrong up the hierarchy. */
}
entity->m_cb_count--;
os_condBroadcast (&entity->m_observers_cond);
os_mutexUnlock (&entity->m_observers_lock);
}
static uint32_t
@ -412,7 +402,7 @@ dds_create_writer(
dds_writer * wr;
dds_entity_t writer;
dds_entity * pub = NULL;
dds_entity * tp;
dds_topic * tp;
dds_entity_t publisher;
struct thread_state1 * const thr = lookup_thread_state();
const bool asleep = !vtime_awake_p(thr->vtime);
@ -420,7 +410,7 @@ dds_create_writer(
dds_return_t ret;
/* Try claiming a participant. If that's not working, then it could be a subscriber. */
if(dds_entity_kind(participant_or_publisher) == DDS_KIND_PARTICIPANT){
if(dds_entity_kind_from_handle(participant_or_publisher) == DDS_KIND_PARTICIPANT){
publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
} else{
publisher = participant_or_publisher;
@ -437,14 +427,14 @@ dds_create_writer(
pub->m_flags |= DDS_ENTITY_IMPLICIT;
}
rc = dds_entity_lock(topic, DDS_KIND_TOPIC, &tp);
rc = dds_topic_lock(topic, &tp);
if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking topic\n");
writer = DDS_ERRNO(rc);
goto err_tp_lock;
}
assert(((dds_topic*)tp)->m_stopic);
assert(pub->m_domain == tp->m_domain);
assert(tp->m_stopic);
assert(pub->m_domain == tp->m_entity.m_domain);
/* Merge Topic & Publisher qos */
wqos = dds_create_qos();
@ -458,9 +448,9 @@ dds_create_writer(
dds_merge_qos(wqos, pub->m_qos);
}
if (tp->m_qos) {
if (tp->m_entity.m_qos) {
/* merge topic qos data to writer qos */
dds_merge_qos(wqos, tp->m_qos);
dds_merge_qos(wqos, tp->m_entity.m_qos);
}
nn_xqos_mergein_missing(wqos, &gv.default_xqos_wr);
@ -475,8 +465,8 @@ dds_create_writer(
wr = dds_alloc(sizeof (*wr));
writer = dds_entity_init(&wr->m_entity, pub, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
wr->m_topic = (dds_topic*)tp;
dds_entity_add_ref_nolock(tp);
wr->m_topic = tp;
dds_entity_add_ref_nolock(&tp->m_entity);
wr->m_xp = nn_xpack_new(conn, get_bandwidth_limit(wqos->transport_priority), config.xpack_send_async);
wr->m_entity.m_deriver.close = dds_writer_close;
wr->m_entity.m_deriver.delete = dds_writer_delete;
@ -491,25 +481,25 @@ dds_create_writer(
assert(0);
}
os_mutexUnlock(&tp->m_mutex);
os_mutexUnlock(&tp->m_entity.m_mutex);
os_mutexUnlock(&pub->m_mutex);
if (asleep) {
thread_state_awake(thr);
}
wr->m_wr = new_writer(&wr->m_entity.m_guid, NULL, &pub->m_participant->m_guid, ((dds_topic*)tp)->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
wr->m_wr = new_writer(&wr->m_entity.m_guid, NULL, &pub->m_participant->m_guid, tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
os_mutexLock(&pub->m_mutex);
os_mutexLock(&tp->m_mutex);
os_mutexLock(&tp->m_entity.m_mutex);
assert(wr->m_wr);
if (asleep) {
thread_state_asleep(thr);
}
dds_entity_unlock(tp);
dds_topic_unlock(tp);
dds_entity_unlock(pub);
return writer;
err_bad_qos:
dds_entity_unlock(tp);
dds_topic_unlock(tp);
err_tp_lock:
dds_entity_unlock(pub);
if((pub->m_flags & DDS_ENTITY_IMPLICIT) != 0){
@ -559,10 +549,10 @@ dds_get_publication_matched_status (
if (status) {
*status = wr->m_publication_matched_status;
}
if (((dds_entity*)wr)->m_status_enable & DDS_PUBLICATION_MATCHED_STATUS) {
if (wr->m_entity.m_status_enable & DDS_PUBLICATION_MATCHED_STATUS) {
wr->m_publication_matched_status.total_count_change = 0;
wr->m_publication_matched_status.current_count_change = 0;
dds_entity_status_reset(wr, DDS_PUBLICATION_MATCHED_STATUS);
dds_entity_status_reset(&wr->m_entity, DDS_PUBLICATION_MATCHED_STATUS);
}
dds_writer_unlock(wr);
fail:
@ -589,9 +579,9 @@ dds_get_liveliness_lost_status (
if (status) {
*status = wr->m_liveliness_lost_status;
}
if (((dds_entity*)wr)->m_status_enable & DDS_LIVELINESS_LOST_STATUS) {
if (wr->m_entity.m_status_enable & DDS_LIVELINESS_LOST_STATUS) {
wr->m_liveliness_lost_status.total_count_change = 0;
dds_entity_status_reset(wr, DDS_LIVELINESS_LOST_STATUS);
dds_entity_status_reset(&wr->m_entity, DDS_LIVELINESS_LOST_STATUS);
}
dds_writer_unlock(wr);
fail:
@ -618,9 +608,9 @@ dds_get_offered_deadline_missed_status(
if (status) {
*status = wr->m_offered_deadline_missed_status;
}
if (((dds_entity*)wr)->m_status_enable & DDS_OFFERED_DEADLINE_MISSED_STATUS) {
if (wr->m_entity.m_status_enable & DDS_OFFERED_DEADLINE_MISSED_STATUS) {
wr->m_offered_deadline_missed_status.total_count_change = 0;
dds_entity_status_reset(wr, DDS_OFFERED_DEADLINE_MISSED_STATUS);
dds_entity_status_reset(&wr->m_entity, DDS_OFFERED_DEADLINE_MISSED_STATUS);
}
dds_writer_unlock(wr);
fail:
@ -647,9 +637,9 @@ dds_get_offered_incompatible_qos_status (
if (status) {
*status = wr->m_offered_incompatible_qos_status;
}
if (((dds_entity*)wr)->m_status_enable & DDS_OFFERED_INCOMPATIBLE_QOS_STATUS) {
if (wr->m_entity.m_status_enable & DDS_OFFERED_INCOMPATIBLE_QOS_STATUS) {
wr->m_offered_incompatible_qos_status.total_count_change = 0;
dds_entity_status_reset(wr, DDS_OFFERED_INCOMPATIBLE_QOS_STATUS);
dds_entity_status_reset(&wr->m_entity, DDS_OFFERED_INCOMPATIBLE_QOS_STATUS);
}
dds_writer_unlock(wr);
fail:

View file

@ -79,7 +79,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/ddsi"
ddsi_tkmap.h
probes-constants.h
q_addrset.h
q_align.h
q_bitset.h
q_bswap.h
q_config.h

View file

@ -178,27 +178,6 @@ struct ddsi_tran_qos
int m_diffserv;
};
/* Functions and pseudo functions (macro wrappers) */
void ddsi_factory_conn_init (ddsi_tran_factory_t, ddsi_tran_conn_t);
#define ddsi_tran_type(b) (((ddsi_tran_base_t) (b))->m_trantype)
#define ddsi_tran_port(b) (((ddsi_tran_base_t) (b))->m_port)
int ddsi_tran_locator (ddsi_tran_base_t base, nn_locator_t * loc);
void ddsi_tran_free (ddsi_tran_base_t base);
void ddsi_tran_free_qos (ddsi_tran_qos_t qos);
ddsi_tran_qos_t ddsi_tran_create_qos (void);
os_socket ddsi_tran_handle (ddsi_tran_base_t base);
#define ddsi_factory_create_listener(f,p,q) (((f)->m_create_listener_fn) ((p), (q)))
#define ddsi_factory_supports(f,k) (((f)->m_supports_fn) (k))
ddsi_tran_conn_t ddsi_factory_create_conn
(
ddsi_tran_factory_t factory,
uint32_t port,
ddsi_tran_qos_t qos
);
void ddsi_tran_factories_fini (void);
void ddsi_factory_add (ddsi_tran_factory_t factory);
void ddsi_factory_free (ddsi_tran_factory_t factory);
@ -206,24 +185,56 @@ ddsi_tran_factory_t ddsi_factory_find (const char * type);
ddsi_tran_factory_t ddsi_factory_find_supported_kind (int32_t kind);
void ddsi_factory_conn_init (ddsi_tran_factory_t factory, ddsi_tran_conn_t conn);
#define ddsi_conn_handle(c) (ddsi_tran_handle (&(c)->m_base))
#define ddsi_conn_locator(c,l) (ddsi_tran_locator (&(c)->m_base,(l)))
OSAPI_EXPORT ssize_t ddsi_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const os_iovec_t *iov, uint32_t flags);
ssize_t ddsi_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, nn_locator_t *srcloc);
inline bool ddsi_factory_supports (ddsi_tran_factory_t factory, int32_t kind) {
return factory->m_supports_fn (kind);
}
inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos) {
return factory->m_create_conn_fn (port, qos);
}
inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, int port, ddsi_tran_qos_t qos) {
return factory->m_create_listener_fn (port, qos);
}
void ddsi_tran_free (ddsi_tran_base_t base);
void ddsi_tran_free_qos (ddsi_tran_qos_t qos);
ddsi_tran_qos_t ddsi_tran_create_qos (void);
inline os_socket ddsi_tran_handle (ddsi_tran_base_t base) {
return base->m_handle_fn (base);
}
inline int ddsi_tran_locator (ddsi_tran_base_t base, nn_locator_t * loc) {
return base->m_locator_fn (base, loc);
}
inline os_socket ddsi_conn_handle (ddsi_tran_conn_t conn) {
return conn->m_base.m_handle_fn (&conn->m_base);
}
inline uint32_t ddsi_conn_type (ddsi_tran_conn_t conn) {
return conn->m_base.m_trantype;
}
inline uint32_t ddsi_conn_port (ddsi_tran_conn_t conn) {
return conn->m_base.m_port;
}
inline int ddsi_conn_locator (ddsi_tran_conn_t conn, nn_locator_t * loc) {
return conn->m_base.m_locator_fn (&conn->m_base, loc);
}
inline ssize_t ddsi_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const os_iovec_t *iov, uint32_t flags) {
return conn->m_closed ? -1 : (conn->m_write_fn) (conn, dst, niov, iov, flags);
}
inline ssize_t ddsi_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, nn_locator_t *srcloc) {
return conn->m_closed ? -1 : conn->m_read_fn (conn, buf, len, srcloc);
}
bool ddsi_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * loc);
void ddsi_conn_disable_multiplexing (ddsi_tran_conn_t conn);
void ddsi_conn_add_ref (ddsi_tran_conn_t conn);
void ddsi_conn_free (ddsi_tran_conn_t conn);
int ddsi_conn_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcip, const nn_locator_t *mcip, const struct nn_interface *interf);
int ddsi_conn_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcip, const nn_locator_t *mcip, const struct nn_interface *interf);
void ddsi_conn_transfer_group_membership (ddsi_tran_conn_t conn, ddsi_tran_conn_t newconn);
int ddsi_conn_rejoin_transferred_mcgroups (ddsi_tran_conn_t conn);
int ddsi_is_mcaddr (const nn_locator_t *loc);
int ddsi_is_ssm_mcaddr (const nn_locator_t *loc);
enum ddsi_nearby_address_result ddsi_is_nearby_address (const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[]);
enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc, const char *str);
/* 8 for transport/
@ -242,9 +253,15 @@ char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_loc
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs);
#define ddsi_listener_locator(s,l) (ddsi_tran_locator (&(s)->m_base,(l)))
ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);
int ddsi_listener_listen (ddsi_tran_listener_t listener);
inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc) {
return listener->m_base.m_locator_fn (&listener->m_base, loc);
}
inline int ddsi_listener_listen (ddsi_tran_listener_t listener) {
return listener->m_listen_fn (listener);
}
inline ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener) {
return listener->m_accept_fn (listener);
}
void ddsi_listener_unblock (ddsi_tran_listener_t listener);
void ddsi_listener_free (ddsi_tran_listener_t listener);

View file

@ -1,18 +0,0 @@
/*
* 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 NN_ALIGN_H
#define NN_ALIGN_H
#define ALIGN4(x) (((x) + 3) & -4u)
#define ALIGN8(x) (((x) + 7) & -8u)
#endif /* NN_ALIGN_H */

View file

@ -17,13 +17,14 @@
#include "ddsi/q_rtps.h" /* for nn_guid_t, nn_guid_prefix_t */
#include "ddsi/q_protocol.h" /* for nn_sequence_number_t */
#define bswap2(x) ((int16_t) bswap2u ((uint16_t) (x)))
#define bswap4(x) ((int32_t) bswap4u ((uint32_t) (x)))
#define bswap8(x) ((int64_t) bswap8u ((uint64_t) (x)))
inline uint16_t bswap2u (uint16_t x)
{
return (unsigned short) ((x >> 8) | (x << 8));
return (uint16_t) ((x >> 8) | (x << 8));
}
inline int16_t bswap2 (int16_t x)
{
return (int16_t) bswap2u ((uint16_t) x);
}
inline uint32_t bswap4u (uint32_t x)
@ -31,6 +32,11 @@ inline uint32_t bswap4u (uint32_t x)
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
}
inline int32_t bswap4 (int32_t x)
{
return (int32_t) bswap4u ((uint32_t) x);
}
inline uint64_t bswap8u (uint64_t x)
{
const uint32_t newhi = bswap4u ((uint32_t) x);
@ -38,6 +44,11 @@ inline uint64_t bswap8u (uint64_t x)
return ((uint64_t) newhi << 32) | (uint64_t) newlo;
}
inline int64_t bswap8 (int64_t x)
{
return (int64_t) bswap8u ((uint64_t) x);
}
inline void bswapSN (nn_sequence_number_t *sn)
{
sn->high = bswap4 (sn->high);

View file

@ -44,7 +44,7 @@ typedef void (*ddsi2direct_directread_cb_t) (const struct nn_rsample_info *sampl
typedef struct status_cb_data
{
uint32_t status;
int raw_status_id;
uint32_t extra;
uint64_t handle;
bool add;

View file

@ -312,6 +312,22 @@ static int ddsi_raweth_is_mcaddr (const ddsi_tran_factory_t tran, const nn_locat
return (loc->address[10] & 1);
}
static int ddsi_raweth_is_ssm_mcaddr (const ddsi_tran_factory_t tran, const nn_locator_t *loc)
{
(void) tran;
(void) loc;
return 0;
}
static enum ddsi_nearby_address_result ddsi_raweth_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[])
{
(void) tran;
(void) loc;
(void) ninterf;
(void) interf;
return DNAR_LOCAL;
}
static enum ddsi_locator_from_string_result ddsi_raweth_address_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str)
{
int i = 0;
@ -371,7 +387,8 @@ int ddsi_raweth_init (void)
ddsi_raweth_factory_g.m_join_mc_fn = ddsi_raweth_join_mc;
ddsi_raweth_factory_g.m_leave_mc_fn = ddsi_raweth_leave_mc;
ddsi_raweth_factory_g.m_is_mcaddr_fn = ddsi_raweth_is_mcaddr;
ddsi_raweth_factory_g.m_is_nearby_address_fn = ddsi_ipaddr_is_nearby_address;
ddsi_raweth_factory_g.m_is_ssm_mcaddr_fn = ddsi_raweth_is_ssm_mcaddr;
ddsi_raweth_factory_g.m_is_nearby_address_fn = ddsi_raweth_is_nearby_address;
ddsi_raweth_factory_g.m_locator_from_string_fn = ddsi_raweth_address_from_string;
ddsi_raweth_factory_g.m_locator_to_string_fn = ddsi_raweth_to_string;
ddsi_raweth_factory_g.m_enumerate_interfaces_fn = ddsi_raweth_enumerate_interfaces;

View file

@ -27,6 +27,7 @@
#define INVALID_PORT (~0u)
typedef struct ddsi_tran_factory * ddsi_tcp_factory_g_t;
static os_atomic_uint32_t ddsi_tcp_init_g = OS_ATOMIC_UINT32_INIT(0);
#ifdef DDSI_INCLUDE_SSL
struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin =
@ -1027,6 +1028,7 @@ static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
static void ddsi_tcp_release_factory (void)
{
if (os_atomic_dec32_nv (&ddsi_tcp_init_g) == 0) {
ut_avlFree (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, ddsi_tcp_node_free);
os_mutexDestroy (&ddsi_tcp_cache_lock_g);
#ifdef DDSI_INCLUDE_SSL
@ -1035,6 +1037,8 @@ static void ddsi_tcp_release_factory (void)
(ddsi_tcp_ssl_plugin.fini) ();
}
#endif
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "tcp de-initialized\n");
}
}
static enum ddsi_locator_from_string_result ddsi_tcp_address_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str)
@ -1042,12 +1046,30 @@ static enum ddsi_locator_from_string_result ddsi_tcp_address_from_string (ddsi_t
return ddsi_ipaddr_from_string(tran, loc, str, ddsi_tcp_factory_g.m_kind);
}
static int ddsi_tcp_is_mcaddr (const ddsi_tran_factory_t tran, const nn_locator_t *loc)
{
(void) tran;
(void) loc;
return 0;
}
static int ddsi_tcp_is_ssm_mcaddr (const ddsi_tran_factory_t tran, const nn_locator_t *loc)
{
(void) tran;
(void) loc;
return 0;
}
static enum ddsi_nearby_address_result ddsi_tcp_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[])
{
return ddsi_ipaddr_is_nearby_address(tran, loc, ninterf, interf);
}
int ddsi_tcp_init (void)
{
static bool init = false;
if (!init)
if (os_atomic_inc32_nv (&ddsi_tcp_init_g) == 1)
{
init = true;
memset (&ddsi_tcp_factory_g, 0, sizeof (ddsi_tcp_factory_g));
ddsi_tcp_factory_g.m_kind = NN_LOCATOR_KIND_TCPv4;
ddsi_tcp_factory_g.m_typename = "tcp";
ddsi_tcp_factory_g.m_stream = true;
@ -1063,6 +1085,9 @@ int ddsi_tcp_init (void)
ddsi_tcp_factory_g.m_locator_from_string_fn = ddsi_tcp_address_from_string;
ddsi_tcp_factory_g.m_locator_to_string_fn = ddsi_ipaddr_to_string;
ddsi_tcp_factory_g.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
ddsi_tcp_factory_g.m_is_mcaddr_fn = ddsi_tcp_is_mcaddr;
ddsi_tcp_factory_g.m_is_ssm_mcaddr_fn = ddsi_tcp_is_ssm_mcaddr;
ddsi_tcp_factory_g.m_is_nearby_address_fn = ddsi_tcp_is_nearby_address;
ddsi_factory_add (&ddsi_tcp_factory_g);
#if OS_SOCKET_HAS_IPV6

View file

@ -19,6 +19,21 @@
static ddsi_tran_factory_t ddsi_tran_factories = NULL;
extern inline uint32_t ddsi_conn_type (ddsi_tran_conn_t conn);
extern inline uint32_t ddsi_conn_port (ddsi_tran_conn_t conn);
extern inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, int port, ddsi_tran_qos_t qos);
extern inline bool ddsi_factory_supports (ddsi_tran_factory_t factory, int32_t kind);
extern inline os_socket ddsi_conn_handle (ddsi_tran_conn_t conn);
extern inline int ddsi_conn_locator (ddsi_tran_conn_t conn, nn_locator_t * loc);
extern inline os_socket ddsi_tran_handle (ddsi_tran_base_t base);
extern inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos);
extern inline int ddsi_tran_locator (ddsi_tran_base_t base, nn_locator_t * loc);
extern inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc);
extern inline int ddsi_listener_listen (ddsi_tran_listener_t listener);
extern inline ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);
extern inline ssize_t ddsi_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, nn_locator_t *srcloc);
extern inline ssize_t ddsi_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const os_iovec_t *iov, uint32_t flags);
void ddsi_factory_add (ddsi_tran_factory_t factory)
{
factory->m_factory = ddsi_tran_factories;
@ -47,8 +62,8 @@ void ddsi_tran_factories_fini (void)
ddsi_tran_factory_t factory;
while ((factory = ddsi_tran_factories) != NULL) {
ddsi_tran_factories = factory->m_factory;
ddsi_factory_free(factory);
ddsi_tran_factories = ddsi_tran_factories->m_factory;
}
}
@ -144,32 +159,6 @@ void ddsi_factory_conn_init (ddsi_tran_factory_t factory, ddsi_tran_conn_t conn)
conn->m_factory = factory;
}
ssize_t ddsi_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, nn_locator_t *srcloc)
{
return (conn->m_closed) ? -1 : (conn->m_read_fn) (conn, buf, len, srcloc);
}
ssize_t ddsi_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const os_iovec_t *iov, uint32_t flags)
{
ssize_t ret = -1;
if (! conn->m_closed)
{
ret = (conn->m_write_fn) (conn, dst, niov, iov, flags);
}
/* Check that write function is atomic (all or nothing) */
#ifndef NDEBUG
{
size_t i, len;
for (i = 0, len = 0; i < niov; i++) {
len += iov[i].iov_len;
}
assert (ret == -1 || (size_t) ret == len);
}
#endif
return ret;
}
void ddsi_conn_disable_multiplexing (ddsi_tran_conn_t conn)
{
if (conn->m_disable_multiplexing_fn) {
@ -202,11 +191,6 @@ int ddsi_conn_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const
return conn->m_factory->m_leave_mc_fn (conn, srcloc, mcloc, interf);
}
os_socket ddsi_tran_handle (ddsi_tran_base_t base)
{
return (base->m_handle_fn) (base);
}
ddsi_tran_qos_t ddsi_tran_create_qos (void)
{
ddsi_tran_qos_t qos;
@ -215,31 +199,6 @@ ddsi_tran_qos_t ddsi_tran_create_qos (void)
return qos;
}
ddsi_tran_conn_t ddsi_factory_create_conn
(
ddsi_tran_factory_t factory,
uint32_t port,
ddsi_tran_qos_t qos
)
{
return factory->m_create_conn_fn (port, qos);
}
int ddsi_tran_locator (ddsi_tran_base_t base, nn_locator_t * loc)
{
return (base->m_locator_fn) (base, loc);
}
int ddsi_listener_listen (ddsi_tran_listener_t listener)
{
return (listener->m_listen_fn) (listener);
}
ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener)
{
return (listener->m_accept_fn) (listener);
}
void ddsi_tran_free (ddsi_tran_base_t base)
{
if (base)
@ -274,21 +233,20 @@ void ddsi_listener_free (ddsi_tran_listener_t listener)
int ddsi_is_mcaddr (const nn_locator_t *loc)
{
/* FIXME: should set m_is_mcaddr_fn to a function returning false if transport doesn't provide an implementation, and get rid of the test */
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind (loc->kind);
return tran && tran->m_is_mcaddr_fn ? tran->m_is_mcaddr_fn (tran, loc) : 0;
return tran ? tran->m_is_mcaddr_fn (tran, loc) : 0;
}
int ddsi_is_ssm_mcaddr (const nn_locator_t *loc)
{
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind);
return tran && tran->m_is_ssm_mcaddr_fn ? tran->m_is_ssm_mcaddr_fn (tran, loc) : 0;
return tran ? tran->m_is_ssm_mcaddr_fn (tran, loc) : 0;
}
enum ddsi_nearby_address_result ddsi_is_nearby_address (const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[])
{
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind);
return tran->m_is_nearby_address_fn ? tran->m_is_nearby_address_fn (tran, loc, ninterf, interf) : DNAR_DISTANT;
return tran ? tran->m_is_nearby_address_fn (tran, loc, ninterf, interf) : DNAR_DISTANT;
}
enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc, const char *str)

View file

@ -14,5 +14,8 @@
extern inline uint16_t bswap2u (uint16_t x);
extern inline uint32_t bswap4u (uint32_t x);
extern inline uint64_t bswap8u (uint64_t x);
extern inline int16_t bswap2 (int16_t x);
extern inline int32_t bswap4 (int32_t x);
extern inline int64_t bswap8 (int64_t x);
extern inline void bswapSN (nn_sequence_number_t *sn);

View file

@ -1016,7 +1016,7 @@ static const char *durability_to_string (nn_durability_kind_t k)
case NN_TRANSIENT_DURABILITY_QOS: return "transient";
case NN_PERSISTENT_DURABILITY_QOS: return "persistent";
}
abort (); return 0;
return "undefined-durability";
}
static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppguid, nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp)

View file

@ -248,16 +248,12 @@ nn_vendorid_t get_entity_vendorid (const struct entity_common *e)
case EK_READER:
case EK_WRITER:
return (nn_vendorid_t) MY_VENDOR_ID;
break;
case EK_PROXY_PARTICIPANT:
return ((const struct proxy_participant *) e)->vendor;
break;
case EK_PROXY_READER:
return ((const struct proxy_reader *) e)->c.vendor;
break;
case EK_PROXY_WRITER:
return ((const struct proxy_writer *) e)->c.vendor;
break;
}
assert (0);
return (nn_vendorid_t) NN_VENDORID_UNKNOWN;
@ -1350,7 +1346,7 @@ static void writer_drop_connection (const struct nn_guid * wr_guid, const struct
if (m != NULL && wr->status_cb)
{
status_cb_data_t data;
data.status = DDS_PUBLICATION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_PUBLICATION_MATCHED_STATUS_ID;
data.add = false;
data.handle = prd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data);
@ -1378,7 +1374,7 @@ static void writer_drop_local_connection (const struct nn_guid *wr_guid, struct
if (m != NULL && wr->status_cb)
{
status_cb_data_t data;
data.status = DDS_PUBLICATION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_PUBLICATION_MATCHED_STATUS_ID;
data.add = false;
data.handle = rd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data);
@ -1412,10 +1408,10 @@ static void reader_drop_connection (const struct nn_guid *rd_guid, const struct
data.add = false;
data.handle = pwr->e.iid;
data.status = DDS_LIVELINESS_CHANGED_STATUS;
data.raw_status_id = (int) DDS_LIVELINESS_CHANGED_STATUS_ID;
(rd->status_cb) (rd->status_cb_entity, &data);
data.status = DDS_SUBSCRIPTION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_SUBSCRIPTION_MATCHED_STATUS_ID;
(rd->status_cb) (rd->status_cb_entity, &data);
}
}
@ -1447,10 +1443,10 @@ static void reader_drop_local_connection (const struct nn_guid *rd_guid, const s
data.add = false;
data.handle = wr->e.iid;
data.status = DDS_LIVELINESS_CHANGED_STATUS;
data.raw_status_id = (int) DDS_LIVELINESS_CHANGED_STATUS_ID;
(rd->status_cb) (rd->status_cb_entity, &data);
data.status = DDS_SUBSCRIPTION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_SUBSCRIPTION_MATCHED_STATUS_ID;
(rd->status_cb) (rd->status_cb_entity, &data);
}
}
@ -1587,7 +1583,7 @@ static void writer_add_connection (struct writer *wr, struct proxy_reader *prd)
if (wr->status_cb)
{
status_cb_data_t data;
data.status = DDS_PUBLICATION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_PUBLICATION_MATCHED_STATUS_ID;
data.add = true;
data.handle = prd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data);
@ -1667,7 +1663,7 @@ static void writer_add_local_connection (struct writer *wr, struct reader *rd)
if (wr->status_cb)
{
status_cb_data_t data;
data.status = DDS_PUBLICATION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_PUBLICATION_MATCHED_STATUS_ID;
data.add = true;
data.handle = rd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data);
@ -1730,7 +1726,7 @@ static void reader_add_connection (struct reader *rd, struct proxy_writer *pwr,
if (rd->status_cb)
{
status_cb_data_t data;
data.status = DDS_SUBSCRIPTION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_SUBSCRIPTION_MATCHED_STATUS_ID;
data.add = true;
data.handle = pwr->e.iid;
(rd->status_cb) (rd->status_cb_entity, &data);
@ -1765,10 +1761,10 @@ static void reader_add_local_connection (struct reader *rd, struct writer *wr)
data.add = true;
data.handle = wr->e.iid;
data.status = DDS_LIVELINESS_CHANGED_STATUS;
data.raw_status_id = (int) DDS_LIVELINESS_CHANGED_STATUS_ID;
(rd->status_cb) (rd->status_cb_entity, &data);
data.status = DDS_SUBSCRIPTION_MATCHED_STATUS;
data.raw_status_id = (int) DDS_SUBSCRIPTION_MATCHED_STATUS_ID;
(rd->status_cb) (rd->status_cb_entity, &data);
}
}
@ -1875,7 +1871,7 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader
if (rd->status_cb)
{
status_cb_data_t data;
data.status = DDS_LIVELINESS_CHANGED_STATUS;
data.raw_status_id = (int) DDS_LIVELINESS_CHANGED_STATUS_ID;
data.add = true;
data.handle = pwr->e.iid;
(rd->status_cb) (rd->status_cb_entity, &data);
@ -1997,7 +1993,7 @@ static void writer_qos_mismatch (struct writer * wr, uint32_t reason)
if (wr->status_cb)
{
status_cb_data_t data;
data.status = DDS_OFFERED_INCOMPATIBLE_QOS_STATUS;
data.raw_status_id = (int) DDS_OFFERED_INCOMPATIBLE_QOS_STATUS_ID;
data.extra = reason;
(wr->status_cb) (wr->status_cb_entity, &data);
}
@ -2018,7 +2014,7 @@ static void reader_qos_mismatch (struct reader * rd, uint32_t reason)
if (rd->status_cb)
{
status_cb_data_t data;
data.status = DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS;
data.raw_status_id = (int) DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS_ID;
data.extra = reason;
(rd->status_cb) (rd->status_cb_entity, &data);
}

View file

@ -29,7 +29,6 @@
#include "ddsi/q_lat_estim.h"
#include "ddsi/q_bitset.h"
#include "ddsi/q_xevent.h"
#include "ddsi/q_align.h"
#include "ddsi/q_addrset.h"
#include "ddsi/q_ddsi_discovery.h"
#include "ddsi/q_radmin.h"
@ -680,7 +679,7 @@ int create_multicast_sockets(void)
gv.disc_conn_mc = disc;
gv.data_conn_mc = data;
DDS_TRACE("Multicast Ports: discovery %d data %d \n",
ddsi_tran_port (gv.disc_conn_mc), ddsi_tran_port (gv.data_conn_mc));
ddsi_conn_port (gv.disc_conn_mc), ddsi_conn_port (gv.data_conn_mc));
return 1;
err_data:
@ -1113,7 +1112,7 @@ int rtps_init (void)
if (gv.m_factory->m_connless)
{
if (!(config.many_sockets_mode == MSM_NO_UNICAST && config.allowMulticast))
DDS_TRACE("Unicast Ports: discovery %d data %d\n", ddsi_tran_port (gv.disc_conn_uc), ddsi_tran_port (gv.data_conn_uc));
DDS_TRACE("Unicast Ports: discovery %d data %d\n", ddsi_conn_port (gv.disc_conn_uc), ddsi_conn_port (gv.data_conn_uc));
if (config.allowMulticast)
{
@ -1128,11 +1127,11 @@ int rtps_init (void)
/* Set multicast locators */
if (!is_unspec_locator(&gv.loc_spdp_mc))
gv.loc_spdp_mc.port = ddsi_tran_port (gv.disc_conn_mc);
gv.loc_spdp_mc.port = ddsi_conn_port (gv.disc_conn_mc);
if (!is_unspec_locator(&gv.loc_meta_mc))
gv.loc_meta_mc.port = ddsi_tran_port (gv.disc_conn_mc);
gv.loc_meta_mc.port = ddsi_conn_port (gv.disc_conn_mc);
if (!is_unspec_locator(&gv.loc_default_mc))
gv.loc_default_mc.port = ddsi_tran_port (gv.data_conn_mc);
gv.loc_default_mc.port = ddsi_conn_port (gv.data_conn_mc);
if (joinleave_spdp_defmcip (1) < 0)
goto err_mc_conn;
@ -1167,7 +1166,7 @@ int rtps_init (void)
/* Create shared transmit connection */
gv.tev_conn = gv.data_conn_uc;
DDS_TRACE("Timed event transmit port: %d\n", (int) ddsi_tran_port (gv.tev_conn));
DDS_TRACE("Timed event transmit port: %d\n", (int) ddsi_conn_port (gv.tev_conn));
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
{

View file

@ -56,29 +56,6 @@ unsigned locator_to_hopefully_unique_uint32 (const nn_locator_t *src)
return id;
}
unsigned short get_socket_port (os_socket socket)
{
os_sockaddr_storage addr;
socklen_t addrlen = sizeof (addr);
if (getsockname (socket, (os_sockaddr *) &addr, &addrlen) < 0)
{
print_sockerror ("getsockname");
return 0;
}
switch (addr.ss_family)
{
case AF_INET:
return ntohs (((os_sockaddr_in *) &addr)->sin_port);
#if OS_SOCKET_HAS_IPV6
case AF_INET6:
return ntohs (((os_sockaddr_in6 *) &addr)->sin6_port);
#endif
default:
abort ();
return 0;
}
}
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
void set_socket_diffserv (os_socket sock, int diffserv)
{

View file

@ -21,7 +21,6 @@
#include "ddsi/q_bswap.h"
#include "ddsi/q_unused.h"
#include "ddsi/q_align.h"
#include "ddsi/q_error.h"
#include "ddsi/q_plist.h"
#include "ddsi/q_time.h"

View file

@ -32,7 +32,6 @@
#include "ddsi/q_config.h"
#include "ddsi/q_log.h"
#include "ddsi/q_align.h"
#include "ddsi/q_plist.h"
#include "ddsi/q_unused.h"
#include "ddsi/q_radmin.h"

View file

@ -30,7 +30,6 @@
#include "ddsi/q_lat_estim.h"
#include "ddsi/q_bitset.h"
#include "ddsi/q_xevent.h"
#include "ddsi/q_align.h"
#include "ddsi/q_addrset.h"
#include "ddsi/q_ddsi_discovery.h"
#include "ddsi/q_radmin.h"

View file

@ -34,7 +34,6 @@
#include "ddsi/q_log.h"
#include "ddsi/q_unused.h"
#include "ddsi/q_xmsg.h"
#include "ddsi/q_align.h"
#include "ddsi/q_config.h"
#include "ddsi/q_entity.h"
#include "ddsi/q_globals.h"
@ -1339,7 +1338,18 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
#endif
{
if (!gv.mute)
{
nbytes = ddsi_conn_write (xp->conn, loc, xp->niov, xp->iov, xp->call_flags);
#ifndef NDEBUG
{
size_t i, len;
for (i = 0, len = 0; i < xp->niov; i++) {
len += xp->iov[i].iov_len;
}
assert (nbytes == -1 || (size_t) nbytes == len);
}
#endif
}
else
{
DDS_TRACE("(dropped)");

View file

@ -17,7 +17,7 @@
*/
#define BYTES_PER_SEC_TO_MEGABITS_PER_SEC 125000
#define MAX_SAMPLES 100
#define MAX_SAMPLES 1000
typedef struct HandleEntry
{
@ -31,7 +31,7 @@ typedef struct HandleMap
HandleEntry *entries;
} HandleMap;
static long pollingDelay = 0;
static long pollingDelay = -1; /* i.e. use a listener */
static HandleMap * imap;
static unsigned long long outOfOrder = 0;
@ -39,8 +39,6 @@ static unsigned long long total_bytes = 0;
static unsigned long long total_samples = 0;
static dds_time_t startTime = 0;
static dds_time_t time_now = 0;
static dds_time_t prev_time = 0;
static unsigned long payloadSize = 0;
@ -48,9 +46,8 @@ static ThroughputModule_DataType data [MAX_SAMPLES];
static void * samples[MAX_SAMPLES];
static dds_entity_t waitSet;
static dds_entity_t pollingWaitset;
static bool done = false;
static volatile sig_atomic_t done = false;
/* Forward declarations */
static HandleMap * HandleMap__alloc (void);
@ -60,7 +57,7 @@ static HandleEntry * retrieve_handle (HandleMap *map, dds_instance_handle_t key)
static void data_available_handler (dds_entity_t reader, void *arg);
static int parse_args(int argc, char **argv, unsigned long long *maxCycles, char **partitionName);
static void process_samples(unsigned long long maxCycles);
static void process_samples(dds_entity_t reader, unsigned long long maxCycles);
static dds_entity_t prepare_dds(dds_entity_t *reader, const char *partitionName);
static void finalize_dds(dds_entity_t participant);
@ -91,9 +88,6 @@ int main (int argc, char **argv)
dds_entity_t participant;
dds_entity_t reader;
time_now = dds_time ();
prev_time = time_now;
/* Register handler for Ctrl-C */
#ifdef _WIN32
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, true);
@ -110,8 +104,7 @@ int main (int argc, char **argv)
return EXIT_FAILURE;
}
printf ("Cycles: %llu | PollingDelay: %lu | Partition: %s\n",
maxCycles, pollingDelay, partitionName);
printf ("Cycles: %llu | PollingDelay: %ld | Partition: %s\n", maxCycles, pollingDelay, partitionName);
participant = prepare_dds(&reader, partitionName);
@ -119,7 +112,7 @@ int main (int argc, char **argv)
/* Process samples until Ctrl-C is pressed or until maxCycles */
/* has been reached (0 = infinite) */
process_samples(maxCycles);
process_samples(reader, maxCycles);
/* Finished, disable callbacks */
dds_set_status_mask (reader, 0);
@ -189,13 +182,12 @@ static HandleEntry * retrieve_handle (HandleMap *map, dds_instance_handle_t key)
return entry;
}
static void data_available_handler (dds_entity_t reader, void *arg)
static int do_take (dds_entity_t reader)
{
int samples_received;
dds_sample_info_t info [MAX_SAMPLES];
dds_instance_handle_t ph = 0;
HandleEntry * current = NULL;
(void)arg;
if (startTime == 0)
{
@ -234,11 +226,13 @@ static void data_available_handler (dds_entity_t reader, void *arg)
total_samples++;
}
}
time_now = dds_time ();
if ((pollingDelay == 0) && (time_now > (prev_time + DDS_SECS (1))))
{
dds_waitset_set_trigger (pollingWaitset, true);
return samples_received;
}
static void data_available_handler (dds_entity_t reader, void *arg)
{
(void)arg;
do_take (reader);
}
static int parse_args(int argc, char **argv, unsigned long long *maxCycles, char **partitionName)
@ -250,7 +244,7 @@ static int parse_args(int argc, char **argv, unsigned long long *maxCycles, char
if (argc == 2 && (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0))
{
printf ("Usage (parameters must be supplied in order):\n");
printf ("./subscriber [maxCycles (0 = infinite)] [pollingDelay (ms, 0 = event based)] [partitionName]\n");
printf ("./subscriber [maxCycles (0 = infinite)] [pollingDelay (ms, 0 = waitset, -1 = listener)] [partitionName]\n");
printf ("Defaults:\n");
printf ("./subscriber 0 0 \"Throughput example\"\n");
return EXIT_FAILURE;
@ -262,7 +256,7 @@ static int parse_args(int argc, char **argv, unsigned long long *maxCycles, char
}
if (argc > 2)
{
pollingDelay = atoi (argv[2]); /* The number of ms to wait between reads (0 = event based) */
pollingDelay = atoi (argv[2]); /* The number of ms to wait between reads (0 = waitset, -1 = listener) */
}
if (argc > 3)
{
@ -271,61 +265,59 @@ static int parse_args(int argc, char **argv, unsigned long long *maxCycles, char
return EXIT_SUCCESS;
}
static void process_samples(unsigned long long maxCycles)
static void process_samples(dds_entity_t reader, unsigned long long maxCycles)
{
dds_return_t status;
unsigned long long prev_bytes = 0;
unsigned long long prev_samples = 0;
dds_attach_t wsresults[1];
size_t wsresultsize = 1U;
dds_attach_t wsresults[2];
dds_time_t deltaTv;
bool first_batch = true;
unsigned long cycles = 0;
double deltaTime = 0;
dds_time_t prev_time = 0;
dds_time_t time_now = 0;
while (!done && (maxCycles == 0 || cycles < maxCycles))
{
if (pollingDelay)
if (pollingDelay > 0)
{
dds_sleepfor (DDS_MSECS (pollingDelay));
while (do_take (reader))
;
}
else
{
status = dds_waitset_wait (waitSet, wsresults, wsresultsize, DDS_INFINITY);
status = dds_waitset_wait (waitSet, wsresults, sizeof(wsresults)/sizeof(wsresults[0]), DDS_SECS(1));
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
if ((status > 0 ) && (dds_triggered (pollingWaitset)))
{
dds_waitset_set_trigger (pollingWaitset, false);
}
while (do_take (reader))
;
}
time_now = dds_time();
if (!first_batch)
{
deltaTv = time_now - prev_time;
deltaTime = (double) deltaTv / DDS_NSECS_IN_SEC;
prev_time = time_now;
printf
(
"=== [Subscriber] Payload size: %lu | Total received: %llu samples, %llu bytes | Out of order: %llu samples "
if (deltaTime >= 1.0 && total_samples != prev_samples)
{
printf ("=== [Subscriber] %5.3f Payload size: %lu | Total received: %llu samples, %llu bytes | Out of order: %llu samples "
"Transfer rate: %.2lf samples/s, %.2lf Mbit/s\n",
payloadSize, total_samples, total_bytes, outOfOrder,
deltaTime, payloadSize, total_samples, total_bytes, outOfOrder,
(deltaTime != 0.0) ? ((double)(total_samples - prev_samples) / deltaTime) : 0,
(deltaTime != 0.0) ? ((double)((total_bytes - prev_bytes) / BYTES_PER_SEC_TO_MEGABITS_PER_SEC) / deltaTime) : 0
);
(deltaTime != 0.0) ? ((double)((total_bytes - prev_bytes) / BYTES_PER_SEC_TO_MEGABITS_PER_SEC) / deltaTime) : 0);
cycles++;
prev_time = time_now;
prev_bytes = total_bytes;
prev_samples = total_samples;
}
}
else
{
prev_time = time_now;
first_batch = false;
}
/* Update the previous values for next iteration */
prev_bytes = total_bytes;
prev_samples = total_samples;
}
/* Output totals and averages */
@ -345,7 +337,7 @@ static dds_entity_t prepare_dds(dds_entity_t *reader, const char *partitionName)
dds_listener_t *rd_listener;
dds_entity_t participant;
int32_t maxSamples = 400;
int32_t maxSamples = 4000;
const char *subParts[1];
dds_qos_t *subQos = dds_create_qos ();
dds_qos_t *drQos = dds_create_qos ();
@ -381,12 +373,6 @@ static dds_entity_t prepare_dds(dds_entity_t *reader, const char *partitionName)
waitSet = dds_create_waitset (participant);
DDS_ERR_CHECK (waitSet, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
pollingWaitset = dds_create_waitset (participant);
DDS_ERR_CHECK (pollingWaitset, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
status = dds_waitset_attach (waitSet, pollingWaitset, pollingWaitset);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
status = dds_waitset_attach (waitSet, waitSet, waitSet);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
@ -398,8 +384,15 @@ static dds_entity_t prepare_dds(dds_entity_t *reader, const char *partitionName)
samples[i] = &data[i];
}
*reader = dds_create_reader (subscriber, topic, drQos, rd_listener);
*reader = dds_create_reader (subscriber, topic, drQos, pollingDelay < 0 ? rd_listener : NULL);
DDS_ERR_CHECK (*reader, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
if (pollingDelay == 0)
{
status = dds_waitset_attach (waitSet, *reader, *reader);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
}
dds_delete_qos (drQos);
dds_delete_listener(rd_listener);
@ -417,10 +410,6 @@ static void finalize_dds(dds_entity_t participant)
status = dds_waitset_detach (waitSet, waitSet);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
status = dds_waitset_detach (waitSet, pollingWaitset);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
status = dds_delete (pollingWaitset);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
status = dds_delete (waitSet);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
status = dds_delete (participant);

View file

@ -140,9 +140,9 @@ static void gethostbyname_test(char *name, int af, int ret)
}
CU_TheoryDataPoints(os_gethostbyname, ipv4) = {
CU_DataPoints(char *, "", "_nah", "127.0.0.1", "127.0.0.1"),
CU_DataPoints(int, AF_UNSPEC, AF_UNSPEC, AF_INET, AF_UNSPEC),
CU_DataPoints(int, OS_HOST_NOT_FOUND, OS_HOST_NOT_FOUND, 0, 0)
CU_DataPoints(char *, "", "127.0.0.1", "127.0.0.1"),
CU_DataPoints(int, AF_UNSPEC, AF_INET, AF_UNSPEC),
CU_DataPoints(int, OS_HOST_NOT_FOUND, 0, 0)
};
CU_Theory((char *name, int af, int ret), os_gethostbyname, ipv4, .init=setup, .fini=teardown)

View file

@ -2308,7 +2308,6 @@ int MAIN(int argc, char *argv[]) {
qpublisher[nqpublisher++] = q;
qsubscriber[nqsubscriber++] = q;
break;
break;
default:
assert(0);
}