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) add_definitions(/W3)
endif() 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 # 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 # the address sanitizer for ordinary debug builds; gcc is giving some grief on
# Travis, so don't enable it for gcc by default # 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 /** @name Communication Status definitions
@{**/ @{**/
/** Another topic exists with the same name but with different characteristics. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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). */ /** 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. */ /** 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. */ /** 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. */ /** 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". */ /** 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". */ /** 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. */ /** 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. */ /** 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 */ /** Read state for a data value */
@ -685,7 +701,7 @@ dds_set_qos(
*/ */
/* TODO: Link to (generic) Listener and status information. */ /* TODO: Link to (generic) Listener and status information. */
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK) _Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)
DDS_EXPORT _Check_return_ dds_return_t DDS_EXPORT dds_return_t
dds_get_listener( dds_get_listener(
_In_ dds_entity_t entity, _In_ dds_entity_t entity,
_Out_ dds_listener_t * listener); _Out_ dds_listener_t * listener);
@ -744,7 +760,7 @@ dds_get_listener(
*/ */
/* TODO: Link to (generic) Listener and status information. */ /* TODO: Link to (generic) Listener and status information. */
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK) _Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)
DDS_EXPORT _Check_return_ dds_return_t DDS_EXPORT dds_return_t
dds_set_listener( dds_set_listener(
_In_ dds_entity_t entity, _In_ dds_entity_t entity,
_In_opt_ const dds_listener_t * listener); _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_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); typedef void (*dds_on_subscription_matched_fn) (dds_entity_t reader, const dds_subscription_matched_status_t status, void* arg);
#if 0 #define DDS_LUNSET 0
/* TODO: Why use (*dds_on_any_fn) (); and DDS_LUNSET? Why not just set the callbacks to NULL? */ struct dds_listener;
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 */ typedef struct dds_listener dds_listener_t;
#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;
/** /**
* @brief Allocate memory and initializes to default values (::DDS_LUNSET) of a listener * @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_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); DDS_DEPRECATED_EXPORT void dds_listener_merge (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src);
/************************************************************************************************ /************************************************************************************************
* Setters * 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 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); 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)) inline char dds_stream_read_char (dds_stream_t *is) { return (char) dds_stream_read_uint8 (is); }
#define dds_stream_read_int8(s) ((int8_t) dds_stream_read_uint8 (s)) inline int8_t dds_stream_read_int8 (dds_stream_t *is) { return (int8_t) dds_stream_read_uint8 (is); }
#define dds_stream_read_int16(s) ((int16_t) dds_stream_read_uint16 (s)) inline int16_t dds_stream_read_int16 (dds_stream_t *is) { return (int16_t) dds_stream_read_uint16 (is); }
#define dds_stream_read_int32(s) ((int32_t) dds_stream_read_uint32 (s)) inline int32_t dds_stream_read_int32 (dds_stream_t *is) { return (int32_t) dds_stream_read_uint32 (is); }
#define dds_stream_read_int64(s) ((int64_t) dds_stream_read_uint64 (s)) 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_bool (dds_stream_t * os, bool val);
DDS_EXPORT void dds_stream_write_uint8 (dds_stream_t * os, uint8_t 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_address (dds_stream_t * s);
DDS_EXPORT void *dds_stream_alignto (dds_stream_t * s, uint32_t a); 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))) inline void dds_stream_write_char (dds_stream_t * os, char val) { dds_stream_write_uint8 (os, (uint8_t) val); }
#define dds_stream_write_int8(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v))) inline void dds_stream_write_int8 (dds_stream_t * os, int8_t val) { dds_stream_write_uint8 (os, (uint8_t) val); }
#define dds_stream_write_int16(s,v) (dds_stream_write_uint16 ((s), (uint16_t)(v))) inline void dds_stream_write_int16 (dds_stream_t * os, int16_t val) { dds_stream_write_uint16 (os, (uint16_t) val); }
#define dds_stream_write_int32(s,v) (dds_stream_write_uint32 ((s), (uint32_t)(v))) inline void dds_stream_write_int32 (dds_stream_t * os, int32_t val) { dds_stream_write_uint32 (os, (uint32_t) val); }
#define dds_stream_write_int64(s,v) (dds_stream_write_uint64 ((s), (uint64_t)(v))) inline void dds_stream_write_int64 (dds_stream_t * os, int64_t val) { dds_stream_write_uint64 (os, (uint64_t) val); }
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -37,25 +37,50 @@ void
dds_entity_add_ref_nolock( dds_entity_add_ref_nolock(
_In_ dds_entity *e); _In_ dds_entity *e);
_Check_return_ dds__retcode_t #define DEFINE_ENTITY_LOCK_UNLOCK(qualifier_, type_, kind_) \
dds_entity_listener_propagation( qualifier_ dds__retcode_t type_##_lock (dds_entity_t hdl, type_ **x) \
_Inout_opt_ dds_entity *e, { \
_In_ dds_entity *src, dds__retcode_t rc; \
_In_ uint32_t status, dds_entity *e; \
_In_opt_ void *metrics, if ((rc = dds_entity_lock (hdl, kind_, &e)) != DDS_RETCODE_OK) \
_In_ bool propagate); 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)) void dds_entity_status_set (dds_entity *e, uint32_t 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)
/* The mutex needs to be unlocked when calling this because the entity can be called inline void dds_entity_status_reset (dds_entity *e, uint32_t t) {
* within the signal callback from other contexts. That shouldn't deadlock. */ e->m_trigger &= ~t;
void }
dds_entity_status_signal(
_In_ dds_entity *e); 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 _Check_return_ dds__retcode_t
dds_valid_hdl( dds_valid_hdl(
@ -74,8 +99,6 @@ void
dds_entity_unlock( dds_entity_unlock(
_Inout_ dds_entity *e); _Inout_ dds_entity *e);
#define dds_entity_kind(hdl) ((hdl > 0) ? (hdl & DDS_ENTITY_KIND_MASK) : 0)
_Check_return_ dds__retcode_t _Check_return_ dds__retcode_t
dds_entity_observer_register_nl( dds_entity_observer_register_nl(
_In_ dds_entity* observed, _In_ dds_entity* observed,

View file

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

View file

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

View file

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

View file

@ -13,6 +13,7 @@
#define _DDS_READER_H_ #define _DDS_READER_H_
#include "dds__types.h" #include "dds__types.h"
#include "dds__entity.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -20,7 +21,9 @@ extern "C" {
struct status_cb_data; struct status_cb_data;
void dds_reader_status_cb (void * entity, const struct status_cb_data * 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 dds_reader_lock_samples: Returns number of samples in read cache and locks the
@ -40,8 +43,7 @@ struct nn_rsample_info;
struct nn_rdata; 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); 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_ENTITY_LOCK_UNLOCK(inline, dds_reader, DDS_KIND_READER)
#define dds_reader_unlock(obj) dds_entity_unlock((dds_entity*)obj);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -13,13 +13,13 @@
#define _DDS_TOPIC_H_ #define _DDS_TOPIC_H_
#include "dds__types.h" #include "dds__types.h"
#include "dds__entity.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
#define dds_topic_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_TOPIC, (dds_entity**)obj) DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_topic, DDS_KIND_TOPIC)
#define dds_topic_unlock(obj) dds_entity_unlock((dds_entity*)obj);
extern struct ddsi_sertopic * dds_topic_lookup (dds_domain * domain, const char * name); 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); 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. */ /* The listener struct. */
typedef struct c_listener { struct dds_listener {
dds_on_inconsistent_topic_fn on_inconsistent_topic; uint32_t inherited;
dds_on_liveliness_lost_fn on_liveliness_lost; dds_on_inconsistent_topic_fn on_inconsistent_topic;
dds_on_offered_deadline_missed_fn on_offered_deadline_missed; void *on_inconsistent_topic_arg;
dds_on_offered_incompatible_qos_fn on_offered_incompatible_qos; dds_on_liveliness_lost_fn on_liveliness_lost;
dds_on_data_on_readers_fn on_data_on_readers; void *on_liveliness_lost_arg;
dds_on_sample_lost_fn on_sample_lost; dds_on_offered_deadline_missed_fn on_offered_deadline_missed;
dds_on_data_available_fn on_data_available; void *on_offered_deadline_missed_arg;
dds_on_sample_rejected_fn on_sample_rejected; dds_on_offered_incompatible_qos_fn on_offered_incompatible_qos;
dds_on_liveliness_changed_fn on_liveliness_changed; void *on_offered_incompatible_qos_arg;
dds_on_requested_deadline_missed_fn on_requested_deadline_missed; dds_on_data_on_readers_fn on_data_on_readers;
dds_on_requested_incompatible_qos_fn on_requested_incompatible_qos; void *on_data_on_readers_arg;
dds_on_publication_matched_fn on_publication_matched; dds_on_sample_lost_fn on_sample_lost;
dds_on_subscription_matched_fn on_subscription_matched; void *on_sample_lost_arg;
void *arg; dds_on_data_available_fn on_data_available;
} c_listener_t; 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 *on_subscription_matched_arg;
};
/* Entity flag values */ /* Entity flag values */
@ -98,7 +111,6 @@ typedef struct dds_entity_deriver {
dds_return_t (*delete)(struct dds_entity *e); 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 (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled);
dds_return_t (*validate_status)(uint32_t mask); 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_return_t (*get_instance_hdl)(struct dds_entity *e, dds_instance_handle_t *i);
} }
dds_entity_deriver; dds_entity_deriver;
@ -126,15 +138,18 @@ typedef struct dds_entity
dds_qos_t * m_qos; dds_qos_t * m_qos;
dds_domainid_t m_domainid; dds_domainid_t m_domainid;
nn_guid_t m_guid; nn_guid_t m_guid;
uint32_t m_status_enable;
uint32_t m_flags; uint32_t m_flags;
uint32_t m_cb_count;
os_mutex m_mutex; os_mutex m_mutex;
os_cond m_cond; os_cond m_cond;
c_listener_t m_listener;
uint32_t m_trigger;
os_mutex m_observers_lock; 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; dds_entity_observer *m_observers;
struct ut_handlelink *m_hdllink; struct ut_handlelink *m_hdllink;
} }
dds_entity; dds_entity;

View file

@ -18,8 +18,7 @@
extern "C" { extern "C" {
#endif #endif
#define dds_writer_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_WRITER, (dds_entity**)obj) DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_writer, DDS_KIND_WRITER)
#define dds_writer_unlock(obj) dds_entity_unlock((dds_entity*)obj);
#if defined (__cplusplus) #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_return_t ret;
dds_entity_t pp; dds_entity_t pp;
dds_participant *p; dds_participant *p;
dds_entity *part_entity;
if ((pp = dds_get_participant (e)) <= 0) if ((pp = dds_get_participant (e)) <= 0)
return pp; 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; return ret;
p = (dds_participant *) part_entity;
if (p->m_builtin_subscriber <= 0) { 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; sub = p->m_builtin_subscriber;
dds_entity_unlock(part_entity); dds_participant_unlock(p);
return sub; return sub;
} }

View file

@ -27,7 +27,7 @@ dds_begin_coherent(
{ {
dds_return_t ret; dds_return_t ret;
switch(dds_entity_kind(entity)) { switch(dds_entity_kind_from_handle(entity)) {
case DDS_KIND_READER: case DDS_KIND_READER:
case DDS_KIND_WRITER: case DDS_KIND_WRITER:
/* Invoking on a writer/reader behaves as if invoked on /* Invoking on a writer/reader behaves as if invoked on
@ -58,7 +58,7 @@ dds_end_coherent(
{ {
dds_return_t ret; dds_return_t ret;
switch(dds_entity_kind(entity)) { switch(dds_entity_kind_from_handle(entity)) {
case DDS_KIND_READER: case DDS_KIND_READER:
case DDS_KIND_WRITER: case DDS_KIND_WRITER:
/* Invoking on a writer/reader behaves as if invoked on /* 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) 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) 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 <string.h>
#include "dds__reader.h" #include "dds__reader.h"
#include "dds__guardcond.h" #include "dds__guardcond.h"
#include "dds__entity.h" #include "dds__participant.h"
#include "dds__err.h" #include "dds__err.h"
#include "ddsi/q_ephash.h" #include "ddsi/q_ephash.h"
#include "ddsi/q_entity.h" #include "ddsi/q_entity.h"
#include "ddsi/q_thread.h" #include "ddsi/q_thread.h"
_Must_inspect_result_ dds_guardcond* DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_guardcond)
dds_create_guardcond(
_In_ dds_participant *pp) dds_entity_t dds_create_guardcondition (dds_entity_t participant)
{ {
dds_guardcond * gcond = dds_alloc(sizeof(*gcond)); dds_participant *pp;
gcond->m_entity.m_hdl = dds_entity_init(&gcond->m_entity, (dds_entity*)pp, DDS_KIND_COND_GUARD, NULL, NULL, 0); dds__retcode_t rc;
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);
}
if ((rc = dds_participant_lock (participant, &pp)) != DDS_RETCODE_OK)
return DDS_ERRNO (rc);
else
{
dds_guardcond * gcond = dds_alloc (sizeof (*gcond));
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; return hdl;
}
} }
_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) ) dds_return_t dds_set_guardcondition (dds_entity_t condition, bool triggered)
dds_return_t
dds_set_guardcondition(
_In_ dds_entity_t condition,
_In_ bool triggered)
{ {
dds_return_t ret; dds_guardcond *gcond;
dds_guardcond *gcond; dds__retcode_t rc;
dds__retcode_t rc;
rc = dds_entity_lock(condition, DDS_KIND_COND_GUARD, (dds_entity**)&gcond); if ((rc = dds_guardcond_lock (condition, &gcond)) != DDS_RETCODE_OK)
if (rc == DDS_RETCODE_OK) { return DDS_ERRNO (dds_valid_hdl (condition, DDS_KIND_COND_GUARD));
if (triggered) { else
dds_entity_status_set(gcond, DDS_WAITSET_TRIGGER_STATUS); {
dds_entity_status_signal(&gcond->m_entity); os_mutexLock (&gcond->m_entity.m_observers_lock);
} else { if (triggered)
dds_entity_status_reset(gcond, DDS_WAITSET_TRIGGER_STATUS); dds_entity_status_set (&gcond->m_entity, DDS_WAITSET_TRIGGER_STATUS);
} else
dds_entity_unlock(&gcond->m_entity); dds_entity_status_reset (&gcond->m_entity, DDS_WAITSET_TRIGGER_STATUS);
ret = DDS_RETCODE_OK; os_mutexUnlock (&gcond->m_entity.m_observers_lock);
} else { dds_guardcond_unlock (gcond);
DDS_ERROR("Argument condition is not valid\n"); return DDS_RETCODE_OK;
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 (dds_entity_t condition, bool *triggered)
dds_return_t
dds_read_guardcondition(
_In_ dds_entity_t condition,
_Out_ bool *triggered)
{ {
dds_return_t ret; dds_guardcond *gcond;
dds_guardcond *gcond; dds__retcode_t rc;
dds__retcode_t rc;
if (triggered != NULL) { if (triggered == NULL)
*triggered = false; return DDS_ERRNO (DDS_RETCODE_BAD_PARAMETER);
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; *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);
os_mutexUnlock (&gcond->m_entity.m_observers_lock);
dds_guardcond_unlock (gcond);
return DDS_RETCODE_OK;
}
} }
_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_GUARD) ) dds_return_t dds_take_guardcondition (dds_entity_t condition, bool *triggered)
dds_return_t
dds_take_guardcondition(
_In_ dds_entity_t condition,
_Out_ bool *triggered)
{ {
dds_return_t ret; dds_guardcond *gcond;
dds_guardcond *gcond; dds__retcode_t rc;
dds__retcode_t rc;
if (triggered != NULL) { if (triggered == NULL)
*triggered = false; return DDS_ERRNO (DDS_RETCODE_BAD_PARAMETER);
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);
}
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,21 +81,22 @@ dds_instance_remove(
} }
} }
static const dds_topic* static const dds_topic *dds_instance_info (dds_entity *e)
dds_instance_info(
_In_ dds_entity *e)
{ {
const dds_topic *topic = NULL; const dds_topic *topic;
switch (dds_entity_kind (e))
assert (e); {
assert ((dds_entity_kind(e->m_hdl) == DDS_KIND_READER) || (dds_entity_kind(e->m_hdl) == DDS_KIND_WRITER)); case DDS_KIND_READER:
topic = ((dds_reader*) e)->m_topic;
if (dds_entity_kind(e->m_hdl) == DDS_KIND_READER) { break;
topic = ((dds_reader*)e)->m_topic; case DDS_KIND_WRITER:
} else { topic = ((dds_writer*) e)->m_topic;
topic = ((dds_writer*)e)->m_topic; break;
} default:
return topic; assert (0);
topic = NULL;
}
return topic;
} }
static const dds_topic * dds_instance_info_by_hdl (dds_entity_t e) static const dds_topic * dds_instance_info_by_hdl (dds_entity_t e)
@ -127,7 +128,7 @@ dds_register_instance(
struct thread_state1 * const thr = lookup_thread_state(); struct thread_state1 * const thr = lookup_thread_state();
const bool asleep = !vtime_awake_p(thr->vtime); const bool asleep = !vtime_awake_p(thr->vtime);
struct ddsi_tkmap_instance * inst; struct ddsi_tkmap_instance * inst;
dds_entity *wr; dds_writer *wr;
dds_return_t ret; dds_return_t ret;
dds__retcode_t rc; dds__retcode_t rc;
@ -141,7 +142,7 @@ dds_register_instance(
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
goto err; goto err;
} }
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr); rc = dds_writer_lock(writer, &wr);
if (rc != DDS_RETCODE_OK) { if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n"); DDS_ERROR("Error occurred on locking writer\n");
ret = DDS_ERRNO(rc); ret = DDS_ERRNO(rc);
@ -150,7 +151,7 @@ dds_register_instance(
if (asleep) { if (asleep) {
thread_state_awake(thr); 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){ if(inst != NULL){
*handle = inst->m_iid; *handle = inst->m_iid;
ret = DDS_RETCODE_OK; ret = DDS_RETCODE_OK;
@ -161,7 +162,7 @@ dds_register_instance(
if (asleep) { if (asleep) {
thread_state_asleep(thr); thread_state_asleep(thr);
} }
dds_entity_unlock(wr); dds_writer_unlock(wr);
err: err:
return ret; return ret;
} }
@ -197,8 +198,7 @@ dds_unregister_instance_ts(
dds__retcode_t rc; dds__retcode_t rc;
bool autodispose = true; bool autodispose = true;
dds_write_action action = DDS_WR_ACTION_UNREGISTER; dds_write_action action = DDS_WR_ACTION_UNREGISTER;
void * sample = (void*) data; dds_writer *wr;
dds_entity *wr;
if (data == NULL){ if (data == NULL){
DDS_ERROR("Argument data is NULL\n"); DDS_ERROR("Argument data is NULL\n");
@ -210,28 +210,28 @@ dds_unregister_instance_ts(
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER);
goto err; goto err;
} }
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr); rc = dds_writer_lock(writer, &wr);
if (rc != DDS_RETCODE_OK) { if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n"); DDS_ERROR("Error occurred on locking writer\n");
ret = DDS_ERRNO(rc); ret = DDS_ERRNO(rc);
goto err; goto err;
} }
if (wr->m_qos) { if (wr->m_entity.m_qos) {
dds_qget_writer_data_lifecycle (wr->m_qos, &autodispose); dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
} }
if (asleep) { if (asleep) {
thread_state_awake(thr); thread_state_awake(thr);
} }
if (autodispose) { 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; 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) { if (asleep) {
thread_state_asleep(thr); thread_state_asleep(thr);
} }
dds_entity_unlock(wr); dds_writer_unlock(wr);
err: err:
return ret; return ret;
} }
@ -249,21 +249,21 @@ dds_unregister_instance_ih_ts(
dds__retcode_t rc; dds__retcode_t rc;
bool autodispose = true; bool autodispose = true;
dds_write_action action = DDS_WR_ACTION_UNREGISTER; dds_write_action action = DDS_WR_ACTION_UNREGISTER;
dds_entity *wr; dds_writer *wr;
struct ddsi_tkmap_instance *tk; 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) { if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n"); DDS_ERROR("Error occurred on locking writer\n");
ret = DDS_ERRNO(rc); ret = DDS_ERRNO(rc);
goto err; goto err;
} }
if (wr->m_qos) { if (wr->m_entity.m_qos) {
dds_qget_writer_data_lifecycle (wr->m_qos, &autodispose); dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
} }
if (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; action |= DDS_WR_DISPOSE_BIT;
} }
@ -272,11 +272,11 @@ dds_unregister_instance_ih_ts(
} }
tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle); tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
if (tk) { 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); void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL); ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk); 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); ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
} else { } else {
DDS_ERROR("No instance related with the provided handle is found\n"); DDS_ERROR("No instance related with the provided handle is found\n");
@ -285,7 +285,7 @@ dds_unregister_instance_ih_ts(
if (asleep) { if (asleep) {
thread_state_asleep(thr); thread_state_asleep(thr);
} }
dds_entity_unlock(wr); dds_writer_unlock(wr);
err: err:
return ret; return ret;
} }
@ -392,7 +392,7 @@ dds_dispose_ih_ts(
thread_state_awake(thr); thread_state_awake(thr);
} }
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) != NULL) { 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); void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL); ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk); ddsi_tkmap_instance_unref (tk);

View file

@ -13,163 +13,200 @@
#include "ddsc/dds.h" #include "ddsc/dds.h"
#include "dds__listener.h" #include "dds__listener.h"
dds_listener_t *dds_create_listener (void* arg)
_Ret_notnull_
dds_listener_t*
dds_create_listener(_In_opt_ void* arg)
{ {
c_listener_t *l = dds_alloc(sizeof(*l)); dds_listener_t *l = dds_alloc (sizeof (*l));
dds_reset_listener(l); dds_reset_listener (l);
l->arg = arg; l->on_inconsistent_topic_arg = arg;
return l; 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 (void* arg)
dds_listener_t*
dds_listener_create(_In_opt_ void* arg)
{ {
return dds_create_listener(arg); return dds_create_listener (arg);
} }
void void dds_delete_listener (dds_listener_t * __restrict listener)
dds_delete_listener(_In_ _Post_invalid_ dds_listener_t * __restrict listener)
{ {
if (listener) { dds_free (listener);
dds_free(listener);
}
} }
void void dds_listener_delete (dds_listener_t * __restrict listener)
dds_listener_delete(_In_ _Post_invalid_ dds_listener_t * __restrict listener)
{ {
dds_delete_listener(listener); dds_delete_listener (listener);
} }
void void dds_reset_listener (dds_listener_t * __restrict listener)
dds_reset_listener(_Out_ dds_listener_t * __restrict listener)
{ {
if (listener) { if (listener)
c_listener_t *l = listener; {
l->on_data_available = DDS_LUNSET; dds_listener_t * const l = listener;
l->on_data_on_readers = DDS_LUNSET; l->inherited = 0;
l->on_inconsistent_topic = DDS_LUNSET; l->on_data_available = 0;
l->on_liveliness_changed = DDS_LUNSET; l->on_data_on_readers = 0;
l->on_liveliness_lost = DDS_LUNSET; l->on_inconsistent_topic = 0;
l->on_offered_deadline_missed = DDS_LUNSET; l->on_liveliness_changed = 0;
l->on_offered_incompatible_qos = DDS_LUNSET; l->on_liveliness_lost = 0;
l->on_publication_matched = DDS_LUNSET; l->on_offered_deadline_missed = 0;
l->on_requested_deadline_missed = DDS_LUNSET; l->on_offered_incompatible_qos = 0;
l->on_requested_incompatible_qos = DDS_LUNSET; l->on_publication_matched = 0;
l->on_sample_lost = DDS_LUNSET; l->on_requested_deadline_missed = 0;
l->on_sample_rejected = DDS_LUNSET; l->on_requested_incompatible_qos = 0;
l->on_subscription_matched = DDS_LUNSET; l->on_sample_lost = 0;
} else { l->on_sample_rejected = 0;
DDS_ERROR("Argument listener is NULL\n"); l->on_subscription_matched = 0;
} }
} }
void void dds_listener_reset (dds_listener_t * __restrict listener)
dds_listener_reset(_Out_ dds_listener_t * __restrict listener)
{ {
dds_reset_listener(listener); dds_reset_listener (listener);
} }
void void dds_copy_listener (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
dds_copy_listener(_Out_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
{ {
const c_listener_t *srcl = src; if (dst && src)
c_listener_t *dstl = dst; *dst = *src;
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;
} }
void void dds_listener_copy(dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
dds_listener_copy(_Out_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
{ {
dds_copy_listener(dst, src); dds_copy_listener (dst, src);
} }
void static bool dds_combine_listener_merge (uint32_t inherited, void (*dst)(void), void (*src)(void))
dds_merge_listener (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
{ {
const c_listener_t *srcl = src; (void)inherited;
c_listener_t *dstl = dst; (void)src;
return dst == 0;
if(!src){
DDS_ERROR("Argument source(src) is NULL\n");
return ;
}
if(!dst){
DDS_ERROR("Argument destination(dst) is NULL\n");
return ;
}
if (dstl->on_data_available == DDS_LUNSET) {
dstl->on_data_available = srcl->on_data_available;
}
if (dstl->on_data_on_readers == DDS_LUNSET) {
dstl->on_data_on_readers = srcl->on_data_on_readers;
}
if (dstl->on_inconsistent_topic == DDS_LUNSET) {
dstl->on_inconsistent_topic = srcl->on_inconsistent_topic;
}
if (dstl->on_liveliness_changed == DDS_LUNSET) {
dstl->on_liveliness_changed = srcl->on_liveliness_changed;
}
if (dstl->on_liveliness_lost == DDS_LUNSET) {
dstl->on_liveliness_lost = srcl->on_liveliness_lost;
}
if (dstl->on_offered_deadline_missed == DDS_LUNSET) {
dstl->on_offered_deadline_missed = srcl->on_offered_deadline_missed;
}
if (dstl->on_offered_incompatible_qos == DDS_LUNSET) {
dstl->on_offered_incompatible_qos = srcl->on_offered_incompatible_qos;
}
if (dstl->on_publication_matched == DDS_LUNSET) {
dstl->on_publication_matched = srcl->on_publication_matched;
}
if (dstl->on_requested_deadline_missed == DDS_LUNSET) {
dstl->on_requested_deadline_missed = srcl->on_requested_deadline_missed;
}
if (dstl->on_requested_incompatible_qos == DDS_LUNSET) {
dstl->on_requested_incompatible_qos = srcl->on_requested_incompatible_qos;
}
if (dstl->on_sample_lost == DDS_LUNSET) {
dstl->on_sample_lost = srcl->on_sample_lost;
}
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;
}
} }
void static bool dds_combine_listener_override_inherited (uint32_t inherited, void (*dst)(void), void (*src)(void))
dds_listener_merge (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
{ {
dds_merge_listener(dst, src); (void)dst;
(void)src;
return inherited;
}
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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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_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) dds_lset_data_available (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_available_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_data_available = callback; listener->on_data_available = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_data_on_readers (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_on_readers_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_data_on_readers = callback; listener->on_data_on_readers = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_inconsistent_topic (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_inconsistent_topic_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_inconsistent_topic = callback; listener->on_inconsistent_topic = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_liveliness_changed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_changed_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_liveliness_changed = callback; listener->on_liveliness_changed = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_liveliness_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_lost_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_liveliness_lost = callback; listener->on_liveliness_lost = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_offered_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_deadline_missed_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_offered_deadline_missed = callback; listener->on_offered_deadline_missed = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_offered_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_incompatible_qos_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_offered_incompatible_qos = callback; listener->on_offered_incompatible_qos = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_publication_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_publication_matched_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_publication_matched = callback; listener->on_publication_matched = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL"); 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) dds_lset_requested_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_deadline_missed_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_requested_deadline_missed = callback; listener->on_requested_deadline_missed = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_requested_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_incompatible_qos_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_requested_incompatible_qos = callback; listener->on_requested_incompatible_qos = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_sample_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_lost_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_sample_lost = callback; listener->on_sample_lost = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_sample_rejected (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_rejected_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_sample_rejected = callback; listener->on_sample_rejected = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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) dds_lset_subscription_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_subscription_matched_fn callback)
{ {
if (listener) { if (listener) {
((c_listener_t*)listener)->on_subscription_matched = callback; listener->on_subscription_matched = callback;
} else { } else {
DDS_ERROR("Argument listener is NULL\n"); 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"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_data_available; *callback = listener->on_data_available;
} }
void 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"); DDS_ERROR("Argument listener is NULL\n");
return ; 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) 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"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_inconsistent_topic; *callback = listener->on_inconsistent_topic;
} }
void void
@ -362,7 +399,7 @@ dds_lget_liveliness_changed (_In_ const dds_listener_t * __restrict listener, _O
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_liveliness_changed; *callback = listener->on_liveliness_changed;
} }
void void
@ -376,7 +413,7 @@ dds_lget_liveliness_lost (_In_ const dds_listener_t * __restrict listener, _Outp
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_liveliness_lost; *callback = listener->on_liveliness_lost;
} }
void void
@ -390,7 +427,7 @@ dds_lget_offered_deadline_missed (_In_ const dds_listener_t * __restrict listene
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_offered_deadline_missed; *callback = listener->on_offered_deadline_missed;
} }
void void
@ -404,7 +441,7 @@ dds_lget_offered_incompatible_qos (_In_ const dds_listener_t * __restrict listen
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_offered_incompatible_qos; *callback = listener->on_offered_incompatible_qos;
} }
void void
@ -418,7 +455,7 @@ dds_lget_publication_matched (_In_ const dds_listener_t * __restrict listener, _
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_publication_matched; *callback = listener->on_publication_matched;
} }
void void
@ -432,7 +469,7 @@ dds_lget_requested_deadline_missed (_In_ const dds_listener_t * __restrict liste
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_requested_deadline_missed; *callback = listener->on_requested_deadline_missed;
} }
void void
@ -446,7 +483,7 @@ dds_lget_requested_incompatible_qos (_In_ const dds_listener_t * __restrict list
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_requested_incompatible_qos; *callback = listener->on_requested_incompatible_qos;
} }
void 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"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_sample_lost; *callback = listener->on_sample_lost;
} }
void void
@ -474,7 +511,7 @@ dds_lget_sample_rejected (_In_ const dds_listener_t *__restrict listener, _Outp
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; return ;
} }
*callback = ((c_listener_t*)listener)->on_sample_rejected; *callback = listener->on_sample_rejected;
} }
void void
@ -488,5 +525,5 @@ dds_lget_subscription_matched (_In_ const dds_listener_t * __restrict listener,
DDS_ERROR("Argument listener is NULL\n"); DDS_ERROR("Argument listener is NULL\n");
return ; 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__err.h"
#include "dds__builtin.h" #include "dds__builtin.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_participant)
#define DDS_PARTICIPANT_STATUS_MASK 0u #define DDS_PARTICIPANT_STATUS_MASK 0u
/* List of created participants */ /* List of created participants */
@ -51,7 +53,7 @@ dds_participant_delete(
assert(e); assert(e);
assert(thr); 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) { if (asleep) {
thread_state_awake(thr); thread_state_awake(thr);

View file

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

View file

@ -21,59 +21,53 @@
#include "ddsi/q_entity.h" #include "ddsi/q_entity.h"
#include "ddsi/ddsi_sertopic.h" #include "ddsi/ddsi_sertopic.h"
static dds__retcode_t dds_read_lock (dds_entity_t hdl, dds_reader **reader, dds_readcond **condition, bool only_reader)
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)
{ {
dds__retcode_t rc = hdl; dds__retcode_t rc;
assert(reader); dds_entity *entity, *parent_entity;
assert(condition); if ((rc = dds_entity_lock (hdl, DDS_KIND_DONTCARE, &entity)) != DDS_RETCODE_OK)
*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; return rc;
}
else if (dds_entity_kind (entity) == DDS_KIND_READER)
{
*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 static void dds_read_unlock (dds_reader *reader, dds_readcond *condition)
dds_read_unlock(
_In_ dds_reader *reader,
_In_ dds_readcond *condition)
{ {
assert(reader); dds_entity_unlock (&reader->m_entity);
dds_entity_unlock((dds_entity*)reader); if (condition)
if (condition) { dds_entity_unlock (&condition->m_entity);
dds_entity_unlock((dds_entity*)condition);
}
} }
/* /*
dds_read_impl: Core read/take function. Usually maxs is size of buf and si 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 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); ret = (dds_return_t)dds_rhc_read(rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
} }
/* read/take resets data available status */ /* 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 */ /* 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); dds_read_unlock(rd, cond);
@ -227,13 +221,13 @@ dds_readcdr_impl(
); );
/* read/take resets data available status */ /* 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 */ /* 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); dds_read_unlock(rd, cond);
} else { } else {

View file

@ -41,7 +41,7 @@ dds_create_readcond(
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE; cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
cond->m_view_states = mask & DDS_ANY_VIEW_STATE; cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
cond->m_instance_states = mask & DDS_ANY_INSTANCE_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); dds_rhc_add_readcondition (cond);
return cond; return cond;
} }
@ -70,17 +70,13 @@ dds_create_readcondition(
return hdl; return hdl;
} }
_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \ dds_entity_t dds_get_datareader (dds_entity_t condition)
((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY) )
dds_entity_t
dds_get_datareader(
_In_ dds_entity_t condition)
{ {
dds_entity_t hdl; 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); 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); hdl = dds_get_parent(condition);
} else { } else {
DDS_ERROR("Argument condition is not valid\n"); DDS_ERROR("Argument condition is not valid\n");
@ -90,39 +86,26 @@ dds_get_datareader(
return hdl; return hdl;
} }
dds_return_t dds_get_mask (dds_entity_t condition, uint32_t *mask)
_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 ret; dds_entity *entity;
dds_readcond *cond; dds__retcode_t rc;
dds__retcode_t rc;
if (mask != NULL) { if (mask == NULL)
*mask = 0; return DDS_ERRNO (DDS_RETCODE_BAD_PARAMETER);
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);
}
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__init.h"
#include "dds__rhc.h" #include "dds__rhc.h"
#include "dds__err.h" #include "dds__err.h"
#include "dds__topic.h"
#include "ddsi/q_entity.h" #include "ddsi/q_entity.h"
#include "ddsi/q_thread.h" #include "ddsi/q_thread.h"
#include "dds__builtin.h" #include "dds__builtin.h"
@ -27,6 +28,7 @@
#include "os/os.h" #include "os/os.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_reader)
#define DDS_READER_STATUS_MASK \ #define DDS_READER_STATUS_MASK \
DDS_SAMPLE_REJECTED_STATUS |\ DDS_SAMPLE_REJECTED_STATUS |\
@ -160,180 +162,196 @@ dds_reader_status_validate(
DDS_RETCODE_OK; DDS_RETCODE_OK;
} }
void void dds_reader_data_available_cb (struct dds_reader *rd)
dds_reader_status_cb(
void *entity,
const status_cb_data_t *data)
{ {
dds_reader *rd; /* DATA_AVAILABLE is special in two ways: firstly, it should first try
dds__retcode_t rc; DATA_ON_READERS on the line of ancestors, and if not consumed set the
void *metrics = NULL; 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;
/* When data is NULL, it means that the DDSI reader is deleted. */ os_mutexLock (&rd->m_entity.m_observers_lock);
if (data == NULL) { while (rd->m_entity.m_cb_count > 0)
/* Release the initial claim that was done during the create. This os_condWait (&rd->m_entity.m_observers_cond, &rd->m_entity.m_observers_lock);
* will indicate that further API deletion is now possible. */ rd->m_entity.m_cb_count++;
ut_handle_release(((dds_entity*)entity)->m_hdl, ((dds_entity*)entity)->m_hdllink);
return; 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)
{
/* Release the initial claim that was done during the create. This
* will indicate that further API deletion is now possible. */
ut_handle_release (entity->m_hdl, entity->m_hdllink);
return;
}
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 };
/* 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. */
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_ID: {
if (dds_reader_lock(((dds_entity*)entity)->m_hdl, &rd) != DDS_RETCODE_OK) { struct dds_requested_incompatible_qos_status * const st = vst = &rd->m_requested_incompatible_qos_status;
return; 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;
} }
assert(rd == entity); case DDS_SAMPLE_LOST_STATUS_ID: {
struct dds_sample_lost_status * const st = vst = &rd->m_sample_lost_status;
/* Reset the status for possible Listener call. st->total_count++;
* When a listener is not called, the status will be set (again). */ st->total_count_change++;
dds_entity_status_reset(entity, data->status); invoke = (lst->on_sample_lost != 0);
reset[0] = &st->total_count_change;
/* Update status metrics. */ break;
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);
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);
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);
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);
break;
}
case DDS_DATA_AVAILABLE_STATUS: {
metrics = NULL;
break;
}
case DDS_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--;
}
} 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++;
}
rd->m_liveliness_changed_status.last_publication_handle = data->handle;
metrics = (void*)&(rd->m_liveliness_changed_status);
break;
}
case DDS_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++;
} else {
rd->m_subscription_matched_status.current_count--;
rd->m_subscription_matched_status.current_count_change--;
}
rd->m_subscription_matched_status.last_publication_handle = data->handle;
metrics = (void*)&(rd->m_subscription_matched_status);
break;
}
default: assert (0);
} }
case DDS_SAMPLE_REJECTED_STATUS_ID: {
/* The reader needs to be unlocked when propagating the (possible) listener struct dds_sample_rejected_status * const st = vst = &rd->m_sample_rejected_status;
* call because the application should be able to call this reader within st->total_count++;
* the callback function. */ st->total_count_change++;
dds_reader_unlock(rd); st->last_reason = data->extra;
st->last_instance_handle = data->handle;
/* DATA_AVAILABLE is handled differently to normal status changes. */ invoke = (lst->on_sample_rejected != 0);
if (data->status == DDS_DATA_AVAILABLE_STATUS) { reset[0] = &st->total_count_change;
dds_entity *parent = rd->m_entity.m_parent; break;
/* 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 ( 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);
} }
case DDS_LIVELINESS_CHANGED_STATUS_ID: {
if (rc == DDS_RETCODE_OK) { struct dds_liveliness_changed_status * const st = vst = &rd->m_liveliness_changed_status;
/* Event was eaten by a listener. */ if (data->add) {
if (dds_reader_lock(((dds_entity*)entity)->m_hdl, &rd) == DDS_RETCODE_OK) { st->alive_count++;
assert(rd == entity); st->alive_count_change++;
if (st->not_alive_count > 0) {
/* Reset the change counts of the metrics. */ st->not_alive_count--;
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) { } else {
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status, consider successful. */ st->alive_count--;
dds_entity_status_set(entity, data->status); st->not_alive_count++;
/* Notify possible interested observers. */ st->not_alive_count_change++;
dds_entity_status_signal(entity); }
} else if (rc == DDS_RETCODE_ALREADY_DELETED) { st->last_publication_handle = data->handle;
/* An entity up the hierarchy is being deleted, consider successful. */ invoke = (lst->on_liveliness_changed != 0);
} else { reset[0] = &st->alive_count_change;
/* Something went wrong up the hierarchy. */ reset[1] = &st->not_alive_count_change;
break;
} }
case DDS_SUBSCRIPTION_MATCHED_STATUS_ID: {
struct dds_subscription_matched_status * const st = vst = &rd->m_subscription_matched_status;
if (data->add) {
st->total_count++;
st->total_count_change++;
st->current_count++;
st->current_count_change++;
} else {
st->current_count--;
st->current_count_change--;
}
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;
}
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);
}
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);
}
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 ) ||\ _Pre_satisfies_(((participant_or_subscriber & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER ) ||\
@ -353,16 +371,16 @@ dds_create_reader(
dds_entity_t subscriber; dds_entity_t subscriber;
dds_reader * rd; dds_reader * rd;
struct rhc * rhc; struct rhc * rhc;
dds_entity * tp; dds_topic * tp;
dds_entity_t reader; dds_entity_t reader;
dds_entity_t t; dds_entity_t t;
struct thread_state1 * const thr = lookup_thread_state (); struct thread_state1 * const thr = lookup_thread_state ();
const bool asleep = !vtime_awake_p (thr->vtime); const bool asleep = !vtime_awake_p (thr->vtime);
dds_return_t ret = DDS_RETCODE_OK; 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. */ /* 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); subscriber = dds_create_subscriber(participant_or_subscriber, qos, NULL);
} else { } else {
subscriber = participant_or_subscriber; subscriber = participant_or_subscriber;
@ -381,19 +399,19 @@ dds_create_reader(
} }
if ((subscriber != participant_or_subscriber) && 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 */ /* Delete implicit subscriber if reader creation fails */
sub->m_flags |= DDS_ENTITY_IMPLICIT; 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) { if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking topic\n"); DDS_ERROR("Error occurred on locking topic\n");
reader = DDS_ERRNO(rc); reader = DDS_ERRNO(rc);
goto err_tp_lock; goto err_tp_lock;
} }
assert (((dds_topic*)tp)->m_stopic); assert (tp->m_stopic);
assert (sub->m_domain == tp->m_domain); assert (sub->m_domain == tp->m_entity.m_domain);
/* Merge qos from topic and subscriber */ /* Merge qos from topic and subscriber */
rqos = dds_create_qos (); rqos = dds_create_qos ();
@ -407,8 +425,8 @@ dds_create_reader(
dds_merge_qos (rqos, sub->m_qos); dds_merge_qos (rqos, sub->m_qos);
} }
if (tp->m_qos) { if (tp->m_entity.m_qos) {
dds_merge_qos (rqos, tp->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 */ /* 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); rqos->present &= ~(QP_DURABILITY_SERVICE | QP_TRANSPORT_PRIORITY | QP_LIFESPAN);
@ -423,7 +441,7 @@ dds_create_reader(
} }
/* Additional checks required for built-in topics */ /* 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_delete_qos(rqos);
DDS_ERROR("Invalid QoS specified for built-in topic reader"); DDS_ERROR("Invalid QoS specified for built-in topic reader");
reader = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY); reader = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY);
@ -434,9 +452,9 @@ dds_create_reader(
rd = dds_alloc (sizeof (*rd)); rd = dds_alloc (sizeof (*rd));
reader = dds_entity_init (&rd->m_entity, sub, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK); 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_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
rd->m_topic = (dds_topic*)tp; rd->m_topic = tp;
rhc = dds_rhc_new (rd, ((dds_topic*)tp)->m_stopic); rhc = dds_rhc_new (rd, tp->m_stopic);
dds_entity_add_ref_nolock (tp); dds_entity_add_ref_nolock (&tp->m_entity);
rd->m_entity.m_deriver.close = dds_reader_close; rd->m_entity.m_deriver.close = dds_reader_close;
rd->m_entity.m_deriver.delete = dds_reader_delete; rd->m_entity.m_deriver.delete = dds_reader_delete;
rd->m_entity.m_deriver.set_qos = dds_reader_qos_set; rd->m_entity.m_deriver.set_qos = dds_reader_qos_set;
@ -449,16 +467,16 @@ dds_create_reader(
assert(0); assert(0);
} }
os_mutexUnlock(&tp->m_mutex); os_mutexUnlock(&tp->m_entity.m_mutex);
os_mutexUnlock(&sub->m_mutex); os_mutexUnlock(&sub->m_mutex);
if (asleep) { if (asleep) {
thread_state_awake (thr); 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); rqos, rhc, dds_reader_status_cb, rd);
os_mutexLock(&sub->m_mutex); os_mutexLock(&sub->m_mutex);
os_mutexLock(&tp->m_mutex); os_mutexLock(&tp->m_entity.m_mutex);
assert (rd->m_rd); assert (rd->m_rd);
if (asleep) { if (asleep) {
thread_state_asleep (thr); 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)) { 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_global.m_dur_reader) (rd, rhc);
} }
dds_entity_unlock(tp); dds_topic_unlock(tp);
dds_entity_unlock(sub); 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 /* If topic is builtin, then the topic entity is local and should
* be deleted because the application won't. */ * be deleted because the application won't. */
dds_delete(t); dds_delete(t);
@ -480,14 +498,14 @@ dds_create_reader(
return reader; return reader;
err_bad_qos: err_bad_qos:
dds_entity_unlock(tp); dds_topic_unlock(tp);
err_tp_lock: err_tp_lock:
dds_entity_unlock(sub); dds_entity_unlock(sub);
if((sub->m_flags & DDS_ENTITY_IMPLICIT) != 0){ if((sub->m_flags & DDS_ENTITY_IMPLICIT) != 0){
(void)dds_delete(subscriber); (void)dds_delete(subscriber);
} }
err_sub_lock: 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 /* If topic is builtin, then the topic entity is local and should
* be deleted because the application won't. */ * be deleted because the application won't. */
dds_delete(t); dds_delete(t);
@ -495,11 +513,7 @@ err_sub_lock:
return reader; return reader;
} }
void void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb, void *cbarg)
dds_reader_ddsi2direct(
dds_entity_t entity,
ddsi2direct_directread_cb_t cb,
void *cbarg)
{ {
dds_reader *dds_rd; dds_reader *dds_rd;
@ -540,77 +554,62 @@ dds_reader_ddsi2direct(
os_mutexLock (&rd->e.lock); os_mutexLock (&rd->e.lock);
} }
os_mutexUnlock (&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 uint32_t dds_reader_lock_samples (dds_entity_t reader)
dds_reader_lock_samples(
dds_entity_t reader)
{ {
uint32_t ret = 0; dds_reader *rd;
dds_reader *rd; uint32_t n;
if (dds_reader_lock(reader, &rd) == DDS_RETCODE_OK) { if (dds_reader_lock (reader, &rd) != DDS_RETCODE_OK)
ret = dds_rhc_lock_samples(rd->m_rd->rhc); return 0;
dds_reader_unlock(rd); n = dds_rhc_lock_samples (rd->m_rd->rhc);
} else { dds_reader_unlock (rd);
ret = 0; return n;
}
return ret;
} }
_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)
{ {
int ret; dds_reader *rd;
dds_reader *rd; int ret;
if ((ret = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK)
assert (reader); return DDS_ERRNO (ret);
switch (rd->m_entity.m_qos->durability.kind)
ret = dds_reader_lock(reader, &rd); {
if (ret == DDS_RETCODE_OK) { case DDS_DURABILITY_VOLATILE:
if (((dds_entity*)rd)->m_qos->durability.kind > NN_TRANSIENT_LOCAL_DURABILITY_QOS) { ret = DDS_RETCODE_OK;
ret = (dds_global.m_dur_wait) (rd, max_wait); break;
} else { case DDS_DURABILITY_TRANSIENT_LOCAL:
DDS_ERROR("Can not wait for historical data on a reader with volatile durability\n"); break;
ret = DDS_ERRNO(DDS_RETCODE_ERROR); case DDS_DURABILITY_TRANSIENT:
} case DDS_DURABILITY_PERSISTENT:
dds_reader_unlock(rd); ret = (dds_global.m_dur_wait) (rd, max_wait);
} else { break;
DDS_ERROR("Error occurred on locking reader\n"); }
ret = DDS_ERRNO(ret); dds_reader_unlock(rd);
} return ret;
return ret;
} }
_Pre_satisfies_(((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) || \ dds_entity_t dds_get_subscriber (dds_entity_t entity)
((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 hdl; dds_entity_t hdl;
if (dds_entity_kind_from_handle (entity) == DDS_KIND_READER)
hdl = dds_get_parent (entity);
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)
hdl = dds_get_subscriber (hdl);
DDS_ERROR ("Reader of this condition is already deleted\n");
}
else
{
DDS_ERROR ("Provided entity is not a reader nor a condition\n");
hdl = DDS_ERRNO (dds_valid_hdl (entity, DDS_KIND_READER));
}
if (dds_entity_kind(entity) == DDS_KIND_READER) { return hdl;
hdl = dds_get_parent(entity);
} else if (dds_entity_kind(entity) == DDS_KIND_COND_READ || dds_entity_kind(entity) == DDS_KIND_COND_QUERY) {
hdl = dds_get_parent(entity);
if(hdl > 0){
hdl = dds_get_subscriber(hdl);
} else {
DDS_ERROR("Reader of this condition is already deleted\n");
}
} else {
DDS_ERROR("Provided entity is not a reader nor a condition\n");
hdl = DDS_ERRNO(dds_valid_hdl(entity, DDS_KIND_READER));
}
return hdl;
} }
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER) _Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
@ -633,10 +632,10 @@ dds_get_subscription_matched_status (
if (status) { if (status) {
*status = rd->m_subscription_matched_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.total_count_change = 0;
rd->m_subscription_matched_status.current_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); dds_reader_unlock(rd);
fail: fail:
@ -663,10 +662,10 @@ dds_get_liveliness_changed_status (
if (status) { if (status) {
*status = rd->m_liveliness_changed_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.alive_count_change = 0;
rd->m_liveliness_changed_status.not_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); dds_reader_unlock(rd);
fail: fail:
@ -692,10 +691,10 @@ dds_return_t dds_get_sample_rejected_status (
if (status) { if (status) {
*status = rd->m_sample_rejected_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.total_count_change = 0;
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED; 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); dds_reader_unlock(rd);
fail: fail:
@ -721,9 +720,9 @@ dds_return_t dds_get_sample_lost_status (
if (status) { if (status) {
*status = rd->m_sample_lost_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; 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); dds_reader_unlock(rd);
fail: fail:
@ -749,9 +748,9 @@ dds_return_t dds_get_requested_deadline_missed_status (
if (status) { if (status) {
*status = rd->m_requested_deadline_missed_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; 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); dds_reader_unlock(rd);
fail: fail:
@ -777,9 +776,9 @@ dds_return_t dds_get_requested_incompatible_qos_status (
if (status) { if (status) {
*status = rd->m_requested_incompatible_qos_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; 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); dds_reader_unlock(rd);
fail: fail:

View file

@ -146,8 +146,6 @@
"signal_conditions" after releasing the RHC lock. "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 /* FIXME: tkmap should perhaps retain data with timestamp set to invalid
An invalid timestamp is (logically) unordered with respect to valid An invalid timestamp is (logically) unordered with respect to valid
timestamps, and that would mean BY_SOURCE order could be respected timestamps, and that would mean BY_SOURCE order could be respected
@ -310,13 +308,40 @@ struct trigger_info
bool has_changed; bool has_changed;
}; };
#define QMASK_OF_SAMPLE(s) ((s)->isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE) static unsigned qmask_of_sample (const struct rhc_sample *s)
#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) return s->isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE;
#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) static unsigned qmask_of_invsample (const struct rhc_instance *i)
#define INST_HAS_UNREAD(i) (INST_NREAD (i) < INST_NSAMPLES (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 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); 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) 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 #ifndef NDEBUG
{ {
const struct rhc_instance *x = rhc->nonempty_instances; 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 *rhc = varg;
struct rhc_instance *inst = vnode; struct rhc_instance *inst = vnode;
struct rhc_sample *s = inst->latest; struct rhc_sample *s = inst->latest;
const bool was_empty = INST_IS_EMPTY (inst); const bool was_empty = inst_is_empty (inst);
if (s) if (s)
{ {
do { 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) static void get_trigger_info (struct trigger_info *info, struct rhc_instance *inst, bool pre)
{ {
info->qminst = qmask_of_inst (inst); info->qminst = qmask_of_inst (inst);
info->has_read = INST_HAS_READ (inst); info->has_read = inst_has_read (inst);
info->has_not_read = INST_HAS_UNREAD (inst); info->has_not_read = inst_has_unread (inst);
/* reset instance has_changed before adding/overwriting a sample */ /* reset instance has_changed before adding/overwriting a sample */
if (pre) 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) 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->extra = DDS_REJECTED_BY_SAMPLES_LIMIT;
cb_data->handle = inst->iid; cb_data->handle = inst->iid;
cb_data->add = true; 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) 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->extra = DDS_REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT;
cb_data->handle = inst->iid; cb_data->handle = inst->iid;
cb_data->add = true; 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) static void drop_instance_noupdate_no_writers (struct rhc *rhc, struct rhc_instance *inst)
{ {
int ret; int ret;
assert (INST_IS_EMPTY (inst)); assert (inst_is_empty (inst));
rhc->n_instances--; rhc->n_instances--;
@ -799,7 +824,7 @@ static void dds_rhc_register (struct rhc *rhc, struct rhc_instance *inst, uint64
inst->no_writers_gen++; inst->no_writers_gen++;
DDS_TRACE("new1"); DDS_TRACE("new1");
if (!INST_IS_EMPTY (inst) && !inst->isdisposed) if (!inst_is_empty (inst) && !inst->isdisposed)
rhc->n_not_alive_no_writers--; rhc->n_not_alive_no_writers--;
} }
else if (inst_wr_iid == 0 && inst->wrcount == 1) 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) 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); add_inst_to_nonempty_list (rhc, inst);
rhc->n_new += inst->isnew; rhc->n_new += inst->isnew;
if (inst->isdisposed) if (inst->isdisposed)
@ -953,7 +978,7 @@ static int rhc_unregister_updateinst
} }
else else
{ {
if (!INST_IS_EMPTY (inst)) if (!inst_is_empty (inst))
{ {
/* Instance still has content - do not drop until application /* Instance still has content - do not drop until application
takes the last sample. Set the invalid sample if the latest 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 */ /* Add invalid samples for transition to no-writers */
DDS_TRACE(",#0,empty,nowriters"); DDS_TRACE(",#0,empty,nowriters");
assert (INST_IS_EMPTY (inst)); assert (inst_is_empty (inst));
inst_set_invsample (rhc, inst); inst_set_invsample (rhc, inst);
update_inst (rhc, inst, pwr_info, false, tstamp); update_inst (rhc, inst, pwr_info, false, tstamp);
account_for_empty_to_nonempty_transition (rhc, inst); 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) 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->extra = DDS_REJECTED_BY_INSTANCES_LIMIT;
cb_data->handle = tk->m_iid; cb_data->handle = tk->m_iid;
cb_data->add = true; cb_data->add = true;
@ -1152,7 +1177,7 @@ bool dds_rhc_store
dummy_instance.iid = tk->m_iid; dummy_instance.iid = tk->m_iid;
stored = RHC_FILTERED; stored = RHC_FILTERED;
cb_data.status = 0; cb_data.raw_status_id = -1;
os_mutexLock (&rhc->lock); os_mutexLock (&rhc->lock);
@ -1204,7 +1229,7 @@ bool dds_rhc_store
} }
/* notify sample lost */ /* 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.extra = 0;
cb_data.handle = 0; cb_data.handle = 0;
cb_data.add = true; cb_data.add = true;
@ -1228,7 +1253,7 @@ bool dds_rhc_store
const int not_alive = inst->wrcount == 0 || inst->isdisposed; const int not_alive = inst->wrcount == 0 || inst->isdisposed;
const bool old_isdisposed = inst->isdisposed; const bool old_isdisposed = inst->isdisposed;
const bool old_isnew = inst->isnew; 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; int inst_became_disposed = 0;
/* Not just an unregister, so a write and/or a dispose (possibly /* Not just an unregister, so a write and/or a dispose (possibly
@ -1314,7 +1339,7 @@ bool dds_rhc_store
} }
else 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)) if (rhc->reader && (rhc->reader->m_entity.m_status_enable & DDS_DATA_AVAILABLE_STATUS))
{ {
os_atomic_inc32 (&rhc->n_cbs); 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); os_atomic_dec32 (&rhc->n_cbs);
} }
} }
if (rhc->reader && trigger_waitsets) if (rhc->reader && trigger_waitsets)
{ {
dds_entity_status_signal((dds_entity*)(rhc->reader)); dds_entity_status_signal(&rhc->reader->m_entity);
} }
return delivered; return delivered;
@ -1386,7 +1411,7 @@ error_or_nochange:
/* Make any reader status callback */ /* 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); os_atomic_inc32 (&rhc->n_cbs);
dds_reader_status_cb (&rhc->reader->m_entity, &cb_data); dds_reader_status_cb (&rhc->reader->m_entity, &cb_data);
@ -1447,7 +1472,7 @@ void dds_rhc_unregister_wr
} }
else else
{ {
const bool was_empty = INST_IS_EMPTY (inst); const bool was_empty = inst_is_empty (inst);
inst_set_invsample (rhc, inst); inst_set_invsample (rhc, inst);
if (was_empty) if (was_empty)
account_for_empty_to_nonempty_transition (rhc, inst); account_for_empty_to_nonempty_transition (rhc, inst);
@ -1476,7 +1501,7 @@ void dds_rhc_unregister_wr
if (trigger_waitsets) 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 (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 */ /* samples present & instance, view state matches */
struct trigger_info pre, post; struct trigger_info pre, post;
const unsigned nread = INST_NREAD (inst); const unsigned nread = inst_nread (inst);
const uint32_t n_first = n; const uint32_t n_first = n;
get_trigger_info (&pre, inst, true); 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; struct rhc_sample *sample = inst->latest->next, * const end1 = sample;
do do
{ {
if ((QMASK_OF_SAMPLE (sample) & qminv) == 0) if ((qmask_of_sample (sample) & qminv) == 0)
{ {
/* sample state matches too */ /* sample state matches too */
set_sample_info (info_seq + n, inst, sample); set_sample_info (info_seq + n, inst, sample);
ddsi_serdata_to_sample (sample->sample, values[n], 0, 0); ddsi_serdata_to_sample (sample->sample, values[n], 0, 0);
if (cond == NULL 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]))) || (cond->m_query.m_filter != NULL && cond->m_query.m_filter(values[n])))
{ {
if (!sample->isread) if (!sample->isread)
@ -1709,7 +1734,7 @@ static int dds_rhc_read_w_qminv
while (sample != end1); 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); set_sample_info_invsample (info_seq + n, inst);
ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0); 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; inst->isnew = 0;
rhc->n_new--; rhc->n_new--;
} }
if (nread != INST_NREAD (inst)) if (nread != inst_nread (inst))
{ {
get_trigger_info (&post, inst, false); get_trigger_info (&post, inst, false);
if (update_conditions_locked (rhc, &pre, &post, NULL)) if (update_conditions_locked (rhc, &pre, &post, NULL))
@ -1754,7 +1779,7 @@ static int dds_rhc_read_w_qminv
if (trigger_waitsets) if (trigger_waitsets)
{ {
dds_entity_status_signal((dds_entity*)(rhc->reader)); dds_entity_status_signal(&rhc->reader->m_entity);
} }
assert (n <= INT_MAX); assert (n <= INT_MAX);
@ -1792,7 +1817,7 @@ static int dds_rhc_take_w_qminv
iid = inst->iid; iid = inst->iid;
if (handle == DDS_HANDLE_NIL || iid == handle) 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; struct trigger_info pre, post;
unsigned nvsamples = inst->nvsamples; unsigned nvsamples = inst->nvsamples;
@ -1807,7 +1832,7 @@ static int dds_rhc_take_w_qminv
{ {
struct rhc_sample * const sample1 = sample->next; struct rhc_sample * const sample1 = sample->next;
if ((QMASK_OF_SAMPLE (sample) & qminv) != 0) if ((qmask_of_sample (sample) & qminv) != 0)
{ {
psample = sample; psample = sample;
} }
@ -1816,7 +1841,7 @@ static int dds_rhc_take_w_qminv
set_sample_info (info_seq + n, inst, sample); set_sample_info (info_seq + n, inst, sample);
ddsi_serdata_to_sample (sample->sample, values[n], 0, 0); ddsi_serdata_to_sample (sample->sample, values[n], 0, 0);
if (cond == NULL 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]))) || ( cond->m_query.m_filter != NULL && cond->m_query.m_filter(values[n])))
{ {
rhc->n_vsamples--; 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); set_sample_info_invsample (info_seq + n, inst);
ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0); 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); remove_inst_from_nonempty_list (rhc, inst);
@ -1918,7 +1943,7 @@ static int dds_rhc_take_w_qminv
if (trigger_waitsets) if (trigger_waitsets)
{ {
dds_entity_status_signal((dds_entity*)(rhc->reader)); dds_entity_status_signal(&rhc->reader->m_entity);
} }
assert (n <= INT_MAX); assert (n <= INT_MAX);
@ -1957,7 +1982,7 @@ static int dds_rhc_takecdr_w_qminv
iid = inst->iid; iid = inst->iid;
if (handle == DDS_HANDLE_NIL || iid == handle) 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; struct trigger_info pre, post;
unsigned nvsamples = inst->nvsamples; unsigned nvsamples = inst->nvsamples;
@ -1972,7 +1997,7 @@ static int dds_rhc_takecdr_w_qminv
{ {
struct rhc_sample * const sample1 = sample->next; struct rhc_sample * const sample1 = sample->next;
if ((QMASK_OF_SAMPLE (sample) & qminv) != 0) if ((qmask_of_sample (sample) & qminv) != 0)
{ {
psample = sample; 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); set_sample_info_invsample (info_seq + n, inst);
values[n] = ddsi_serdata_ref(inst->tk->m_sample); 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); remove_inst_from_nonempty_list (rhc, inst);
@ -2069,7 +2094,7 @@ static int dds_rhc_takecdr_w_qminv
if (trigger_waitsets) if (trigger_waitsets)
{ {
dds_entity_status_signal((dds_entity*)(rhc->reader)); dds_entity_status_signal(&rhc->reader->m_entity);
} }
assert (n <= INT_MAX); 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) switch (c->m_sample_states)
{ {
case DDS_SST_READ: case DDS_SST_READ:
m = m && INST_HAS_READ (inst); m = m && inst_has_read (inst);
break; break;
case DDS_SST_NOT_READ: case DDS_SST_NOT_READ:
m = m && INST_HAS_UNREAD (inst); m = m && inst_has_unread (inst);
break; break;
case DDS_SST_READ | DDS_SST_NOT_READ: case DDS_SST_READ | DDS_SST_NOT_READ:
case 0: case 0:
/* note: we get here only if inst not empty, so this is a no-op */ /* 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; break;
default: default:
DDS_FATAL("update_readconditions: sample_states invalid: %x\n", c->m_sample_states); 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); os_mutexLock (&rhc->lock);
for (inst = ut_hhIterFirst (rhc->instances, &iter); inst; inst = ut_hhIterNext (&iter)) 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); cond->m_entity.m_trigger += rhc_get_cond_trigger (inst, cond);
if (((dds_entity*)cond)->m_trigger) { if (cond->m_entity.m_trigger) {
dds_entity_status_signal((dds_entity*)cond); dds_entity_status_signal(&cond->m_entity);
} }
} }
} }
@ -2225,7 +2250,7 @@ static bool update_conditions_locked
} }
else if (m_pre < m_post) 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); tmp = ddsi_sertopic_alloc_sample (rhc->topic);
ddsi_serdata_to_sample (sample, tmp, NULL, NULL); ddsi_serdata_to_sample (sample, tmp, NULL, NULL);
@ -2233,7 +2258,7 @@ static bool update_conditions_locked
if if
( (
(sample == NULL) (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)) || (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)) for (inst = ut_hhIterFirst (rhc->instances, &iter); inst; inst = ut_hhIterNext (&iter))
{ {
n_instances++; n_instances++;
if (!INST_IS_EMPTY (inst)) if (!inst_is_empty (inst))
{ {
/* samples present (or an invalid sample is) */ /* samples present (or an invalid sample is) */
unsigned n_vsamples_in_instance = 0, n_read_vsamples_in_instance = 0; 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; dds_readcond * rciter = rhc->conds;
for (i = 0; i < (rhc->nconds < CHECK_MAX_CONDS ? rhc->nconds : CHECK_MAX_CONDS); i++) 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); 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; dds_readcond * rciter = rhc->conds;
for (i = 0; i < (rhc->nconds < CHECK_MAX_CONDS ? rhc->nconds : CHECK_MAX_CONDS); i++) 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); 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; inst = rhc->nonempty_instances;
n_nonempty_instances = 0; n_nonempty_instances = 0;
do { do {
assert (!INST_IS_EMPTY (inst)); assert (!inst_is_empty (inst));
assert (prev->next == inst); assert (prev->next == inst);
assert (inst->prev == prev); assert (inst->prev == prev);
prev = inst; 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 }; const uint32_t dds_op_size[5] = { 0, 1u, 2u, 4u, 8u };
static void dds_stream_write static void dds_stream_write (dds_stream_t * os, const char * data, const uint32_t * ops);
(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_read
(dds_stream_t * is, char * data, const uint32_t * ops);
#define DDS_SWAP16(v) \ #define DDS_SWAP16(v) \
((uint16_t)(((v) >> 8) | ((v) << 8))) ((uint16_t)(((v) >> 8) | ((v) << 8)))
@ -258,6 +256,12 @@ uint64_t dds_stream_read_uint64 (dds_stream_t * is)
return val; 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 dds_stream_read_float (dds_stream_t * is)
{ {
float val = 0.0; 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); 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) void dds_stream_write_float (dds_stream_t * os, float val)
{ {
union { float f; uint32_t u; } u; union { float f; uint32_t u; } u;

View file

@ -97,28 +97,6 @@ dds_subscriber_status_validate(
return ret; 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) _Requires_exclusive_lock_held_(participant)
_Check_return_ dds_entity_t _Check_return_ dds_entity_t
dds__create_subscriber_l( 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); 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.set_qos = dds_subscriber_qos_set;
sub->m_entity.m_deriver.validate_status = dds_subscriber_status_validate; 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; sub->m_entity.m_deriver.get_instance_hdl = dds_subscriber_instance_hdl;
return subscriber; return subscriber;

View file

@ -26,6 +26,8 @@
#include "os/os_atomics.h" #include "os/os_atomics.h"
#include "ddsi/ddsi_iid.h" #include "ddsi/ddsi_iid.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_topic)
#define DDS_TOPIC_STATUS_MASK \ #define DDS_TOPIC_STATUS_MASK \
DDS_INCONSISTENT_TOPIC_STATUS DDS_INCONSISTENT_TOPIC_STATUS
@ -90,55 +92,29 @@ dds_topic_status_validate(
status (only defined status on a topic). status (only defined status on a topic).
*/ */
static void static void dds_topic_status_cb (struct dds_topic *tp)
dds_topic_status_cb(
struct dds_topic *cb_t)
{ {
dds_topic *topic; struct dds_listener const * const lst = &tp->m_entity.m_listener;
dds__retcode_t rc;
if (dds_topic_lock(((dds_entity*)cb_t)->m_hdl, &topic) != DDS_RETCODE_OK) { os_mutexLock (&tp->m_entity.m_observers_lock);
return; while (tp->m_entity.m_cb_count > 0)
} os_condWait (&tp->m_entity.m_observers_cond, &tp->m_entity.m_observers_lock);
assert(topic == cb_t); tp->m_entity.m_cb_count++;
/* Reset the status for possible Listener call. tp->m_inconsistent_topic_status.total_count++;
* When a listener is not called, the status will be set (again). */ 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;
}
/* Update status metrics. */ dds_entity_status_set(&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
topic->m_inconsistent_topic_status.total_count++; tp->m_entity.m_cb_count--;
topic->m_inconsistent_topic_status.total_count_change++; os_condBroadcast (&tp->m_entity.m_observers_cond);
os_mutexUnlock (&tp->m_entity.m_observers_lock);
/* 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. */
}
} }
struct ddsi_sertopic * struct ddsi_sertopic *
@ -184,7 +160,7 @@ dds_topic_free(
assert (st); assert (st);
os_mutexLock (&dds_global.m_mutex); 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) { if (domain != NULL) {
ut_avlDelete (&dds_topictree_def, &domain->m_topics, st); ut_avlDelete (&dds_topictree_def, &domain->m_topics, st);
} }
@ -715,9 +691,9 @@ dds_get_inconsistent_topic_status(
if (status) { if (status) {
*status = t->m_inconsistent_topic_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; 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); dds_topic_unlock(t);
fail: fail:

View file

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

View file

@ -20,10 +20,13 @@
#include "dds__qos.h" #include "dds__qos.h"
#include "dds__err.h" #include "dds__err.h"
#include "dds__init.h" #include "dds__init.h"
#include "dds__topic.h"
#include "ddsi/ddsi_tkmap.h" #include "ddsi/ddsi_tkmap.h"
#include "dds__whc.h" #include "dds__whc.h"
#include "ddsc/ddsc_project.h" #include "ddsc/ddsc_project.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_writer)
#define DDS_WRITER_STATUS_MASK \ #define DDS_WRITER_STATUS_MASK \
DDS_LIVELINESS_LOST_STATUS |\ DDS_LIVELINESS_LOST_STATUS |\
DDS_OFFERED_DEADLINE_MISSED_STATUS |\ DDS_OFFERED_DEADLINE_MISSED_STATUS |\
@ -62,123 +65,110 @@ dds_writer_status_validate(
then status conditions is not triggered. then status conditions is not triggered.
*/ */
static void static void dds_writer_status_cb (void *ventity, const status_cb_data_t *data)
dds_writer_status_cb(
void *entity,
const status_cb_data_t *data)
{ {
dds_writer *wr; struct dds_entity * const entity = ventity;
dds__retcode_t rc;
void *metrics = NULL;
/* When data is NULL, it means that the writer is deleted. */ /* 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. */ /* Release the initial claim that was done during the create. This
ut_handle_release(((dds_entity*)entity)->m_hdl, ((dds_entity*)entity)->m_hdllink); * will indicate that further API deletion is now possible. */
return; ut_handle_release (entity->m_hdl, entity->m_hdllink);
return;
}
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, 1u << status_id);
/* Update status metrics. */
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_ID: {
if (dds_writer_lock(((dds_entity*)entity)->m_hdl, &wr) != DDS_RETCODE_OK) { struct dds_liveliness_lost_status * const st = vst = &wr->m_liveliness_lost_status;
/* There's a deletion or closing going on. */ st->total_count++;
return; st->total_count_change++;
invoke = (lst->on_liveliness_lost != 0);
reset[0] = &st->total_count_change;
break;
} }
assert(wr == entity); case DDS_OFFERED_INCOMPATIBLE_QOS_STATUS_ID: {
struct dds_offered_incompatible_qos_status * const st = vst = &wr->m_offered_incompatible_qos_status;
/* Reset the status for possible Listener call. st->total_count++;
* When a listener is not called, the status will be set (again). */ st->total_count_change++;
dds_entity_status_reset(entity, data->status); st->last_policy_id = data->extra;
invoke = (lst->on_offered_incompatible_qos != 0);
/* Update status metrics. */ reset[0] = &st->total_count_change;
switch (data->status) { break;
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);
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);
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);
break;
}
case DDS_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++;
} else {
wr->m_publication_matched_status.current_count--;
wr->m_publication_matched_status.current_count_change--;
}
wr->m_publication_matched_status.last_subscription_handle = data->handle;
metrics = (void*)&(wr->m_publication_matched_status);
break;
}
default: assert (0);
} }
case DDS_PUBLICATION_MATCHED_STATUS_ID: {
/* The writer needs to be unlocked when propagating the (possible) listener struct dds_publication_matched_status * const st = vst = &wr->m_publication_matched_status;
* call because the application should be able to call this writer within if (data->add) {
* the callback function. */ st->total_count++;
dds_writer_unlock(wr); st->total_count_change++;
st->current_count++;
/* Is anybody interested within the entity hierarchy through listeners? */ st->current_count_change++;
rc = dds_entity_listener_propagation(entity, entity, data->status, metrics, true); } else {
st->current_count--;
if (rc == DDS_RETCODE_OK) { st->current_count_change--;
/* Event was eaten by a listener. */ }
if (dds_writer_lock(((dds_entity*)entity)->m_hdl, &wr) == DDS_RETCODE_OK) { wr->m_publication_matched_status.last_subscription_handle = data->handle;
assert(wr == entity); invoke = (lst->on_publication_matched != 0);
reset[0] = &st->total_count_change;
/* Reset the status. */ reset[1] = &st->current_count_change;
dds_entity_status_reset(entity, data->status); break;
/* 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. */
} }
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);
}
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);
}
entity->m_cb_count--;
os_condBroadcast (&entity->m_observers_cond);
os_mutexUnlock (&entity->m_observers_lock);
} }
static uint32_t static uint32_t
@ -412,7 +402,7 @@ dds_create_writer(
dds_writer * wr; dds_writer * wr;
dds_entity_t writer; dds_entity_t writer;
dds_entity * pub = NULL; dds_entity * pub = NULL;
dds_entity * tp; dds_topic * tp;
dds_entity_t publisher; dds_entity_t publisher;
struct thread_state1 * const thr = lookup_thread_state(); struct thread_state1 * const thr = lookup_thread_state();
const bool asleep = !vtime_awake_p(thr->vtime); const bool asleep = !vtime_awake_p(thr->vtime);
@ -420,7 +410,7 @@ dds_create_writer(
dds_return_t ret; dds_return_t ret;
/* Try claiming a participant. If that's not working, then it could be a subscriber. */ /* 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); publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
} else{ } else{
publisher = participant_or_publisher; publisher = participant_or_publisher;
@ -437,14 +427,14 @@ dds_create_writer(
pub->m_flags |= DDS_ENTITY_IMPLICIT; 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) { if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking topic\n"); DDS_ERROR("Error occurred on locking topic\n");
writer = DDS_ERRNO(rc); writer = DDS_ERRNO(rc);
goto err_tp_lock; goto err_tp_lock;
} }
assert(((dds_topic*)tp)->m_stopic); assert(tp->m_stopic);
assert(pub->m_domain == tp->m_domain); assert(pub->m_domain == tp->m_entity.m_domain);
/* Merge Topic & Publisher qos */ /* Merge Topic & Publisher qos */
wqos = dds_create_qos(); wqos = dds_create_qos();
@ -458,9 +448,9 @@ dds_create_writer(
dds_merge_qos(wqos, pub->m_qos); dds_merge_qos(wqos, pub->m_qos);
} }
if (tp->m_qos) { if (tp->m_entity.m_qos) {
/* merge topic qos data to writer 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); nn_xqos_mergein_missing(wqos, &gv.default_xqos_wr);
@ -475,8 +465,8 @@ dds_create_writer(
wr = dds_alloc(sizeof (*wr)); wr = dds_alloc(sizeof (*wr));
writer = dds_entity_init(&wr->m_entity, pub, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK); writer = dds_entity_init(&wr->m_entity, pub, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
wr->m_topic = (dds_topic*)tp; wr->m_topic = tp;
dds_entity_add_ref_nolock(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_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.close = dds_writer_close;
wr->m_entity.m_deriver.delete = dds_writer_delete; wr->m_entity.m_deriver.delete = dds_writer_delete;
@ -491,25 +481,25 @@ dds_create_writer(
assert(0); assert(0);
} }
os_mutexUnlock(&tp->m_mutex); os_mutexUnlock(&tp->m_entity.m_mutex);
os_mutexUnlock(&pub->m_mutex); os_mutexUnlock(&pub->m_mutex);
if (asleep) { if (asleep) {
thread_state_awake(thr); 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(&pub->m_mutex);
os_mutexLock(&tp->m_mutex); os_mutexLock(&tp->m_entity.m_mutex);
assert(wr->m_wr); assert(wr->m_wr);
if (asleep) { if (asleep) {
thread_state_asleep(thr); thread_state_asleep(thr);
} }
dds_entity_unlock(tp); dds_topic_unlock(tp);
dds_entity_unlock(pub); dds_entity_unlock(pub);
return writer; return writer;
err_bad_qos: err_bad_qos:
dds_entity_unlock(tp); dds_topic_unlock(tp);
err_tp_lock: err_tp_lock:
dds_entity_unlock(pub); dds_entity_unlock(pub);
if((pub->m_flags & DDS_ENTITY_IMPLICIT) != 0){ if((pub->m_flags & DDS_ENTITY_IMPLICIT) != 0){
@ -559,10 +549,10 @@ dds_get_publication_matched_status (
if (status) { if (status) {
*status = wr->m_publication_matched_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.total_count_change = 0;
wr->m_publication_matched_status.current_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); dds_writer_unlock(wr);
fail: fail:
@ -589,9 +579,9 @@ dds_get_liveliness_lost_status (
if (status) { if (status) {
*status = wr->m_liveliness_lost_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; 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); dds_writer_unlock(wr);
fail: fail:
@ -618,9 +608,9 @@ dds_get_offered_deadline_missed_status(
if (status) { if (status) {
*status = wr->m_offered_deadline_missed_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; 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); dds_writer_unlock(wr);
fail: fail:
@ -647,9 +637,9 @@ dds_get_offered_incompatible_qos_status (
if (status) { if (status) {
*status = wr->m_offered_incompatible_qos_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; 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); dds_writer_unlock(wr);
fail: fail:

View file

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

View file

@ -178,27 +178,6 @@ struct ddsi_tran_qos
int m_diffserv; 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_tran_factories_fini (void);
void ddsi_factory_add (ddsi_tran_factory_t factory); void ddsi_factory_add (ddsi_tran_factory_t factory);
void ddsi_factory_free (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); 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); 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)) inline bool ddsi_factory_supports (ddsi_tran_factory_t factory, int32_t kind) {
#define ddsi_conn_locator(c,l) (ddsi_tran_locator (&(c)->m_base,(l))) return factory->m_supports_fn (kind);
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 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); 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_disable_multiplexing (ddsi_tran_conn_t conn);
void ddsi_conn_add_ref (ddsi_tran_conn_t conn); void ddsi_conn_add_ref (ddsi_tran_conn_t conn);
void ddsi_conn_free (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_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); 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); 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_conn_rejoin_transferred_mcgroups (ddsi_tran_conn_t conn);
int ddsi_is_mcaddr (const nn_locator_t *loc); int ddsi_is_mcaddr (const nn_locator_t *loc);
int ddsi_is_ssm_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_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); enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc, const char *str);
/* 8 for transport/ /* 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); 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))) inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc) {
ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener); return listener->m_base.m_locator_fn (&listener->m_base, loc);
int ddsi_listener_listen (ddsi_tran_listener_t listener); }
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_unblock (ddsi_tran_listener_t listener);
void ddsi_listener_free (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_rtps.h" /* for nn_guid_t, nn_guid_prefix_t */
#include "ddsi/q_protocol.h" /* for nn_sequence_number_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) 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) 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); 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) inline uint64_t bswap8u (uint64_t x)
{ {
const uint32_t newhi = bswap4u ((uint32_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; 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) inline void bswapSN (nn_sequence_number_t *sn)
{ {
sn->high = bswap4 (sn->high); sn->high = bswap4 (sn->high);

View file

@ -44,14 +44,14 @@ typedef void (*ddsi2direct_directread_cb_t) (const struct nn_rsample_info *sampl
typedef struct status_cb_data typedef struct status_cb_data
{ {
uint32_t status; int raw_status_id;
uint32_t extra; uint32_t extra;
uint64_t handle; uint64_t handle;
bool add; bool add;
} }
status_cb_data_t; status_cb_data_t;
typedef void (*status_cb_t) (void * entity, const status_cb_data_t * data); typedef void (*status_cb_t) (void *entity, const status_cb_data_t *data);
struct prd_wr_match { struct prd_wr_match {
ut_avlNode_t avlnode; ut_avlNode_t avlnode;

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); 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) 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; 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_join_mc_fn = ddsi_raweth_join_mc;
ddsi_raweth_factory_g.m_leave_mc_fn = ddsi_raweth_leave_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_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_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_locator_to_string_fn = ddsi_raweth_to_string;
ddsi_raweth_factory_g.m_enumerate_interfaces_fn = ddsi_raweth_enumerate_interfaces; ddsi_raweth_factory_g.m_enumerate_interfaces_fn = ddsi_raweth_enumerate_interfaces;

View file

@ -27,6 +27,7 @@
#define INVALID_PORT (~0u) #define INVALID_PORT (~0u)
typedef struct ddsi_tran_factory * ddsi_tcp_factory_g_t; 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 #ifdef DDSI_INCLUDE_SSL
struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin = struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin =
@ -1027,14 +1028,17 @@ static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
static void ddsi_tcp_release_factory (void) static void ddsi_tcp_release_factory (void)
{ {
ut_avlFree (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, ddsi_tcp_node_free); if (os_atomic_dec32_nv (&ddsi_tcp_init_g) == 0) {
os_mutexDestroy (&ddsi_tcp_cache_lock_g); ut_avlFree (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, ddsi_tcp_node_free);
os_mutexDestroy (&ddsi_tcp_cache_lock_g);
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.fini) if (ddsi_tcp_ssl_plugin.fini)
{ {
(ddsi_tcp_ssl_plugin.fini) (); (ddsi_tcp_ssl_plugin.fini) ();
} }
#endif #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) 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); 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) int ddsi_tcp_init (void)
{ {
static bool init = false; if (os_atomic_inc32_nv (&ddsi_tcp_init_g) == 1)
if (!init)
{ {
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_kind = NN_LOCATOR_KIND_TCPv4;
ddsi_tcp_factory_g.m_typename = "tcp"; ddsi_tcp_factory_g.m_typename = "tcp";
ddsi_tcp_factory_g.m_stream = true; 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_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_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_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); ddsi_factory_add (&ddsi_tcp_factory_g);
#if OS_SOCKET_HAS_IPV6 #if OS_SOCKET_HAS_IPV6

View file

@ -19,6 +19,21 @@
static ddsi_tran_factory_t ddsi_tran_factories = NULL; 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) void ddsi_factory_add (ddsi_tran_factory_t factory)
{ {
factory->m_factory = ddsi_tran_factories; factory->m_factory = ddsi_tran_factories;
@ -47,8 +62,8 @@ void ddsi_tran_factories_fini (void)
ddsi_tran_factory_t factory; ddsi_tran_factory_t factory;
while ((factory = ddsi_tran_factories) != NULL) { while ((factory = ddsi_tran_factories) != NULL) {
ddsi_tran_factories = factory->m_factory;
ddsi_factory_free(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; 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) void ddsi_conn_disable_multiplexing (ddsi_tran_conn_t conn)
{ {
if (conn->m_disable_multiplexing_fn) { 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); 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 ddsi_tran_create_qos (void)
{ {
ddsi_tran_qos_t qos; ddsi_tran_qos_t qos;
@ -215,31 +199,6 @@ ddsi_tran_qos_t ddsi_tran_create_qos (void)
return qos; 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) void ddsi_tran_free (ddsi_tran_base_t base)
{ {
if (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) 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);
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind); return tran ? tran->m_is_mcaddr_fn (tran, loc) : 0;
return tran && tran->m_is_mcaddr_fn ? tran->m_is_mcaddr_fn (tran, loc) : 0;
} }
int ddsi_is_ssm_mcaddr (const nn_locator_t *loc) int ddsi_is_ssm_mcaddr (const nn_locator_t *loc)
{ {
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind); 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[]) 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); 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) 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 uint16_t bswap2u (uint16_t x);
extern inline uint32_t bswap4u (uint32_t x); extern inline uint32_t bswap4u (uint32_t x);
extern inline uint64_t bswap8u (uint64_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); 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_TRANSIENT_DURABILITY_QOS: return "transient";
case NN_PERSISTENT_DURABILITY_QOS: return "persistent"; 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) 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_READER:
case EK_WRITER: case EK_WRITER:
return (nn_vendorid_t) MY_VENDOR_ID; return (nn_vendorid_t) MY_VENDOR_ID;
break;
case EK_PROXY_PARTICIPANT: case EK_PROXY_PARTICIPANT:
return ((const struct proxy_participant *) e)->vendor; return ((const struct proxy_participant *) e)->vendor;
break;
case EK_PROXY_READER: case EK_PROXY_READER:
return ((const struct proxy_reader *) e)->c.vendor; return ((const struct proxy_reader *) e)->c.vendor;
break;
case EK_PROXY_WRITER: case EK_PROXY_WRITER:
return ((const struct proxy_writer *) e)->c.vendor; return ((const struct proxy_writer *) e)->c.vendor;
break;
} }
assert (0); assert (0);
return (nn_vendorid_t) NN_VENDORID_UNKNOWN; 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) if (m != NULL && wr->status_cb)
{ {
status_cb_data_t data; 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.add = false;
data.handle = prd->e.iid; data.handle = prd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data); (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) if (m != NULL && wr->status_cb)
{ {
status_cb_data_t data; 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.add = false;
data.handle = rd->e.iid; data.handle = rd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data); (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.add = false;
data.handle = pwr->e.iid; 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); (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); (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.add = false;
data.handle = wr->e.iid; 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); (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); (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) if (wr->status_cb)
{ {
status_cb_data_t data; 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.add = true;
data.handle = prd->e.iid; data.handle = prd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data); (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) if (wr->status_cb)
{ {
status_cb_data_t data; 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.add = true;
data.handle = rd->e.iid; data.handle = rd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data); (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) if (rd->status_cb)
{ {
status_cb_data_t data; 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.add = true;
data.handle = pwr->e.iid; data.handle = pwr->e.iid;
(rd->status_cb) (rd->status_cb_entity, &data); (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.add = true;
data.handle = wr->e.iid; 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); (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); (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) if (rd->status_cb)
{ {
status_cb_data_t data; 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.add = true;
data.handle = pwr->e.iid; data.handle = pwr->e.iid;
(rd->status_cb) (rd->status_cb_entity, &data); (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) if (wr->status_cb)
{ {
status_cb_data_t data; 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; data.extra = reason;
(wr->status_cb) (wr->status_cb_entity, &data); (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) if (rd->status_cb)
{ {
status_cb_data_t data; 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; data.extra = reason;
(rd->status_cb) (rd->status_cb_entity, &data); (rd->status_cb) (rd->status_cb_entity, &data);
} }

View file

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

View file

@ -56,29 +56,6 @@ unsigned locator_to_hopefully_unique_uint32 (const nn_locator_t *src)
return id; 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 #ifdef DDSI_INCLUDE_NETWORK_CHANNELS
void set_socket_diffserv (os_socket sock, int diffserv) void set_socket_diffserv (os_socket sock, int diffserv)
{ {

View file

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

View file

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

View file

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

View file

@ -34,7 +34,6 @@
#include "ddsi/q_log.h" #include "ddsi/q_log.h"
#include "ddsi/q_unused.h" #include "ddsi/q_unused.h"
#include "ddsi/q_xmsg.h" #include "ddsi/q_xmsg.h"
#include "ddsi/q_align.h"
#include "ddsi/q_config.h" #include "ddsi/q_config.h"
#include "ddsi/q_entity.h" #include "ddsi/q_entity.h"
#include "ddsi/q_globals.h" #include "ddsi/q_globals.h"
@ -1339,7 +1338,18 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
#endif #endif
{ {
if (!gv.mute) if (!gv.mute)
{
nbytes = ddsi_conn_write (xp->conn, loc, xp->niov, xp->iov, xp->call_flags); 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 else
{ {
DDS_TRACE("(dropped)"); DDS_TRACE("(dropped)");

View file

@ -17,7 +17,7 @@
*/ */
#define BYTES_PER_SEC_TO_MEGABITS_PER_SEC 125000 #define BYTES_PER_SEC_TO_MEGABITS_PER_SEC 125000
#define MAX_SAMPLES 100 #define MAX_SAMPLES 1000
typedef struct HandleEntry typedef struct HandleEntry
{ {
@ -31,7 +31,7 @@ typedef struct HandleMap
HandleEntry *entries; HandleEntry *entries;
} HandleMap; } HandleMap;
static long pollingDelay = 0; static long pollingDelay = -1; /* i.e. use a listener */
static HandleMap * imap; static HandleMap * imap;
static unsigned long long outOfOrder = 0; 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 unsigned long long total_samples = 0;
static dds_time_t startTime = 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; static unsigned long payloadSize = 0;
@ -48,9 +46,8 @@ static ThroughputModule_DataType data [MAX_SAMPLES];
static void * samples[MAX_SAMPLES]; static void * samples[MAX_SAMPLES];
static dds_entity_t waitSet; static dds_entity_t waitSet;
static dds_entity_t pollingWaitset;
static bool done = false; static volatile sig_atomic_t done = false;
/* Forward declarations */ /* Forward declarations */
static HandleMap * HandleMap__alloc (void); 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 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 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 dds_entity_t prepare_dds(dds_entity_t *reader, const char *partitionName);
static void finalize_dds(dds_entity_t participant); 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 participant;
dds_entity_t reader; dds_entity_t reader;
time_now = dds_time ();
prev_time = time_now;
/* Register handler for Ctrl-C */ /* Register handler for Ctrl-C */
#ifdef _WIN32 #ifdef _WIN32
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, true); SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, true);
@ -110,8 +104,7 @@ int main (int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf ("Cycles: %llu | PollingDelay: %lu | Partition: %s\n", printf ("Cycles: %llu | PollingDelay: %ld | Partition: %s\n", maxCycles, pollingDelay, partitionName);
maxCycles, pollingDelay, partitionName);
participant = prepare_dds(&reader, 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 */ /* Process samples until Ctrl-C is pressed or until maxCycles */
/* has been reached (0 = infinite) */ /* has been reached (0 = infinite) */
process_samples(maxCycles); process_samples(reader, maxCycles);
/* Finished, disable callbacks */ /* Finished, disable callbacks */
dds_set_status_mask (reader, 0); dds_set_status_mask (reader, 0);
@ -189,13 +182,12 @@ static HandleEntry * retrieve_handle (HandleMap *map, dds_instance_handle_t key)
return entry; return entry;
} }
static void data_available_handler (dds_entity_t reader, void *arg) static int do_take (dds_entity_t reader)
{ {
int samples_received; int samples_received;
dds_sample_info_t info [MAX_SAMPLES]; dds_sample_info_t info [MAX_SAMPLES];
dds_instance_handle_t ph = 0; dds_instance_handle_t ph = 0;
HandleEntry * current = NULL; HandleEntry * current = NULL;
(void)arg;
if (startTime == 0) if (startTime == 0)
{ {
@ -234,11 +226,13 @@ static void data_available_handler (dds_entity_t reader, void *arg)
total_samples++; total_samples++;
} }
} }
time_now = dds_time (); return samples_received;
if ((pollingDelay == 0) && (time_now > (prev_time + DDS_SECS (1)))) }
{
dds_waitset_set_trigger (pollingWaitset, true); 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) 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)) if (argc == 2 && (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0))
{ {
printf ("Usage (parameters must be supplied in order):\n"); 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 ("Defaults:\n");
printf ("./subscriber 0 0 \"Throughput example\"\n"); printf ("./subscriber 0 0 \"Throughput example\"\n");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -262,7 +256,7 @@ static int parse_args(int argc, char **argv, unsigned long long *maxCycles, char
} }
if (argc > 2) 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) if (argc > 3)
{ {
@ -271,61 +265,59 @@ static int parse_args(int argc, char **argv, unsigned long long *maxCycles, char
return EXIT_SUCCESS; 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; dds_return_t status;
unsigned long long prev_bytes = 0; unsigned long long prev_bytes = 0;
unsigned long long prev_samples = 0; unsigned long long prev_samples = 0;
dds_attach_t wsresults[1]; dds_attach_t wsresults[2];
size_t wsresultsize = 1U;
dds_time_t deltaTv; dds_time_t deltaTv;
bool first_batch = true; bool first_batch = true;
unsigned long cycles = 0; unsigned long cycles = 0;
double deltaTime = 0; double deltaTime = 0;
dds_time_t prev_time = 0;
dds_time_t time_now = 0;
while (!done && (maxCycles == 0 || cycles < maxCycles)) while (!done && (maxCycles == 0 || cycles < maxCycles))
{ {
if (pollingDelay) if (pollingDelay > 0)
{ {
dds_sleepfor (DDS_MSECS (pollingDelay)); dds_sleepfor (DDS_MSECS (pollingDelay));
while (do_take (reader))
;
} }
else 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); DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
while (do_take (reader))
if ((status > 0 ) && (dds_triggered (pollingWaitset))) ;
{
dds_waitset_set_trigger (pollingWaitset, false);
}
} }
time_now = dds_time();
if (!first_batch) if (!first_batch)
{ {
deltaTv = time_now - prev_time; deltaTv = time_now - prev_time;
deltaTime = (double) deltaTv / DDS_NSECS_IN_SEC; deltaTime = (double) deltaTv / DDS_NSECS_IN_SEC;
prev_time = time_now;
printf if (deltaTime >= 1.0 && total_samples != prev_samples)
( {
"=== [Subscriber] Payload size: %lu | Total received: %llu samples, %llu bytes | Out of order: %llu 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", "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_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++;
cycles++; prev_time = time_now;
prev_bytes = total_bytes;
prev_samples = total_samples;
}
} }
else else
{ {
prev_time = time_now; prev_time = time_now;
first_batch = false; first_batch = false;
} }
/* Update the previous values for next iteration */
prev_bytes = total_bytes;
prev_samples = total_samples;
} }
/* Output totals and averages */ /* 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_listener_t *rd_listener;
dds_entity_t participant; dds_entity_t participant;
int32_t maxSamples = 400; int32_t maxSamples = 4000;
const char *subParts[1]; const char *subParts[1];
dds_qos_t *subQos = dds_create_qos (); dds_qos_t *subQos = dds_create_qos ();
dds_qos_t *drQos = 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); waitSet = dds_create_waitset (participant);
DDS_ERR_CHECK (waitSet, DDS_CHECK_REPORT | DDS_CHECK_EXIT); 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); status = dds_waitset_attach (waitSet, waitSet, waitSet);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT); 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]; 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); 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_qos (drQos);
dds_delete_listener(rd_listener); dds_delete_listener(rd_listener);
@ -417,10 +410,6 @@ static void finalize_dds(dds_entity_t participant)
status = dds_waitset_detach (waitSet, waitSet); status = dds_waitset_detach (waitSet, waitSet);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT); 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); status = dds_delete (waitSet);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
status = dds_delete (participant); 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_TheoryDataPoints(os_gethostbyname, ipv4) = {
CU_DataPoints(char *, "", "_nah", "127.0.0.1", "127.0.0.1"), CU_DataPoints(char *, "", "127.0.0.1", "127.0.0.1"),
CU_DataPoints(int, AF_UNSPEC, AF_UNSPEC, AF_INET, AF_UNSPEC), CU_DataPoints(int, AF_UNSPEC, AF_INET, AF_UNSPEC),
CU_DataPoints(int, OS_HOST_NOT_FOUND, OS_HOST_NOT_FOUND, 0, 0) CU_DataPoints(int, OS_HOST_NOT_FOUND, 0, 0)
}; };
CU_Theory((char *name, int af, int ret), os_gethostbyname, ipv4, .init=setup, .fini=teardown) 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; qpublisher[nqpublisher++] = q;
qsubscriber[nqsubscriber++] = q; qsubscriber[nqsubscriber++] = q;
break; break;
break;
default: default:
assert(0); assert(0);
} }