From a25f683bcfbf722a6a8b63dddaab4f962acb470f Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 26 Oct 2018 16:25:26 +0800 Subject: [PATCH 01/13] abstract the internal representation of a sample besides the old state being in dire need of cleaning up, this also paves the way for having any number of different sample representations in the system Signed-off-by: Erik Boasson --- src/core/ddsc/CMakeLists.txt | 2 - src/core/ddsc/include/ddsc/dds.h | 7 +- src/core/ddsc/include/ddsc/dds_public_impl.h | 2 +- .../ddsc/include/ddsc/dds_public_stream.h | 10 +- src/core/ddsc/src/dds__rhc.h | 8 +- src/core/ddsc/src/dds__stream.h | 18 +- src/core/ddsc/src/dds__tkmap.h | 10 +- src/core/ddsc/src/dds__topic.h | 4 +- src/core/ddsc/src/dds__types.h | 4 +- src/core/ddsc/src/dds__write.h | 4 +- src/core/ddsc/src/dds_builtin.c | 1 - src/core/ddsc/src/dds_init.c | 2 +- src/core/ddsc/src/dds_instance.c | 9 +- src/core/ddsc/src/dds_key.c | 2 +- src/core/ddsc/src/dds_participant.c | 1 - src/core/ddsc/src/dds_querycond.c | 6 +- src/core/ddsc/src/dds_read.c | 4 +- src/core/ddsc/src/dds_rhc.c | 89 +-- src/core/ddsc/src/dds_stream.c | 60 +-- src/core/ddsc/src/dds_tkmap.c | 82 +-- src/core/ddsc/src/dds_topic.c | 79 +-- src/core/ddsc/src/dds_whc.c | 25 +- src/core/ddsc/src/dds_write.c | 35 +- src/core/ddsc/src/dds_writer.c | 2 +- src/core/ddsc/src/q__osplser.h | 39 -- src/core/ddsc/src/q_osplser.c | 142 ----- src/core/ddsi/CMakeLists.txt | 9 +- src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h | 8 +- src/core/ddsi/include/ddsi/ddsi_serdata.h | 158 ++++++ .../{ddsi_ser.h => ddsi_serdata_default.h} | 123 ++--- src/core/ddsi/include/ddsi/ddsi_sertopic.h | 48 ++ src/core/ddsi/include/ddsi/q_entity.h | 12 +- src/core/ddsi/include/ddsi/q_globals.h | 2 + src/core/ddsi/include/ddsi/q_plist.h | 3 +- src/core/ddsi/include/ddsi/q_transmit.h | 14 +- src/core/ddsi/include/ddsi/q_whc.h | 8 +- src/core/ddsi/include/ddsi/q_xmsg.h | 8 +- src/core/ddsi/src/ddsi_ser.c | 242 --------- src/core/ddsi/src/ddsi_serdata.c | 48 ++ src/core/ddsi/src/ddsi_serdata_default.c | 510 ++++++++++++++++++ src/core/ddsi/src/ddsi_sertopic.c | 46 ++ src/core/ddsi/src/ddsi_sertopic_default.c | 35 ++ src/core/ddsi/src/q_ddsi_discovery.c | 221 +++----- src/core/ddsi/src/q_debmon.c | 7 +- src/core/ddsi/src/q_entity.c | 45 +- src/core/ddsi/src/q_init.c | 39 +- src/core/ddsi/src/q_lease.c | 2 +- src/core/ddsi/src/q_plist.c | 16 + src/core/ddsi/src/q_receive.c | 88 +-- src/core/ddsi/src/q_transmit.c | 97 ++-- src/core/ddsi/src/q_xevent.c | 56 +- src/core/ddsi/src/q_xmsg.c | 33 +- 52 files changed, 1400 insertions(+), 1125 deletions(-) delete mode 100644 src/core/ddsc/src/q__osplser.h delete mode 100644 src/core/ddsc/src/q_osplser.c create mode 100644 src/core/ddsi/include/ddsi/ddsi_serdata.h rename src/core/ddsi/include/ddsi/{ddsi_ser.h => ddsi_serdata_default.h} (51%) create mode 100644 src/core/ddsi/include/ddsi/ddsi_sertopic.h delete mode 100644 src/core/ddsi/src/ddsi_ser.c create mode 100644 src/core/ddsi/src/ddsi_serdata.c create mode 100644 src/core/ddsi/src/ddsi_serdata_default.c create mode 100644 src/core/ddsi/src/ddsi_sertopic.c create mode 100644 src/core/ddsi/src/ddsi_sertopic_default.c diff --git a/src/core/ddsc/CMakeLists.txt b/src/core/ddsc/CMakeLists.txt index ab4740d..d895ce3 100644 --- a/src/core/ddsc/CMakeLists.txt +++ b/src/core/ddsc/CMakeLists.txt @@ -21,7 +21,6 @@ PREPEND(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds_publisher.c dds_rhc.c dds_time.c - q_osplser.c dds_domain.c dds_instance.c dds_qos.c @@ -82,7 +81,6 @@ PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds__write.h dds__writer.h dds__whc.h - q__osplser.h ) configure_file( diff --git a/src/core/ddsc/include/ddsc/dds.h b/src/core/ddsc/include/ddsc/dds.h index cd3a1e5..93c9328 100644 --- a/src/core/ddsc/include/ddsc/dds.h +++ b/src/core/ddsc/include/ddsc/dds.h @@ -55,8 +55,7 @@ typedef _Return_type_success_(return > 0) int32_t dds_entity_t; extern "C" { #endif -/* FIXME: rename serdata, abstract it properly, etc */ -struct serdata; +struct ddsi_serdata; /** * @brief Returns the default domain identifier. @@ -1710,7 +1709,7 @@ _Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER) DDS_EXPORT int dds_writecdr( dds_entity_t writer, - struct serdata *serdata); + struct ddsi_serdata *serdata); /** * @brief Write the value of a data instance along with the source timestamp passed. @@ -2722,7 +2721,7 @@ dds_take_mask_wl( DDS_EXPORT int dds_takecdr( dds_entity_t reader_or_condition, - struct serdata **buf, + struct ddsi_serdata **buf, uint32_t maxs, dds_sample_info_t *si, uint32_t mask); diff --git a/src/core/ddsc/include/ddsc/dds_public_impl.h b/src/core/ddsc/include/ddsc/dds_public_impl.h index d0170c7..d1c041e 100644 --- a/src/core/ddsc/include/ddsc/dds_public_impl.h +++ b/src/core/ddsc/include/ddsc/dds_public_impl.h @@ -56,7 +56,7 @@ dds_key_descriptor_t; typedef struct dds_topic_descriptor { - const size_t m_size; /* Size of topic type */ + const uint32_t m_size; /* Size of topic type */ const uint32_t m_align; /* Alignment of topic type */ const uint32_t m_flagset; /* Flags */ const uint32_t m_nkeys; /* Number of keys (can be 0) */ diff --git a/src/core/ddsc/include/ddsc/dds_public_stream.h b/src/core/ddsc/include/ddsc/dds_public_stream.h index 4c96379..f729ff6 100644 --- a/src/core/ddsc/include/ddsc/dds_public_stream.h +++ b/src/core/ddsc/include/ddsc/dds_public_stream.h @@ -45,8 +45,8 @@ dds_uptr_t; typedef struct dds_stream { dds_uptr_t m_buffer; /* Union of pointers to start of buffer */ - size_t m_size; /* Buffer size */ - size_t m_index; /* Read/write offset from start of buffer */ + uint32_t m_size; /* Buffer size */ + uint32_t m_index; /* Read/write offset from start of buffer */ bool m_endian; /* Endian: big (false) or little (true) */ bool m_failed; /* Attempt made to read beyond end of buffer */ } @@ -55,13 +55,13 @@ dds_stream_t; #define DDS_STREAM_BE false #define DDS_STREAM_LE true -DDS_EXPORT dds_stream_t * dds_stream_create (size_t size); +DDS_EXPORT dds_stream_t * dds_stream_create (uint32_t size); DDS_EXPORT dds_stream_t * dds_stream_from_buffer (const void *buf, size_t sz, int bswap); DDS_EXPORT void dds_stream_delete (dds_stream_t * st); DDS_EXPORT void dds_stream_fini (dds_stream_t * st); DDS_EXPORT void dds_stream_reset (dds_stream_t * st); -DDS_EXPORT void dds_stream_init (dds_stream_t * st, size_t size); -DDS_EXPORT void dds_stream_grow (dds_stream_t * st, size_t size); +DDS_EXPORT void dds_stream_init (dds_stream_t * st, uint32_t size); +DDS_EXPORT void dds_stream_grow (dds_stream_t * st, uint32_t size); DDS_EXPORT bool dds_stream_endian (void); struct dds_topic_descriptor; diff --git a/src/core/ddsc/src/dds__rhc.h b/src/core/ddsc/src/dds__rhc.h index 315bd84..13ff911 100644 --- a/src/core/ddsc/src/dds__rhc.h +++ b/src/core/ddsc/src/dds__rhc.h @@ -23,11 +23,11 @@ extern "C" { struct rhc; struct nn_xqos; -struct serdata; +struct ddsi_serdata; struct tkmap_instance; struct proxy_writer_info; -struct rhc * dds_rhc_new (dds_reader * reader, const struct sertopic * topic); +struct rhc * dds_rhc_new (dds_reader * reader, const struct ddsi_sertopic * topic); void dds_rhc_free (struct rhc * rhc); void dds_rhc_fini (struct rhc * rhc); @@ -36,7 +36,7 @@ uint32_t dds_rhc_lock_samples (struct rhc * rhc); DDS_EXPORT bool dds_rhc_store ( struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info, - struct serdata * __restrict sample, struct tkmap_instance * __restrict tk + struct ddsi_serdata * __restrict sample, struct tkmap_instance * __restrict tk ); void dds_rhc_unregister_wr (struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info); void dds_rhc_relinquish_ownership (struct rhc * __restrict rhc, const uint64_t wr_iid); @@ -72,7 +72,7 @@ int dds_rhc_remove_waitset (dds_readcond * cond, dds_waitset * waitset); int dds_rhc_takecdr ( - struct rhc *rhc, bool lock, struct serdata **values, dds_sample_info_t *info_seq, + struct rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, unsigned sample_states, unsigned view_states, unsigned instance_states, dds_instance_handle_t handle diff --git a/src/core/ddsc/src/dds__stream.h b/src/core/ddsc/src/dds__stream.h index 52d8737..47da8c4 100644 --- a/src/core/ddsc/src/dds__stream.h +++ b/src/core/ddsc/src/dds__stream.h @@ -12,7 +12,8 @@ #ifndef _DDS_STREAM_H_ #define _DDS_STREAM_H_ -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_serdata_default.h" #if defined (__cplusplus) extern "C" { @@ -22,25 +23,20 @@ void dds_stream_write_sample ( dds_stream_t * os, const void * data, - const struct sertopic * topic + const struct ddsi_sertopic_default * topic ); void dds_stream_read_sample ( dds_stream_t * is, void * data, - const struct sertopic * topic + const struct ddsi_sertopic_default * topic ); size_t dds_stream_check_optimize (_In_ const dds_topic_descriptor_t * desc); -void dds_stream_from_serstate (_Out_ dds_stream_t * s, _In_ const serstate_t st); -void dds_stream_add_to_serstate (_Inout_ dds_stream_t * s, _Inout_ serstate_t st); +void dds_stream_from_serdata_default (dds_stream_t * s, const struct ddsi_serdata_default *d); +void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d); -void dds_stream_write_key -( - dds_stream_t * os, - const char * sample, - const dds_topic_descriptor_t * desc -); +void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic); void dds_stream_read_key ( dds_stream_t * is, diff --git a/src/core/ddsc/src/dds__tkmap.h b/src/core/ddsc/src/dds__tkmap.h index 64d78d2..613fb51 100644 --- a/src/core/ddsc/src/dds__tkmap.h +++ b/src/core/ddsc/src/dds__tkmap.h @@ -20,12 +20,12 @@ extern "C" { #endif struct tkmap; -struct serdata; +struct ddsi_serdata; struct dds_topic; struct tkmap_instance { - struct serdata * m_sample; + struct ddsi_serdata * m_sample; struct tkmap * m_map; uint64_t m_iid; os_atomic_uint32_t m_refc; @@ -35,15 +35,15 @@ struct tkmap_instance struct tkmap * dds_tkmap_new (void); void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap *tkmap); void dds_tkmap_instance_ref (_In_ struct tkmap_instance *tk); -uint64_t dds_tkmap_lookup (_In_ struct tkmap *tkmap, _In_ const struct serdata *serdata); +uint64_t dds_tkmap_lookup (_In_ struct tkmap *tkmap, _In_ const struct ddsi_serdata *serdata); _Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample); _Check_return_ struct tkmap_instance * dds_tkmap_find( - _In_ struct serdata * sd, + _In_ struct ddsi_serdata * sd, _In_ const bool rd, _In_ const bool create); _Check_return_ struct tkmap_instance * dds_tkmap_find_by_id (_In_ struct tkmap * map, _In_ uint64_t iid); -DDS_EXPORT _Check_return_ struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct serdata * sd); +DDS_EXPORT _Check_return_ struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd); DDS_EXPORT void dds_tkmap_instance_unref (_In_ struct tkmap_instance * tk); #if defined (__cplusplus) diff --git a/src/core/ddsc/src/dds__topic.h b/src/core/ddsc/src/dds__topic.h index 43e238c..32bd8ca 100644 --- a/src/core/ddsc/src/dds__topic.h +++ b/src/core/ddsc/src/dds__topic.h @@ -21,8 +21,8 @@ extern "C" { #define dds_topic_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_TOPIC, (dds_entity**)obj) #define dds_topic_unlock(obj) dds_entity_unlock((dds_entity*)obj); -extern struct sertopic * dds_topic_lookup (dds_domain * domain, const char * name); -extern void dds_topic_free (dds_domainid_t domainid, struct sertopic * st); +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); #ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED #define DDS_TOPIC_INTERN_FILTER_FN_DEFINED diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index f77464a..07d73c6 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -38,7 +38,7 @@ struct dds_readcond; struct dds_guardcond; struct dds_statuscond; -struct sertopic; +struct ddsi_sertopic; struct rhc; /* Internal entity status flags */ @@ -203,7 +203,7 @@ dds_writer; typedef struct dds_topic { struct dds_entity m_entity; - struct sertopic * m_stopic; + struct ddsi_sertopic * m_stopic; const dds_topic_descriptor_t * m_descriptor; /* Status metrics */ diff --git a/src/core/ddsc/src/dds__write.h b/src/core/ddsc/src/dds__write.h index c12d99f..e78d65e 100644 --- a/src/core/ddsc/src/dds__write.h +++ b/src/core/ddsc/src/dds__write.h @@ -20,6 +20,8 @@ extern "C" { #define DDS_WR_DISPOSE_BIT 0x02 #define DDS_WR_UNREGISTER_BIT 0x04 +struct ddsi_serdata; + typedef enum { DDS_WR_ACTION_WRITE = 0, @@ -39,7 +41,7 @@ dds_write_impl( int dds_writecdr_impl( _In_ dds_writer *wr, - _Inout_ struct serdata *d, + _Inout_ struct ddsi_serdata *d, _In_ dds_time_t tstamp, _In_ dds_write_action action); diff --git a/src/core/ddsc/src/dds_builtin.c b/src/core/ddsc/src/dds_builtin.c index 70373be..b2325d9 100644 --- a/src/core/ddsc/src/dds_builtin.c +++ b/src/core/ddsc/src/dds_builtin.c @@ -15,7 +15,6 @@ #include "ddsi/q_thread.h" #include "ddsi/q_config.h" #include "ddsi/q_builtin_topic.h" -#include "q__osplser.h" #include "dds__init.h" #include "dds__qos.h" #include "dds__domain.h" diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c index f27694f..7517006 100644 --- a/src/core/ddsc/src/dds_init.c +++ b/src/core/ddsc/src/dds_init.c @@ -22,7 +22,7 @@ #include "dds__err.h" #include "dds__builtin.h" #include "dds__report.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" #include "ddsi/q_servicelease.h" #include "ddsi/q_entity.h" #include diff --git a/src/core/ddsc/src/dds_instance.c b/src/core/ddsc/src/dds_instance.c index 4255b14..f0736ae 100644 --- a/src/core/ddsc/src/dds_instance.c +++ b/src/core/ddsc/src/dds_instance.c @@ -18,10 +18,9 @@ #include "dds__rhc.h" #include "dds__tkmap.h" #include "dds__err.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" #include "ddsi/q_entity.h" #include "ddsi/q_thread.h" -#include "q__osplser.h" #include "dds__report.h" @@ -70,7 +69,7 @@ dds_instance_find( _In_ const void *data, _In_ const bool create) { - serdata_t sd = serialize_key (topic->m_stopic, data); + struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data); struct tkmap_instance * inst = dds_tkmap_find (sd, false, create); ddsi_serdata_unref (sd); return inst; @@ -407,7 +406,7 @@ dds_instance_lookup( dds_instance_handle_t ih = DDS_HANDLE_NIL; const dds_topic * topic; struct tkmap * map = gv.m_tkmap; - serdata_t sd; + struct ddsi_serdata *sd; dds_return_t ret; DDS_REPORT_STACK(); @@ -419,7 +418,7 @@ dds_instance_lookup( topic = dds_instance_info_by_hdl (entity); if (topic) { - sd = serialize_key (topic->m_stopic, data); + sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data); ih = dds_tkmap_lookup (map, sd); ddsi_serdata_unref (sd); ret = DDS_RETCODE_OK; diff --git a/src/core/ddsc/src/dds_key.c b/src/core/ddsc/src/dds_key.c index d4441c8..2bd804b 100644 --- a/src/core/ddsc/src/dds_key.c +++ b/src/core/ddsc/src/dds_key.c @@ -13,7 +13,7 @@ #include #include "dds__key.h" #include "dds__stream.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" #include "ddsi/q_bswap.h" #include "ddsi/q_md5.h" diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index 14b3b05..91542ca 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -13,7 +13,6 @@ #include "ddsi/q_entity.h" #include "ddsi/q_thread.h" #include "ddsi/q_config.h" -#include "q__osplser.h" #include "dds__init.h" #include "dds__qos.h" #include "dds__domain.h" diff --git a/src/core/ddsc/src/dds_querycond.c b/src/core/ddsc/src/dds_querycond.c index fd3da3c..7551539 100644 --- a/src/core/ddsc/src/dds_querycond.c +++ b/src/core/ddsc/src/dds_querycond.c @@ -16,7 +16,8 @@ #include "dds__querycond.h" #include "dds__readcond.h" #include "dds__err.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_sertopic.h" #include "dds__report.h" _Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER) @@ -44,9 +45,12 @@ dds_create_querycondition( dds_reader_unlock(r); rc = dds_topic_lock(topic, &t); if (rc == DDS_RETCODE_OK) { + abort(); +#if 0 if (t->m_stopic->filter_sample == NULL) { t->m_stopic->filter_sample = dds_alloc(t->m_descriptor->m_size); } +#endif dds_topic_unlock(t); } else { (void)dds_delete(hdl); diff --git a/src/core/ddsc/src/dds_read.c b/src/core/ddsc/src/dds_read.c index 4b2b032..77eb516 100644 --- a/src/core/ddsc/src/dds_read.c +++ b/src/core/ddsc/src/dds_read.c @@ -188,7 +188,7 @@ static dds_return_t dds_readcdr_impl( _In_ bool take, _In_ dds_entity_t reader_or_condition, - _Out_ struct serdata ** buf, + _Out_ struct ddsi_serdata ** buf, _In_ uint32_t maxs, _Out_ dds_sample_info_t * si, _In_ uint32_t mask, @@ -630,7 +630,7 @@ dds_take_mask_wl( int dds_takecdr( dds_entity_t rd_or_cnd, - struct serdata **buf, + struct ddsi_serdata **buf, uint32_t maxs, dds_sample_info_t *si, uint32_t mask) diff --git a/src/core/ddsc/src/dds_rhc.c b/src/core/ddsc/src/dds_rhc.c index 9946c35..bea7ec7 100644 --- a/src/core/ddsc/src/dds_rhc.c +++ b/src/core/ddsc/src/dds_rhc.c @@ -31,11 +31,12 @@ #include "ddsi/q_xqos.h" #include "ddsi/q_error.h" #include "ddsi/q_unused.h" -#include "q__osplser.h" #include "ddsi/q_config.h" #include "ddsi/q_globals.h" #include "ddsi/q_radmin.h" /* sampleinfo */ #include "ddsi/q_entity.h" /* proxy_writer_info */ +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_serdata_default.h" #include "ddsi/sysdeps.h" #include "dds__report.h" @@ -223,7 +224,7 @@ void lwregs_dump (struct lwregs *rt) struct rhc_sample { - struct serdata *sample; /* serialised data (either just_key or real data) */ + struct ddsi_serdata *sample; /* serialised data (either just_key or real data) */ struct rhc_sample *next; /* next sample in time ordering, or oldest sample if most recent */ uint64_t wr_iid; /* unique id for writer of this sample (perhaps better in serdata) */ bool isread; /* READ or NOT_READ sample state */ @@ -293,7 +294,7 @@ struct rhc bool reliable; /* true if reliability RELIABLE */ dds_reader * reader; /* reader */ - const struct sertopic * topic; /* topic description */ + const struct ddsi_sertopic * topic; /* topic description */ unsigned history_depth; /* depth, 1 for KEEP_LAST_1, 2**32-1 for KEEP_ALL */ os_mutex lock; @@ -319,7 +320,7 @@ struct trigger_info #define INST_HAS_UNREAD(i) (INST_NREAD (i) < INST_NSAMPLES (i)) static unsigned qmask_of_inst (const struct rhc_instance *inst); -static bool update_conditions_locked (struct rhc *rhc, const struct trigger_info *pre, const struct trigger_info *post, const struct 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); #ifndef NDEBUG static int rhc_check_counts_locked (struct rhc *rhc, bool check_conds); #endif @@ -389,7 +390,7 @@ static void remove_inst_from_nonempty_list (struct rhc *rhc, struct rhc_instance rhc->n_nonempty_instances--; } -struct rhc * dds_rhc_new (dds_reader * reader, const struct sertopic * topic) +struct rhc * dds_rhc_new (dds_reader * reader, const struct ddsi_sertopic * topic) { struct rhc * rhc = dds_alloc (sizeof (*rhc)); @@ -578,7 +579,7 @@ static bool add_sample struct rhc * rhc, struct rhc_instance * inst, const struct proxy_writer_info * pwr_info, - const struct serdata * sample, + const struct ddsi_serdata * sample, status_cb_data_t * cb_data ) { @@ -652,7 +653,7 @@ static bool add_sample rhc->n_vsamples++; } - s->sample = ddsi_serdata_ref ((serdata_t) sample); /* drops const (tho refcount does change) */ + s->sample = ddsi_serdata_ref ((struct ddsi_serdata *) sample); /* drops const (tho refcount does change) */ s->wr_iid = pwr_info->iid; s->isread = false; s->disposed_gen = inst->disposed_gen; @@ -662,15 +663,16 @@ static bool add_sample return true; } -static bool content_filter_accepts (const struct sertopic * topic, const struct serdata *sample) +static bool content_filter_accepts (const struct ddsi_sertopic * topic, const struct ddsi_serdata *sample) { bool ret = true; - +#if 0 /* FIXME: content filter */ if (topic->filter_fn) { deserialize_into ((char*) topic->filter_sample, sample); ret = (topic->filter_fn) (topic->filter_sample, topic->filter_ctx); } +#endif return ret; } @@ -683,16 +685,16 @@ static int inst_accepts_sample ( const struct rhc *rhc, const struct rhc_instance *inst, const struct proxy_writer_info *pwr_info, - const struct serdata *sample, const bool has_data + const struct ddsi_serdata *sample, const bool has_data ) { if (rhc->by_source_ordering) { - if (sample->v.msginfo.timestamp.v > inst->tstamp.v) + if (sample->timestamp.v > inst->tstamp.v) { /* ok */ } - else if (sample->v.msginfo.timestamp.v < inst->tstamp.v) + else if (sample->timestamp.v < inst->tstamp.v) { return 0; } @@ -1019,7 +1021,7 @@ static void dds_rhc_unregister static struct rhc_instance * alloc_new_instance ( const struct proxy_writer_info *pwr_info, - struct serdata *serdata, + struct ddsi_serdata *serdata, struct tkmap_instance *tk ) { @@ -1029,8 +1031,8 @@ static struct rhc_instance * alloc_new_instance inst = dds_alloc (sizeof (*inst)); inst->iid = tk->m_iid; inst->tk = tk; - inst->wrcount = (serdata->v.msginfo.statusinfo & NN_STATUSINFO_UNREGISTER) ? 0 : 1; - inst->isdisposed = (serdata->v.msginfo.statusinfo & NN_STATUSINFO_DISPOSE); + inst->wrcount = (serdata->statusinfo & NN_STATUSINFO_UNREGISTER) ? 0 : 1; + inst->isdisposed = (serdata->statusinfo & NN_STATUSINFO_DISPOSE); inst->isnew = 1; inst->inv_exists = 0; inst->inv_isread = 0; /* don't care */ @@ -1038,7 +1040,7 @@ static struct rhc_instance * alloc_new_instance inst->wr_iid = pwr_info->iid; inst->wr_iid_islive = (inst->wrcount != 0); inst->wr_guid = pwr_info->guid; - inst->tstamp = serdata->v.msginfo.timestamp; + inst->tstamp = serdata->timestamp; inst->strength = pwr_info->ownership_strength; return inst; } @@ -1048,7 +1050,7 @@ static rhc_store_result_t rhc_store_new_instance struct trigger_info * post, struct rhc *rhc, const struct proxy_writer_info *pwr_info, - struct serdata *sample, + struct ddsi_serdata *sample, struct tkmap_instance *tk, const bool has_data, status_cb_data_t * cb_data @@ -1121,12 +1123,12 @@ static rhc_store_result_t rhc_store_new_instance bool dds_rhc_store ( struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info, - struct serdata * __restrict sample, struct tkmap_instance * __restrict tk + struct ddsi_serdata * __restrict sample, struct tkmap_instance * __restrict tk ) { const uint64_t wr_iid = pwr_info->iid; - const unsigned statusinfo = sample->v.msginfo.statusinfo; - const bool has_data = (sample->v.st->kind == STK_DATA); + const unsigned statusinfo = sample->statusinfo; + const bool has_data = (sample->kind == SDK_DATA); const int is_dispose = (statusinfo & NN_STATUSINFO_DISPOSE) != 0; struct rhc_instance dummy_instance; struct rhc_instance *inst; @@ -1193,7 +1195,7 @@ bool dds_rhc_store } if (statusinfo & NN_STATUSINFO_UNREGISTER) { - dds_rhc_unregister (&post, rhc, inst, pwr_info, sample->v.msginfo.timestamp); + dds_rhc_unregister (&post, rhc, inst, pwr_info, sample->timestamp); } else { @@ -1282,7 +1284,7 @@ bool dds_rhc_store if (inst_became_disposed && (inst->latest == NULL )) inst_set_invsample (rhc, inst); - update_inst (rhc, inst, pwr_info, true, sample->v.msginfo.timestamp); + update_inst (rhc, inst, pwr_info, true, sample->timestamp); /* Can only add samples => only need to give special treatment to instances that were empty before. It is, however, not @@ -1326,7 +1328,7 @@ bool dds_rhc_store mean an application reading "x" after the write and reading it again after the unregister will see a change in the no_writers_generation field? */ - dds_rhc_unregister (&post, rhc, inst, pwr_info, sample->v.msginfo.timestamp); + dds_rhc_unregister (&post, rhc, inst, pwr_info, sample->timestamp); } else { @@ -1582,7 +1584,7 @@ static void set_sample_info (dds_sample_info_t *si, const struct rhc_instance *i si->generation_rank = 0; /* __/ */ si->absolute_generation_rank = (inst->disposed_gen + inst->no_writers_gen) - (sample->disposed_gen + sample->no_writers_gen); si->valid_data = true; - si->source_timestamp = sample->sample->v.msginfo.timestamp.v; + si->source_timestamp = sample->sample->timestamp.v; } static void set_sample_info_invsample (dds_sample_info_t *si, const struct rhc_instance *inst) @@ -1626,7 +1628,12 @@ static int dds_rhc_read_w_qminv { bool trigger_waitsets = false; uint32_t n = 0; +#if 0 const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) rhc->topic->type; +#else /* FIXME: hack hack -- deserialize_into */ + const struct ddsi_sertopic_default *sertopic_def = (const struct ddsi_sertopic_default *)rhc->topic; + const struct dds_topic_descriptor * desc = sertopic_def->type; +#endif if (lock) { @@ -1664,7 +1671,7 @@ static int dds_rhc_read_w_qminv { /* sample state matches too */ set_sample_info (info_seq + n, inst, sample); - deserialize_into ((char*) values[n], sample->sample); + ddsi_serdata_to_sample (sample->sample, values[n], 0, 0); if (cond == NULL || (dds_entity_kind(cond->m_entity.m_hdl) != DDS_KIND_COND_QUERY) || (cond->m_query.m_filter != NULL && cond->m_query.m_filter(values[n]))) @@ -1696,7 +1703,7 @@ static int dds_rhc_read_w_qminv if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0) { set_sample_info_invsample (info_seq + n, inst); - deserialize_into ((char*) values[n], inst->tk->m_sample); + ddsi_serdata_to_sample (inst->tk->m_sample, values[n], 0, 0); if (!inst->inv_isread) { inst->inv_isread = 1; @@ -1754,7 +1761,12 @@ static int dds_rhc_take_w_qminv bool trigger_waitsets = false; uint64_t iid; uint32_t n = 0; +#if 0 const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) rhc->topic->type; +#else /* FIXME: hack hack -- deserialize_into */ + const struct ddsi_sertopic_default *sertopic_def = (const struct ddsi_sertopic_default *)rhc->topic; + const struct dds_topic_descriptor * desc = sertopic_def->type; +#endif if (lock) { @@ -1799,7 +1811,7 @@ static int dds_rhc_take_w_qminv else { set_sample_info (info_seq + n, inst, sample); - deserialize_into ((char*) values[n], sample->sample); + ddsi_serdata_to_sample (sample->sample, values[n], 0, 0); if (cond == NULL || (dds_entity_kind(cond->m_entity.m_hdl) != DDS_KIND_COND_QUERY) || ( cond->m_query.m_filter != NULL && cond->m_query.m_filter(values[n]))) @@ -1843,7 +1855,7 @@ static int dds_rhc_take_w_qminv if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0) { set_sample_info_invsample (info_seq + n, inst); - deserialize_into ((char*) values[n], inst->tk->m_sample); + ddsi_serdata_to_sample (inst->tk->m_sample, values[n], 0, 0); inst_clear_invsample (rhc, inst); ++n; } @@ -1912,7 +1924,7 @@ static int dds_rhc_take_w_qminv static int dds_rhc_takecdr_w_qminv ( - struct rhc *rhc, bool lock, struct serdata ** values, dds_sample_info_t *info_seq, + struct rhc *rhc, bool lock, struct ddsi_serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, unsigned qminv, dds_instance_handle_t handle, dds_readcond *cond ) { @@ -2159,7 +2171,7 @@ static bool update_conditions_locked ( struct rhc *rhc, const struct trigger_info *pre, const struct trigger_info *post, - const struct serdata *sample + const struct ddsi_serdata *sample ) { /* Pre: rhc->lock held; returns 1 if triggering required, else 0. */ @@ -2167,7 +2179,9 @@ static bool update_conditions_locked dds_readcond * iter; int m_pre; int m_post; +#if 0 /* FIXME: content filter, query cond */ bool deserialised = (rhc->topic->filter_fn != NULL); +#endif TRACE (("update_conditions_locked(%p) - inst %u nonempty %u disp %u nowr %u new %u samples %u read %u\n", (void *) rhc, rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed, @@ -2210,6 +2224,7 @@ static bool update_conditions_locked } else if (m_pre < m_post) { +#if 0 /* FIXME: content filter, query cond */ if (sample && !deserialised && (dds_entity_kind(iter->m_entity.m_hdl) == DDS_KIND_COND_QUERY)) { deserialize_into ((char*)rhc->topic->filter_sample, sample); @@ -2229,6 +2244,18 @@ static bool update_conditions_locked trigger = true; } } +#else + assert (dds_entity_kind(iter->m_entity.m_hdl) != DDS_KIND_COND_QUERY); + if (sample == NULL) + { + TRACE (("now matches")); + if (iter->m_entity.m_trigger++ == 0) + { + TRACE ((" (cond now triggers)")); + trigger = true; + } + } +#endif } else { @@ -2286,7 +2313,7 @@ dds_rhc_take( int dds_rhc_takecdr ( - struct rhc *rhc, bool lock, struct serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, + struct rhc *rhc, bool lock, struct ddsi_serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, unsigned sample_states, unsigned view_states, unsigned instance_states, dds_instance_handle_t handle) { unsigned qminv = qmask_from_dcpsquery (sample_states, view_states, instance_states); diff --git a/src/core/ddsc/src/dds_stream.c b/src/core/ddsc/src/dds_stream.c index 49d5546..cd429a3 100644 --- a/src/core/ddsc/src/dds_stream.c +++ b/src/core/ddsc/src/dds_stream.c @@ -147,7 +147,7 @@ size_t dds_stream_check_optimize (_In_ const dds_topic_descriptor_t * desc) void * sample = dds_alloc (desc->m_size); uint8_t * ptr1; uint8_t * ptr2; - size_t size = desc->m_size; + uint32_t size = desc->m_size; uint8_t val = 1; dds_stream_init (&os, size); @@ -169,7 +169,7 @@ size_t dds_stream_check_optimize (_In_ const dds_topic_descriptor_t * desc) return size; } -dds_stream_t * dds_stream_create (size_t size) +dds_stream_t * dds_stream_create (uint32_t size) { dds_stream_t * stream = (dds_stream_t*) dds_alloc (sizeof (*stream)); dds_stream_init (stream, size); @@ -190,7 +190,7 @@ void dds_stream_fini (dds_stream_t * st) } } -void dds_stream_init (dds_stream_t * st, size_t size) +void dds_stream_init (dds_stream_t * st, uint32_t size) { memset (st, 0, sizeof (*st)); DDS_CDR_REINIT (st, size); @@ -201,13 +201,13 @@ void dds_stream_reset (dds_stream_t * st) DDS_CDR_RESET (st); } -void dds_stream_grow (dds_stream_t * st, size_t size) +void dds_stream_grow (dds_stream_t * st, uint32_t size) { - size_t needed = size + st->m_index; + uint32_t needed = size + st->m_index; /* Reallocate on 4k boundry */ - size_t newSize = (needed & ~(size_t)0xfff) + 0x1000; + uint32_t newSize = (needed & ~(uint32_t)0xfff) + 0x1000; uint8_t * old = st->m_buffer.p8; st->m_buffer.p8 = dds_realloc (old, newSize); @@ -378,21 +378,17 @@ void dds_stream_read_buffer (dds_stream_t * is, uint8_t * buffer, uint32_t len) } } -void dds_stream_read_sample (dds_stream_t * is, void * data, const struct sertopic * topic) +void dds_stream_read_sample (dds_stream_t * is, void * data, const struct ddsi_sertopic_default * topic) { const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) topic->type; - + /* Check if can copy directly from stream buffer */ + if (topic->opt_size && DDS_IS_OK (is, desc->m_size) && (is->m_endian == DDS_ENDIAN)) { - /* Check if can copy directly from stream buffer */ - - if (topic->opt_size && DDS_IS_OK (is, desc->m_size) && (is->m_endian == DDS_ENDIAN)) - { - DDS_IS_GET_BYTES (is, data, desc->m_size); - } - else - { - dds_stream_read (is, data, desc->m_ops); - } + DDS_IS_GET_BYTES (is, data, desc->m_size); + } + else + { + dds_stream_read (is, data, desc->m_ops); } } @@ -1162,7 +1158,7 @@ static void dds_stream_read (dds_stream_t * is, char * data, const uint32_t * op #endif } -void dds_stream_write_sample (dds_stream_t * os, const void * data, const struct sertopic * topic) +void dds_stream_write_sample (dds_stream_t * os, const void * data, const struct ddsi_sertopic_default * topic) { const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) topic->type; @@ -1176,16 +1172,16 @@ void dds_stream_write_sample (dds_stream_t * os, const void * data, const struct } } -void dds_stream_from_serstate (_Out_ dds_stream_t * s, _In_ const serstate_t st) +void dds_stream_from_serdata_default (_Out_ dds_stream_t * s, _In_ const struct ddsi_serdata_default *d) { s->m_failed = false; - s->m_buffer.p8 = (uint8_t*) st->data; - s->m_size = st->size + offsetof (struct serdata, data); - s->m_index = offsetof (struct serdata, data); - s->m_endian = (st->data->v.bswap) ? (! DDS_ENDIAN) : DDS_ENDIAN; + s->m_buffer.p8 = (uint8_t*) d; + s->m_index = (uint32_t) offsetof (struct ddsi_serdata_default, data); + s->m_size = d->size + s->m_index; + s->m_endian = (d->bswap) ? (! DDS_ENDIAN) : DDS_ENDIAN; } -void dds_stream_add_to_serstate (_Inout_ dds_stream_t * s, _Inout_ serstate_t st) +void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d) { /* DDSI requires 4 byte alignment */ @@ -1193,18 +1189,14 @@ void dds_stream_add_to_serstate (_Inout_ dds_stream_t * s, _Inout_ serstate_t st /* Reset data pointer as stream may have reallocated */ - st->data = s->m_buffer.pv; - st->pos += (s->m_index - offsetof (struct serdata, data)); - st->size = (s->m_size - offsetof(struct serdata, data)); + (*d) = s->m_buffer.pv; + (*d)->pos = (s->m_index - (uint32_t)offsetof (struct ddsi_serdata_default, data)); + (*d)->size = (s->m_size - (uint32_t)offsetof(struct ddsi_serdata_default, data)); } -void dds_stream_write_key -( - dds_stream_t * os, - const char * sample, - const dds_topic_descriptor_t * desc -) +void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic) { + const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) topic->type; uint32_t i; const char * src; const uint32_t * op; diff --git a/src/core/ddsc/src/dds_tkmap.c b/src/core/ddsc/src/dds_tkmap.c index a11165b..ad13f98 100644 --- a/src/core/ddsc/src/dds_tkmap.c +++ b/src/core/ddsc/src/dds_tkmap.c @@ -22,7 +22,7 @@ #include "util/ut_hopscotch.h" #include "dds__stream.h" #include "os/os.h" -#include "q__osplser.h" +#include "ddsi/ddsi_serdata.h" #define REFC_DELETE 0x80000000 #define REFC_MASK 0x0fffffff @@ -62,68 +62,9 @@ static void gc_tkmap_instance (struct tkmap_instance *tk) gcreq_enqueue (gcreq); } -/* Fixed seed and length */ - -#define DDS_MH3_LEN 16 -#define DDS_MH3_SEED 0 - -#define DDS_MH3_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) - -/* Really - http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp, - MurmurHash3_x86_32 -*/ - -static uint32_t dds_mh3 (const void * key) -{ - const uint8_t *data = (const uint8_t *) key; - const intptr_t nblocks = (intptr_t) (DDS_MH3_LEN / 4); - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; - - uint32_t h1 = DDS_MH3_SEED; - - const uint32_t *blocks = (const uint32_t *) (data + nblocks * 4); - register intptr_t i; - - for (i = -nblocks; i; i++) - { - uint32_t k1 = blocks[i]; - - k1 *= c1; - k1 = DDS_MH3_ROTL32 (k1, 15); - k1 *= c2; - - h1 ^= k1; - h1 = DDS_MH3_ROTL32 (h1, 13); - h1 = h1 * 5+0xe6546b64; - } - - /* finalization */ - - h1 ^= DDS_MH3_LEN; - h1 ^= h1 >> 16; - h1 *= 0x85ebca6b; - h1 ^= h1 >> 13; - h1 *= 0xc2b2ae35; - h1 ^= h1 >> 16; - - return h1; -} - static uint32_t dds_tk_hash (const struct tkmap_instance * inst) { - volatile struct serdata * sd = (volatile struct serdata *) inst->m_sample; - - if (! sd->v.hash_valid) - { - const uint32_t * k = (const uint32_t *) sd->v.keyhash.m_hash; - const uint32_t hash0 = sd->v.st->topic ? sd->v.st->topic->hash : 0; - sd->v.hash = ((sd->v.keyhash.m_flags & DDS_KEY_IS_HASH) ? dds_mh3 (k) : (*k)) ^ hash0; - sd->v.hash_valid = 1; - } - - return sd->v.hash; + return inst->m_sample->hash; } static uint32_t dds_tk_hash_void (const void * inst) @@ -133,7 +74,7 @@ static uint32_t dds_tk_hash_void (const void * inst) static int dds_tk_equals (const struct tkmap_instance *a, const struct tkmap_instance *b) { - return serdata_cmp (a->m_sample, b->m_sample) == 0; + return (a->m_sample->ops == b->m_sample->ops) ? ddsi_serdata_eqkey (a->m_sample, b->m_sample) : 0; } static int dds_tk_equals_void (const void *a, const void *b) @@ -166,11 +107,11 @@ void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap * map) dds_free (map); } -uint64_t dds_tkmap_lookup (_In_ struct tkmap * map, _In_ const struct serdata * sd) +uint64_t dds_tkmap_lookup (_In_ struct tkmap * map, _In_ const struct ddsi_serdata * sd) { struct tkmap_instance dummy; struct tkmap_instance * tk; - dummy.m_sample = (struct serdata *) sd; + dummy.m_sample = (struct ddsi_serdata *) sd; tk = ut_chhLookup (map->m_hh, &dummy); return (tk) ? tk->m_iid : DDS_HANDLE_NIL; } @@ -189,7 +130,7 @@ static void dds_tkmap_get_key_fn (void * vtk, void * varg) tkmap_get_key_arg * arg = (tkmap_get_key_arg*) varg; if (tk->m_iid == arg->m_iid) { - deserialize_into (arg->m_sample, tk->m_sample); + ddsi_serdata_to_sample (tk->m_sample, arg->m_sample, 0, 0); arg->m_ret = true; } } @@ -243,7 +184,7 @@ struct tkmap_instance * dds_tkmap_find_by_id (_In_ struct tkmap * map, _In_ uint _Check_return_ struct tkmap_instance * dds_tkmap_find( - _In_ struct serdata * sd, + _In_ struct ddsi_serdata * sd, _In_ const bool rd, _In_ const bool create) { @@ -251,7 +192,10 @@ struct tkmap_instance * dds_tkmap_find( struct tkmap_instance * tk; struct tkmap * map = gv.m_tkmap; + /* FIXME: check this */ +#if 0 assert(sd->v.keyhash.m_flags & DDS_KEY_HASH_SET); +#endif dummy.m_sample = sd; retry: @@ -300,7 +244,7 @@ retry: } _Check_return_ -struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct serdata * sd) +struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd) { assert (vtime_awake_p (lookup_thread_state ()->vtime)); #if 0 @@ -337,7 +281,9 @@ void dds_tkmap_instance_unref (_In_ struct tkmap_instance * tk) struct tkmap *map = tk->m_map; /* Remove from hash table */ - (void)ut_chhRemove(map->m_hh, tk); + int removed = ut_chhRemove(map->m_hh, tk); + assert (removed); + (void)removed; /* Signal any threads blocked in their retry loops in lookup */ os_mutexLock(&map->m_lock); diff --git a/src/core/ddsc/src/dds_topic.c b/src/core/ddsc/src/dds_topic.c index 0f6c3c2..bc79f26 100644 --- a/src/core/ddsc/src/dds_topic.c +++ b/src/core/ddsc/src/dds_topic.c @@ -21,19 +21,19 @@ #include "dds__err.h" #include "ddsi/q_entity.h" #include "ddsi/q_thread.h" -#include "q__osplser.h" +#include "ddsi/ddsi_sertopic.h" #include "ddsi/q_ddsi_discovery.h" #include "os/os_atomics.h" #include "dds__report.h" - +#include "dds__iid.h" #define DDS_TOPIC_STATUS_MASK \ DDS_INCONSISTENT_TOPIC_STATUS const ut_avlTreedef_t dds_topictree_def = UT_AVL_TREEDEF_INITIALIZER_INDKEY ( - offsetof (struct sertopic, avlnode), - offsetof (struct sertopic, name_typename), + offsetof (struct ddsi_sertopic, avlnode), + offsetof (struct ddsi_sertopic, name_typename), (int (*) (const void *, const void *)) strcmp, 0 ); @@ -151,12 +151,12 @@ dds_topic_status_cb( DDS_REPORT_FLUSH(rc != DDS_RETCODE_OK); } -sertopic_t +struct ddsi_sertopic * dds_topic_lookup_locked( dds_domain *domain, const char *name) { - sertopic_t st = NULL; + struct ddsi_sertopic *st = NULL; ut_avlIter_t iter; assert (domain); @@ -172,12 +172,12 @@ dds_topic_lookup_locked( return st; } -sertopic_t +struct ddsi_sertopic * dds_topic_lookup( dds_domain *domain, const char *name) { - sertopic_t st; + struct ddsi_sertopic *st; os_mutexLock (&dds_global.m_mutex); st = dds_topic_lookup_locked(domain, name); os_mutexUnlock (&dds_global.m_mutex); @@ -187,7 +187,7 @@ dds_topic_lookup( void dds_topic_free( dds_domainid_t domainid, - struct sertopic *st) + struct ddsi_sertopic *st) { dds_domain *domain; @@ -200,13 +200,13 @@ dds_topic_free( } os_mutexUnlock (&dds_global.m_mutex); st->status_cb_entity = NULL; - sertopic_free (st); + ddsi_sertopic_unref (st); } static void dds_topic_add_locked( dds_domainid_t id, - sertopic_t st) + struct ddsi_sertopic *st) { dds_domain * dom; dom = dds_domain_find_locked (id); @@ -222,7 +222,7 @@ dds_find_topic( { dds_entity_t tp; dds_entity *p = NULL; - sertopic_t st; + struct ddsi_sertopic *st; dds__retcode_t rc; DDS_REPORT_STACK(); @@ -307,7 +307,7 @@ dds_topic_qos_set( return ret; } -static bool dupdef_qos_ok(const dds_qos_t *qos, const struct sertopic *st) +static bool dupdef_qos_ok(const dds_qos_t *qos, const struct ddsi_sertopic *st) { if ((qos == NULL) != (st->status_cb_entity->m_entity.m_qos == NULL)) { return false; @@ -327,10 +327,9 @@ dds_create_topic( _In_opt_ const dds_qos_t *qos, _In_opt_ const dds_listener_t *listener) { - static uint32_t next_topicid = 0; - char *key = NULL; - sertopic_t st; + struct ddsi_sertopic *stgeneric; + struct ddsi_sertopic_default *st; const char *typename; dds__retcode_t rc; dds_entity *par; @@ -378,16 +377,17 @@ dds_create_topic( /* Check if topic already exists with same name */ os_mutexLock (&dds_global.m_mutex); - if ((st = dds_topic_lookup_locked (par->m_domain, name)) != NULL) { + if ((stgeneric = dds_topic_lookup_locked (par->m_domain, name)) != NULL) { + st = (struct ddsi_sertopic_default *)stgeneric; if (st->type != desc) { /* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */ hdl = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "Create topic with mismatching type."); - } else if (!dupdef_qos_ok(qos, st)) { + } else if (!dupdef_qos_ok(qos, stgeneric)) { /* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */ hdl = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Create topic with mismatching qos."); } else { - dds_entity_add_ref (&st->status_cb_entity->m_entity); - hdl = st->status_cb_entity->m_entity.m_hdl; + dds_entity_add_ref (&st->c.status_cb_entity->m_entity); + hdl = st->c.status_cb_entity->m_entity.m_hdl; } os_mutexUnlock (&dds_global.m_mutex); } else { @@ -413,34 +413,33 @@ dds_create_topic( top->m_entity.m_deriver.validate_status = dds_topic_status_validate; st = dds_alloc (sizeof (*st)); + + os_atomic_st32 (&st->c.refc, 1); + st->c.iid = dds_iid_gen (); + st->c.status_cb = dds_topic_status_cb; + st->c.status_cb_entity = top; + st->c.name_typename = key; + st->c.name = dds_alloc (strlen (name) + 1); + strcpy (st->c.name, name); + st->c.typename = dds_alloc (strlen (typename) + 1); + strcpy (st->c.typename, typename); + st->c.ops = &ddsi_sertopic_ops_default; + st->c.serdata_ops = &ddsi_serdata_ops_cdr; + st->native_encoding_identifier = (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE); + st->type = (void*) desc; - os_atomic_st32 (&st->refcount, 1); - st->status_cb = dds_topic_status_cb; - st->status_cb_entity = top; - st->name_typename = key; - st->name = dds_alloc (strlen (name) + 1); - strcpy (st->name, name); - st->typename = dds_alloc (strlen (typename) + 1); - strcpy (st->typename, typename); st->nkeys = desc->m_nkeys; st->keys = desc->m_keys; - st->id = next_topicid++; - -#ifdef VXWORKS_RTP - st->hash = (uint32_t)((st->id * UINT64_C (12844332200329132887UL)) >> 32); -#else - st->hash = (uint32_t)((st->id * UINT64_C (12844332200329132887)) >> 32); -#endif /* Check if topic cannot be optimised (memcpy marshal) */ if ((desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) == 0) { st->opt_size = dds_stream_check_optimize (desc); } - top->m_stopic = st; + top->m_stopic = &st->c; /* Add topic to extent */ - dds_topic_add_locked (par->m_domainid, st); + dds_topic_add_locked (par->m_domainid, &st->c); os_mutexUnlock (&dds_global.m_mutex); nn_plist_init_empty (&plist); @@ -449,8 +448,8 @@ dds_create_topic( } /* Set Topic meta data (for SEDP publication) */ - plist.qos.topic_name = dds_string_dup (st->name); - plist.qos.type_name = dds_string_dup (st->typename); + plist.qos.topic_name = dds_string_dup (st->c.name); + plist.qos.type_name = dds_string_dup (st->c.typename); plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME); if (desc->m_meta) { plist.type_description = dds_string_dup (desc->m_meta); @@ -503,6 +502,7 @@ dds_topic_mod_filter( void **ctx, bool set) { +#if 0 /* FIXME: content filter */ dds_topic *t; if (dds_topic_lock(topic, &t) == DDS_RETCODE_OK) { if (set) { @@ -523,6 +523,7 @@ dds_topic_mod_filter( *filter = 0; *ctx = NULL; } +#endif } _Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC) diff --git a/src/core/ddsc/src/dds_whc.c b/src/core/ddsc/src/dds_whc.c index b0a5236..19f9680 100644 --- a/src/core/ddsc/src/dds_whc.c +++ b/src/core/ddsc/src/dds_whc.c @@ -14,10 +14,9 @@ #include #include "os/os.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" #include "ddsi/q_unused.h" #include "ddsi/q_config.h" -#include "q__osplser.h" #include "dds__whc.h" #include "dds__tkmap.h" @@ -42,7 +41,7 @@ struct whc_node { unsigned borrowed: 1; /* at most one can borrow it at any time */ nn_mtime_t last_rexmit_ts; unsigned rexmit_count; - struct serdata *serdata; + struct ddsi_serdata *serdata; }; struct whc_intvnode { @@ -143,10 +142,10 @@ static void get_state_locked(const struct whc_impl *whc, struct whc_state *st); static unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); static void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); static void whc_get_state(const struct whc *whc, struct whc_state *st); -static int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, serdata_t serdata, struct tkmap_instance *tk); +static int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); static seqno_t whc_next_seq (const struct whc *whc, seqno_t seq); static bool whc_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); -static bool whc_borrow_sample_key (const struct whc *whc, const struct serdata *serdata_key, struct whc_borrowed_sample *sample); +static bool whc_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); static void whc_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info); static unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st); static void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it); @@ -331,7 +330,7 @@ static struct whc_node *whc_findseq (const struct whc_impl *whc, seqno_t seq) #endif } -static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct serdata *serdata_key) +static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct ddsi_serdata *serdata_key) { union { struct whc_idxnode idxn; @@ -1035,7 +1034,7 @@ static unsigned whc_remove_acked_messages (struct whc *whc_generic, seqno_t max_ return cnt; } -static struct whc_node *whc_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, serdata_t serdata) +static struct whc_node *whc_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata) { struct whc_node *newn = NULL; @@ -1096,7 +1095,7 @@ static struct whc_node *whc_insert_seq (struct whc_impl *whc, seqno_t max_drop_s return newn; } -static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, serdata_t serdata, struct tkmap_instance *tk) +static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) { struct whc_impl * const whc = (struct whc_impl *)whc_generic; struct whc_node *newn = NULL; @@ -1113,7 +1112,7 @@ static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t se { struct whc_state whcst; get_state_locked(whc, &whcst); - TRACE_WHC(("whc_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%x)\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, *(unsigned *)serdata->v.keyhash.m_hash)); + TRACE_WHC(("whc_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash)); TRACE_WHC((" whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n", whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth)); } @@ -1132,7 +1131,7 @@ static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t se TRACE_WHC((" whcn %p:", (void*)newn)); /* Special case of empty data (such as commit messages) can't go into index, and if we're not maintaining an index, we're done, too */ - if (ddsi_serdata_is_empty(serdata) || whc->idxdepth == 0) + if (serdata->kind == SDK_EMPTY || whc->idxdepth == 0) { TRACE_WHC((" empty or no hist\n")); os_mutexUnlock (&whc->lock); @@ -1144,7 +1143,7 @@ static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t se { /* Unregisters cause deleting of index entry, non-unregister of adding/overwriting in history */ TRACE_WHC((" idxn %p", (void *)idxn)); - if (serdata->v.msginfo.statusinfo & NN_STATUSINFO_UNREGISTER) + if (serdata->statusinfo & NN_STATUSINFO_UNREGISTER) { TRACE_WHC((" unreg:delete\n")); delete_one_instance_from_idx (whc, max_drop_seq, idxn); @@ -1200,7 +1199,7 @@ static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t se { TRACE_WHC((" newkey")); /* Ignore unregisters, but insert everything else */ - if (!(serdata->v.msginfo.statusinfo & NN_STATUSINFO_UNREGISTER)) + if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER)) { unsigned i; idxn = os_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0])); @@ -1264,7 +1263,7 @@ static bool whc_borrow_sample (const struct whc *whc_generic, seqno_t seq, struc return found; } -static bool whc_borrow_sample_key (const struct whc *whc_generic, const struct serdata *serdata_key, struct whc_borrowed_sample *sample) +static bool whc_borrow_sample_key (const struct whc *whc_generic, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample) { const struct whc_impl * const whc = (const struct whc_impl *)whc_generic; struct whc_node *whcn; diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index a02c33b..545a061 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -15,7 +15,8 @@ #include "dds__tkmap.h" #include "ddsi/q_error.h" #include "ddsi/q_thread.h" -#include "q__osplser.h" +#include "ddsi/q_xmsg.h" +#include "ddsi/ddsi_serdata.h" #include "dds__stream.h" #include "dds__err.h" #include "ddsi/q_transmit.h" @@ -57,7 +58,7 @@ _Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER) int dds_writecdr( dds_entity_t writer, - struct serdata *serdata) + struct ddsi_serdata *serdata) { dds_return_t ret; dds__retcode_t rc; @@ -112,7 +113,7 @@ err: static int deliver_locally( _In_ struct writer *wr, - _In_ serdata_t payload, + _In_ struct ddsi_serdata *payload, _In_ struct tkmap_instance *tk) { dds_return_t ret = DDS_RETCODE_OK; @@ -191,34 +192,32 @@ dds_write_impl( dds_writer * writer = (dds_writer*) wr; struct writer * ddsi_wr = writer->m_wr; struct tkmap_instance * tk; - serdata_t d; + struct ddsi_serdata *d; if (data == NULL) { return DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "No data buffer provided"); } +#if 0 /* FIXME: content filter */ /* Check for topic filter */ if (ddsi_wr->topic->filter_fn && ! writekey) { if (!(ddsi_wr->topic->filter_fn) (data, ddsi_wr->topic->filter_ctx)) { - goto filtered; + return DDS_RECTODE_OK; } } +#endif if (asleep) { thread_state_awake (thr); } /* Serialize and write data or key */ - if (writekey) { - d = serialize_key (ddsi_wr->topic, data); - } else { - d = serialize (ddsi_wr->topic, data); - } + d = ddsi_serdata_from_sample (ddsi_wr->topic, writekey ? SDK_KEY : SDK_DATA, data); /* Set if disposing or unregistering */ - d->v.msginfo.statusinfo = ((action & DDS_WR_DISPOSE_BIT ) ? NN_STATUSINFO_DISPOSE : 0) | - ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0) ; - d->v.msginfo.timestamp.v = tstamp; + d->statusinfo = ((action & DDS_WR_DISPOSE_BIT ) ? NN_STATUSINFO_DISPOSE : 0) | + ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0) ; + d->timestamp.v = tstamp; ddsi_serdata_ref(d); tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (d); w_rc = write_sample_gc (writer->m_xp, ddsi_wr, d, tk); @@ -246,14 +245,13 @@ dds_write_impl( thread_state_asleep (thr); } -filtered: return ret; } int dds_writecdr_impl( _In_ dds_writer *wr, - _Inout_ serdata_t d, + _Inout_ struct ddsi_serdata *d, _In_ dds_time_t tstamp, _In_ dds_write_action action) { @@ -264,24 +262,25 @@ dds_writecdr_impl( struct thread_state1 * const thr = lookup_thread_state (); const bool asleep = !vtime_awake_p (thr->vtime); - const bool writekey = action & DDS_WR_KEY_BIT; struct writer * ddsi_wr = wr->m_wr; struct tkmap_instance * tk; +#if 0 /* FIXME: content filter */ /* Check for topic filter */ if (ddsi_wr->topic->filter_fn && ! writekey) { abort(); } +#endif if (asleep) { thread_state_awake (thr); } /* Set if disposing or unregistering */ - d->v.msginfo.statusinfo = + d->statusinfo = ((action & DDS_WR_DISPOSE_BIT ) ? NN_STATUSINFO_DISPOSE : 0) | ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0) ; - d->v.msginfo.timestamp.v = tstamp; + d->timestamp.v = tstamp; ddsi_serdata_ref(d); tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (d); w_rc = write_sample_gc (wr->m_xp, ddsi_wr, d, tk); diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index aed6829..2961d03 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -14,7 +14,7 @@ #include "ddsi/q_config.h" #include "ddsi/q_entity.h" #include "ddsi/q_thread.h" -#include "q__osplser.h" +#include "ddsi/q_xmsg.h" #include "dds__writer.h" #include "dds__listener.h" #include "dds__qos.h" diff --git a/src/core/ddsc/src/q__osplser.h b/src/core/ddsc/src/q__osplser.h deleted file mode 100644 index 021b79b..0000000 --- a/src/core/ddsc/src/q__osplser.h +++ /dev/null @@ -1,39 +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 DDS_OSPLSER_H -#define DDS_OSPLSER_H - -#include "ddsi/ddsi_ser.h" -#include "ddsi/q_xmsg.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -int serdata_cmp (const struct serdata * a, const struct serdata * b); -uint32_t serdata_hash (const struct serdata *a); - -serdata_t serialize (const struct sertopic * tp, const void * sample); -serdata_t serialize_key (const struct sertopic * tp, const void * sample); - -void deserialize_into (void *sample, const struct serdata *serdata); -void free_deserialized (const struct serdata *serdata, void *vx); - -void sertopic_free (struct sertopic * tp); -void serstate_set_key (serstate_t st, int justkey, const void *key); -void serstate_init (serstate_t st, const struct sertopic * topic); -void serstate_free (serstate_t st); - -#if defined (__cplusplus) -} -#endif -#endif diff --git a/src/core/ddsc/src/q_osplser.c b/src/core/ddsc/src/q_osplser.c deleted file mode 100644 index d7afadc..0000000 --- a/src/core/ddsc/src/q_osplser.c +++ /dev/null @@ -1,142 +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 - */ -#include -#include -#include "os/os.h" -#include "dds__key.h" -#include "dds__tkmap.h" -#include "dds__stream.h" -#include "ddsi/q_bswap.h" -#include "q__osplser.h" - -serdata_t serialize (const struct sertopic * tp, const void * sample) -{ - dds_stream_t os; - serstate_t st = ddsi_serstate_new (tp); - dds_key_gen ((const dds_topic_descriptor_t*) tp->type, &st->data->v.keyhash, (char*) sample); - dds_stream_from_serstate (&os, st); - dds_stream_write_sample (&os, sample, tp); - dds_stream_add_to_serstate (&os, st); - return st->data; -} - -int serdata_cmp (const struct serdata *a, const struct serdata *b) -{ - /* First compare on topic */ - - if (a->v.st->topic != b->v.st->topic) - { - return a->v.st->topic < b->v.st->topic ? -1 : 1; - } - - /* Samples with a keyless topic map to the default instance */ - - if - ( - (a->v.st->topic) && - (((dds_topic_descriptor_t*) a->v.st->topic->type)->m_keys == 0) - ) - { - return 0; - } - - /* Check key has been hashed */ - - assert (a->v.keyhash.m_flags & DDS_KEY_HASH_SET); - - /* Compare by hash */ - - return memcmp (a->v.keyhash.m_hash, b->v.keyhash.m_hash, 16); -} - -serdata_t serialize_key (const struct sertopic * tp, const void * sample) -{ - serdata_t sd; - dds_stream_t os; - dds_topic_descriptor_t * desc = (dds_topic_descriptor_t*) tp->type; - serstate_t st = ddsi_serstate_new (tp); - dds_key_gen (desc, &st->data->v.keyhash, (char*) sample); - dds_stream_from_serstate (&os, st); - dds_stream_write_key (&os, sample, desc); - dds_stream_add_to_serstate (&os, st); - sd = st->data; - sd->v.st->kind = STK_KEY; - return sd; -} - -void deserialize_into (void * sample, const struct serdata * serdata) -{ - const serstate_t st = serdata->v.st; - dds_stream_t is; - - dds_stream_from_serstate (&is, st); - if (st->kind == STK_KEY) - { - dds_stream_read_key (&is, sample, (const dds_topic_descriptor_t*) st->topic->type); - } - else - { - dds_stream_read_sample (&is, sample, st->topic); - } -} - -void serstate_set_key (serstate_t st, int justkey, const void *key) -{ - st->kind = justkey ? STK_KEY : STK_DATA; - memcpy (&st->data->v.keyhash.m_hash, key, 16); - st->data->v.keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH; - st->data->v.keyhash.m_key_len = 16; -} - -void serstate_init (serstate_t st, const struct sertopic * topic) -{ - st->pos = 0; - st->topic = topic; - st->kind = STK_DATA; - st->twrite.v = -1; - os_atomic_st32 (&st->refcount, 1); - - if (topic) - { - os_atomic_inc32 (&(((struct sertopic *) topic)->refcount)); - } - - st->data->hdr.identifier = topic ? - (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE) : - (PLATFORM_IS_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE); - - st->data->v.hash_valid = (topic == NULL || topic->nkeys) ? 0 : 1; - st->data->v.hash = 0; - st->data->v.bswap = false; - memset (st->data->v.keyhash.m_hash, 0, sizeof (st->data->v.keyhash.m_hash)); - st->data->v.keyhash.m_key_len = 0; - st->data->v.keyhash.m_flags = 0; -} - -void serstate_free (serstate_t st) -{ - dds_free (st->data->v.keyhash.m_key_buff); - dds_free (st->data); - dds_free (st); -} - -void sertopic_free (struct sertopic * tp) -{ - if (tp && (os_atomic_dec32_nv (&tp->refcount) == 0)) - { - dds_free (tp->name); - dds_free (tp->typename); - dds_free (tp->name_typename); - dds_sample_free (tp->filter_sample, (const struct dds_topic_descriptor *) tp->type, DDS_FREE_ALL); - dds_free (tp); - } -} diff --git a/src/core/ddsi/CMakeLists.txt b/src/core/ddsi/CMakeLists.txt index e7129df..d7707f2 100644 --- a/src/core/ddsi/CMakeLists.txt +++ b/src/core/ddsi/CMakeLists.txt @@ -11,7 +11,6 @@ # PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src" ddsi_eth.c - ddsi_ser.c ddsi_ssl.c ddsi_tcp.c ddsi_tran.c @@ -19,6 +18,10 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src" ddsi_raweth.c ddsi_ipaddr.c ddsi_mcgroup.c + ddsi_serdata.c + ddsi_serdata_default.c + ddsi_sertopic.c + ddsi_sertopic_default.c ddsi_rhc_plugin.c q_addrset.c q_bitset_inlines.c @@ -60,7 +63,6 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src" # The includes should reside close to the code. As long as that's not the case, # pull them in from this CMakeLists.txt. PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/ddsi" - ddsi_ser.h ddsi_ssl.h ddsi_tcp.h ddsi_tran.h @@ -68,6 +70,9 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/ddsi" ddsi_raweth.h ddsi_ipaddr.h ddsi_mcgroup.h + ddsi_serdata.h + ddsi_sertopic.h + ddsi_serdata_default.h ddsi_rhc_plugin.h probes-constants.h q_addrset.h diff --git a/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h b/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h index 317d382..ba378a3 100644 --- a/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h +++ b/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h @@ -15,8 +15,8 @@ struct rhc; struct nn_xqos; struct tkmap_instance; -struct serdata; -struct sertopic; +struct ddsi_serdata; +struct ddsi_sertopic; struct entity_common; struct proxy_writer_info @@ -33,13 +33,13 @@ struct ddsi_rhc_plugin void (*rhc_fini_fn) (struct rhc *rhc); bool (*rhc_store_fn) (struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info, - struct serdata * __restrict sample, struct tkmap_instance * __restrict tk); + struct ddsi_serdata * __restrict sample, struct tkmap_instance * __restrict tk); void (*rhc_unregister_wr_fn) (struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info); void (*rhc_relinquish_ownership_fn) (struct rhc * __restrict rhc, const uint64_t wr_iid); void (*rhc_set_qos_fn) (struct rhc * rhc, const struct nn_xqos * qos); - struct tkmap_instance * (*rhc_lookup_fn) (struct serdata *serdata); + struct tkmap_instance * (*rhc_lookup_fn) (struct ddsi_serdata *serdata); void (*rhc_unref_fn) (struct tkmap_instance *tk); }; diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata.h b/src/core/ddsi/include/ddsi/ddsi_serdata.h new file mode 100644 index 0000000..71ef1d8 --- /dev/null +++ b/src/core/ddsi/include/ddsi/ddsi_serdata.h @@ -0,0 +1,158 @@ +/* + * 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 DDSI_SERDATA_H +#define DDSI_SERDATA_H + +#include "ddsi/q_time.h" +#include "ddsi/ddsi_sertopic.h" +#include "ddsi/sysdeps.h" /* for ddsi_iovec_t */ + +struct nn_rdata; +struct nn_keyhash; + +enum ddsi_serdata_kind { + SDK_EMPTY, + SDK_KEY, + SDK_DATA +}; + +struct ddsi_serdata { + const struct ddsi_serdata_ops *ops; /* cached from topic->serdata_ops */ + uint32_t hash; + os_atomic_uint32_t refc; + enum ddsi_serdata_kind kind; + const struct ddsi_sertopic *topic; + + /* these get set by generic code after creating the serdata */ + nn_wctime_t timestamp; + uint32_t statusinfo; + + /* FIXME: can I get rid of this one? */ + nn_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ +}; + +/* Serialised size of sample: uint32_t because the protocol can't handle samples larger than 4GB anyway */ +typedef uint32_t (*ddsi_serdata_size_t) (const struct ddsi_serdata *d); + +/* Free a serdata (called by unref when refcount goes to 0) */ +typedef void (*ddsi_serdata_free_t) (struct ddsi_serdata *d); + +/* Construct a serdata from a fragchain received over the network */ +typedef struct ddsi_serdata * (*ddsi_serdata_from_ser_t) (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size); + +/* Construct a serdata from a keyhash (an SDK_KEY by definition) */ +typedef struct ddsi_serdata * (*ddsi_serdata_from_keyhash_t) (const struct ddsi_sertopic *topic, const struct nn_keyhash *keyhash); + +/* Construct a serdata from an application sample */ +typedef struct ddsi_serdata * (*ddsi_serdata_from_sample_t) (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const void *sample); + +/* Fill buffer with 'size' bytes of serialised data, starting from 'off'; 0 <= off < off+sz <= + alignup4(size(d)) */ +typedef void (*ddsi_serdata_to_ser_t) (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf); + +/* Provide a pointer to 'size' bytes of serialised data, starting from 'off'; 0 <= off < off+sz <= + alignup4(size(d)); it must remain valid until the corresponding call to to_ser_unref. Multiple + calls to to_ser_ref() may be issued in parallel, the separate ref/unref bit is there to at least + have the option of lazily creating the serialised representation and freeing it when no one needs + it, while the sample itself remains valid */ +typedef struct ddsi_serdata * (*ddsi_serdata_to_ser_ref_t) (const struct ddsi_serdata *d, size_t off, size_t sz, ddsi_iovec_t *ref); + +/* Release a lock on serialised data, ref must be a pointer previously obtained by calling + to_ser_ref(d, off, sz) for some offset off. */ +typedef void (*ddsi_serdata_to_ser_unref_t) (struct ddsi_serdata *d, const ddsi_iovec_t *ref); + +/* Turn serdata into an application sample (or just the key values if only key values are + available); return false on error (typically out-of-memory, but if from_ser doesn't do any + validation it might be a deserialisation error, too). + + If (bufptr != 0), then *bufptr .. buflim is space to be used from *bufptr up (with minimal + padding) for any data in the sample that needs to be allocated (e.g., strings, sequences); + otherwise malloc() is to be used for those. (This allows read/take to be given a block of memory + by the caller.) */ +typedef bool (*ddsi_serdata_to_sample_t) (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); + +/* Compare key values of two serdatas (with the same ddsi_serdata_ops, but not necessarily of the + same topic) (FIXME: not sure I need this one) */ +typedef int (*ddsi_serdata_cmpkey_t) (const struct ddsi_serdata *a, const struct ddsi_serdata *b); + +/* Test key values of two serdatas for equality (with the same ddsi_serdata_ops, but not necessarily + of the same topic) */ +typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct ddsi_serdata *b); + +struct ddsi_serdata_ops { + ddsi_serdata_size_t get_size; + ddsi_serdata_from_ser_t from_ser; + ddsi_serdata_from_keyhash_t from_keyhash; + ddsi_serdata_from_sample_t from_sample; + ddsi_serdata_to_ser_t to_ser; + ddsi_serdata_to_ser_ref_t to_ser_ref; + ddsi_serdata_to_ser_unref_t to_ser_unref; + ddsi_serdata_to_sample_t to_sample; + ddsi_serdata_cmpkey_t cmpkey; + ddsi_serdata_eqkey_t eqkey; + ddsi_serdata_free_t free; +}; + +void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertopic *tp, enum ddsi_serdata_kind kind); + +inline struct ddsi_serdata *ddsi_serdata_ref (const struct ddsi_serdata *serdata_const) { + struct ddsi_serdata *serdata = (struct ddsi_serdata *)serdata_const; + os_atomic_inc32 (&serdata->refc); + return serdata; +} + +inline void ddsi_serdata_unref (struct ddsi_serdata *serdata) { + if (os_atomic_dec32_ov (&serdata->refc) == 1) + serdata->ops->free (serdata); +} + +inline uint32_t ddsi_serdata_size (const struct ddsi_serdata *d) { + return d->ops->get_size (d); +} + +inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size) { + return topic->serdata_ops->from_ser (topic, kind, fragchain, size); +} + +inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertopic *topic, const struct nn_keyhash *keyhash) { + return topic->serdata_ops->from_keyhash (topic, keyhash); +} + +inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const void *sample) { + return topic->serdata_ops->from_sample (topic, kind, sample); +} + +inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf) { + return d->ops->to_ser (d, off, sz, buf); +} + +inline struct ddsi_serdata *ddsi_serdata_to_ser_ref (const struct ddsi_serdata *d, size_t off, size_t sz, ddsi_iovec_t *ref) { + return d->ops->to_ser_ref (d, off, sz, ref); +} + +inline void ddsi_serdata_to_ser_unref (struct ddsi_serdata *d, const ddsi_iovec_t *ref) { + d->ops->to_ser_unref (d, ref); +} + +inline bool ddsi_serdata_to_sample (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) { + return d->ops->to_sample (d, sample, bufptr, buflim); +} + +inline int ddsi_serdata_cmpkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b) { + return a->ops->cmpkey (a, b); +} + +inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b) { + return a->ops->eqkey (a, b); +} + +#endif diff --git a/src/core/ddsi/include/ddsi/ddsi_ser.h b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h similarity index 51% rename from src/core/ddsi/include/ddsi/ddsi_ser.h rename to src/core/ddsi/include/ddsi/ddsi_serdata_default.h index 9c2c125..f08d8d7 100644 --- a/src/core/ddsi/include/ddsi/ddsi_ser.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h @@ -17,6 +17,8 @@ #include "ddsi/q_freelist.h" #include "util/ut_avl.h" #include "sysdeps.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_sertopic.h" #include "ddsc/dds.h" #include "dds__topic.h" @@ -39,47 +41,20 @@ #define CDR_LE 0x0001 #endif -typedef struct serstatepool * serstatepool_t; -typedef struct serstate * serstate_t; -typedef struct serdata * serdata_t; -typedef struct sertopic * sertopic_t; - struct CDRHeader { unsigned short identifier; unsigned short options; }; -struct serdata_msginfo -{ - unsigned statusinfo; - nn_wctime_t timestamp; -}; - -enum serstate_kind { - STK_EMPTY, - STK_KEY, - STK_DATA -}; - -struct serstate -{ - serdata_t data; - nn_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ - os_atomic_uint32_t refcount; - size_t pos; - size_t size; - const struct sertopic * topic; - enum serstate_kind kind; - serstatepool_t pool; - struct serstate *next; /* in pool->freelist */ -}; - -struct serstatepool +struct serstatepool /* FIXME: now a serdatapool */ { struct nn_freelist freelist; }; +struct serstate { + struct ddsi_serdata_default *data; +}; #define DDS_KEY_SET 0x0001 #define DDS_KEY_HASH_SET 0x0002 @@ -87,7 +62,7 @@ struct serstatepool typedef struct dds_key_hash { - char m_hash [16]; /* Key hash value. Also possibly key. */ + char m_hash [16]; /* Key hash value. Also possibly key. Suitably aligned for accessing as uint32_t's */ uint32_t m_key_len; /* Length of key (may be in m_hash or m_key_buff) */ uint32_t m_key_buff_size; /* Size of allocated key buffer (m_key_buff) */ char * m_key_buff; /* Key buffer */ @@ -95,57 +70,48 @@ typedef struct dds_key_hash } dds_key_hash_t; -struct serdata_base +struct ddsi_serdata_default { - serstate_t st; /* back pointer to (opaque) serstate so RTPS impl only needs serdata */ - struct serdata_msginfo msginfo; - int hash_valid; /* whether hash is valid or must be computed from key/data */ - uint32_t hash; /* cached serdata hash, valid only if hash_valid != 0 */ + struct ddsi_serdata c; + uint32_t pos; + uint32_t size; + bool bswap; +#ifndef NDEBUG + bool fixed; +#endif dds_key_hash_t keyhash; - bool bswap; /* Whether state is native endian or requires swapping */ -}; -struct serdata -{ - struct serdata_base v; + struct serstatepool *pool; + struct ddsi_serdata_default *next; /* in pool->freelist */ + /* padding to ensure CDRHeader is at an offset 4 mod 8 from the start of the memory, so that data is 8-byte aligned provided serdata is 8-byte aligned */ - char pad[8 - ((sizeof (struct serdata_base) + 4) % 8)]; + char pad[8 - ((sizeof (struct ddsi_serdata) + 4) % 8)]; struct CDRHeader hdr; char data[1]; }; - struct dds_key_descriptor; - -struct dds_topic; -typedef void (*topic_cb_t) (struct dds_topic * topic); #ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED #define DDS_TOPIC_INTERN_FILTER_FN_DEFINED typedef bool (*dds_topic_intern_filter_fn) (const void * sample, void *ctx); #endif -struct sertopic +struct ddsi_sertopic_default { - ut_avlNode_t avlnode; - char * name_typename; - char * name; - char * typename; + struct ddsi_sertopic c; + uint16_t native_encoding_identifier; /* (PL_)?CDR_(LE|BE) */ + void * type; unsigned nkeys; - uint32_t id; - uint32_t hash; uint32_t flags; size_t opt_size; - os_atomic_uint32_t refcount; - topic_cb_t status_cb; dds_topic_intern_filter_fn filter_fn; void * filter_sample; void * filter_ctx; - struct dds_topic * status_cb_entity; const struct dds_key_descriptor * keys; /* @@ -162,29 +128,30 @@ struct sertopic */ }; -serstatepool_t ddsi_serstatepool_new (void); -void ddsi_serstatepool_free (serstatepool_t pool); +struct ddsi_plist_sample { + void *blob; + size_t size; + nn_parameterid_t keyparam; +}; -serdata_t ddsi_serdata_ref (serdata_t serdata); -OSAPI_EXPORT void ddsi_serdata_unref (serdata_t serdata); -int ddsi_serdata_refcount_is_1 (serdata_t serdata); -nn_mtime_t ddsi_serdata_twrite (const struct serdata * serdata); -void ddsi_serdata_set_twrite (struct serdata * serdata, nn_mtime_t twrite); -uint32_t ddsi_serdata_size (const struct serdata * serdata); -int ddsi_serdata_is_key (const struct serdata * serdata); -int ddsi_serdata_is_empty (const struct serdata * serdata); +struct ddsi_rawcdr_sample { + void *blob; + size_t size; + void *key; + size_t keysize; +}; -OSAPI_EXPORT void ddsi_serstate_append_blob (serstate_t st, size_t align, size_t sz, const void *data); -OSAPI_EXPORT void ddsi_serstate_set_msginfo (serstate_t st, unsigned statusinfo, nn_wctime_t timestamp); -OSAPI_EXPORT serstate_t ddsi_serstate_new (const struct sertopic * topic); -OSAPI_EXPORT serdata_t ddsi_serstate_fix (serstate_t st); -nn_mtime_t ddsi_serstate_twrite (const struct serstate *serstate); -void ddsi_serstate_set_twrite (struct serstate *serstate, nn_mtime_t twrite); -void ddsi_serstate_release (serstate_t st); -void * ddsi_serstate_append (serstate_t st, size_t n); -void * ddsi_serstate_append_align (serstate_t st, size_t a); -void * ddsi_serstate_append_aligned (serstate_t st, size_t n, size_t a); +extern const struct ddsi_sertopic_ops ddsi_sertopic_ops_default; -OSAPI_EXPORT void ddsi_serdata_getblob (void **raw, size_t *sz, serdata_t serdata); +extern const struct ddsi_serdata_ops ddsi_serdata_ops_cdr; +extern const struct ddsi_serdata_ops ddsi_serdata_ops_plist; +extern const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr; + +struct serstatepool * ddsi_serstatepool_new (void); +void ddsi_serstatepool_free (struct serstatepool * pool); + +OSAPI_EXPORT void ddsi_serstate_append_blob (struct serstate * st, size_t align, size_t sz, const void *data); +void * ddsi_serstate_append (struct serstate * st, size_t n); +void * ddsi_serstate_append_aligned (struct serstate * st, size_t n, size_t a); #endif diff --git a/src/core/ddsi/include/ddsi/ddsi_sertopic.h b/src/core/ddsi/include/ddsi/ddsi_sertopic.h new file mode 100644 index 0000000..03a21cb --- /dev/null +++ b/src/core/ddsi/include/ddsi/ddsi_sertopic.h @@ -0,0 +1,48 @@ +/* + * 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 DDSI_SERTOPIC_H +#define DDSI_SERTOPIC_H + +#include "util/ut_avl.h" + +struct ddsi_serdata; +struct ddsi_serdata_ops; + +struct dds_topic; +typedef void (*topic_cb_t) (struct dds_topic * topic); + +struct ddsi_sertopic_ops; + +struct ddsi_sertopic { + ut_avlNode_t avlnode; /* index on name_typename */ + const struct ddsi_sertopic_ops *ops; + const struct ddsi_serdata_ops *serdata_ops; + char *name_typename; + char *name; + char *typename; + uint64_t iid; + os_atomic_uint32_t refc; /* counts refs from entities, not from data */ + + topic_cb_t status_cb; + struct dds_topic * status_cb_entity; +}; + +typedef void (*ddsi_sertopic_deinit_t) (struct ddsi_sertopic *tp); + +struct ddsi_sertopic_ops { + ddsi_sertopic_deinit_t deinit; +}; + +struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *tp); +void ddsi_sertopic_unref (struct ddsi_sertopic *tp); + +#endif diff --git a/src/core/ddsi/include/ddsi/q_entity.h b/src/core/ddsi/include/ddsi/q_entity.h index 654e508..164d56b 100644 --- a/src/core/ddsi/include/ddsi/q_entity.h +++ b/src/core/ddsi/include/ddsi/q_entity.h @@ -33,7 +33,7 @@ struct nn_reorder; struct nn_defrag; struct nn_dqueue; struct addrset; -struct sertopic; +struct ddsi_sertopic; struct whc; struct nn_xqos; struct nn_plist; @@ -234,7 +234,7 @@ struct writer unsigned supports_ssm: 1; struct addrset *ssm_as; #endif - const struct sertopic * topic; /* topic, but may be NULL for built-ins */ + const struct ddsi_sertopic * topic; /* topic, but may be NULL for built-ins */ struct addrset *as; /* set of addresses to publish to */ struct addrset *as_group; /* alternate case, used for SPDP, when using Cloud with multiple bootstrap locators */ struct xevent *heartbeat_xevent; /* timed event for "periodically" publishing heartbeats when unack'd data present, NULL <=> unreliable */ @@ -276,7 +276,7 @@ struct reader #ifdef DDSI_INCLUDE_NETWORK_PARTITIONS struct addrset *as; #endif - const struct sertopic * topic; /* topic is NULL for built-in readers */ + const struct ddsi_sertopic * topic; /* topic is NULL for built-in readers */ ut_avlTree_t writers; /* all matching PROXY writers, see struct rd_pwr_match */ ut_avlTree_t local_writers; /* all matching LOCAL writers, see struct rd_wr_match */ ddsi2direct_directread_cb_t ddsi2direct_cb; @@ -328,7 +328,7 @@ struct proxy_endpoint_common struct proxy_endpoint_common *next_ep; /* next \ endpoint belonging to this proxy participant */ struct proxy_endpoint_common *prev_ep; /* prev / -- this is in arbitrary ordering */ struct nn_xqos *xqos; /* proxy endpoint QoS lives here; FIXME: local ones should have it moved to common as well */ - const struct sertopic * topic; /* topic may be NULL: for built-ins, but also for never-yet matched proxies (so we don't have to know the topic; when we match, we certainly do know) */ + const struct ddsi_sertopic * topic; /* topic may be NULL: for built-ins, but also for never-yet matched proxies (so we don't have to know the topic; when we match, we certainly do know) */ struct addrset *as; /* address set to use for communicating with this endpoint */ nn_guid_t group_guid; /* 0:0:0:0 if not available */ nn_vendorid_t vendor; /* cached from proxypp->vendor */ @@ -473,9 +473,9 @@ struct writer *get_builtin_writer (const struct participant *pp, unsigned entity GUID "ppguid". May return NULL if participant unknown or writer/reader already known. */ -struct writer * new_writer (struct nn_guid *wrguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct sertopic *topic, const struct nn_xqos *xqos, struct whc * whc, status_cb_t status_cb, void * status_cb_arg); +struct writer * new_writer (struct nn_guid *wrguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct whc * whc, status_cb_t status_cb, void * status_cb_arg); -struct reader * new_reader (struct nn_guid *rdguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct sertopic *topic, const struct nn_xqos *xqos, struct rhc * rhc, status_cb_t status_cb, void * status_cb_arg); +struct reader * new_reader (struct nn_guid *rdguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct rhc * rhc, status_cb_t status_cb, void * status_cb_arg); struct whc_node; struct whc_state; diff --git a/src/core/ddsi/include/ddsi/q_globals.h b/src/core/ddsi/include/ddsi/q_globals.h index d9f16f9..3ae72d2 100644 --- a/src/core/ddsi/include/ddsi/q_globals.h +++ b/src/core/ddsi/include/ddsi/q_globals.h @@ -277,6 +277,8 @@ struct q_globals { transmit queue*/ struct serstatepool *serpool; struct nn_xmsgpool *xmsgpool; + struct ddsi_sertopic *plist_topic; /* used for all discovery data */ + struct ddsi_sertopic *rawcdr_topic; /* used for participant message data */ /* Network ID needed by v_groupWrite -- FIXME: might as well pass it to the receive thread instead of making it global (and that would diff --git a/src/core/ddsi/include/ddsi/q_plist.h b/src/core/ddsi/include/ddsi/q_plist.h index eadb552..f97d44f 100644 --- a/src/core/ddsi/include/ddsi/q_plist.h +++ b/src/core/ddsi/include/ddsi/q_plist.h @@ -200,7 +200,7 @@ typedef struct nn_plist_src { nn_protocol_version_t protocol_version; nn_vendorid_t vendorid; int encoding; - unsigned char *buf; + const unsigned char *buf; size_t bufsz; } nn_plist_src_t; @@ -233,6 +233,7 @@ struct nn_rsample_info; struct nn_rdata; unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const nn_plist_src_t *src); +const unsigned char *nn_plist_findparam_native_unchecked (const void *src, nn_parameterid_t pid); #if defined (__cplusplus) } diff --git a/src/core/ddsi/include/ddsi/q_transmit.h b/src/core/ddsi/include/ddsi/q_transmit.h index b3ba762..7573592 100644 --- a/src/core/ddsi/include/ddsi/q_transmit.h +++ b/src/core/ddsi/include/ddsi/q_transmit.h @@ -24,7 +24,7 @@ struct nn_xmsg; struct writer; struct whc_state; struct proxy_reader; -struct serdata; +struct ddsi_serdata; struct tkmap_instance; /* Writing new data; serdata_twrite (serdata) is assumed to be really @@ -34,14 +34,14 @@ struct tkmap_instance; "nogc": no GC may occur, so it may not block to throttle the writer if the high water mark of the WHC is reached, which implies true KEEP_LAST behaviour. This is true for all the DDSI built-in writers. "gc": GC may occur, which means the writer history and watermarks can be anything. This must be used for all application data. */ -int write_sample_gc (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata, struct tkmap_instance *tk); -int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata, struct tkmap_instance *tk); -int write_sample_gc_notk (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata); -int write_sample_nogc_notk (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata); +int write_sample_gc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +int write_sample_gc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata); +int write_sample_nogc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata); /* When calling the following functions, wr->lock must be held */ -int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_plist *plist, struct serdata *serdata, unsigned fragnum, struct proxy_reader *prd,struct nn_xmsg **msg, int isnew); -int enqueue_sample_wrlock_held (struct writer *wr, seqno_t seq, const struct nn_plist *plist, struct serdata *serdata, struct proxy_reader *prd, int isnew); +int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_plist *plist, struct ddsi_serdata *serdata, unsigned fragnum, struct proxy_reader *prd,struct nn_xmsg **msg, int isnew); +int enqueue_sample_wrlock_held (struct writer *wr, seqno_t seq, const struct nn_plist *plist, struct ddsi_serdata *serdata, struct proxy_reader *prd, int isnew); void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_state *whcst, int hbansreq, nn_entityid_t dst, int issync); #if defined (__cplusplus) diff --git a/src/core/ddsi/include/ddsi/q_whc.h b/src/core/ddsi/include/ddsi/q_whc.h index 7e7de47..c9cfa55 100644 --- a/src/core/ddsi/include/ddsi/q_whc.h +++ b/src/core/ddsi/include/ddsi/q_whc.h @@ -16,7 +16,7 @@ extern "C" { #endif -struct serdata; +struct ddsi_serdata; struct nn_plist; struct tkmap_instance; struct whc_node; /* opaque, but currently used for deferred free lists */ @@ -24,7 +24,7 @@ struct whc; struct whc_borrowed_sample { seqno_t seq; - struct serdata *serdata; + struct ddsi_serdata *serdata; struct nn_plist *plist; bool unacked; nn_mtime_t last_rexmit_ts; @@ -56,7 +56,7 @@ struct whc_sample_iter { typedef seqno_t (*whc_next_seq_t)(const struct whc *whc, seqno_t seq); typedef void (*whc_get_state_t)(const struct whc *whc, struct whc_state *st); typedef bool (*whc_borrow_sample_t)(const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); -typedef bool (*whc_borrow_sample_key_t)(const struct whc *whc, const struct serdata *serdata_key, struct whc_borrowed_sample *sample); +typedef bool (*whc_borrow_sample_key_t)(const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); typedef void (*whc_return_sample_t)(struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info); typedef void (*whc_sample_iter_init_t)(const struct whc *whc, struct whc_sample_iter *it); typedef bool (*whc_sample_iter_borrow_next_t)(struct whc_sample_iter *it, struct whc_borrowed_sample *sample); @@ -66,7 +66,7 @@ typedef void (*whc_free_t)(struct whc *whc); reliable readers that have not acknowledged all data */ /* max_drop_seq must go soon, it's way too ugly. */ /* plist may be NULL or os_malloc'd, WHC takes ownership of plist */ -typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct serdata *serdata, struct tkmap_instance *tk); +typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); typedef unsigned (*whc_downgrade_to_volatile_t)(struct whc *whc, struct whc_state *st); typedef unsigned (*whc_remove_acked_messages_t)(struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); typedef void (*whc_free_deferred_free_list_t)(struct whc *whc, struct whc_node *deferred_free_list); diff --git a/src/core/ddsi/include/ddsi/q_xmsg.h b/src/core/ddsi/include/ddsi/q_xmsg.h index b3d2aab..5ae7ba7 100644 --- a/src/core/ddsi/include/ddsi/q_xmsg.h +++ b/src/core/ddsi/include/ddsi/q_xmsg.h @@ -22,7 +22,7 @@ extern "C" { #endif -struct serdata; +struct ddsi_serdata; struct addrset; struct proxy_reader; struct proxy_writer; @@ -33,6 +33,7 @@ struct nn_xmsgpool; struct nn_xmsg_data; struct nn_xmsg; struct nn_xpack; +struct ddsi_plist_sample; struct nn_xmsg_marker { size_t offset; @@ -107,13 +108,14 @@ int nn_xmsg_compare_fragid (const struct nn_xmsg *a, const struct nn_xmsg *b); void nn_xmsg_free (struct nn_xmsg *msg); size_t nn_xmsg_size (const struct nn_xmsg *m); void *nn_xmsg_payload (size_t *sz, struct nn_xmsg *m); +void nn_xmsg_payload_to_plistsample (struct ddsi_plist_sample *dst, nn_parameterid_t keyparam, const struct nn_xmsg *m); enum nn_xmsg_kind nn_xmsg_kind (const struct nn_xmsg *m); void nn_xmsg_guid_seq_fragid (const struct nn_xmsg *m, nn_guid_t *wrguid, seqno_t *wrseq, nn_fragment_number_t *wrfragid); void *nn_xmsg_submsg_from_marker (struct nn_xmsg *msg, struct nn_xmsg_marker marker); void *nn_xmsg_append (struct nn_xmsg *m, struct nn_xmsg_marker *marker, size_t sz); void nn_xmsg_shrink (struct nn_xmsg *m, struct nn_xmsg_marker marker, size_t sz); -void nn_xmsg_serdata (struct nn_xmsg *m, struct serdata *serdata, size_t off, size_t len); +void nn_xmsg_serdata (struct nn_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len); void nn_xmsg_submsg_setnext (struct nn_xmsg *msg, struct nn_xmsg_marker marker); void nn_xmsg_submsg_init (struct nn_xmsg *msg, struct nn_xmsg_marker marker, SubmessageKind_t smkind); void nn_xmsg_add_timestamp (struct nn_xmsg *m, nn_wctime_t t); @@ -125,7 +127,7 @@ void nn_xmsg_addpar_stringseq (struct nn_xmsg *m, unsigned pid, const nn_strings void nn_xmsg_addpar_guid (struct nn_xmsg *m, unsigned pid, const nn_guid_t *guid); void nn_xmsg_addpar_BE4u (struct nn_xmsg *m, unsigned pid, unsigned x); void nn_xmsg_addpar_4u (struct nn_xmsg *m, unsigned pid, unsigned x); -void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct serdata *serdata); +void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct ddsi_serdata *serdata); void nn_xmsg_addpar_statusinfo (struct nn_xmsg *m, unsigned statusinfo); void nn_xmsg_addpar_reliability (struct nn_xmsg *m, unsigned pid, const struct nn_reliability_qospolicy *rq); void nn_xmsg_addpar_share (struct nn_xmsg *m, unsigned pid, const struct nn_share_qospolicy *rq); diff --git a/src/core/ddsi/src/ddsi_ser.c b/src/core/ddsi/src/ddsi_ser.c deleted file mode 100644 index 2dff4ed..0000000 --- a/src/core/ddsi/src/ddsi_ser.c +++ /dev/null @@ -1,242 +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 - */ -#include "ddsi/ddsi_ser.h" - -#include -#include -#include -#include - -#include "os/os_stdlib.h" -#include "os/os_defs.h" -#include "os/os_thread.h" -#include "os/os_heap.h" -#include "os/os_atomics.h" -#include "ddsi/sysdeps.h" -#include "ddsi/q_md5.h" -#include "ddsi/q_bswap.h" -#include "ddsi/q_config.h" -#include "ddsi/q_freelist.h" -#include "q__osplser.h" - -#define MAX_POOL_SIZE 16384 -#define CLEAR_PADDING 0 - -#ifndef NDEBUG -static int ispowerof2_size (size_t x) -{ - return x > 0 && !(x & (x-1)); -} -#endif - -static size_t alignup_size (size_t x, size_t a); -static serstate_t serstate_allocnew (serstatepool_t pool, const struct sertopic * topic); - -serstatepool_t ddsi_serstatepool_new (void) -{ - serstatepool_t pool; - pool = os_malloc (sizeof (*pool)); - nn_freelist_init (&pool->freelist, MAX_POOL_SIZE, offsetof (struct serstate, next)); - return pool; -} - -static void serstate_free_wrap (void *elem) -{ - serstate_free (elem); -} - -void ddsi_serstatepool_free (serstatepool_t pool) -{ - TRACE (("ddsi_serstatepool_free(%p)\n", pool)); - nn_freelist_fini (&pool->freelist, serstate_free_wrap); - os_free (pool); -} - -int ddsi_serdata_refcount_is_1 (serdata_t serdata) -{ - return (os_atomic_ld32 (&serdata->v.st->refcount) == 1); -} - -serdata_t ddsi_serdata_ref (serdata_t serdata) -{ - os_atomic_inc32 (&serdata->v.st->refcount); - return serdata; -} - -void ddsi_serdata_unref (serdata_t serdata) -{ - ddsi_serstate_release (serdata->v.st); -} - -nn_mtime_t ddsi_serdata_twrite (const struct serdata *serdata) -{ - return ddsi_serstate_twrite (serdata->v.st); -} - -void ddsi_serdata_set_twrite (serdata_t serdata, nn_mtime_t twrite) -{ - ddsi_serstate_set_twrite (serdata->v.st, twrite); -} - -serstate_t ddsi_serstate_new (const struct sertopic * topic) -{ - serstate_t st; - if ((st = nn_freelist_pop (&gv.serpool->freelist)) != NULL) - serstate_init (st, topic); - else - st = serstate_allocnew (gv.serpool, topic); - return st; -} - -serdata_t ddsi_serstate_fix (serstate_t st) -{ - /* see serialize_raw_private() */ - ddsi_serstate_append_aligned (st, 0, 4); - return st->data; -} - -nn_mtime_t ddsi_serstate_twrite (const struct serstate *serstate) -{ - assert (serstate->twrite.v >= 0); - return serstate->twrite; -} - -void ddsi_serstate_set_twrite (serstate_t st, nn_mtime_t twrite) -{ - st->twrite = twrite; -} - -void ddsi_serstate_append_blob (serstate_t st, size_t align, size_t sz, const void *data) -{ - char *p = ddsi_serstate_append_aligned (st, sz, align); - memcpy (p, data, sz); -} - -void ddsi_serstate_set_msginfo (serstate_t st, unsigned statusinfo, nn_wctime_t timestamp) -{ - serdata_t d = st->data; - d->v.msginfo.statusinfo = statusinfo; - d->v.msginfo.timestamp = timestamp; -} - -uint32_t ddsi_serdata_size (const struct serdata *serdata) -{ - const struct serstate *st = serdata->v.st; - if (serdata->v.st->kind == STK_EMPTY) - return 0; - else - return (uint32_t) (sizeof (struct CDRHeader) + st->pos); -} - -void ddsi_serdata_getblob (void **raw, size_t *sz, serdata_t serdata) -{ - const struct serstate *st = serdata->v.st; - if (serdata->v.st->kind == STK_EMPTY) - { - *sz = 0; - *raw = NULL; - } - else - { - *sz = sizeof (struct CDRHeader) + st->pos; - *raw = &serdata->hdr; - } -} - -int ddsi_serdata_is_key (const struct serdata * serdata) -{ - return serdata->v.st->kind == STK_KEY; -} - -int ddsi_serdata_is_empty (const struct serdata * serdata) -{ - return serdata->v.st->kind == STK_EMPTY; -} - -/* Internal static functions */ - -static serstate_t serstate_allocnew (serstatepool_t pool, const struct sertopic * topic) -{ - serstate_t st = os_malloc (sizeof (*st)); - size_t size; - - memset (st, 0, sizeof (*st)); - - st->size = 128; - st->pool = pool; - - size = offsetof (struct serdata, data) + st->size; - st->data = os_malloc (size); - memset (st->data, 0, sizeof (*st->data)); - st->data->v.st = st; - serstate_init (st, topic); - return st; -} - -void * ddsi_serstate_append (serstate_t st, size_t n) -{ - char *p; - if (st->pos + n > st->size) - { - size_t size1 = alignup_size (st->pos + n, 128); - serdata_t data1 = os_realloc (st->data, offsetof (struct serdata, data) + size1); - st->data = data1; - st->size = size1; - } - assert (st->pos + n <= st->size); - p = st->data->data + st->pos; - st->pos += n; - return p; -} - -void ddsi_serstate_release (serstate_t st) -{ - if (os_atomic_dec32_ov (&st->refcount) == 1) - { - serstatepool_t pool = st->pool; - sertopic_free ((sertopic_t) st->topic); - if (!nn_freelist_push (&pool->freelist, st)) - serstate_free (st); - } -} - -void * ddsi_serstate_append_align (serstate_t st, size_t sz) -{ - return ddsi_serstate_append_aligned (st, sz, sz); -} - -void * ddsi_serstate_append_aligned (serstate_t st, size_t n, size_t a) -{ - /* Simply align st->pos, without verifying it fits in the allocated - buffer: ddsi_serstate_append() is called immediately afterward and will - grow the buffer as soon as the end of the requested space no - longer fits. */ -#if CLEAR_PADDING - size_t pos0 = st->pos; -#endif - char *p; - assert (ispowerof2_size (a)); - st->pos = alignup_size (st->pos, a); - p = ddsi_serstate_append (st, n); -#if CLEAR_PADDING - if (p && st->pos > pos0) - memset (st->data->data + pos0, 0, st->pos - pos0); -#endif - return p; -} - -static size_t alignup_size (size_t x, size_t a) -{ - size_t m = a-1; - assert (ispowerof2_size (a)); - return (x+m) & ~m; -} diff --git a/src/core/ddsi/src/ddsi_serdata.c b/src/core/ddsi/src/ddsi_serdata.c new file mode 100644 index 0000000..6cbd605 --- /dev/null +++ b/src/core/ddsi/src/ddsi_serdata.c @@ -0,0 +1,48 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include +#include +#include + +#include "os/os.h" +#include "ddsi/sysdeps.h" +#include "ddsi/q_md5.h" +#include "ddsi/q_bswap.h" +#include "ddsi/q_config.h" +#include "ddsi/q_freelist.h" +#include "ddsi/ddsi_serdata.h" + +void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertopic *tp, enum ddsi_serdata_kind kind) +{ + d->topic = tp; + d->ops = tp->serdata_ops; + d->kind = kind; + d->hash = 0; + d->statusinfo = 0; + d->timestamp.v = INT64_MIN; + d->twrite.v = INT64_MIN; + os_atomic_st32 (&d->refc, 1); +} + +extern inline struct ddsi_serdata *ddsi_serdata_ref (const struct ddsi_serdata *serdata_const); +extern inline void ddsi_serdata_unref (struct ddsi_serdata *serdata); +extern inline uint32_t ddsi_serdata_size (const struct ddsi_serdata *d); +extern inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size); +extern inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertopic *topic, const struct nn_keyhash *keyhash); +extern inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const void *sample); +extern inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf); +extern inline struct ddsi_serdata *ddsi_serdata_to_ser_ref (const struct ddsi_serdata *d, size_t off, size_t sz, ddsi_iovec_t *ref); +extern inline void ddsi_serdata_to_ser_unref (struct ddsi_serdata *d, const ddsi_iovec_t *ref); +extern inline bool ddsi_serdata_to_sample (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); +extern inline int ddsi_serdata_cmpkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b); +extern inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b); diff --git a/src/core/ddsi/src/ddsi_serdata_default.c b/src/core/ddsi/src/ddsi_serdata_default.c new file mode 100644 index 0000000..4bb6012 --- /dev/null +++ b/src/core/ddsi/src/ddsi_serdata_default.c @@ -0,0 +1,510 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include +#include +#include + +#include "os/os.h" +#include "ddsi/sysdeps.h" +#include "ddsi/q_md5.h" +#include "ddsi/q_bswap.h" +#include "ddsi/q_config.h" +#include "ddsi/q_freelist.h" +#include +#include +#include "os/os.h" +#include "dds__key.h" +#include "dds__tkmap.h" +#include "dds__stream.h" +#include "ddsi/q_radmin.h" +#include "ddsi/ddsi_serdata_default.h" + +#define MAX_POOL_SIZE 16384 +#define CLEAR_PADDING 0 + +#ifndef NDEBUG +static int ispowerof2_size (size_t x) +{ + return x > 0 && !(x & (x-1)); +} +#endif + +static size_t alignup_size (size_t x, size_t a); + +struct serstatepool * ddsi_serstatepool_new (void) +{ + struct serstatepool * pool; + pool = os_malloc (sizeof (*pool)); + nn_freelist_init (&pool->freelist, MAX_POOL_SIZE, offsetof (struct ddsi_serdata_default, next)); + return pool; +} + +static void serstate_free_wrap (void *elem) +{ +#ifndef NDEBUG + struct ddsi_serdata_default *d = elem; + assert(os_atomic_ld32(&d->c.refc) == 1); +#endif + ddsi_serdata_unref(elem); +} + +void ddsi_serstatepool_free (struct serstatepool * pool) +{ + TRACE (("ddsi_serstatepool_free(%p)\n", pool)); + nn_freelist_fini (&pool->freelist, serstate_free_wrap); + os_free (pool); +} + +void ddsi_serstate_append_blob (struct serstate * st, size_t align, size_t sz, const void *data) +{ + char *p = ddsi_serstate_append_aligned (st, sz, align); + memcpy (p, data, sz); +} + +static size_t alignup_size (size_t x, size_t a) +{ + size_t m = a-1; + assert (ispowerof2_size (a)); + return (x+m) & ~m; +} + +static size_t alignup4 (size_t x) +{ + return alignup_size (x, 4); +} + +void * ddsi_serstate_append (struct serstate * st, size_t n) +{ + char *p; + if (st->data->pos + n > st->data->size) + { + size_t size1 = alignup_size (st->data->pos + n, 128); + struct ddsi_serdata_default * data1 = os_realloc (st->data, offsetof (struct ddsi_serdata_default, data) + size1); + st->data = data1; + st->data->size = (uint32_t)size1; + } + assert (st->data->pos + n <= st->data->size); + p = st->data->data + st->data->pos; + st->data->pos += (uint32_t)n; + return p; +} + +void * ddsi_serstate_append_aligned (struct serstate * st, size_t n, size_t a) +{ + /* Simply align st->pos, without verifying it fits in the allocated + buffer: ddsi_serstate_append() is called immediately afterward and will + grow the buffer as soon as the end of the requested space no + longer fits. */ +#if CLEAR_PADDING + size_t pos0 = st->pos; +#endif + char *p; + assert (ispowerof2_size (a)); + st->data->pos = (uint32_t) alignup_size (st->data->pos, a); + p = ddsi_serstate_append (st, n); +#if CLEAR_PADDING + if (p && st->pos > pos0) + memset (st->data->data + pos0, 0, st->pos - pos0); +#endif + return p; +} + +/* Fixed seed and length */ + +#define DDS_MH3_LEN 16 +#define DDS_MH3_SEED 0 + +#define DDS_MH3_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) + +/* Really + http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp, + MurmurHash3_x86_32 + */ + +static uint32_t dds_mh3 (const void * key) +{ + const uint8_t *data = (const uint8_t *) key; + const intptr_t nblocks = (intptr_t) (DDS_MH3_LEN / 4); + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + uint32_t h1 = DDS_MH3_SEED; + + const uint32_t *blocks = (const uint32_t *) (data + nblocks * 4); + register intptr_t i; + + for (i = -nblocks; i; i++) + { + uint32_t k1 = blocks[i]; + + k1 *= c1; + k1 = DDS_MH3_ROTL32 (k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = DDS_MH3_ROTL32 (h1, 13); + h1 = h1 * 5+0xe6546b64; + } + + /* finalization */ + + h1 ^= DDS_MH3_LEN; + h1 ^= h1 >> 16; + h1 *= 0x85ebca6b; + h1 ^= h1 >> 13; + h1 *= 0xc2b2ae35; + h1 ^= h1 >> 16; + + return h1; +} + +static struct ddsi_serdata *fix_serdata_default(struct ddsi_serdata_default *d, uint64_t tp_iid) +{ + if (d->keyhash.m_flags & DDS_KEY_IS_HASH) + d->c.hash = dds_mh3 (d->keyhash.m_hash) ^ (uint32_t)tp_iid; + else + d->c.hash = *((uint32_t *)d->keyhash.m_hash) ^ (uint32_t)tp_iid; + return &d->c; +} + +static uint32_t serdata_default_get_size(const struct ddsi_serdata *dcmn) +{ + const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *) dcmn; + return d->pos + (uint32_t)sizeof (struct CDRHeader); +} + +static bool serdata_default_eqkey(const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn) +{ + const struct ddsi_serdata_default *a = (const struct ddsi_serdata_default *)acmn; + const struct ddsi_serdata_default *b = (const struct ddsi_serdata_default *)bcmn; + const struct ddsi_sertopic_default *tp; + + assert(a->c.ops == b->c.ops); + tp = (struct ddsi_sertopic_default *)a->c.topic; + if (tp->nkeys == 0) + return true; + else + { + assert (a->keyhash.m_flags & DDS_KEY_HASH_SET); + return memcmp (a->keyhash.m_hash, b->keyhash.m_hash, 16) == 0; + } +} + +static void serdata_default_free(struct ddsi_serdata *dcmn) +{ + struct ddsi_serdata_default *d = (struct ddsi_serdata_default *)dcmn; + dds_free (d->keyhash.m_key_buff); + dds_free (d); +} + +static void serdata_default_init(struct ddsi_serdata_default *d, const struct ddsi_sertopic_default *tp, enum ddsi_serdata_kind kind) +{ + ddsi_serdata_init (&d->c, &tp->c, kind); + d->pos = 0; +#ifndef NDEBUG + d->fixed = false; +#endif + d->hdr.identifier = tp->native_encoding_identifier; + d->hdr.options = 0; + d->bswap = false; + memset (d->keyhash.m_hash, 0, sizeof (d->keyhash.m_hash)); + d->keyhash.m_key_len = 0; + d->keyhash.m_flags = 0; + d->keyhash.m_key_buff = NULL; + d->keyhash.m_key_buff_size = 0; +} + +static struct ddsi_serdata_default *serdata_default_allocnew(struct serstatepool *pool) +{ + const uint32_t init_size = 128; + struct ddsi_serdata_default *d = os_malloc(offsetof (struct ddsi_serdata_default, data) + init_size); + d->size = init_size; + d->pool = pool; + return d; +} + +static struct ddsi_serdata_default *serdata_default_new(const struct ddsi_sertopic_default *tp, enum ddsi_serdata_kind kind) +{ + struct ddsi_serdata_default *d; + if ((d = nn_freelist_pop (&gv.serpool->freelist)) == NULL) + d = serdata_default_allocnew(gv.serpool); + serdata_default_init(d, tp, kind); + return d; +} + +/* Construct a serdata from a fragchain received over the network */ +static struct ddsi_serdata *serdata_default_from_ser (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size) +{ + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; + struct ddsi_serdata_default *d = serdata_default_new(tp, kind); + uint32_t off = 4; /* must skip the CDR header */ + struct serstate st = { .data = d }; + + assert (fragchain->min == 0); + assert (fragchain->maxp1 >= off); /* CDR header must be in first fragment */ + (void)size; + + memcpy (&d->hdr, NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)), sizeof (d->hdr)); + switch (d->hdr.identifier) { + case CDR_LE: + case PL_CDR_LE: + d->bswap = ! PLATFORM_IS_LITTLE_ENDIAN; + break; + case CDR_BE: + case PL_CDR_BE: + d->bswap = PLATFORM_IS_LITTLE_ENDIAN; + break; + default: + /* must not ever try to use a serdata format for an unsupported encoding */ + abort (); + } + + while (fragchain) + { + assert (fragchain->min <= off); + assert (fragchain->maxp1 <= size); + if (fragchain->maxp1 > off) + { + /* only copy if this fragment adds data */ + const unsigned char *payload = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)); + ddsi_serstate_append_blob (&st, 1, fragchain->maxp1 - off, payload + off - fragchain->min); + off = fragchain->maxp1; + } + fragchain = fragchain->nextfrag; + } + + /* FIXME: assignment here is because of reallocs, but doing it this way is a bit hacky */ + d = st.data; + + dds_stream_t is; + dds_stream_from_serdata_default (&is, d); + dds_stream_read_keyhash (&is, &d->keyhash, (const dds_topic_descriptor_t *)tp->type, kind == SDK_KEY); + return fix_serdata_default (d, tp->c.iid); +} + +struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash) +{ + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; + struct ddsi_serdata_default *d = serdata_default_new(tp, SDK_KEY); + struct serstate st = { .data = d }; + /* FIXME: not quite sure this is correct */ + ddsi_serstate_append_blob (&st, 1, sizeof (keyhash->value), keyhash->value); + /* FIXME: assignment here is because of reallocs, but doing it this way is a bit hacky */ + d = st.data; + return fix_serdata_default(d, tp->c.iid); +} + +static struct ddsi_serdata *serdata_default_from_sample_cdr (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample) +{ + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; + struct ddsi_serdata_default *d = serdata_default_new(tp, kind); + dds_stream_t os; + dds_key_gen ((const dds_topic_descriptor_t *)tp->type, &d->keyhash, (char*)sample); + dds_stream_from_serdata_default (&os, d); + switch (kind) + { + case SDK_EMPTY: + break; + case SDK_KEY: + dds_stream_write_key (&os, sample, tp); + break; + case SDK_DATA: + dds_stream_write_sample (&os, sample, tp); + break; + } + dds_stream_add_to_serdata_default (&os, &d); + return fix_serdata_default (d, tp->c.iid); +} + +static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample) +{ + /* Currently restricted to DDSI discovery data (XTypes will need a rethink of the default representation and that may result in discovery data being moved to that new representation), and that means: keys are either GUIDs or an unbounded string for topics, for which MD5 is acceptable. Furthermore, these things don't get written very often, so scanning the parameter list to get the key value out is good enough for now. And at least it keeps the DDSI discovery data writing out of the internals of the sample representation */ + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; + const struct ddsi_plist_sample *sample = vsample; + struct ddsi_serdata_default *d = serdata_default_new(tp, kind); + struct serstate st = { .data = d }; + ddsi_serstate_append_blob (&st, 1, sample->size, sample->blob); + d = st.data; + const unsigned char *rawkey = nn_plist_findparam_native_unchecked (sample->blob, sample->keyparam); +#ifndef NDEBUG + size_t keysize; +#endif + switch (sample->keyparam) + { + case PID_PARTICIPANT_GUID: + case PID_ENDPOINT_GUID: + case PID_GROUP_GUID: + d->keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH; + d->keyhash.m_key_len = 16; + memcpy (&d->keyhash.m_hash, rawkey, d->keyhash.m_key_len); +#ifndef NDEBUG + keysize = d->keyhash.m_key_len; +#endif + break; + + case PID_TOPIC_NAME: { + const char *topic_name = (const char *) (rawkey + sizeof(uint32_t)); + uint32_t topic_name_sz; + uint32_t topic_name_sz_BE; + md5_state_t md5st; + md5_byte_t digest[16]; + topic_name_sz = (uint32_t) strlen (topic_name) + 1; + d->keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET; + d->keyhash.m_key_len = 16; + md5_init (&md5st); + md5_append (&md5st, (const md5_byte_t *) &topic_name_sz_BE, sizeof (topic_name_sz_BE)); + md5_append (&md5st, (const md5_byte_t *) topic_name, topic_name_sz); + md5_finish (&md5st, digest); + memcpy (&d->keyhash.m_hash, digest, d->keyhash.m_key_len); +#ifndef NDEBUG + keysize = sizeof (uint32_t) + topic_name_sz; +#endif + break; + } + + default: + abort(); + } + + /* if we're it is supposed to be just a key, rawkey must be be the first field and followed only by a sentinel */ + assert (kind != SDK_KEY || rawkey == (const unsigned char *)sample->blob + sizeof (nn_parameter_t)); + assert (kind != SDK_KEY || sample->size == sizeof (nn_parameter_t) + alignup4 (keysize) + sizeof (nn_parameter_t)); + return fix_serdata_default (d, tp->c.iid); +} + +static struct ddsi_serdata *serdata_default_from_sample_rawcdr (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample) +{ + /* Currently restricted to DDSI discovery data (XTypes will need a rethink of the default representation and that may result in discovery data being moved to that new representation), and that means: keys are either GUIDs or an unbounded string for topics, for which MD5 is acceptable. Furthermore, these things don't get written very often, so scanning the parameter list to get the key value out is good enough for now. And at least it keeps the DDSI discovery data writing out of the internals of the sample representation */ + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; + const struct ddsi_rawcdr_sample *sample = vsample; + struct ddsi_serdata_default *d = serdata_default_new(tp, kind); + struct serstate st = { .data = d }; + assert (sample->keysize <= 16); + ddsi_serstate_append_blob (&st, 1, sample->size, sample->blob); + d = st.data; + d->keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH; + d->keyhash.m_key_len = (uint32_t) sample->keysize; + if (sample->keysize > 0) + memcpy (&d->keyhash.m_hash, sample->key, sample->keysize); + return fix_serdata_default (d, tp->c.iid); +} + +/* Fill buffer with 'size' bytes of serialised data, starting from 'off'; 0 <= off < off+sz <= alignup4(size(d)) */ +static void serdata_default_to_ser (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, void *buf) +{ + const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; + assert (off < d->pos + sizeof(struct CDRHeader)); + assert (sz <= alignup4 (d->pos + sizeof(struct CDRHeader)) - off); + /* FIXME: maybe I should pull the header out ... */ + memcpy (buf, (char *)&d->hdr + off, sz); +} + +static struct ddsi_serdata *serdata_default_to_ser_ref (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, ddsi_iovec_t *ref) +{ + const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; + assert (off < d->pos + sizeof(struct CDRHeader)); + assert (sz <= alignup4 (d->pos + sizeof(struct CDRHeader)) - off); + ref->iov_base = (char *)&d->hdr + off; + ref->iov_len = sz; + return ddsi_serdata_ref(serdata_common); +} + +static void serdata_default_to_ser_unref (struct ddsi_serdata *serdata_common, const ddsi_iovec_t *ref) +{ + (void)ref; + ddsi_serdata_unref(serdata_common); +} + +static bool serdata_default_to_sample_cdr (const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim) +{ + const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; + dds_stream_t is; + if (bufptr) abort(); else { (void)buflim; } /* FIXME: haven't implemented that bit yet! */ + dds_stream_from_serdata_default(&is, d); + if (d->c.kind == SDK_KEY) + dds_stream_read_key (&is, sample, (const dds_topic_descriptor_t*) ((struct ddsi_sertopic_default *)d->c.topic)->type); + else + dds_stream_read_sample (&is, sample, (const struct ddsi_sertopic_default *)d->c.topic); + return true; /* FIXME: can't conversion to sample fail? */ +} + +static bool serdata_default_to_sample_plist (const struct ddsi_serdata *serdata_common, void *vsample, void **bufptr, void *buflim) +{ +#if 0 + const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; + struct ddsi_plist_sample *sample = vsample; + /* output of to_sample for normal samples is a copy, and so it should be for this one; only for native format (like the inverse) */ + if (bufptr) abort(); else { (void)buflim; } /* FIXME: haven't implemented that bit yet! */ + assert (d->hdr.identifier == PLATFORM_IS_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE); + sample->size = d->pos; + sample->blob = os_malloc (sample->size); + memcpy (sample->blob, (char *)&d->hdr + sizeof(struct CDRHeader), sample->size); + sample->keyparam = PID_PAD; + return true; +#else + /* I don't think I need this */ + (void)serdata_common; (void)vsample; (void)bufptr; (void)buflim; + abort(); + return false; +#endif +} + +static bool serdata_default_to_sample_rawcdr (const struct ddsi_serdata *serdata_common, void *vsample, void **bufptr, void *buflim) +{ + /* I don't think I need this */ + (void)serdata_common; (void)vsample; (void)bufptr; (void)buflim; + abort(); + return false; +} + +const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { + .get_size = serdata_default_get_size, + .cmpkey = 0, + .eqkey = serdata_default_eqkey, + .free = serdata_default_free, + .from_ser = serdata_default_from_ser, + .from_keyhash = ddsi_serdata_from_keyhash_cdr, + .from_sample = serdata_default_from_sample_cdr, + .to_ser = serdata_default_to_ser, + .to_sample = serdata_default_to_sample_cdr, + .to_ser_ref = serdata_default_to_ser_ref, + .to_ser_unref = serdata_default_to_ser_unref +}; + +const struct ddsi_serdata_ops ddsi_serdata_ops_plist = { + .get_size = serdata_default_get_size, + .cmpkey = 0, + .eqkey = serdata_default_eqkey, + .free = serdata_default_free, + .from_ser = serdata_default_from_ser, + .from_keyhash = 0, /* q_ddsi_discovery.c takes care of it internally */ + .from_sample = serdata_default_from_sample_plist, + .to_ser = serdata_default_to_ser, + .to_sample = serdata_default_to_sample_plist, + .to_ser_ref = serdata_default_to_ser_ref, + .to_ser_unref = serdata_default_to_ser_unref +}; + +const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr = { + .get_size = serdata_default_get_size, + .cmpkey = 0, + .eqkey = serdata_default_eqkey, + .free = serdata_default_free, + .from_ser = serdata_default_from_ser, + .from_keyhash = 0, /* q_ddsi_discovery.c takes care of it internally */ + .from_sample = serdata_default_from_sample_rawcdr, + .to_ser = serdata_default_to_ser, + .to_sample = serdata_default_to_sample_rawcdr, + .to_ser_ref = serdata_default_to_ser_ref, + .to_ser_unref = serdata_default_to_ser_unref +}; diff --git a/src/core/ddsi/src/ddsi_sertopic.c b/src/core/ddsi/src/ddsi_sertopic.c new file mode 100644 index 0000000..0dc2d10 --- /dev/null +++ b/src/core/ddsi/src/ddsi_sertopic.c @@ -0,0 +1,46 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include +#include +#include + +#include "os/os.h" +#include "ddsi/sysdeps.h" +#include "ddsi/q_md5.h" +#include "ddsi/q_bswap.h" +#include "ddsi/q_config.h" +#include "ddsi/q_freelist.h" +#include "ddsi/ddsi_sertopic.h" + +struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *sertopic_const) +{ + struct ddsi_sertopic *sertopic = (struct ddsi_sertopic *)sertopic_const; + if (sertopic) + os_atomic_inc32 (&sertopic->refc); + return sertopic; +} + +void ddsi_sertopic_unref (struct ddsi_sertopic *sertopic) +{ + if (sertopic) + { + if (os_atomic_dec32_ov (&sertopic->refc) == 1) + { + sertopic->ops->deinit (sertopic); + os_free (sertopic->name_typename); + os_free (sertopic->name); + os_free (sertopic->typename); + os_free (sertopic); + } + } +} diff --git a/src/core/ddsi/src/ddsi_sertopic_default.c b/src/core/ddsi/src/ddsi_sertopic_default.c new file mode 100644 index 0000000..56a3650 --- /dev/null +++ b/src/core/ddsi/src/ddsi_sertopic_default.c @@ -0,0 +1,35 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include +#include +#include + +#include "os/os.h" +#include "ddsi/sysdeps.h" +#include "ddsi/q_md5.h" +#include "ddsi/q_bswap.h" +#include "ddsi/q_config.h" +#include "ddsi/q_freelist.h" +#include "ddsi/ddsi_sertopic.h" +#include "ddsi/ddsi_serdata_default.h" + +/* FIXME: sertopic /= ddstopic so a lot of stuff needs to be moved here from dds_topic.c and the free function needs to be implemented properly */ + +static void deinit_sertopic_default (struct ddsi_sertopic *tp) +{ + (void)tp; +} + +const struct ddsi_sertopic_ops ddsi_sertopic_ops_default = { + .deinit = deinit_sertopic_default +}; diff --git a/src/core/ddsi/src/q_ddsi_discovery.c b/src/core/ddsi/src/q_ddsi_discovery.c index ad8c81c..3655ee9 100644 --- a/src/core/ddsi/src/q_ddsi_discovery.c +++ b/src/core/ddsi/src/q_ddsi_discovery.c @@ -18,7 +18,6 @@ #include "os/os.h" #include "util/ut_avl.h" -#include "ddsi/ddsi_ser.h" #include "ddsi/q_protocol.h" #include "ddsi/q_rtps.h" #include "ddsi/q_misc.h" @@ -39,7 +38,7 @@ #include "ddsi/q_lease.h" #include "ddsi/q_error.h" #include "ddsi/q_builtin_topic.h" -#include "q__osplser.h" +#include "ddsi/ddsi_serdata_default.h" #include "ddsi/q_md5.h" #include "ddsi/q_feature_check.h" @@ -173,21 +172,28 @@ static void maybe_add_pp_as_meta_to_as_disc (const struct addrset *as_meta) } } +static int write_mpayload (struct writer *wr, int alive, nn_parameterid_t keyparam, struct nn_xmsg *mpayload) +{ + struct ddsi_plist_sample plist_sample; + struct ddsi_serdata *serdata; + nn_xmsg_payload_to_plistsample (&plist_sample, keyparam, mpayload); + serdata = ddsi_serdata_from_sample (gv.plist_topic, alive ? SDK_DATA : SDK_KEY, &plist_sample); + serdata->statusinfo = alive ? 0 : NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER; + serdata->timestamp = now (); + return write_sample_nogc_notk (NULL, wr, serdata); +} + int spdp_write (struct participant *pp) { static const nn_vendorid_t myvendorid = MY_VENDOR_ID; - serdata_t serdata; - serstate_t serstate; struct nn_xmsg *mpayload; - size_t payload_sz; - char *payload_blob; struct nn_locators_one def_uni_loc_one, def_multi_loc_one, meta_uni_loc_one, meta_multi_loc_one; nn_plist_t ps; - nn_guid_t kh; struct writer *wr; size_t size; char node[64]; uint64_t qosdiff; + int ret; if (pp->e.onlylocal) { /* This topic is only locally available. */ @@ -317,32 +323,19 @@ int spdp_write (struct participant *pp) nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, 0); nn_plist_addtomsg (mpayload, pp->plist, 0, qosdiff); nn_xmsg_addpar_sentinel (mpayload); + nn_plist_fini (&ps); - /* A NULL topic implies a parameter list, now that we do PMD through - the serializer */ - serstate = ddsi_serstate_new (NULL); - payload_blob = nn_xmsg_payload (&payload_sz, mpayload); - ddsi_serstate_append_blob (serstate, 4, payload_sz, payload_blob); - kh = nn_hton_guid (pp->e.guid); - serstate_set_key (serstate, 0, &kh); - ddsi_serstate_set_msginfo (serstate, 0, now ()); - serdata = ddsi_serstate_fix (serstate); - nn_plist_fini(&ps); + ret = write_mpayload (wr, 1, PID_PARTICIPANT_GUID, mpayload); nn_xmsg_free (mpayload); - - return write_sample_nogc_notk (NULL, wr, serdata); + return ret; } int spdp_dispose_unregister (struct participant *pp) { struct nn_xmsg *mpayload; - size_t payload_sz; - char *payload_blob; nn_plist_t ps; - serdata_t serdata; - serstate_t serstate; - nn_guid_t kh; struct writer *wr; + int ret; if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL) { @@ -356,17 +349,11 @@ int spdp_dispose_unregister (struct participant *pp) ps.participant_guid = pp->e.guid; nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0); nn_xmsg_addpar_sentinel (mpayload); + nn_plist_fini (&ps); - serstate = ddsi_serstate_new (NULL); - payload_blob = nn_xmsg_payload (&payload_sz, mpayload); - ddsi_serstate_append_blob (serstate, 4, payload_sz, payload_blob); - kh = nn_hton_guid (pp->e.guid); - serstate_set_key (serstate, 1, &kh); - ddsi_serstate_set_msginfo (serstate, NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER, now ()); - serdata = ddsi_serstate_fix (serstate); + ret = write_mpayload (wr, 0, PID_PARTICIPANT_GUID, mpayload); nn_xmsg_free (mpayload); - - return write_sample_nogc_notk (NULL, wr, serdata); + return ret; } static unsigned pseudo_random_delay (const nn_guid_t *x, const nn_guid_t *y, nn_mtime_t tnow) @@ -718,13 +705,17 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time /* If unicast locators not present, then try to obtain from connection */ if (!config.tcp_use_peeraddr_for_unicast && (datap->present & PP_DEFAULT_UNICAST_LOCATOR) && (get_locator (&loc, &datap->default_unicast_locators, uc_same_subnet))) add_to_addrset (as_default, &loc); - else - nn_log (LC_DISCOVERY, " (srclocD)"), add_to_addrset (as_default, &rst->srcloc); + else { + nn_log (LC_DISCOVERY, " (srclocD)"); + add_to_addrset (as_default, &rst->srcloc); + } if (!config.tcp_use_peeraddr_for_unicast && (datap->present & PP_METATRAFFIC_UNICAST_LOCATOR) && (get_locator (&loc, &datap->metatraffic_unicast_locators, uc_same_subnet))) add_to_addrset (as_meta, &loc); - else - nn_log (LC_DISCOVERY, " (srclocM)"), add_to_addrset (as_meta, &rst->srcloc); + else { + nn_log (LC_DISCOVERY, " (srclocM)"); + add_to_addrset (as_meta, &rst->srcloc); + } nn_log_addrset (LC_DISCOVERY, " (data", as_default); nn_log_addrset (LC_DISCOVERY, " meta", as_meta); @@ -880,22 +871,16 @@ static void add_locator_to_ps (const nn_locator_t *loc, void *arg) static int sedp_write_endpoint ( - struct writer *wr, int end_of_life, const nn_guid_t *epguid, + struct writer *wr, int alive, const nn_guid_t *epguid, const struct entity_common *common, const struct endpoint_common *epcommon, const nn_xqos_t *xqos, struct addrset *as) { const nn_xqos_t *defqos = is_writer_entityid (epguid->entityid) ? &gv.default_xqos_wr : &gv.default_xqos_rd; const nn_vendorid_t my_vendor_id = MY_VENDOR_ID; - const int just_key = end_of_life; struct nn_xmsg *mpayload; uint64_t qosdiff; - nn_guid_t kh; nn_plist_t ps; - serstate_t serstate; - serdata_t serdata; - void *payload_blob; - size_t payload_sz; - unsigned statusinfo; + int ret; nn_plist_init_empty (&ps); ps.present |= PP_ENDPOINT_GUID; @@ -908,7 +893,7 @@ static int sedp_write_endpoint ps.entity_name = common->name; } - if (end_of_life) + if (!alive) { assert (xqos == NULL); assert (epcommon == NULL); @@ -966,23 +951,10 @@ static int sedp_write_endpoint nn_xmsg_addpar_sentinel (mpayload); nn_plist_fini (&ps); - /* Then we take the payload from the message and turn it into a - serdata, and then we can write it as normal data */ - serstate = ddsi_serstate_new (NULL); - payload_blob = nn_xmsg_payload (&payload_sz, mpayload); - ddsi_serstate_append_blob (serstate, 4, payload_sz, payload_blob); - kh = nn_hton_guid (*epguid); - serstate_set_key (serstate, just_key, &kh); - if (end_of_life) - statusinfo = NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER; - else - statusinfo = 0; - ddsi_serstate_set_msginfo (serstate, statusinfo, now ()); - serdata = ddsi_serstate_fix (serstate); - nn_xmsg_free (mpayload); - TRACE (("sedp: write for %x:%x:%x:%x via %x:%x:%x:%x\n", PGUID (*epguid), PGUID (wr->e.guid))); - return write_sample_nogc_notk (NULL, wr, serdata); + ret = write_mpayload (wr, alive, PID_ENDPOINT_GUID, mpayload); + nn_xmsg_free (mpayload); + return ret; } static struct writer *get_sedp_writer (const struct participant *pp, unsigned entityid) @@ -1003,7 +975,7 @@ int sedp_write_writer (struct writer *wr) #else struct addrset *as = NULL; #endif - return sedp_write_endpoint (sedp_wr, 0, &wr->e.guid, &wr->e, &wr->c, wr->xqos, as); + return sedp_write_endpoint (sedp_wr, 1, &wr->e.guid, &wr->e, &wr->c, wr->xqos, as); } return 0; } @@ -1018,7 +990,7 @@ int sedp_write_reader (struct reader *rd) #else struct addrset *as = NULL; #endif - return sedp_write_endpoint (sedp_wr, 0, &rd->e.guid, &rd->e, &rd->c, rd->xqos, as); + return sedp_write_endpoint (sedp_wr, 1, &rd->e.guid, &rd->e, &rd->c, rd->xqos, as); } return 0; } @@ -1028,7 +1000,7 @@ int sedp_dispose_unregister_writer (struct writer *wr) if ((!is_builtin_entityid(wr->e.guid.entityid, ownvendorid)) && (!wr->e.onlylocal)) { struct writer *sedp_wr = get_sedp_writer (wr->c.pp, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER); - return sedp_write_endpoint (sedp_wr, 1, &wr->e.guid, NULL, NULL, NULL, NULL); + return sedp_write_endpoint (sedp_wr, 0, &wr->e.guid, NULL, NULL, NULL, NULL); } return 0; } @@ -1038,7 +1010,7 @@ int sedp_dispose_unregister_reader (struct reader *rd) if ((!is_builtin_entityid(rd->e.guid.entityid, ownvendorid)) && (!rd->e.onlylocal)) { struct writer *sedp_wr = get_sedp_writer (rd->c.pp, NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER); - return sedp_write_endpoint (sedp_wr, 1, &rd->e.guid, NULL, NULL, NULL, NULL); + return sedp_write_endpoint (sedp_wr, 0, &rd->e.guid, NULL, NULL, NULL, NULL); } return 0; } @@ -1255,9 +1227,14 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat if (!config.tcp_use_peeraddr_for_unicast && (datap->present & PP_UNICAST_LOCATOR) && get_locator (&loc, &datap->unicast_locators, 0)) add_to_addrset (as, &loc); else if (config.tcp_use_peeraddr_for_unicast) - nn_log (LC_DISCOVERY, " (srcloc)"), add_to_addrset (as, &rst->srcloc); + { + nn_log (LC_DISCOVERY, " (srcloc)"); + add_to_addrset (as, &rst->srcloc); + } else + { copy_addrset_into_addrset_uc (as, pp->as_default); + } if ((datap->present & PP_MULTICAST_LOCATOR) && get_locator (&loc, &datap->multicast_locators, 0)) allowmulticast_aware_add_to_addrset (as, &loc); else @@ -1404,15 +1381,8 @@ int sedp_write_topic (struct participant *pp, const struct nn_plist *datap) { struct writer *sedp_wr; struct nn_xmsg *mpayload; - serstate_t serstate; - serdata_t serdata; - void *payload_blob; - size_t payload_sz; - uint32_t topic_name_sz; - uint32_t topic_name_sz_BE; uint64_t delta; - unsigned char digest[16]; - md5_state_t md5st; + int ret; assert (datap->qos.present & QP_TOPIC_NAME); @@ -1430,25 +1400,10 @@ int sedp_write_topic (struct participant *pp, const struct nn_plist *datap) nn_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta); nn_xmsg_addpar_sentinel (mpayload); - serstate = ddsi_serstate_new (NULL); - payload_blob = nn_xmsg_payload (&payload_sz, mpayload); - ddsi_serstate_append_blob (serstate, 4, payload_sz, payload_blob); - - topic_name_sz = (uint32_t) strlen (datap->qos.topic_name) + 1; - topic_name_sz_BE = toBE4u (topic_name_sz); - - md5_init (&md5st); - md5_append (&md5st, (const md5_byte_t *) &topic_name_sz_BE, sizeof (topic_name_sz_BE)); - md5_append (&md5st, (const md5_byte_t *) datap->qos.topic_name, topic_name_sz); - md5_finish (&md5st, digest); - - serstate_set_key (serstate, 0, digest); - ddsi_serstate_set_msginfo (serstate, 0, now ()); - serdata = ddsi_serstate_fix (serstate); - nn_xmsg_free (mpayload); - TRACE (("sedp: write topic %s via %x:%x:%x:%x\n", datap->qos.topic_name, PGUID (sedp_wr->e.guid))); - return write_sample_nogc_notk (NULL, sedp_wr, serdata); + ret = write_mpayload (sedp_wr, 1, PID_TOPIC_NAME, mpayload); + nn_xmsg_free (mpayload); + return ret; } @@ -1462,13 +1417,8 @@ int sedp_write_cm_participant (struct participant *pp, int alive) { struct writer * sedp_wr; struct nn_xmsg *mpayload; - serstate_t serstate; - serdata_t serdata; nn_plist_t ps; - nn_guid_t kh; - void *payload_blob; - size_t payload_sz; - unsigned statusinfo; + int ret; if (pp->e.onlylocal) { /* This topic is only locally available. */ @@ -1487,9 +1437,10 @@ int sedp_write_cm_participant (struct participant *pp, int alive) nn_plist_init_empty (&ps); ps.present = PP_PARTICIPANT_GUID; ps.participant_guid = pp->e.guid; + nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0); + nn_plist_fini (&ps); if (alive) { - nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0); nn_plist_addtomsg (mpayload, pp->plist, PP_PRISMTECH_NODE_NAME | PP_PRISMTECH_EXEC_NAME | PP_PRISMTECH_PROCESS_ID | PP_PRISMTECH_WATCHDOG_SCHEDULING | PP_PRISMTECH_LISTENER_SCHEDULING | @@ -1498,23 +1449,11 @@ int sedp_write_cm_participant (struct participant *pp, int alive) } nn_xmsg_addpar_sentinel (mpayload); - /* Then we take the payload from the message and turn it into a - serdata, and then we can write it as normal data */ - serstate = ddsi_serstate_new (NULL); - payload_blob = nn_xmsg_payload (&payload_sz, mpayload); - ddsi_serstate_append_blob (serstate, 4, payload_sz, payload_blob); - kh = nn_hton_guid (pp->e.guid); - serstate_set_key (serstate, !alive, &kh); - if (!alive) - statusinfo = NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER; - else - statusinfo = 0; - ddsi_serstate_set_msginfo (serstate, statusinfo, now ()); - serdata = ddsi_serstate_fix (serstate); + TRACE (("sedp: write CMParticipant ST%x for %x:%x:%x:%x via %x:%x:%x:%x\n", + alive ? 0 : NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER, PGUID (pp->e.guid), PGUID (sedp_wr->e.guid))); + ret = write_mpayload (sedp_wr, alive, PID_PARTICIPANT_GUID, mpayload); nn_xmsg_free (mpayload); - - TRACE (("sedp: write CMParticipant ST%x for %x:%x:%x:%x via %x:%x:%x:%x\n", statusinfo, PGUID (pp->e.guid), PGUID (sedp_wr->e.guid))); - return write_sample_nogc_notk (NULL, sedp_wr, serdata); + return ret; } static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_entity_id, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) @@ -1576,13 +1515,8 @@ int sedp_write_cm_publisher (const struct nn_plist *datap, int alive) struct participant *pp; struct writer *sedp_wr; struct nn_xmsg *mpayload; - serstate_t serstate; - serdata_t serdata; - nn_guid_t kh; - void *payload_blob; - size_t payload_sz; - unsigned statusinfo; uint64_t delta; + int ret; if ((pp = group_guid_to_participant (&datap->group_guid)) == NULL) { @@ -1607,23 +1541,9 @@ int sedp_write_cm_publisher (const struct nn_plist *datap, int alive) } nn_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta); nn_xmsg_addpar_sentinel (mpayload); - - /* Then we take the payload from the message and turn it into a - serdata, and then we can write it as normal data */ - serstate = ddsi_serstate_new (NULL); - payload_blob = nn_xmsg_payload (&payload_sz, mpayload); - ddsi_serstate_append_blob (serstate, 4, payload_sz, payload_blob); - kh = nn_hton_guid (datap->group_guid); - serstate_set_key (serstate, !alive, &kh); - if (!alive) - statusinfo = NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER; - else - statusinfo = 0; - ddsi_serstate_set_msginfo (serstate, statusinfo, now ()); - serdata = ddsi_serstate_fix (serstate); + ret = write_mpayload (sedp_wr, alive, PID_GROUP_GUID ,mpayload); nn_xmsg_free (mpayload); - - return write_sample_nogc_notk (NULL, sedp_wr, serdata); + return ret; } int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive) @@ -1631,13 +1551,8 @@ int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive) struct participant *pp; struct writer *sedp_wr; struct nn_xmsg *mpayload; - serstate_t serstate; - serdata_t serdata; - nn_guid_t kh; - void *payload_blob; - size_t payload_sz; - unsigned statusinfo; uint64_t delta; + int ret; if ((pp = group_guid_to_participant (&datap->group_guid)) == NULL) { @@ -1662,23 +1577,9 @@ int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive) } nn_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta); nn_xmsg_addpar_sentinel (mpayload); - - /* Then we take the payload from the message and turn it into a - serdata, and then we can write it as normal data */ - serstate = ddsi_serstate_new (NULL); - payload_blob = nn_xmsg_payload (&payload_sz, mpayload); - ddsi_serstate_append_blob (serstate, 4, payload_sz, payload_blob); - kh = nn_hton_guid (datap->group_guid); - serstate_set_key (serstate, !alive, &kh); - if (!alive) - statusinfo = NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER; - else - statusinfo = 0; - ddsi_serstate_set_msginfo (serstate, statusinfo, now ()); - serdata = ddsi_serstate_fix (serstate); + ret = write_mpayload (sedp_wr, alive, PID_GROUP_GUID, mpayload); nn_xmsg_free (mpayload); - - return write_sample_nogc_notk (NULL, sedp_wr, serdata); + return ret; } static void handle_SEDP_GROUP_alive (nn_plist_t *datap /* note: potentially modifies datap */, nn_wctime_t timestamp) diff --git a/src/core/ddsi/src/q_debmon.c b/src/core/ddsi/src/q_debmon.c index 94f22bf..4b1f839 100644 --- a/src/core/ddsi/src/q_debmon.c +++ b/src/core/ddsi/src/q_debmon.c @@ -23,7 +23,6 @@ #include "ddsi/q_misc.h" #include "ddsi/q_log.h" #include "ddsi/q_plist.h" -#include "q__osplser.h" #include "ddsi/q_ephash.h" #include "ddsi/q_globals.h" #include "ddsi/q_addrset.h" @@ -33,7 +32,7 @@ #include "ddsi/q_unused.h" #include "ddsi/q_error.h" #include "ddsi/q_debmon.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" #include "ddsi/ddsi_tran.h" #include "ddsi/ddsi_tcp.h" @@ -107,7 +106,7 @@ static int print_addrset_if_notempty (ddsi_tran_conn_t conn, const char *prefix, } static int print_any_endpoint_common (ddsi_tran_conn_t conn, const char *label, const struct entity_common *e, - const struct nn_xqos *xqos, const struct sertopic *topic) + const struct nn_xqos *xqos, const struct ddsi_sertopic *topic) { int x = 0; x += cpf (conn, " %s %x:%x:%x:%x ", label, PGUID (e->guid)); @@ -126,7 +125,7 @@ static int print_any_endpoint_common (ddsi_tran_conn_t conn, const char *label, return x; } -static int print_endpoint_common (ddsi_tran_conn_t conn, const char *label, const struct entity_common *e, const struct endpoint_common *c, const struct nn_xqos *xqos, const struct sertopic *topic) +static int print_endpoint_common (ddsi_tran_conn_t conn, const char *label, const struct entity_common *e, const struct endpoint_common *c, const struct nn_xqos *xqos, const struct ddsi_sertopic *topic) { OS_UNUSED_ARG (c); return print_any_endpoint_common (conn, label, e, xqos, topic); diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 35f9ce2..0e61baf 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -24,7 +24,6 @@ #include "util/ut_avl.h" #include "ddsi/q_plist.h" #include "ddsi/q_lease.h" -#include "q__osplser.h" #include "ddsi/q_qosmatch.h" #include "ddsi/q_ephash.h" #include "ddsi/q_globals.h" @@ -37,7 +36,7 @@ #include "ddsi/q_unused.h" #include "ddsi/q_error.h" #include "ddsi/q_builtin_topic.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata_default.h" #include "ddsi/ddsi_mcgroup.h" #include "ddsi/q_receive.h" @@ -85,8 +84,8 @@ static const unsigned prismtech_builtin_writers_besmask = NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_WRITER | NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_WRITER; -static struct writer * new_writer_guid (const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp, const struct sertopic *topic, const struct nn_xqos *xqos, struct whc *whc, status_cb_t status_cb, void *status_cbarg); -static struct reader * new_reader_guid (const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp, const struct sertopic *topic, const struct nn_xqos *xqos, struct rhc *rhc, status_cb_t status_cb, void *status_cbarg); +static struct writer * new_writer_guid (const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct whc *whc, status_cb_t status_cb, void *status_cbarg); +static struct reader * new_reader_guid (const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct rhc *rhc, status_cb_t status_cb, void *status_cbarg); static struct participant *ref_participant (struct participant *pp, const struct nn_guid *guid_of_refing_entity); static void unref_participant (struct participant *pp, const struct nn_guid *guid_of_refing_entity); static void delete_proxy_group_locked (struct proxy_group *pgroup, nn_wctime_t timestamp, int isimplicit); @@ -1611,7 +1610,7 @@ static void writer_add_local_connection (struct writer *wr, struct reader *rd) while (wr->whc->ops->sample_iter_borrow_next(&it, &sample)) { struct proxy_writer_info pwr_info; - serdata_t payload = sample.serdata; + struct ddsi_serdata *payload = sample.serdata; /* FIXME: whc has tk reference in its index nodes, which is what we really should be iterating over anyway, and so we don't really have to look them up anymore */ struct tkmap_instance *tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (payload); make_proxy_writer_info(&pwr_info, &wr->e, wr->xqos); @@ -2297,7 +2296,7 @@ static void match_proxy_reader_with_writers (struct proxy_reader *prd, nn_mtime_ /* ENDPOINT --------------------------------------------------------- */ -static void new_reader_writer_common (const struct nn_guid *guid, const struct sertopic * topic, const struct nn_xqos *xqos) +static void new_reader_writer_common (const struct nn_guid *guid, const struct ddsi_sertopic * topic, const struct nn_xqos *xqos) { const char *partition = "(default)"; const char *partition_suffix = ""; @@ -2353,7 +2352,7 @@ static void endpoint_common_fini (struct entity_common *e, struct endpoint_commo entity_common_fini (e); } -static int set_topic_type_name (nn_xqos_t *xqos, const struct sertopic * topic) +static int set_topic_type_name (nn_xqos_t *xqos, const struct ddsi_sertopic * topic) { if (!(xqos->present & QP_TYPE_NAME) && topic) { @@ -2556,7 +2555,7 @@ unsigned remove_acked_messages (struct writer *wr, struct whc_state *whcst, stru return n; } -static struct writer * new_writer_guid (const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp, const struct sertopic *topic, const struct nn_xqos *xqos, struct whc *whc, status_cb_t status_cb, void * status_entity) +static struct writer * new_writer_guid (const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct whc *whc, status_cb_t status_cb, void * status_entity) { struct writer *wr; nn_mtime_t tnow = now_mt (); @@ -2651,11 +2650,7 @@ static struct writer * new_writer_guid (const struct nn_guid *guid, const struct (wr->xqos->durability.kind == NN_VOLATILE_DURABILITY_QOS && wr->xqos->reliability.kind != NN_BEST_EFFORT_RELIABILITY_QOS); } - if (topic) - { - os_atomic_inc32 (&((struct sertopic *)topic)->refcount); - } - wr->topic = topic; + wr->topic = ddsi_sertopic_ref (topic); wr->as = new_addrset (); wr->as_group = NULL; @@ -2796,11 +2791,10 @@ static struct writer * new_writer_guid (const struct nn_guid *guid, const struct return wr; } -struct writer * new_writer (struct nn_guid *wrguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct sertopic *topic, const struct nn_xqos *xqos, struct whc * whc, status_cb_t status_cb, void * status_cb_arg) +struct writer * new_writer (struct nn_guid *wrguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct whc * whc, status_cb_t status_cb, void * status_cb_arg) { struct participant *pp; struct writer * wr; - unsigned entity_kind; if ((pp = ephash_lookup_participant_guid (ppguid)) == NULL) { @@ -2810,9 +2804,8 @@ struct writer * new_writer (struct nn_guid *wrguid, const struct nn_guid *group_ /* participant can't be freed while we're mucking around cos we are awake and do not touch the thread's vtime (ephash_lookup already verifies we're awake) */ - entity_kind = (topic->nkeys ? NN_ENTITYID_KIND_WRITER_WITH_KEY : NN_ENTITYID_KIND_WRITER_NO_KEY); wrguid->prefix = pp->e.guid.prefix; - if (pp_allocate_entityid (&wrguid->entityid, entity_kind, pp) < 0) + if (pp_allocate_entityid (&wrguid->entityid, NN_ENTITYID_KIND_WRITER_WITH_KEY, pp) < 0) return NULL; wr = new_writer_guid (wrguid, group_guid, pp, topic, xqos, whc, status_cb, status_cb_arg); return wr; @@ -2872,7 +2865,7 @@ static void gc_delete_writer (struct gcreq *gcreq) local_reader_ary_fini (&wr->rdary); os_condDestroy (&wr->throttle_cond); - sertopic_free ((struct sertopic *) wr->topic); + ddsi_sertopic_unref ((struct ddsi_sertopic *) wr->topic); endpoint_common_fini (&wr->e, &wr->c); os_free (wr); } @@ -3117,7 +3110,7 @@ static struct reader * new_reader_guid const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp, - const struct sertopic *topic, + const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct rhc *rhc, status_cb_t status_cb, @@ -3155,11 +3148,7 @@ static struct reader * new_reader_guid rd->reliable = (rd->xqos->reliability.kind != NN_BEST_EFFORT_RELIABILITY_QOS); assert (rd->xqos->present & QP_DURABILITY); rd->handle_as_transient_local = (rd->xqos->durability.kind == NN_TRANSIENT_LOCAL_DURABILITY_QOS); - if (topic) - { - os_atomic_inc32 (&((struct sertopic *)topic)->refcount); - } - rd->topic = topic; + rd->topic = ddsi_sertopic_ref (topic); rd->ddsi2direct_cb = 0; rd->ddsi2direct_cbarg = 0; rd->init_acknack_count = 0; @@ -3253,7 +3242,7 @@ struct reader * new_reader struct nn_guid *rdguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, - const struct sertopic *topic, + const struct ddsi_sertopic *topic, const struct nn_xqos *xqos, struct rhc * rhc, status_cb_t status_cb, @@ -3262,16 +3251,14 @@ struct reader * new_reader { struct participant * pp; struct reader * rd; - unsigned entity_kind; if ((pp = ephash_lookup_participant_guid (ppguid)) == NULL) { nn_log (LC_DISCOVERY, "new_reader - participant %x:%x:%x:%x not found\n", PGUID (*ppguid)); return NULL; } - entity_kind = (topic->nkeys ? NN_ENTITYID_KIND_READER_WITH_KEY : NN_ENTITYID_KIND_READER_NO_KEY); rdguid->prefix = pp->e.guid.prefix; - if (pp_allocate_entityid (&rdguid->entityid, entity_kind, pp) < 0) + if (pp_allocate_entityid (&rdguid->entityid, NN_ENTITYID_KIND_READER_WITH_KEY, pp) < 0) return NULL; rd = new_reader_guid (rdguid, group_guid, pp, topic, xqos, rhc, status_cb, status_cbarg); return rd; @@ -3312,7 +3299,7 @@ static void gc_delete_reader (struct gcreq *gcreq) { (rd->status_cb) (rd->status_cb_entity, NULL); } - sertopic_free ((struct sertopic *) rd->topic); + ddsi_sertopic_unref ((struct ddsi_sertopic *) rd->topic); nn_xqos_fini (rd->xqos); os_free (rd->xqos); diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index 736896a..3f653f0 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -50,12 +50,12 @@ #include "ddsi/sysdeps.h" -#include "ddsi/ddsi_ser.h" #include "ddsi/ddsi_tran.h" #include "ddsi/ddsi_udp.h" #include "ddsi/ddsi_tcp.h" #include "ddsi/ddsi_raweth.h" #include "ddsi/ddsi_mcgroup.h" +#include "ddsi/ddsi_serdata_default.h" #include "dds__tkmap.h" #include "dds__whc.h" @@ -752,6 +752,39 @@ static void wait_for_receive_threads (void) } } +static struct ddsi_sertopic *make_special_topic (uint16_t enc_id, const struct ddsi_serdata_ops *ops) +{ + /* FIXME: two things (at least) + - it claims there is a key, but the underlying type description is missing + that only works as long as it ends up comparing the keyhash field ... + the keyhash field should be eliminated; but this can simply be moved over to an alternate + topic class, it need not use the "default" one, that's mere expediency + - initialising/freeing them here, in this manner, is not very clean + it should be moved to somewhere in the topic implementation + (kinda natural if they stop being "default" ones) */ + struct ddsi_sertopic_default *st = os_malloc (sizeof (*st)); + memset (st, 0, sizeof (*st)); + os_atomic_st32 (&st->c.refc, 1); + st->c.ops = &ddsi_sertopic_ops_default; + st->c.serdata_ops = ops; + st->native_encoding_identifier = enc_id; + st->c.iid = ddsi_plugin.iidgen_fn(); + st->nkeys = 1; + return (struct ddsi_sertopic *)st; +} + +static void make_special_topics (void) +{ + gv.plist_topic = make_special_topic (PLATFORM_IS_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE, &ddsi_serdata_ops_plist); + gv.rawcdr_topic = make_special_topic (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE, &ddsi_serdata_ops_rawcdr); +} + +static void free_special_topics (void) +{ + ddsi_sertopic_unref (gv.plist_topic); + ddsi_sertopic_unref (gv.rawcdr_topic); +} + static int setup_and_start_recv_threads (void) { unsigned i; @@ -998,6 +1031,8 @@ int rtps_init (void) make_builtin_endpoint_xqos (&gv.builtin_endpoint_xqos_rd, &gv.default_xqos_rd); make_builtin_endpoint_xqos (&gv.builtin_endpoint_xqos_wr, &gv.default_xqos_wr); + make_special_topics (); /* FIXME: leaking these for now */ + os_mutexInit (&gv.participant_set_lock); os_condInit (&gv.participant_set_cond, &gv.participant_set_lock); lease_management_init (); @@ -1309,6 +1344,7 @@ err_unicast_sockets: lease_management_term (); os_condDestroy (&gv.participant_set_cond); os_mutexDestroy (&gv.participant_set_lock); + free_special_topics (); #ifdef DDSI_INCLUDE_ENCRYPTION if (q_security_plugin.free_decoder) q_security_plugin.free_decoder (gv.recvSecurityCodec); @@ -1586,6 +1622,7 @@ void rtps_term (void) lease_management_term (); os_mutexDestroy (&gv.participant_set_lock); os_condDestroy (&gv.participant_set_cond); + free_special_topics (); nn_xqos_fini (&gv.builtin_endpoint_xqos_wr); nn_xqos_fini (&gv.builtin_endpoint_xqos_rd); diff --git a/src/core/ddsi/src/q_lease.c b/src/core/ddsi/src/q_lease.c index 1dd7e5d..ce6ed57 100644 --- a/src/core/ddsi/src/q_lease.c +++ b/src/core/ddsi/src/q_lease.c @@ -17,7 +17,7 @@ #include "util/ut_fibheap.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata_default.h" #include "ddsi/q_protocol.h" #include "ddsi/q_rtps.h" #include "ddsi/q_misc.h" diff --git a/src/core/ddsi/src/q_plist.c b/src/core/ddsi/src/q_plist.c index cb1ebe2..2623754 100644 --- a/src/core/ddsi/src/q_plist.c +++ b/src/core/ddsi/src/q_plist.c @@ -3066,6 +3066,22 @@ int nn_plist_init_frommsg return ERR_INVALID; } +const unsigned char *nn_plist_findparam_native_unchecked (const void *src, nn_parameterid_t pid) +{ + /* Scans the parameter list starting at src looking just for pid, returning NULL if not found; + no further checking is done and the input is assumed to valid and in native format. Clearly + this is only to be used for internally generated data -- to precise, for grabbing the key + value from discovery data that is being sent out. */ + const nn_parameter_t *par = src; + while (par->parameterid != pid) + { + if (pid == PID_SENTINEL) + return NULL; + par = (const nn_parameter_t *) ((const char *) (par + 1) + par->length); + } + return (unsigned char *) (par + 1); +} + unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const nn_plist_src_t *src) { /* Sets a few fields in dest, returns address of first byte diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index c9c145d..5c3b69b 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -16,10 +16,8 @@ #include "os/os.h" - #include "ddsi/q_md5.h" #include "util/ut_avl.h" -#include "q__osplser.h" #include "dds__stream.h" #include "ddsi/q_protocol.h" #include "ddsi/q_rtps.h" @@ -49,6 +47,8 @@ #include "ddsi/q_static_assert.h" #include "ddsi/q_init.h" #include "ddsi/ddsi_mcgroup.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_serdata_default.h" /* FIXME: get rid of this */ #include "ddsi/sysdeps.h" #include "dds__whc.h" @@ -1784,70 +1784,28 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm return 1; } -static serstate_t make_raw_serstate -( - struct sertopic const * const topic, - const struct nn_rdata *fragchain, uint32_t sz, int justkey, - unsigned statusinfo, nn_wctime_t tstamp -) +static struct ddsi_serdata *get_serdata (struct ddsi_sertopic const * const topic, const struct nn_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, nn_wctime_t tstamp) { - serstate_t st = ddsi_serstate_new (topic); - ddsi_serstate_set_msginfo (st, statusinfo, tstamp); - st->kind = justkey ? STK_KEY : STK_DATA; - /* the CDR header is always fully contained in the first fragment - (see valid_DataFrag), so extracting it is easy */ - assert (fragchain->min == 0); - (void)sz; - - /* alignment at head-of-stream is guaranteed, requesting 1 byte - alignment is therefore fine for pasting together fragments of - data */ - { - uint32_t off = 4; /* must skip the CDR header */ - while (fragchain) - { - assert (fragchain->min <= off); - assert (fragchain->maxp1 <= sz); - if (fragchain->maxp1 > off) - { - /* only copy if this fragment adds data */ - const unsigned char *payload = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)); - ddsi_serstate_append_blob (st, 1, fragchain->maxp1 - off, payload + off - fragchain->min); - off = fragchain->maxp1; - } - fragchain = fragchain->nextfrag; - } - } - return st; + struct ddsi_serdata *sd = ddsi_serdata_from_ser (topic, justkey ? SDK_KEY : SDK_DATA, fragchain, sz); + sd->statusinfo = statusinfo; + sd->timestamp = tstamp; + return sd; } -static serdata_t ddsi_serstate_fix_with_key (serstate_t st, const struct sertopic *topic, bool bswap) -{ - serdata_t sample = ddsi_serstate_fix(st); - dds_stream_t is; - assert(sample->v.keyhash.m_flags == 0); - sample->v.bswap = bswap; - dds_stream_from_serstate (&is, sample->v.st); - /* FIXME: the relationship between dds_topic, topic_descriptor and sertopic clearly needs some work */ - dds_stream_read_keyhash (&is, &sample->v.keyhash, topic->status_cb_entity->m_descriptor, sample->v.st->kind == STK_KEY); - return sample; -} - -static serdata_t extract_sample_from_data +static struct ddsi_serdata *extract_sample_from_data ( const struct nn_rsample_info *sampleinfo, unsigned char data_smhdr_flags, const nn_plist_t *qos, const struct nn_rdata *fragchain, unsigned statusinfo, - nn_wctime_t tstamp, struct sertopic const * const topic + nn_wctime_t tstamp, struct ddsi_sertopic const * const topic ) { static const nn_guid_t null_guid = {{{0,0,0,0,0,0,0,0,0,0,0,0}},{0}}; const char *failmsg = NULL; - serdata_t sample = NULL; + struct ddsi_serdata * sample = NULL; if (statusinfo == 0) { /* normal write */ - serstate_t st; if (!(data_smhdr_flags & DATA_FLAG_DATAFLAG) || sampleinfo->size == 0) { const struct proxy_writer *pwr = sampleinfo->pwr; @@ -1859,25 +1817,21 @@ static serdata_t extract_sample_from_data data_smhdr_flags, sampleinfo->size)); return NULL; } - st = make_raw_serstate (topic, fragchain, sampleinfo->size, 0, statusinfo, tstamp); - sample = ddsi_serstate_fix_with_key (st, topic, sampleinfo->bswap); + sample = get_serdata (topic, fragchain, sampleinfo->size, 0, statusinfo, tstamp); } else if (sampleinfo->size) { /* dispose or unregister with included serialized key or data (data is a PrismTech extension) -- i.e., dispose or unregister as one would expect to receive */ - serstate_t st; if (data_smhdr_flags & DATA_FLAG_KEYFLAG) { - st = make_raw_serstate (topic, fragchain, sampleinfo->size, 1, statusinfo, tstamp); - sample = ddsi_serstate_fix_with_key (st, topic, sampleinfo->bswap); + sample = get_serdata (topic, fragchain, sampleinfo->size, 1, statusinfo, tstamp); } else { assert (data_smhdr_flags & DATA_FLAG_DATAFLAG); - st = make_raw_serstate (topic, fragchain, sampleinfo->size, 0, statusinfo, tstamp); - sample = ddsi_serstate_fix_with_key (st, topic, sampleinfo->bswap); + sample = get_serdata (topic, fragchain, sampleinfo->size, 0, statusinfo, tstamp); } } else if (data_smhdr_flags & DATA_FLAG_INLINE_QOS) @@ -1890,12 +1844,9 @@ static serdata_t extract_sample_from_data failmsg = "qos present but without keyhash"; else { - serstate_t st; - st = ddsi_serstate_new (topic); - ddsi_serstate_set_msginfo (st, statusinfo, tstamp); - st->kind = STK_KEY; - ddsi_serstate_append_blob (st, 1, sizeof (qos->keyhash), qos->keyhash.value); - sample = ddsi_serstate_fix_with_key (st, topic, sampleinfo->bswap); + sample = ddsi_serdata_from_keyhash (topic, &qos->keyhash); + sample->statusinfo = statusinfo; + sample->timestamp = tstamp; } } else @@ -1943,20 +1894,17 @@ unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr, in } } - - - static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, int pwr_locked) { struct receiver_state const * const rst = sampleinfo->rst; struct proxy_writer * const pwr = sampleinfo->pwr; - struct sertopic const * const topic = pwr->c.topic; + struct ddsi_sertopic const * const topic = pwr->c.topic; unsigned statusinfo; Data_DataFrag_common_t *msg; unsigned char data_smhdr_flags; nn_plist_t qos; int need_keyhash; - serdata_t payload; + struct ddsi_serdata * payload; if (pwr->ddsi2direct_cb) { diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index 7808aa9..cbd8e39 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -32,7 +32,8 @@ #include "ddsi/q_hbcontrol.h" #include "ddsi/q_static_assert.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_sertopic.h" #include "ddsi/sysdeps.h" #include "dds__whc.h" @@ -394,13 +395,26 @@ void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_sta nn_xmsg_submsg_setnext (msg, sm_marker); } -static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struct serdata *serdata, struct nn_xmsg **pmsg) +static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struct ddsi_serdata *serdata, struct nn_xmsg **pmsg) { const size_t expected_inline_qos_size = 4+8+20+4 + 32; struct nn_xmsg_marker sm_marker; - const unsigned char contentflag = (ddsi_serdata_is_empty (serdata) ? 0 : ddsi_serdata_is_key (serdata) ? DATA_FLAG_KEYFLAG : DATA_FLAG_DATAFLAG); + unsigned char contentflag; Data_t *data; + switch (serdata->kind) + { + case SDK_EMPTY: + contentflag = 0; + break; + case SDK_KEY: + contentflag = DATA_FLAG_KEYFLAG; + break; + case SDK_DATA: + contentflag = DATA_FLAG_DATAFLAG; + break; + } + ASSERT_MUTEX_HELD (&wr->e.lock); if ((*pmsg = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, sizeof (InfoTimestamp_t) + sizeof (Data_t) + expected_inline_qos_size, NN_XMSG_KIND_DATA)) == NULL) @@ -413,7 +427,7 @@ static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struc nn_xmsg_setdstN (*pmsg, wr->as, wr->as_group); nn_xmsg_setmaxdelay (*pmsg, nn_from_ddsi_duration (wr->xqos->latency_budget.duration)); - nn_xmsg_add_timestamp (*pmsg, serdata->v.msginfo.timestamp); + nn_xmsg_add_timestamp (*pmsg, serdata->timestamp); data = nn_xmsg_append (*pmsg, &sm_marker, sizeof (Data_t)); nn_xmsg_submsg_init (*pmsg, sm_marker, SMID_DATA); @@ -430,8 +444,8 @@ static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struc /* Adding parameters means potential reallocing, so sm, ddcmn now likely become invalid */ if (wr->include_keyhash) nn_xmsg_addpar_keyhash (*pmsg, serdata); - if (serdata->v.msginfo.statusinfo) - nn_xmsg_addpar_statusinfo (*pmsg, serdata->v.msginfo.statusinfo); + if (serdata->statusinfo) + nn_xmsg_addpar_statusinfo (*pmsg, serdata->statusinfo); if (nn_xmsg_addpar_sentinel_ifparam (*pmsg) > 0) { data = nn_xmsg_submsg_from_marker (*pmsg, sm_marker); @@ -443,7 +457,7 @@ static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struc return 0; } -int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_plist *plist, struct serdata *serdata, unsigned fragnum, struct proxy_reader *prd, struct nn_xmsg **pmsg, int isnew) +int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_plist *plist, struct ddsi_serdata *serdata, unsigned fragnum, struct proxy_reader *prd, struct nn_xmsg **pmsg, int isnew) { /* We always fragment into FRAGMENT_SIZEd fragments, which are near the smallest allowed fragment size & can't be bothered (yet) to @@ -464,14 +478,15 @@ int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_pli void *sm; Data_DataFrag_common_t *ddcmn; int fragging; - unsigned fragstart, fraglen; + uint32_t fragstart, fraglen; enum nn_xmsg_kind xmsg_kind = isnew ? NN_XMSG_KIND_DATA : NN_XMSG_KIND_DATA_REXMIT; + const uint32_t size = ddsi_serdata_size (serdata); int ret = 0; (void)plist; ASSERT_MUTEX_HELD (&wr->e.lock); - if (fragnum * config.fragment_size >= ddsi_serdata_size (serdata) && ddsi_serdata_size (serdata) > 0) + if (fragnum * config.fragment_size >= size && size > 0) { /* This is the first chance to detect an attempt at retransmitting an non-existent fragment, which a malicious (or buggy) remote @@ -480,7 +495,7 @@ int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_pli return ERR_INVALID; } - fragging = (config.fragment_size < ddsi_serdata_size (serdata)); + fragging = (config.fragment_size < size); if ((*pmsg = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, sizeof (InfoTimestamp_t) + sizeof (DataFrag_t) + expected_inline_qos_size, xmsg_kind)) == NULL) return ERR_OUT_OF_MEMORY; @@ -509,7 +524,7 @@ int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_pli /* Timestamp only needed once, for the first fragment */ if (fragnum == 0) { - nn_xmsg_add_timestamp (*pmsg, serdata->v.msginfo.timestamp); + nn_xmsg_add_timestamp (*pmsg, serdata->timestamp); } sm = nn_xmsg_append (*pmsg, &sm_marker, fragging ? sizeof (DataFrag_t) : sizeof (Data_t)); @@ -517,13 +532,19 @@ int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_pli if (!fragging) { - const unsigned char contentflag = (ddsi_serdata_is_empty (serdata) ? 0 : ddsi_serdata_is_key (serdata) ? DATA_FLAG_KEYFLAG : DATA_FLAG_DATAFLAG); + unsigned char contentflag = 0; Data_t *data = sm; + switch (serdata->kind) + { + case SDK_EMPTY: contentflag = 0; break; + case SDK_KEY: contentflag = DATA_FLAG_KEYFLAG; break; + case SDK_DATA: contentflag = DATA_FLAG_DATAFLAG; break; + } nn_xmsg_submsg_init (*pmsg, sm_marker, SMID_DATA); ddcmn->smhdr.flags = (unsigned char) (ddcmn->smhdr.flags | contentflag); fragstart = 0; - fraglen = ddsi_serdata_size (serdata); + fraglen = size; ddcmn->octetsToInlineQos = (unsigned short) ((char*) (data+1) - ((char*) &ddcmn->octetsToInlineQos + 2)); if (wr->reliable) @@ -533,18 +554,18 @@ int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_pli { const unsigned char contentflag = set_smhdr_flags_asif_data - ? (ddsi_serdata_is_key (serdata) ? DATA_FLAG_KEYFLAG : DATA_FLAG_DATAFLAG) - : (ddsi_serdata_is_key (serdata) ? DATAFRAG_FLAG_KEYFLAG : 0); + ? (serdata->kind == SDK_KEY ? DATA_FLAG_KEYFLAG : DATA_FLAG_DATAFLAG) + : (serdata->kind == SDK_KEY ? DATAFRAG_FLAG_KEYFLAG : 0); DataFrag_t *frag = sm; /* empty means size = 0, which means it never needs fragmenting */ - assert (!ddsi_serdata_is_empty (serdata)); + assert (serdata->kind != SDK_EMPTY); nn_xmsg_submsg_init (*pmsg, sm_marker, SMID_DATA_FRAG); ddcmn->smhdr.flags = (unsigned char) (ddcmn->smhdr.flags | contentflag); frag->fragmentStartingNum = fragnum + 1; frag->fragmentsInSubmessage = 1; frag->fragmentSize = (unsigned short) config.fragment_size; - frag->sampleSize = ddsi_serdata_size (serdata); + frag->sampleSize = (uint32_t)size; fragstart = fragnum * config.fragment_size; #if MULTIPLE_FRAGS_IN_SUBMSG /* ugly hack for testing only */ @@ -555,8 +576,8 @@ int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_pli #endif fraglen = config.fragment_size * frag->fragmentsInSubmessage; - if (fragstart + fraglen > ddsi_serdata_size (serdata)) - fraglen = ddsi_serdata_size (serdata) - fragstart; + if (fragstart + fraglen > size) + fraglen = (uint32_t)(size - fragstart); ddcmn->octetsToInlineQos = (unsigned short) ((char*) (frag+1) - ((char*) &ddcmn->octetsToInlineQos + 2)); if (wr->reliable && (!isnew || fragstart + fraglen == ddsi_serdata_size (serdata))) @@ -588,9 +609,9 @@ int create_fragment_message (struct writer *wr, seqno_t seq, const struct nn_pli { nn_xmsg_addpar_keyhash (*pmsg, serdata); } - if (serdata->v.msginfo.statusinfo) + if (serdata->statusinfo) { - nn_xmsg_addpar_statusinfo (*pmsg, serdata->v.msginfo.statusinfo); + nn_xmsg_addpar_statusinfo (*pmsg, serdata->statusinfo); } rc = nn_xmsg_addpar_sentinel_ifparam (*pmsg); if (rc > 0) @@ -670,7 +691,7 @@ static int must_skip_frag (const char *frags_to_skip, unsigned frag) } #endif -static void transmit_sample_lgmsg_unlocked (struct nn_xpack *xp, struct writer *wr, const struct whc_state *whcst, seqno_t seq, const struct nn_plist *plist, serdata_t serdata, struct proxy_reader *prd, int isnew, unsigned nfrags) +static void transmit_sample_lgmsg_unlocked (struct nn_xpack *xp, struct writer *wr, const struct whc_state *whcst, seqno_t seq, const struct nn_plist *plist, struct ddsi_serdata *serdata, struct proxy_reader *prd, int isnew, unsigned nfrags) { unsigned i; #if 0 @@ -715,7 +736,7 @@ static void transmit_sample_lgmsg_unlocked (struct nn_xpack *xp, struct writer * struct nn_xmsg *msg = NULL; int hbansreq; os_mutexLock (&wr->e.lock); - msg = writer_hbcontrol_piggyback (wr, whcst, ddsi_serdata_twrite (serdata), nn_xpack_packetid (xp), &hbansreq); + msg = writer_hbcontrol_piggyback (wr, whcst, serdata->twrite, nn_xpack_packetid (xp), &hbansreq); os_mutexUnlock (&wr->e.lock); if (msg) { @@ -726,17 +747,17 @@ static void transmit_sample_lgmsg_unlocked (struct nn_xpack *xp, struct writer * } } -static void transmit_sample_unlocks_wr (struct nn_xpack *xp, struct writer *wr, const struct whc_state *whcst, seqno_t seq, const struct nn_plist *plist, serdata_t serdata, struct proxy_reader *prd, int isnew) +static void transmit_sample_unlocks_wr (struct nn_xpack *xp, struct writer *wr, const struct whc_state *whcst, seqno_t seq, const struct nn_plist *plist, struct ddsi_serdata *serdata, struct proxy_reader *prd, int isnew) { /* on entry: &wr->e.lock held; on exit: lock no longer held */ struct nn_xmsg *fmsg; - unsigned sz; + uint32_t sz; assert(xp); sz = ddsi_serdata_size (serdata); if (sz > config.fragment_size || !isnew || plist != NULL || prd != NULL) { - unsigned nfrags; + uint32_t nfrags; os_mutexUnlock (&wr->e.lock); nfrags = (sz + config.fragment_size - 1) / config.fragment_size; transmit_sample_lgmsg_unlocked (xp, wr, whcst, seq, plist, serdata, prd, isnew, nfrags); @@ -754,7 +775,7 @@ static void transmit_sample_unlocks_wr (struct nn_xpack *xp, struct writer *wr, /* Note: wr->heartbeat_xevent != NULL <=> wr is reliable */ if (wr->heartbeat_xevent) - hmsg = writer_hbcontrol_piggyback (wr, whcst, ddsi_serdata_twrite (serdata), nn_xpack_packetid (xp), &hbansreq); + hmsg = writer_hbcontrol_piggyback (wr, whcst, serdata->twrite, nn_xpack_packetid (xp), &hbansreq); else hmsg = NULL; @@ -767,9 +788,9 @@ static void transmit_sample_unlocks_wr (struct nn_xpack *xp, struct writer *wr, } } -int enqueue_sample_wrlock_held (struct writer *wr, seqno_t seq, const struct nn_plist *plist, serdata_t serdata, struct proxy_reader *prd, int isnew) +int enqueue_sample_wrlock_held (struct writer *wr, seqno_t seq, const struct nn_plist *plist, struct ddsi_serdata *serdata, struct proxy_reader *prd, int isnew) { - unsigned i, sz, nfrags; + uint32_t i, sz, nfrags; int enqueued = 1; ASSERT_MUTEX_HELD (&wr->e.lock); @@ -821,7 +842,7 @@ int enqueue_sample_wrlock_held (struct writer *wr, seqno_t seq, const struct nn_ return enqueued ? 0 : -1; } -static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist *plist, serdata_t serdata, struct tkmap_instance *tk) +static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) { /* returns: < 0 on error, 0 if no need to insert in whc, > 0 if inserted */ int do_insert, insres, res; @@ -839,9 +860,7 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist nn_log (LC_TRACE, "write_sample %x:%x:%x:%x #%"PRId64"", PGUID (wr->e.guid), seq); if (plist != 0 && (plist->present & PP_COHERENT_SET)) nn_log (LC_TRACE, " C#%"PRId64"", fromSN (plist->coherent_set_seqno)); - nn_log (LC_TRACE, ": ST%u %s/%s:%s%s\n", - serdata->v.msginfo.statusinfo, tname, ttname, - ppbuf, tmp < (int) sizeof (ppbuf) ? "" : " (trunc)"); + nn_log (LC_TRACE, ": ST%u %s/%s:%s%s\n", serdata->statusinfo, tname, ttname, ppbuf, tmp < (int) sizeof (ppbuf) ? "" : " (trunc)"); } assert (wr->reliable || have_reliable_subs (wr) == 0); @@ -999,7 +1018,7 @@ static int maybe_grow_whc (struct writer *wr) return 0; } -static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, serdata_t serdata, struct tkmap_instance *tk, int end_of_txn, int gc_allowed) +static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk, int end_of_txn, int gc_allowed) { int r; seqno_t seq; @@ -1061,7 +1080,7 @@ static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_p /* Always use the current monotonic time */ tnow = now_mt (); - ddsi_serdata_set_twrite (serdata, tnow); + serdata->twrite = tnow; seq = ++wr->seq; if (wr->cs_seq != 0) @@ -1135,17 +1154,17 @@ drop: return r; } -int write_sample_gc (struct nn_xpack *xp, struct writer *wr, serdata_t serdata, struct tkmap_instance *tk) +int write_sample_gc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk) { return write_sample_eot (xp, wr, NULL, serdata, tk, 0, 1); } -int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, serdata_t serdata, struct tkmap_instance *tk) +int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk) { return write_sample_eot (xp, wr, NULL, serdata, tk, 0, 0); } -int write_sample_gc_notk (struct nn_xpack *xp, struct writer *wr, serdata_t serdata) +int write_sample_gc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata) { struct tkmap_instance *tk; int res; @@ -1155,7 +1174,7 @@ int write_sample_gc_notk (struct nn_xpack *xp, struct writer *wr, serdata_t serd return res; } -int write_sample_nogc_notk (struct nn_xpack *xp, struct writer *wr, serdata_t serdata) +int write_sample_nogc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata) { struct tkmap_instance *tk; int res; diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index 932736a..97f7f6a 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -36,8 +36,8 @@ #include "ddsi/q_bitset.h" #include "ddsi/q_lease.h" #include "ddsi/q_xmsg.h" -#include "q__osplser.h" -#include "ddsi/ddsi_ser.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_serdata_default.h" #include "dds__whc.h" #include "ddsi/sysdeps.h" @@ -966,9 +966,6 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e struct proxy_reader *prd; struct writer *spdp_wr; struct whc_borrowed_sample sample; - serstate_t st; - serdata_t sd; - nn_guid_t kh; #ifndef NDEBUG bool sample_found; #endif @@ -977,6 +974,8 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e { TRACE (("handle_xevk_spdp %x:%x:%x:%x - unknown guid\n", PGUID (ev->u.spdp.pp_guid))); + if (ev->u.spdp.directed) + delete_xevent (ev); return; } @@ -984,6 +983,8 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e { TRACE (("handle_xevk_spdp %x:%x:%x:%x - spdp writer of participant not found\n", PGUID (ev->u.spdp.pp_guid))); + if (ev->u.spdp.directed) + delete_xevent (ev); return; } @@ -1005,15 +1006,21 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e } } - /* Look up data in (transient-local) WHC by key value */ - if ((st = ddsi_serstate_new (NULL)) == NULL) - { - TRACE (("xmit spdp: skip %x:%x:%x:%x: out of memory\n", PGUID (ev->u.spdp.pp_guid))); - goto skip; - } - kh = nn_hton_guid (ev->u.spdp.pp_guid); - serstate_set_key (st, 1, &kh); - sd = ddsi_serstate_fix (st); + /* Look up data in (transient-local) WHC by key value -- FIXME: clearly + a slightly more efficient and elegant way of looking up the key value + is to be preferred */ + nn_plist_t ps; + nn_plist_init_empty (&ps); + ps.present |= PP_PARTICIPANT_GUID; + ps.participant_guid = ev->u.spdp.pp_guid; + struct nn_xmsg *mpayload = nn_xmsg_new (gv.xmsgpool, &ev->u.spdp.pp_guid.prefix, 0, NN_XMSG_KIND_DATA); + nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0); + nn_xmsg_addpar_sentinel (mpayload); + nn_plist_fini (&ps); + struct ddsi_plist_sample plist_sample; + nn_xmsg_payload_to_plistsample (&plist_sample, PID_PARTICIPANT_GUID, mpayload); + struct ddsi_serdata *sd = ddsi_serdata_from_sample (gv.plist_topic, SDK_KEY, &plist_sample); + nn_xmsg_free (mpayload); os_mutexLock (&spdp_wr->e.lock); if (spdp_wr->whc->ops->borrow_sample_key (spdp_wr->whc, sd, &sample)) @@ -1120,8 +1127,7 @@ static void write_pmd_message (struct nn_xpack *xp, struct participant *pp, unsi ParticipantMessageData_t pmd; char pad[offsetof (ParticipantMessageData_t, value) + PMD_DATA_LENGTH]; } u; - serdata_t serdata; - serstate_t serstate; + struct ddsi_serdata *serdata; struct tkmap_instance *tk; if ((wr = get_builtin_writer (pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER)) == NULL) @@ -1135,16 +1141,14 @@ static void write_pmd_message (struct nn_xpack *xp, struct participant *pp, unsi u.pmd.length = PMD_DATA_LENGTH; memset (u.pmd.value, 0, u.pmd.length); - serstate = ddsi_serstate_new (NULL); - ddsi_serstate_append_blob (serstate, 4, sizeof (u.pad), &u.pmd); - serstate_set_key (serstate, 0, &u.pmd); - ddsi_serstate_set_msginfo (serstate, 0, now ()); - serdata = ddsi_serstate_fix (serstate); - - /* HORRIBLE HACK ALERT -- serstate/serdata looks at whether topic is - a null pointer to choose PL_CDR_x encoding or regular CDR_x - encoding. */ - serdata->hdr.identifier = PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE; + struct ddsi_rawcdr_sample raw = { + .blob = &u, + .size = offsetof (ParticipantMessageData_t, value) + PMD_DATA_LENGTH, + .key = &u.pmd, + .keysize = 16 + }; + serdata = ddsi_serdata_from_sample (gv.rawcdr_topic, SDK_DATA, &raw); + serdata->timestamp = now (); tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (serdata); write_sample_nogc (xp, wr, serdata, tk); diff --git a/src/core/ddsi/src/q_xmsg.c b/src/core/ddsi/src/q_xmsg.c index 034013b..c32a509 100644 --- a/src/core/ddsi/src/q_xmsg.c +++ b/src/core/ddsi/src/q_xmsg.c @@ -24,7 +24,6 @@ #include "util/ut_avl.h" #include "util/ut_thread_pool.h" -#include "ddsi/ddsi_ser.h" #include "ddsi/q_protocol.h" #include "ddsi/q_xqos.h" #include "ddsi/q_bswap.h" @@ -41,7 +40,7 @@ #include "ddsi/q_globals.h" #include "ddsi/q_ephash.h" #include "ddsi/q_freelist.h" -#include "q__osplser.h" +#include "ddsi/ddsi_serdata_default.h" #include "ddsi/sysdeps.h" @@ -73,7 +72,7 @@ struct nn_xmsg { size_t maxsz; size_t sz; int have_params; - struct serdata *refd_payload; + struct ddsi_serdata *refd_payload; ddsi_iovec_t refd_payload_iov; int64_t maxdelay; #ifdef DDSI_INCLUDE_NETWORK_PARTITIONS @@ -345,16 +344,16 @@ void nn_xmsg_free (struct nn_xmsg *m) { struct nn_xmsgpool *pool = m->pool; if (m->refd_payload) - { - ddsi_serdata_unref (m->refd_payload); - } + ddsi_serdata_to_ser_unref (m->refd_payload, &m->refd_payload_iov); if (m->dstmode == NN_XMSG_DST_ALL) { unref_addrset (m->dstaddr.all.as); unref_addrset (m->dstaddr.all.as_group); } if (!nn_freelist_push (&pool->freelist, m)) + { nn_xmsg_realfree (m); + } } /************************************************/ @@ -468,6 +467,13 @@ void *nn_xmsg_payload (size_t *sz, struct nn_xmsg *m) return m->data->payload; } +void nn_xmsg_payload_to_plistsample (struct ddsi_plist_sample *dst, nn_parameterid_t keyparam, const struct nn_xmsg *m) +{ + dst->blob = m->data->payload; + dst->size = m->sz; + dst->keyparam = keyparam; +} + void nn_xmsg_submsg_init (struct nn_xmsg *msg, struct nn_xmsg_marker marker, SubmessageKind_t smkind) { SubmessageHeader_t *hdr = (SubmessageHeader_t *) (msg->data->payload + marker.offset); @@ -554,15 +560,13 @@ void nn_xmsg_add_entityid (struct nn_xmsg * m) nn_xmsg_submsg_setnext (m, sm); } -void nn_xmsg_serdata (struct nn_xmsg *m, serdata_t serdata, size_t off, size_t len) +void nn_xmsg_serdata (struct nn_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len) { - if (!ddsi_serdata_is_empty (serdata)) + if (serdata->kind != SDK_EMPTY) { size_t len4 = align4u (len); assert (m->refd_payload == NULL); - m->refd_payload = ddsi_serdata_ref (serdata); - m->refd_payload_iov.iov_base = (char *) &m->refd_payload->hdr + off; - m->refd_payload_iov.iov_len = (ddsi_iov_len_t) len4; + m->refd_payload = ddsi_serdata_to_ser_ref (serdata, off, len4, &m->refd_payload_iov); } } @@ -889,12 +893,13 @@ void nn_xmsg_addpar_stringseq (struct nn_xmsg *m, unsigned pid, const nn_strings } } -void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct serdata *serdata) +void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct ddsi_serdata *serdata) { - if (!ddsi_serdata_is_empty (serdata)) + if (serdata->kind != SDK_EMPTY) { + const struct ddsi_serdata_default *serdata_def = (const struct ddsi_serdata_default *)serdata; char *p = nn_xmsg_addpar (m, PID_KEYHASH, 16); - memcpy (p, serdata->v.keyhash.m_hash, 16); + memcpy (p, serdata_def->keyhash.m_hash, 16); } } From 791a0efe7eea088512e1dc646c08dc70699fd541 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 26 Oct 2018 16:26:30 +0800 Subject: [PATCH 02/13] replace some implementation dependent types in protocol message specifications Signed-off-by: Erik Boasson --- src/core/ddsi/include/ddsi/q_protocol.h | 46 ++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/core/ddsi/include/ddsi/q_protocol.h b/src/core/ddsi/include/ddsi/q_protocol.h index 30371e0..d1243f0 100644 --- a/src/core/ddsi/include/ddsi/q_protocol.h +++ b/src/core/ddsi/include/ddsi/q_protocol.h @@ -29,19 +29,19 @@ extern "C" { #endif typedef struct { - unsigned char id[4]; + uint8_t id[4]; } nn_protocolid_t; typedef struct { - int high; - unsigned low; + int32_t high; + uint32_t low; } nn_sequence_number_t; #define NN_SEQUENCE_NUMBER_UNKNOWN_HIGH -1 #define NN_SEQUENCE_NUMBER_UNKNOWN_LOW 0 #define NN_SEQUENCE_NUMBER_UNKNOWN ((seqno_t) (((uint64_t)NN_SEQUENCE_NUMBER_UNKNOWN_HIGH << 32) | NN_SEQUENCE_NUMBER_UNKNOWN_LOW)) typedef struct nn_sequence_number_set { nn_sequence_number_t bitmap_base; - unsigned numbits; - unsigned bits[1]; + uint32_t numbits; + uint32_t bits[1]; } nn_sequence_number_set_t; /* Why strict C90? zero-length/flexible array members are far nicer */ /* SequenceNumberSet size is base (2 words) + numbits (1 word) + bitmap ((numbits+31)/32 words), and this at 4 bytes/word */ @@ -50,30 +50,30 @@ typedef struct nn_sequence_number_set { typedef unsigned nn_fragment_number_t; typedef struct nn_fragment_number_set { nn_fragment_number_t bitmap_base; - unsigned numbits; - unsigned bits[1]; + uint32_t numbits; + uint32_t bits[1]; } nn_fragment_number_set_t; /* FragmentNumberSet size is base (2 words) + numbits (1 word) + bitmap ((numbits+31)/32 words), and this at 4 bytes/word */ #define NN_FRAGMENT_NUMBER_SET_BITS_SIZE(numbits) ((unsigned) (4 * (((numbits) + 31) / 32))) #define NN_FRAGMENT_NUMBER_SET_SIZE(numbits) (offsetof (nn_fragment_number_set_t, bits) + NN_FRAGMENT_NUMBER_SET_BITS_SIZE (numbits)) -typedef int nn_count_t; +typedef int32_t nn_count_t; #define DDSI_COUNT_MIN (-2147483647 - 1) #define DDSI_COUNT_MAX (2147483647) /* address field in locator maintained in network byte order, the rest in host (yes: that's a FIXME) */ typedef struct { int32_t kind; - unsigned port; + uint32_t port; unsigned char address[16]; } nn_locator_t; typedef struct nn_udpv4mcgen_address { /* base IPv4 MC address is ipv4, host bits are bits base .. base+count-1, this machine is bit idx */ struct in_addr ipv4; - unsigned char base; - unsigned char count; - unsigned char idx; /* must be last: then sorting will put them consecutively */ + uint8_t base; + uint8_t count; + uint8_t idx; /* must be last: then sorting will put them consecutively */ } nn_udpv4mcgen_address_t; @@ -162,9 +162,9 @@ typedef struct Header { #define RTPS_MESSAGE_HEADER_SIZE (sizeof (Header_t)) typedef struct SubmessageHeader { - unsigned char submessageId; - unsigned char flags; - unsigned short octetsToNextHeader; + uint8_t submessageId; + uint8_t flags; + uint16_t octetsToNextHeader; } SubmessageHeader_t; #define RTPS_SUBMESSAGE_HEADER_SIZE (sizeof (SubmessageHeader_t)) #define SMFLAG_ENDIANNESS 0x01u @@ -223,14 +223,14 @@ typedef struct InfoSRC { typedef unsigned short nn_parameterid_t; /* spec says short */ typedef struct nn_parameter { nn_parameterid_t parameterid; - unsigned short length; /* spec says short */ + uint16_t length; /* spec says signed short */ /* char value[]; O! how I long for C99 */ } nn_parameter_t; typedef struct Data_DataFrag_common { SubmessageHeader_t smhdr; - unsigned short extraFlags; - unsigned short octetsToInlineQos; + uint16_t extraFlags; + uint16_t octetsToInlineQos; nn_entityid_t readerId; nn_entityid_t writerId; nn_sequence_number_t writerSN; @@ -246,9 +246,9 @@ typedef struct Data { typedef struct DataFrag { Data_DataFrag_common_t x; nn_fragment_number_t fragmentStartingNum; - unsigned short fragmentsInSubmessage; - unsigned short fragmentSize; - unsigned sampleSize; + uint16_t fragmentsInSubmessage; + uint16_t fragmentSize; + uint32_t sampleSize; } DataFrag_t; #define DATAFRAG_FLAG_INLINE_QOS 0x02u #define DATAFRAG_FLAG_KEYFLAG 0x04u @@ -339,8 +339,8 @@ typedef union Submessage { typedef struct ParticipantMessageData { nn_guid_prefix_t participantGuidPrefix; - unsigned kind; /* really 4 octets */ - unsigned length; + uint32_t kind; /* really 4 octets */ + uint32_t length; char value[1 /* length */]; } ParticipantMessageData_t; #define PARTICIPANT_MESSAGE_DATA_KIND_UNKNOWN 0x0u From e841e4bf9428820a65024abd57f1fb767b168fa0 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 26 Oct 2018 20:05:18 +0800 Subject: [PATCH 03/13] add back in the broken filter and query condition support the implementation was and is terrible, but without it too many tests fail Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds__types.h | 8 +++++ src/core/ddsc/src/dds_querycond.c | 16 --------- src/core/ddsc/src/dds_rhc.c | 41 ++++++++++-------------- src/core/ddsc/src/dds_topic.c | 19 +++-------- src/core/ddsc/src/dds_write.c | 13 +++----- src/core/ddsi/src/ddsi_serdata_default.c | 11 ++----- 6 files changed, 37 insertions(+), 71 deletions(-) diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index 07d73c6..4821c76 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -200,12 +200,20 @@ typedef struct dds_writer } dds_writer; +#ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED +#define DDS_TOPIC_INTERN_FILTER_FN_DEFINED +typedef bool (*dds_topic_intern_filter_fn) (const void * sample, void *ctx); +#endif + typedef struct dds_topic { struct dds_entity m_entity; struct ddsi_sertopic * m_stopic; const dds_topic_descriptor_t * m_descriptor; + dds_topic_intern_filter_fn filter_fn; + void * filter_ctx; + /* Status metrics */ dds_inconsistent_topic_status_t m_inconsistent_topic_status; diff --git a/src/core/ddsc/src/dds_querycond.c b/src/core/ddsc/src/dds_querycond.c index 7551539..efc2d41 100644 --- a/src/core/ddsc/src/dds_querycond.c +++ b/src/core/ddsc/src/dds_querycond.c @@ -27,11 +27,9 @@ dds_create_querycondition( _In_ uint32_t mask, _In_ dds_querycondition_filter_fn filter) { - dds_entity_t topic; dds_entity_t hdl; dds__retcode_t rc; dds_reader *r; - dds_topic *t; DDS_REPORT_STACK(); @@ -41,21 +39,7 @@ dds_create_querycondition( assert(cond); hdl = cond->m_entity.m_hdl; cond->m_query.m_filter = filter; - topic = r->m_topic->m_entity.m_hdl; dds_reader_unlock(r); - rc = dds_topic_lock(topic, &t); - if (rc == DDS_RETCODE_OK) { - abort(); -#if 0 - if (t->m_stopic->filter_sample == NULL) { - t->m_stopic->filter_sample = dds_alloc(t->m_descriptor->m_size); - } -#endif - dds_topic_unlock(t); - } else { - (void)dds_delete(hdl); - hdl = DDS_ERRNO(rc, "Error occurred on locking topic"); - } } else { hdl = DDS_ERRNO(rc, "Error occurred on locking reader"); } diff --git a/src/core/ddsc/src/dds_rhc.c b/src/core/ddsc/src/dds_rhc.c index bea7ec7..9e8f587 100644 --- a/src/core/ddsc/src/dds_rhc.c +++ b/src/core/ddsc/src/dds_rhc.c @@ -663,16 +663,19 @@ static bool add_sample return true; } -static bool content_filter_accepts (const struct ddsi_sertopic * topic, const struct ddsi_serdata *sample) +static bool content_filter_accepts (const struct ddsi_sertopic * sertopic, const struct ddsi_serdata *sample) { bool ret = true; -#if 0 /* FIXME: content filter */ - if (topic->filter_fn) + const struct dds_topic *tp = sertopic->status_cb_entity; + if (tp->filter_fn) { - deserialize_into ((char*) topic->filter_sample, sample); - ret = (topic->filter_fn) (topic->filter_sample, topic->filter_ctx); + const dds_topic_descriptor_t * desc = tp->m_descriptor; + char tmp[desc->m_size]; + memset (tmp, 0, sizeof (tmp)); + ddsi_serdata_to_sample (sample, tmp, NULL, NULL); + ret = (tp->filter_fn) (tmp, tp->filter_ctx); + dds_sample_free(tmp, desc, DDS_FREE_CONTENTS_BIT); } -#endif return ret; } @@ -2179,9 +2182,9 @@ static bool update_conditions_locked dds_readcond * iter; int m_pre; int m_post; -#if 0 /* FIXME: content filter, query cond */ - bool deserialised = (rhc->topic->filter_fn != NULL); -#endif + bool deserialised = (rhc->topic->status_cb_entity->filter_fn != 0); + const struct dds_topic_descriptor *desc = rhc->topic->status_cb_entity->m_descriptor; + char tmp[desc->m_size]; TRACE (("update_conditions_locked(%p) - inst %u nonempty %u disp %u nowr %u new %u samples %u read %u\n", (void *) rhc, rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed, @@ -2224,17 +2227,17 @@ static bool update_conditions_locked } else if (m_pre < m_post) { -#if 0 /* FIXME: content filter, query cond */ if (sample && !deserialised && (dds_entity_kind(iter->m_entity.m_hdl) == DDS_KIND_COND_QUERY)) { - deserialize_into ((char*)rhc->topic->filter_sample, sample); + memset (tmp, 0, sizeof (tmp)); + ddsi_serdata_to_sample (sample, tmp, NULL, NULL); deserialised = true; } if ( (sample == NULL) || (dds_entity_kind(iter->m_entity.m_hdl) != DDS_KIND_COND_QUERY) - || (iter->m_query.m_filter != NULL && iter->m_query.m_filter (rhc->topic->filter_sample)) + || (iter->m_query.m_filter != NULL && iter->m_query.m_filter (tmp)) ) { TRACE (("now matches")); @@ -2244,18 +2247,6 @@ static bool update_conditions_locked trigger = true; } } -#else - assert (dds_entity_kind(iter->m_entity.m_hdl) != DDS_KIND_COND_QUERY); - if (sample == NULL) - { - TRACE (("now matches")); - if (iter->m_entity.m_trigger++ == 0) - { - TRACE ((" (cond now triggers)")); - trigger = true; - } - } -#endif } else { @@ -2273,6 +2264,8 @@ static bool update_conditions_locked iter = iter->m_rhc_next; } + if (deserialised) + dds_sample_free (tmp, desc, DDS_FREE_CONTENTS_BIT); return trigger; } diff --git a/src/core/ddsc/src/dds_topic.c b/src/core/ddsc/src/dds_topic.c index bc79f26..a1684f5 100644 --- a/src/core/ddsc/src/dds_topic.c +++ b/src/core/ddsc/src/dds_topic.c @@ -502,28 +502,20 @@ dds_topic_mod_filter( void **ctx, bool set) { -#if 0 /* FIXME: content filter */ dds_topic *t; if (dds_topic_lock(topic, &t) == DDS_RETCODE_OK) { if (set) { - t->m_stopic->filter_fn = *filter; - t->m_stopic->filter_ctx = *ctx; - - /* Create sample for read filtering */ - - if (t->m_stopic->filter_sample == NULL) { - t->m_stopic->filter_sample = dds_alloc (t->m_descriptor->m_size); - } + t->filter_fn = *filter; + t->filter_ctx = *ctx; } else { - *filter = t->m_stopic->filter_fn; - *ctx = t->m_stopic->filter_ctx; + *filter = t->filter_fn; + *ctx = t->filter_ctx; } dds_topic_unlock(t); } else { *filter = 0; *ctx = NULL; } -#endif } _Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC) @@ -545,8 +537,7 @@ dds_topic_get_filter( dds_topic_intern_filter_fn filter; void *ctx; dds_topic_mod_filter (topic, &filter, &ctx, false); - return - (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn)ctx : 0; + return (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn)ctx : 0; } void diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 545a061..50a8fd1 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -198,14 +198,12 @@ dds_write_impl( return DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "No data buffer provided"); } -#if 0 /* FIXME: content filter */ /* Check for topic filter */ - if (ddsi_wr->topic->filter_fn && ! writekey) { - if (!(ddsi_wr->topic->filter_fn) (data, ddsi_wr->topic->filter_ctx)) { - return DDS_RECTODE_OK; + if (wr->m_topic->filter_fn && ! writekey) { + if (!(wr->m_topic->filter_fn) (data, wr->m_topic->filter_ctx)) { + return DDS_RETCODE_OK; } } -#endif if (asleep) { thread_state_awake (thr); @@ -265,12 +263,9 @@ dds_writecdr_impl( struct writer * ddsi_wr = wr->m_wr; struct tkmap_instance * tk; -#if 0 /* FIXME: content filter */ - /* Check for topic filter */ - if (ddsi_wr->topic->filter_fn && ! writekey) { + if (wr->m_topic->filter_fn) { abort(); } -#endif if (asleep) { thread_state_awake (thr); diff --git a/src/core/ddsi/src/ddsi_serdata_default.c b/src/core/ddsi/src/ddsi_serdata_default.c index 4bb6012..e050c8a 100644 --- a/src/core/ddsi/src/ddsi_serdata_default.c +++ b/src/core/ddsi/src/ddsi_serdata_default.c @@ -78,11 +78,6 @@ static size_t alignup_size (size_t x, size_t a) return (x+m) & ~m; } -static size_t alignup4 (size_t x) -{ - return alignup_size (x, 4); -} - void * ddsi_serstate_append (struct serstate * st, size_t n) { char *p; @@ -378,7 +373,7 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi /* if we're it is supposed to be just a key, rawkey must be be the first field and followed only by a sentinel */ assert (kind != SDK_KEY || rawkey == (const unsigned char *)sample->blob + sizeof (nn_parameter_t)); - assert (kind != SDK_KEY || sample->size == sizeof (nn_parameter_t) + alignup4 (keysize) + sizeof (nn_parameter_t)); + assert (kind != SDK_KEY || sample->size == sizeof (nn_parameter_t) + alignup_size (keysize, 4) + sizeof (nn_parameter_t)); return fix_serdata_default (d, tp->c.iid); } @@ -404,7 +399,7 @@ static void serdata_default_to_ser (const struct ddsi_serdata *serdata_common, s { const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; assert (off < d->pos + sizeof(struct CDRHeader)); - assert (sz <= alignup4 (d->pos + sizeof(struct CDRHeader)) - off); + assert (sz <= alignup_size (d->pos + sizeof(struct CDRHeader), 4) - off); /* FIXME: maybe I should pull the header out ... */ memcpy (buf, (char *)&d->hdr + off, sz); } @@ -413,7 +408,7 @@ static struct ddsi_serdata *serdata_default_to_ser_ref (const struct ddsi_serdat { const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; assert (off < d->pos + sizeof(struct CDRHeader)); - assert (sz <= alignup4 (d->pos + sizeof(struct CDRHeader)) - off); + assert (sz <= alignup_size (d->pos + sizeof(struct CDRHeader), 4) - off); ref->iov_base = (char *)&d->hdr + off; ref->iov_len = sz; return ddsi_serdata_ref(serdata_common); From fd931a26054f3a4018b621860151ba725c17c30a Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 26 Oct 2018 20:32:47 +0800 Subject: [PATCH 04/13] remove accidental return statement on the return of a void function Signed-off-by: Erik Boasson --- src/core/ddsi/include/ddsi/ddsi_serdata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata.h b/src/core/ddsi/include/ddsi/ddsi_serdata.h index 71ef1d8..8511dff 100644 --- a/src/core/ddsi/include/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata.h @@ -132,7 +132,7 @@ inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertopic } inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf) { - return d->ops->to_ser (d, off, sz, buf); + d->ops->to_ser (d, off, sz, buf); } inline struct ddsi_serdata *ddsi_serdata_to_ser_ref (const struct ddsi_serdata *d, size_t off, size_t sz, ddsi_iovec_t *ref) { From 8e20ae547ee5b541484a04402e8445ce0ad95c2b Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 26 Oct 2018 20:34:35 +0800 Subject: [PATCH 05/13] avoid declaring an array on stack with non-constant size Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_rhc.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/core/ddsc/src/dds_rhc.c b/src/core/ddsc/src/dds_rhc.c index 9e8f587..28d769b 100644 --- a/src/core/ddsc/src/dds_rhc.c +++ b/src/core/ddsc/src/dds_rhc.c @@ -670,11 +670,12 @@ static bool content_filter_accepts (const struct ddsi_sertopic * sertopic, const if (tp->filter_fn) { const dds_topic_descriptor_t * desc = tp->m_descriptor; - char tmp[desc->m_size]; - memset (tmp, 0, sizeof (tmp)); + char *tmp = os_malloc (desc->m_size); + memset (tmp, 0, desc->m_size); ddsi_serdata_to_sample (sample, tmp, NULL, NULL); ret = (tp->filter_fn) (tmp, tp->filter_ctx); dds_sample_free(tmp, desc, DDS_FREE_CONTENTS_BIT); + os_free (tmp); } return ret; } @@ -2182,9 +2183,8 @@ static bool update_conditions_locked dds_readcond * iter; int m_pre; int m_post; - bool deserialised = (rhc->topic->status_cb_entity->filter_fn != 0); const struct dds_topic_descriptor *desc = rhc->topic->status_cb_entity->m_descriptor; - char tmp[desc->m_size]; + char *tmp = NULL; TRACE (("update_conditions_locked(%p) - inst %u nonempty %u disp %u nowr %u new %u samples %u read %u\n", (void *) rhc, rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed, @@ -2227,11 +2227,11 @@ static bool update_conditions_locked } else if (m_pre < m_post) { - if (sample && !deserialised && (dds_entity_kind(iter->m_entity.m_hdl) == DDS_KIND_COND_QUERY)) + if (sample && tmp == NULL && (dds_entity_kind(iter->m_entity.m_hdl) == DDS_KIND_COND_QUERY)) { - memset (tmp, 0, sizeof (tmp)); + tmp = os_malloc (desc->m_size); + memset (tmp, 0, desc->m_size); ddsi_serdata_to_sample (sample, tmp, NULL, NULL); - deserialised = true; } if ( @@ -2264,8 +2264,11 @@ static bool update_conditions_locked iter = iter->m_rhc_next; } - if (deserialised) + if (tmp) + { dds_sample_free (tmp, desc, DDS_FREE_CONTENTS_BIT); + os_free (tmp); + } return trigger; } From 9cab5e769cd0f29248f333605476eb21c082f764 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Sun, 28 Oct 2018 13:28:23 +0800 Subject: [PATCH 06/13] various interconnected changes for ddsi_serdata - topic-erased key-only serdata for use in tkmap - restoration of including key values in invalid samples - special handling of keyless topics - keyhash generation via streams - elimination of dynamically allocated buffers in keyhash - removal of the last vestiges of "serstate" Signed-off-by: Erik Boasson --- .../ddsc/include/ddsc/dds_public_stream.h | 4 +- src/core/ddsc/src/dds__stream.h | 1 + src/core/ddsc/src/dds__tkmap.h | 2 +- src/core/ddsc/src/dds_instance.c | 6 +- src/core/ddsc/src/dds_key.c | 138 +++----- src/core/ddsc/src/dds_rhc.c | 28 +- src/core/ddsc/src/dds_stream.c | 162 +++++----- src/core/ddsc/src/dds_tkmap.c | 23 +- src/core/ddsc/src/dds_topic.c | 3 +- src/core/ddsi/include/ddsi/ddsi_serdata.h | 21 +- .../ddsi/include/ddsi/ddsi_serdata_default.h | 28 +- src/core/ddsi/include/ddsi/ddsi_sertopic.h | 2 + src/core/ddsi/include/ddsi/q_globals.h | 4 +- src/core/ddsi/src/ddsi_serdata.c | 3 +- src/core/ddsi/src/ddsi_serdata_default.c | 296 ++++++++++-------- src/core/ddsi/src/ddsi_sertopic.c | 15 + src/core/ddsi/src/q_init.c | 9 +- src/core/ddsi/src/q_receive.c | 3 +- src/core/ddsi/src/q_transmit.c | 10 + 19 files changed, 375 insertions(+), 383 deletions(-) diff --git a/src/core/ddsc/include/ddsc/dds_public_stream.h b/src/core/ddsc/include/ddsc/dds_public_stream.h index f729ff6..ef125c8 100644 --- a/src/core/ddsc/include/ddsc/dds_public_stream.h +++ b/src/core/ddsc/include/ddsc/dds_public_stream.h @@ -90,7 +90,9 @@ DDS_EXPORT void dds_stream_write_uint64 (dds_stream_t * os, uint64_t val); DDS_EXPORT void dds_stream_write_float (dds_stream_t * os, float val); DDS_EXPORT void dds_stream_write_double (dds_stream_t * os, double val); DDS_EXPORT void dds_stream_write_string (dds_stream_t * os, const char * val); -DDS_EXPORT void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, uint8_t * buffer); +DDS_EXPORT void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, const uint8_t * buffer); +DDS_EXPORT void *dds_stream_address (dds_stream_t * s); +DDS_EXPORT void *dds_stream_alignto (dds_stream_t * s, uint32_t a); #define dds_stream_write_char(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v))) #define dds_stream_write_int8(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v))) diff --git a/src/core/ddsc/src/dds__stream.h b/src/core/ddsc/src/dds__stream.h index 47da8c4..56350b9 100644 --- a/src/core/ddsc/src/dds__stream.h +++ b/src/core/ddsc/src/dds__stream.h @@ -37,6 +37,7 @@ void dds_stream_from_serdata_default (dds_stream_t * s, const struct ddsi_serdat void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d); void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic); +void dds_stream_read_sample_write_key (dds_stream_t *os, dds_stream_t *is, const struct ddsi_sertopic_default *topic); void dds_stream_read_key ( dds_stream_t * is, diff --git a/src/core/ddsc/src/dds__tkmap.h b/src/core/ddsc/src/dds__tkmap.h index 613fb51..c25be3e 100644 --- a/src/core/ddsc/src/dds__tkmap.h +++ b/src/core/ddsc/src/dds__tkmap.h @@ -36,7 +36,7 @@ struct tkmap * dds_tkmap_new (void); void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap *tkmap); void dds_tkmap_instance_ref (_In_ struct tkmap_instance *tk); uint64_t dds_tkmap_lookup (_In_ struct tkmap *tkmap, _In_ const struct ddsi_serdata *serdata); -_Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample); +_Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample); _Check_return_ struct tkmap_instance * dds_tkmap_find( _In_ struct ddsi_serdata * sd, _In_ const bool rd, diff --git a/src/core/ddsc/src/dds_instance.c b/src/core/ddsc/src/dds_instance.c index f0736ae..8d43026 100644 --- a/src/core/ddsc/src/dds_instance.c +++ b/src/core/ddsc/src/dds_instance.c @@ -285,7 +285,7 @@ dds_unregister_instance_ih_ts( map = gv.m_tkmap; topic = dds_instance_info((dds_entity*)wr); sample = dds_alloc (topic->m_descriptor->m_size); - if (dds_tkmap_get_key (map, handle, sample)) { + if (dds_tkmap_get_key (map, topic->m_stopic, handle, sample)) { ret = dds_write_impl ((dds_writer*)wr, sample, timestamp, action); } else{ ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided handle is found"); @@ -383,7 +383,7 @@ dds_dispose_ih_ts( struct tkmap *map = gv.m_tkmap; const dds_topic *topic = dds_instance_info((dds_entity*)wr); void *sample = dds_alloc (topic->m_descriptor->m_size); - if (dds_tkmap_get_key (map, handle, sample)) { + if (dds_tkmap_get_key (map, topic->m_stopic, handle, sample)) { ret = dds_dispose_impl(wr, sample, handle, timestamp); } else { ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided handle is found"); @@ -455,7 +455,7 @@ dds_instance_get_key( } memset (data, 0, topic->m_descriptor->m_size); - if (dds_tkmap_get_key (map, inst, data)) { + if (dds_tkmap_get_key (map, topic->m_stopic, inst, data)) { ret = DDS_RETCODE_OK; } else{ ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided entity is found"); diff --git a/src/core/ddsc/src/dds_key.c b/src/core/ddsc/src/dds_key.c index 2bd804b..a7652c2 100644 --- a/src/core/ddsc/src/dds_key.c +++ b/src/core/ddsc/src/dds_key.c @@ -20,94 +20,21 @@ #ifndef NDEBUG static bool keyhash_is_reset(const dds_key_hash_t *kh) { - static const char nullhash[sizeof(kh->m_hash)] = { 0 }; - return kh->m_flags == 0 && memcmp(kh->m_hash, nullhash, sizeof(nullhash)) == 0; + return !kh->m_set; } #endif -void dds_key_md5 (dds_key_hash_t * kh) -{ - md5_state_t md5st; - md5_init (&md5st); - md5_append (&md5st, (md5_byte_t*) kh->m_key_buff, kh->m_key_len); - md5_finish (&md5st, (unsigned char *) kh->m_hash); -} - /* dds_key_gen: Generates key and keyhash for a sample. See section 9.6.3.3 of DDSI spec. */ -void dds_key_gen -( - const dds_topic_descriptor_t * const desc, - dds_key_hash_t * kh, - const char * sample -) +static void dds_key_gen_stream (const dds_topic_descriptor_t * const desc, dds_stream_t *os, const char *sample) { const char * src; const uint32_t * op; uint32_t i; uint32_t len = 0; - char * dst; - - assert(keyhash_is_reset(kh)); - - if (desc->m_nkeys == 0) - { - kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH; - kh->m_key_len = sizeof (kh->m_hash); - return; - } - - kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET; - - /* Select key buffer to use */ - - if (desc->m_flagset & DDS_TOPIC_FIXED_KEY) - { - kh->m_flags |= DDS_KEY_IS_HASH; - kh->m_key_len = sizeof (kh->m_hash); - dst = kh->m_hash; - } - else - { - /* Calculate key length */ - - for (i = 0; i < desc->m_nkeys; i++) - { - op = desc->m_ops + desc->m_keys[i].m_index; - src = sample + op[1]; - - switch (DDS_OP_TYPE (*op)) - { - case DDS_OP_VAL_1BY: len += 1; break; - case DDS_OP_VAL_2BY: len += 2; break; - case DDS_OP_VAL_4BY: len += 4; break; - case DDS_OP_VAL_8BY: len += 8; break; - case DDS_OP_VAL_STR: - src = *((char**) src); - /* FALLS THROUGH */ - case DDS_OP_VAL_BST: - len += (uint32_t) (5 + strlen (src)); - break; - case DDS_OP_VAL_ARR: - len += op[2] * dds_op_size[DDS_OP_SUBTYPE (*op)]; - break; - default: assert (0); - } - } - - kh->m_key_len = len; - if (len > kh->m_key_buff_size) - { - kh->m_key_buff = dds_realloc_zero (kh->m_key_buff, len); - kh->m_key_buff_size = len; - } - dst = kh->m_key_buff; - } - - /* Write keys to buffer (Big Endian CDR encoded with no padding) */ for (i = 0; i < desc->m_nkeys; i++) { @@ -119,29 +46,22 @@ void dds_key_gen { case DDS_OP_VAL_1BY: { - *dst = *src; - dst++; + dds_stream_write_uint8 (os, *((const uint8_t *) src)); break; } case DDS_OP_VAL_2BY: { - uint16_t u16 = toBE2u (*((const uint16_t*) src)); - memcpy (dst, &u16, sizeof (u16)); - dst += sizeof (u16); + dds_stream_write_uint16 (os, *((const uint16_t *) src)); break; } case DDS_OP_VAL_4BY: { - uint32_t u32 = toBE4u (*((const uint32_t*) src)); - memcpy (dst, &u32, sizeof (u32)); - dst += sizeof (u32); + dds_stream_write_uint32 (os, *((const uint32_t *) src)); break; } case DDS_OP_VAL_8BY: { - uint64_t u64 = toBE8u (*((const uint64_t*) src)); - memcpy (dst, &u64, sizeof (u64)); - dst += sizeof (u64); + dds_stream_write_uint64 (os, *((const uint64_t *) src)); break; } case DDS_OP_VAL_STR: @@ -151,35 +71,55 @@ void dds_key_gen /* FALLS THROUGH */ case DDS_OP_VAL_BST: { - uint32_t u32; len = (uint32_t) (strlen (src) + 1); - u32 = toBE4u (len); - memcpy (dst, &u32, sizeof (u32)); - dst += sizeof (u32); - memcpy (dst, src, len); - dst += len; + dds_stream_write_uint32 (os, len); + dds_stream_write_buffer (os, len, (const uint8_t *) src); break; } case DDS_OP_VAL_ARR: { uint32_t size = dds_op_size[DDS_OP_SUBTYPE (*op)]; + char *dst; len = size * op[2]; - memcpy (dst, src, len); + dst = dds_stream_alignto (os, op[2]); + dds_stream_write_buffer (os, len, (const uint8_t *) src); if (dds_stream_endian () && (size != 1u)) - { dds_stream_swap (dst, size, op[2]); - } - dst += len; break; } default: assert (0); } } +} - /* Hash is md5 of key */ +void dds_key_gen (const dds_topic_descriptor_t * const desc, dds_key_hash_t * kh, const char * sample) +{ + assert(keyhash_is_reset(kh)); - if ((kh->m_flags & DDS_KEY_IS_HASH) == 0) + kh->m_set = 1; + if (desc->m_nkeys == 0) + kh->m_iskey = 1; + else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY) { - dds_key_md5 (kh); + dds_stream_t os; + kh->m_iskey = 1; + dds_stream_init(&os, 0); + os.m_endian = 0; + os.m_buffer.pv = kh->m_hash; + os.m_size = 16; + dds_key_gen_stream (desc, &os, sample); + } + else + { + dds_stream_t os; + md5_state_t md5st; + kh->m_iskey = 0; + dds_stream_init(&os, 64); + os.m_endian = 0; + dds_key_gen_stream (desc, &os, sample); + md5_init (&md5st); + md5_append (&md5st, os.m_buffer.p8, os.m_index); + md5_finish (&md5st, (unsigned char *) kh->m_hash); + dds_stream_fini (&os); } } diff --git a/src/core/ddsc/src/dds_rhc.c b/src/core/ddsc/src/dds_rhc.c index 28d769b..b9d9cb5 100644 --- a/src/core/ddsc/src/dds_rhc.c +++ b/src/core/ddsc/src/dds_rhc.c @@ -149,11 +149,11 @@ static const status_cb_data_t dds_rhc_data_avail_cb_data = { DDS_DATA_AVAILABLE_STATUS, 0, 0, true }; -/* FIXME: populate tkmap with key-only derived serdata, with timestamp - set to invalid. An invalid timestamp is (logically) unordered with - respect to valid timestamps, and that would mean BY_SOURCE order - would be respected even when generating an invalid sample for an - unregister message using the tkmap data. */ +/* FIXME: tkmap should perhaps retain data with timestamp set to invalid + An invalid timestamp is (logically) unordered with respect to valid + timestamps, and that would mean BY_SOURCE order could be respected + even when generating an invalid sample for an unregister message using + the tkmap data. */ /****************************** ****** LIVE WRITERS ****** @@ -1632,12 +1632,7 @@ static int dds_rhc_read_w_qminv { bool trigger_waitsets = false; uint32_t n = 0; -#if 0 - const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) rhc->topic->type; -#else /* FIXME: hack hack -- deserialize_into */ - const struct ddsi_sertopic_default *sertopic_def = (const struct ddsi_sertopic_default *)rhc->topic; - const struct dds_topic_descriptor * desc = sertopic_def->type; -#endif + const struct dds_topic_descriptor * desc = rhc->topic->status_cb_entity->m_descriptor; if (lock) { @@ -1707,7 +1702,7 @@ static int dds_rhc_read_w_qminv if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0) { set_sample_info_invsample (info_seq + n, inst); - ddsi_serdata_to_sample (inst->tk->m_sample, values[n], 0, 0); + ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0); if (!inst->inv_isread) { inst->inv_isread = 1; @@ -1765,12 +1760,7 @@ static int dds_rhc_take_w_qminv bool trigger_waitsets = false; uint64_t iid; uint32_t n = 0; -#if 0 - const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) rhc->topic->type; -#else /* FIXME: hack hack -- deserialize_into */ - const struct ddsi_sertopic_default *sertopic_def = (const struct ddsi_sertopic_default *)rhc->topic; - const struct dds_topic_descriptor * desc = sertopic_def->type; -#endif + const struct dds_topic_descriptor * desc = rhc->topic->status_cb_entity->m_descriptor; if (lock) { @@ -1859,7 +1849,7 @@ static int dds_rhc_take_w_qminv if (inst->inv_exists && n < max_samples && (QMASK_OF_INVSAMPLE (inst) & qminv) == 0) { set_sample_info_invsample (info_seq + n, inst); - ddsi_serdata_to_sample (inst->tk->m_sample, values[n], 0, 0); + ddsi_serdata_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0); inst_clear_invsample (rhc, inst); ++n; } diff --git a/src/core/ddsc/src/dds_stream.c b/src/core/ddsc/src/dds_stream.c index cd429a3..e7371d2 100644 --- a/src/core/ddsc/src/dds_stream.c +++ b/src/core/ddsc/src/dds_stream.c @@ -17,12 +17,12 @@ #include "dds__key.h" #include "dds__alloc.h" #include "os/os.h" +#include "ddsi/q_md5.h" + +//#define OP_DEBUG_READ 1 +//#define OP_DEBUG_WRITE 1 +//#define OP_DEBUG_KEY 1 -/* -#define OP_DEBUG_READ 1 -#define OP_DEBUG_WRITE 1 -#define OP_DEBUG_KEY 1 -*/ #if defined OP_DEBUG_WRITE || defined OP_DEBUG_READ || defined OP_DEBUG_KEY static const char * stream_op_type[11] = @@ -452,11 +452,22 @@ void dds_stream_write_string (dds_stream_t * os, const char * val) } } -void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, uint8_t * buffer) +void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, const uint8_t * buffer) { DDS_OS_PUT_BYTES (os, buffer, len); } +void *dds_stream_address (dds_stream_t * s) +{ + return DDS_CDR_ADDRESS(s, void); +} + +void *dds_stream_alignto (dds_stream_t * s, uint32_t a) +{ + DDS_CDR_ALIGNTO (s, a); + return DDS_CDR_ADDRESS (s, void); +} + static void dds_stream_write ( dds_stream_t * os, @@ -1178,7 +1189,8 @@ void dds_stream_from_serdata_default (_Out_ dds_stream_t * s, _In_ const struct s->m_buffer.p8 = (uint8_t*) d; s->m_index = (uint32_t) offsetof (struct ddsi_serdata_default, data); s->m_size = d->size + s->m_index; - s->m_endian = (d->bswap) ? (! DDS_ENDIAN) : DDS_ENDIAN; + assert (d->hdr.identifier == CDR_LE || d->hdr.identifier == CDR_BE); + s->m_endian = (d->hdr.identifier == CDR_LE); } void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d) @@ -1191,7 +1203,7 @@ void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_de (*d) = s->m_buffer.pv; (*d)->pos = (s->m_index - (uint32_t)offsetof (struct ddsi_serdata_default, data)); - (*d)->size = (s->m_size - (uint32_t)offsetof(struct ddsi_serdata_default, data)); + (*d)->size = (s->m_size - (uint32_t)offsetof (struct ddsi_serdata_default, data)); } void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic) @@ -1250,7 +1262,7 @@ void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct static uint32_t dds_stream_get_keyhash ( dds_stream_t * is, - char * dst, + dds_stream_t * os, const uint32_t * ops, const bool just_key ) @@ -1261,9 +1273,9 @@ static uint32_t dds_stream_get_keyhash uint32_t subtype; uint32_t num; uint32_t len; + const uint32_t origin = os->m_index; bool is_key; bool have_data; - const char * origin = dst; while ((op = *ops) != DDS_OP_RTS) { @@ -1272,7 +1284,7 @@ static uint32_t dds_stream_get_keyhash case DDS_OP_ADR: { type = DDS_OP_TYPE (op); - is_key = (op & DDS_OP_FLAG_KEY) && (dst != NULL); + is_key = (op & DDS_OP_FLAG_KEY) && (os != NULL); have_data = is_key || !just_key; ops += 2; if (type <= DDS_OP_VAL_8BY) @@ -1305,43 +1317,29 @@ static uint32_t dds_stream_get_keyhash { case DDS_OP_VAL_1BY: { - *dst++ = (char) DDS_IS_GET1 (is); + uint8_t v = DDS_IS_GET1 (is); + DDS_OS_PUT1 (os, v); break; } case DDS_OP_VAL_2BY: { - uint16_t u16 = *DDS_CDR_ADDRESS (is, uint16_t); - if (is->m_endian) - { - u16 = DDS_SWAP16 (u16); - } - memcpy (dst, &u16, sizeof (u16)); - is->m_index += 2; - dst += 2; + uint16_t v; + DDS_IS_GET2 (is, v); + DDS_OS_PUT2 (os, v); break; } case DDS_OP_VAL_4BY: { - uint32_t u32 = *DDS_CDR_ADDRESS (is, uint32_t); - if (is->m_endian) - { - u32 = DDS_SWAP32 (u32); - } - memcpy (dst, &u32, sizeof (u32)); - is->m_index += 4; - dst += 4; + uint32_t v; + DDS_IS_GET4 (is, v, uint32_t); + DDS_OS_PUT4 (os, v, uint32_t); break; } case DDS_OP_VAL_8BY: { - uint64_t u64 = *DDS_CDR_ADDRESS (is, uint64_t); - if (is->m_endian) - { - u64 = DDS_SWAP64 (u64); - } - memcpy (dst, &u64, sizeof (u64)); - is->m_index += 8; - dst += 8; + uint64_t v; + DDS_IS_GET8 (is, v, uint64_t); + DDS_OS_PUT8 (os, v, uint64_t); break; } case DDS_OP_VAL_STR: @@ -1352,11 +1350,8 @@ static uint32_t dds_stream_get_keyhash len = dds_stream_read_uint32 (is); if (is_key) { - uint32_t be32 = toBE4u (len); - memcpy (dst, &be32, 4); - dst += 4; - memcpy (dst, DDS_CDR_ADDRESS (is, void), len); - dst += len; + DDS_OS_PUT4 (os, len, uint32_t); + DDS_OS_PUT_BYTES(os, DDS_CDR_ADDRESS (is, void), len); #ifdef OP_DEBUG_KEY TRACE (("K-ADR: String/BString (%d)\n", len)); #endif @@ -1443,8 +1438,11 @@ static uint32_t dds_stream_get_keyhash align = dds_op_size[subtype]; if (is_key) { + char *dst; + DDS_CDR_ALIGNTO (os, align); + dst = DDS_CDR_ADDRESS(os, char); dds_stream_read_fixed_buffer (is, dst, num, align, is->m_endian); - dst += num * align; + os->m_index += num * align; } is->m_index += num * align; } @@ -1563,21 +1561,40 @@ static uint32_t dds_stream_get_keyhash } case DDS_OP_JSR: /* Implies nested type */ { - dst += dds_stream_get_keyhash (is, dst, ops + DDS_OP_JUMP (op), just_key); + dds_stream_get_keyhash (is, os, ops + DDS_OP_JUMP (op), just_key); ops++; break; } default: assert (0); } } - return (uint32_t) (dst - origin); + return os->m_index - origin; +} + +void dds_stream_read_sample_write_key (dds_stream_t *os, dds_stream_t *is, const struct ddsi_sertopic_default *topic) +{ + const struct dds_topic_descriptor *desc = (const struct dds_topic_descriptor *) topic->type; + uint32_t nbytes; + os->m_endian = 0; + if (os->m_size < is->m_size) + { + os->m_buffer.p8 = dds_realloc (os->m_buffer.p8, is->m_size); + os->m_size = is->m_size; + } + nbytes = dds_stream_get_keyhash (is, os, desc->m_ops, false); + os->m_index += nbytes; + if (os->m_index < os->m_size) + { + os->m_buffer.p8 = dds_realloc (os->m_buffer.p8, os->m_index); + os->m_size = os->m_index; + } } #ifndef NDEBUG static bool keyhash_is_reset(const dds_key_hash_t *kh) { static const char nullhash[sizeof(kh->m_hash)] = { 0 }; - return kh->m_flags == 0 && memcmp(kh->m_hash, nullhash, sizeof(nullhash)) == 0; + return !kh->m_set && memcmp(kh->m_hash, nullhash, sizeof(nullhash)) == 0; } #endif @@ -1589,44 +1606,35 @@ void dds_stream_read_keyhash const bool just_key ) { - char * dst; - assert (keyhash_is_reset(kh)); - + kh->m_set = 1; if (desc->m_nkeys == 0) + kh->m_iskey = 1; + else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY) { - kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH; - return; - } - - /* Select key buffer to use */ - - kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET; - if (desc->m_flagset & DDS_TOPIC_FIXED_KEY) - { - kh->m_flags |= DDS_KEY_IS_HASH; - dst = kh->m_hash; + dds_stream_t os; + uint32_t ncheck; + kh->m_iskey = 1; + dds_stream_init(&os, 0); + os.m_buffer.pv = kh->m_hash; + os.m_size = 16; + os.m_endian = 0; + ncheck = dds_stream_get_keyhash (is, &os, desc->m_ops, just_key); + assert(ncheck <= 16); + (void)ncheck; } else { - if (is->m_size > kh->m_key_buff_size) - { - kh->m_key_buff = dds_realloc (kh->m_key_buff, is->m_size); - kh->m_key_buff_size = (uint32_t) is->m_size; - } - dst = kh->m_key_buff; - } - kh->m_key_len = dds_stream_get_keyhash (is, dst, desc->m_ops, just_key); - - if (kh->m_flags & DDS_KEY_IS_HASH) - { - assert (kh->m_key_len <= 16); - kh->m_key_len = 16; - } - else - { - /* Hash is md5 of key */ - dds_key_md5 (kh); + dds_stream_t os; + md5_state_t md5st; + kh->m_iskey = 0; + dds_stream_init (&os, 0); + os.m_endian = 0; + dds_stream_get_keyhash (is, &os, desc->m_ops, just_key); + md5_init (&md5st); + md5_append (&md5st, os.m_buffer.p8, os.m_index); + md5_finish (&md5st, (unsigned char *) kh->m_hash); + dds_stream_fini (&os); } } diff --git a/src/core/ddsc/src/dds_tkmap.c b/src/core/ddsc/src/dds_tkmap.c index ad13f98..6348226 100644 --- a/src/core/ddsc/src/dds_tkmap.c +++ b/src/core/ddsc/src/dds_tkmap.c @@ -118,6 +118,7 @@ uint64_t dds_tkmap_lookup (_In_ struct tkmap * map, _In_ const struct ddsi_serda typedef struct { + const struct ddsi_sertopic *topic; uint64_t m_iid; void * m_sample; bool m_ret; @@ -130,15 +131,15 @@ static void dds_tkmap_get_key_fn (void * vtk, void * varg) tkmap_get_key_arg * arg = (tkmap_get_key_arg*) varg; if (tk->m_iid == arg->m_iid) { - ddsi_serdata_to_sample (tk->m_sample, arg->m_sample, 0, 0); + ddsi_serdata_topicless_to_sample (arg->topic, tk->m_sample, arg->m_sample, 0, 0); arg->m_ret = true; } } _Check_return_ -bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample) +bool dds_tkmap_get_key (_In_ struct tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample) { - tkmap_get_key_arg arg = { iid, sample, false }; + tkmap_get_key_arg arg = { topic, iid, sample, false }; os_mutexLock (&map->m_lock); ut_chhEnumUnsafe (map->m_hh, dds_tkmap_get_key_fn, &arg); os_mutexUnlock (&map->m_lock); @@ -192,12 +193,7 @@ struct tkmap_instance * dds_tkmap_find( struct tkmap_instance * tk; struct tkmap * map = gv.m_tkmap; - /* FIXME: check this */ -#if 0 - assert(sd->v.keyhash.m_flags & DDS_KEY_HASH_SET); -#endif dummy.m_sample = sd; - retry: if ((tk = ut_chhLookup(map->m_hh, &dummy)) != NULL) { @@ -223,7 +219,7 @@ retry: if ((tk = dds_alloc (sizeof (*tk))) == NULL) return NULL; - tk->m_sample = ddsi_serdata_ref (sd); + tk->m_sample = ddsi_serdata_to_topicless (sd); tk->m_map = map; os_atomic_st32 (&tk->m_refc, 1); tk->m_iid = dds_iid_gen (); @@ -238,7 +234,7 @@ retry: if (tk && rd) { - TRACE (("tk=%p iid=%"PRIx64"", &tk, tk->m_iid)); + TRACE (("tk=%p iid=%"PRIx64" ", &tk, tk->m_iid)); } return tk; } @@ -247,13 +243,6 @@ _Check_return_ struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd) { assert (vtime_awake_p (lookup_thread_state ()->vtime)); -#if 0 - /* Topic might have been deleted -- FIXME: no way the topic may be deleted when there're still users out there */ - if (sd->v.st->topic == NULL) - { - return NULL; - } -#endif return dds_tkmap_find (sd, true, true); } diff --git a/src/core/ddsc/src/dds_topic.c b/src/core/ddsc/src/dds_topic.c index a1684f5..442499e 100644 --- a/src/core/ddsc/src/dds_topic.c +++ b/src/core/ddsc/src/dds_topic.c @@ -424,7 +424,8 @@ dds_create_topic( st->c.typename = dds_alloc (strlen (typename) + 1); strcpy (st->c.typename, typename); st->c.ops = &ddsi_sertopic_ops_default; - st->c.serdata_ops = &ddsi_serdata_ops_cdr; + st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey; + st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops); st->native_encoding_identifier = (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE); st->type = (void*) desc; diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata.h b/src/core/ddsi/include/ddsi/ddsi_serdata.h index 8511dff..4b2c8ba 100644 --- a/src/core/ddsi/include/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata.h @@ -55,6 +55,9 @@ typedef struct ddsi_serdata * (*ddsi_serdata_from_keyhash_t) (const struct ddsi_ /* Construct a serdata from an application sample */ typedef struct ddsi_serdata * (*ddsi_serdata_from_sample_t) (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const void *sample); +/* Construct a topic-less serdata with a keyvalue given a normal serdata (either key or data) - used for tkmap */ +typedef struct ddsi_serdata * (*ddsi_serdata_to_topicless_t) (const struct ddsi_serdata *d); + /* Fill buffer with 'size' bytes of serialised data, starting from 'off'; 0 <= off < off+sz <= alignup4(size(d)) */ typedef void (*ddsi_serdata_to_ser_t) (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf); @@ -79,16 +82,14 @@ typedef void (*ddsi_serdata_to_ser_unref_t) (struct ddsi_serdata *d, const ddsi_ otherwise malloc() is to be used for those. (This allows read/take to be given a block of memory by the caller.) */ typedef bool (*ddsi_serdata_to_sample_t) (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); - -/* Compare key values of two serdatas (with the same ddsi_serdata_ops, but not necessarily of the - same topic) (FIXME: not sure I need this one) */ -typedef int (*ddsi_serdata_cmpkey_t) (const struct ddsi_serdata *a, const struct ddsi_serdata *b); +typedef bool (*ddsi_serdata_topicless_to_sample_t) (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); /* Test key values of two serdatas for equality (with the same ddsi_serdata_ops, but not necessarily of the same topic) */ typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct ddsi_serdata *b); struct ddsi_serdata_ops { + ddsi_serdata_eqkey_t eqkey; ddsi_serdata_size_t get_size; ddsi_serdata_from_ser_t from_ser; ddsi_serdata_from_keyhash_t from_keyhash; @@ -97,8 +98,8 @@ struct ddsi_serdata_ops { ddsi_serdata_to_ser_ref_t to_ser_ref; ddsi_serdata_to_ser_unref_t to_ser_unref; ddsi_serdata_to_sample_t to_sample; - ddsi_serdata_cmpkey_t cmpkey; - ddsi_serdata_eqkey_t eqkey; + ddsi_serdata_to_topicless_t to_topicless; + ddsi_serdata_topicless_to_sample_t topicless_to_sample; ddsi_serdata_free_t free; }; @@ -131,6 +132,10 @@ inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertopic return topic->serdata_ops->from_sample (topic, kind, sample); } +inline struct ddsi_serdata *ddsi_serdata_to_topicless (const struct ddsi_serdata *d) { + return d->ops->to_topicless (d); +} + inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf) { d->ops->to_ser (d, off, sz, buf); } @@ -147,8 +152,8 @@ inline bool ddsi_serdata_to_sample (const struct ddsi_serdata *d, void *sample, return d->ops->to_sample (d, sample, bufptr, buflim); } -inline int ddsi_serdata_cmpkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b) { - return a->ops->cmpkey (a, b); +inline bool ddsi_serdata_topicless_to_sample (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) { + return d->ops->topicless_to_sample (topic, d, sample, bufptr, buflim); } inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b) { diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata_default.h b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h index f08d8d7..61b0712 100644 --- a/src/core/ddsi/include/ddsi/ddsi_serdata_default.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h @@ -47,26 +47,16 @@ struct CDRHeader unsigned short options; }; -struct serstatepool /* FIXME: now a serdatapool */ +struct serdatapool /* FIXME: now a serdatapool */ { struct nn_freelist freelist; }; -struct serstate { - struct ddsi_serdata_default *data; -}; - -#define DDS_KEY_SET 0x0001 -#define DDS_KEY_HASH_SET 0x0002 -#define DDS_KEY_IS_HASH 0x0004 - typedef struct dds_key_hash { char m_hash [16]; /* Key hash value. Also possibly key. Suitably aligned for accessing as uint32_t's */ - uint32_t m_key_len; /* Length of key (may be in m_hash or m_key_buff) */ - uint32_t m_key_buff_size; /* Size of allocated key buffer (m_key_buff) */ - char * m_key_buff; /* Key buffer */ - uint32_t m_flags; /* State of key/hash (see DDS_KEY_XXX) */ + unsigned m_set : 1; /* has it been initialised? */ + unsigned m_iskey : 1; /* m_hash is key value */ } dds_key_hash_t; @@ -75,13 +65,12 @@ struct ddsi_serdata_default struct ddsi_serdata c; uint32_t pos; uint32_t size; - bool bswap; #ifndef NDEBUG bool fixed; #endif dds_key_hash_t keyhash; - struct serstatepool *pool; + struct serdatapool *pool; struct ddsi_serdata_default *next; /* in pool->freelist */ /* padding to ensure CDRHeader is at an offset 4 mod 8 from the @@ -144,14 +133,11 @@ struct ddsi_rawcdr_sample { extern const struct ddsi_sertopic_ops ddsi_sertopic_ops_default; extern const struct ddsi_serdata_ops ddsi_serdata_ops_cdr; +extern const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey; extern const struct ddsi_serdata_ops ddsi_serdata_ops_plist; extern const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr; -struct serstatepool * ddsi_serstatepool_new (void); -void ddsi_serstatepool_free (struct serstatepool * pool); - -OSAPI_EXPORT void ddsi_serstate_append_blob (struct serstate * st, size_t align, size_t sz, const void *data); -void * ddsi_serstate_append (struct serstate * st, size_t n); -void * ddsi_serstate_append_aligned (struct serstate * st, size_t n, size_t a); +struct serdatapool * ddsi_serdatapool_new (void); +void ddsi_serdatapool_free (struct serdatapool * pool); #endif diff --git a/src/core/ddsi/include/ddsi/ddsi_sertopic.h b/src/core/ddsi/include/ddsi/ddsi_sertopic.h index 03a21cb..09b2048 100644 --- a/src/core/ddsi/include/ddsi/ddsi_sertopic.h +++ b/src/core/ddsi/include/ddsi/ddsi_sertopic.h @@ -26,6 +26,7 @@ struct ddsi_sertopic { ut_avlNode_t avlnode; /* index on name_typename */ const struct ddsi_sertopic_ops *ops; const struct ddsi_serdata_ops *serdata_ops; + uint32_t serdata_basehash; char *name_typename; char *name; char *typename; @@ -44,5 +45,6 @@ struct ddsi_sertopic_ops { struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *tp); void ddsi_sertopic_unref (struct ddsi_sertopic *tp); +uint32_t ddsi_sertopic_compute_serdata_basehash (const struct ddsi_serdata_ops *ops); #endif diff --git a/src/core/ddsi/include/ddsi/q_globals.h b/src/core/ddsi/include/ddsi/q_globals.h index 3ae72d2..f8b6087 100644 --- a/src/core/ddsi/include/ddsi/q_globals.h +++ b/src/core/ddsi/include/ddsi/q_globals.h @@ -33,7 +33,7 @@ extern "C" { #endif struct nn_xmsgpool; -struct serstatepool; +struct serdatapool; struct nn_dqueue; struct nn_reorder; struct nn_defrag; @@ -275,7 +275,7 @@ struct q_globals { /* Transmit side: pools for the serializer & transmit messages and a transmit queue*/ - struct serstatepool *serpool; + struct serdatapool *serpool; struct nn_xmsgpool *xmsgpool; struct ddsi_sertopic *plist_topic; /* used for all discovery data */ struct ddsi_sertopic *rawcdr_topic; /* used for participant message data */ diff --git a/src/core/ddsi/src/ddsi_serdata.c b/src/core/ddsi/src/ddsi_serdata.c index 6cbd605..382d524 100644 --- a/src/core/ddsi/src/ddsi_serdata.c +++ b/src/core/ddsi/src/ddsi_serdata.c @@ -40,9 +40,10 @@ extern inline uint32_t ddsi_serdata_size (const struct ddsi_serdata *d); extern inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size); extern inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertopic *topic, const struct nn_keyhash *keyhash); extern inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const void *sample); +extern inline struct ddsi_serdata *ddsi_serdata_to_topicless (const struct ddsi_serdata *d); extern inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf); extern inline struct ddsi_serdata *ddsi_serdata_to_ser_ref (const struct ddsi_serdata *d, size_t off, size_t sz, ddsi_iovec_t *ref); extern inline void ddsi_serdata_to_ser_unref (struct ddsi_serdata *d, const ddsi_iovec_t *ref); extern inline bool ddsi_serdata_to_sample (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); -extern inline int ddsi_serdata_cmpkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b); +extern inline bool ddsi_serdata_topicless_to_sample (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); extern inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b); diff --git a/src/core/ddsi/src/ddsi_serdata_default.c b/src/core/ddsi/src/ddsi_serdata_default.c index e050c8a..a933626 100644 --- a/src/core/ddsi/src/ddsi_serdata_default.c +++ b/src/core/ddsi/src/ddsi_serdata_default.c @@ -41,15 +41,15 @@ static int ispowerof2_size (size_t x) static size_t alignup_size (size_t x, size_t a); -struct serstatepool * ddsi_serstatepool_new (void) +struct serdatapool * ddsi_serdatapool_new (void) { - struct serstatepool * pool; + struct serdatapool * pool; pool = os_malloc (sizeof (*pool)); nn_freelist_init (&pool->freelist, MAX_POOL_SIZE, offsetof (struct ddsi_serdata_default, next)); return pool; } -static void serstate_free_wrap (void *elem) +static void serdata_free_wrap (void *elem) { #ifndef NDEBUG struct ddsi_serdata_default *d = elem; @@ -58,19 +58,13 @@ static void serstate_free_wrap (void *elem) ddsi_serdata_unref(elem); } -void ddsi_serstatepool_free (struct serstatepool * pool) +void ddsi_serdatapool_free (struct serdatapool * pool) { - TRACE (("ddsi_serstatepool_free(%p)\n", pool)); - nn_freelist_fini (&pool->freelist, serstate_free_wrap); + TRACE (("ddsi_serdatapool_free(%p)\n", pool)); + nn_freelist_fini (&pool->freelist, serdata_free_wrap); os_free (pool); } -void ddsi_serstate_append_blob (struct serstate * st, size_t align, size_t sz, const void *data) -{ - char *p = ddsi_serstate_append_aligned (st, sz, align); - memcpy (p, data, sz); -} - static size_t alignup_size (size_t x, size_t a) { size_t m = a-1; @@ -78,42 +72,43 @@ static size_t alignup_size (size_t x, size_t a) return (x+m) & ~m; } -void * ddsi_serstate_append (struct serstate * st, size_t n) +static void *serdata_default_append (struct ddsi_serdata_default **d, size_t n) { char *p; - if (st->data->pos + n > st->data->size) + if ((*d)->pos + n > (*d)->size) { - size_t size1 = alignup_size (st->data->pos + n, 128); - struct ddsi_serdata_default * data1 = os_realloc (st->data, offsetof (struct ddsi_serdata_default, data) + size1); - st->data = data1; - st->data->size = (uint32_t)size1; + size_t size1 = alignup_size ((*d)->pos + n, 128); + *d = os_realloc (*d, offsetof (struct ddsi_serdata_default, data) + size1); + (*d)->size = (uint32_t)size1; } - assert (st->data->pos + n <= st->data->size); - p = st->data->data + st->data->pos; - st->data->pos += (uint32_t)n; + assert ((*d)->pos + n <= (*d)->size); + p = (*d)->data + (*d)->pos; + (*d)->pos += (uint32_t)n; return p; } -void * ddsi_serstate_append_aligned (struct serstate * st, size_t n, size_t a) +static void *serdata_default_append_aligned (struct ddsi_serdata_default **d, size_t n, size_t a) { - /* Simply align st->pos, without verifying it fits in the allocated - buffer: ddsi_serstate_append() is called immediately afterward and will - grow the buffer as soon as the end of the requested space no - longer fits. */ #if CLEAR_PADDING size_t pos0 = st->pos; #endif char *p; assert (ispowerof2_size (a)); - st->data->pos = (uint32_t) alignup_size (st->data->pos, a); - p = ddsi_serstate_append (st, n); + (*d)->pos = (uint32_t) alignup_size ((*d)->pos, a); + p = serdata_default_append (d, n); #if CLEAR_PADDING - if (p && st->pos > pos0) - memset (st->data->data + pos0, 0, st->pos - pos0); + if (p && (*d)->pos > pos0) + memset ((*d)->data + pos0, 0, (*d)->pos - pos0); #endif return p; } +static void serdata_default_append_blob (struct ddsi_serdata_default **d, size_t align, size_t sz, const void *data) +{ + char *p = serdata_default_append_aligned (d, sz, align); + memcpy (p, data, sz); +} + /* Fixed seed and length */ #define DDS_MH3_LEN 16 @@ -163,12 +158,12 @@ static uint32_t dds_mh3 (const void * key) return h1; } -static struct ddsi_serdata *fix_serdata_default(struct ddsi_serdata_default *d, uint64_t tp_iid) +static struct ddsi_serdata *fix_serdata_default(struct ddsi_serdata_default *d, uint32_t basehash) { - if (d->keyhash.m_flags & DDS_KEY_IS_HASH) - d->c.hash = dds_mh3 (d->keyhash.m_hash) ^ (uint32_t)tp_iid; + if (d->keyhash.m_iskey) + d->c.hash = dds_mh3 (d->keyhash.m_hash) ^ basehash; else - d->c.hash = *((uint32_t *)d->keyhash.m_hash) ^ (uint32_t)tp_iid; + d->c.hash = *((uint32_t *)d->keyhash.m_hash) ^ basehash; return &d->c; } @@ -182,23 +177,29 @@ static bool serdata_default_eqkey(const struct ddsi_serdata *acmn, const struct { const struct ddsi_serdata_default *a = (const struct ddsi_serdata_default *)acmn; const struct ddsi_serdata_default *b = (const struct ddsi_serdata_default *)bcmn; - const struct ddsi_sertopic_default *tp; - - assert(a->c.ops == b->c.ops); - tp = (struct ddsi_sertopic_default *)a->c.topic; - if (tp->nkeys == 0) - return true; - else - { - assert (a->keyhash.m_flags & DDS_KEY_HASH_SET); - return memcmp (a->keyhash.m_hash, b->keyhash.m_hash, 16) == 0; + assert (a->keyhash.m_set); +#if 0 + char astr[50], bstr[50]; + for (int i = 0; i < 16; i++) { + sprintf (astr + 3*i, ":%02x", (unsigned char)a->keyhash.m_hash[i]); } + for (int i = 0; i < 16; i++) { + sprintf (bstr + 3*i, ":%02x", (unsigned char)b->keyhash.m_hash[i]); + } + printf("serdata_default_eqkey: %s %s\n", astr+1, bstr+1); +#endif + return memcmp (a->keyhash.m_hash, b->keyhash.m_hash, 16) == 0; +} + +static bool serdata_default_eqkey_nokey (const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn) +{ + (void)acmn; (void)bcmn; + return true; } static void serdata_default_free(struct ddsi_serdata *dcmn) { struct ddsi_serdata_default *d = (struct ddsi_serdata_default *)dcmn; - dds_free (d->keyhash.m_key_buff); dds_free (d); } @@ -211,15 +212,12 @@ static void serdata_default_init(struct ddsi_serdata_default *d, const struct dd #endif d->hdr.identifier = tp->native_encoding_identifier; d->hdr.options = 0; - d->bswap = false; memset (d->keyhash.m_hash, 0, sizeof (d->keyhash.m_hash)); - d->keyhash.m_key_len = 0; - d->keyhash.m_flags = 0; - d->keyhash.m_key_buff = NULL; - d->keyhash.m_key_buff_size = 0; + d->keyhash.m_set = 0; + d->keyhash.m_iskey = 0; } -static struct ddsi_serdata_default *serdata_default_allocnew(struct serstatepool *pool) +static struct ddsi_serdata_default *serdata_default_allocnew(struct serdatapool *pool) { const uint32_t init_size = 128; struct ddsi_serdata_default *d = os_malloc(offsetof (struct ddsi_serdata_default, data) + init_size); @@ -243,26 +241,13 @@ static struct ddsi_serdata *serdata_default_from_ser (const struct ddsi_sertopic const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; struct ddsi_serdata_default *d = serdata_default_new(tp, kind); uint32_t off = 4; /* must skip the CDR header */ - struct serstate st = { .data = d }; assert (fragchain->min == 0); assert (fragchain->maxp1 >= off); /* CDR header must be in first fragment */ (void)size; memcpy (&d->hdr, NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)), sizeof (d->hdr)); - switch (d->hdr.identifier) { - case CDR_LE: - case PL_CDR_LE: - d->bswap = ! PLATFORM_IS_LITTLE_ENDIAN; - break; - case CDR_BE: - case PL_CDR_BE: - d->bswap = PLATFORM_IS_LITTLE_ENDIAN; - break; - default: - /* must not ever try to use a serdata format for an unsupported encoding */ - abort (); - } + assert (d->hdr.identifier == CDR_LE || d->hdr.identifier == CDR_BE); while (fragchain) { @@ -272,31 +257,48 @@ static struct ddsi_serdata *serdata_default_from_ser (const struct ddsi_sertopic { /* only copy if this fragment adds data */ const unsigned char *payload = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)); - ddsi_serstate_append_blob (&st, 1, fragchain->maxp1 - off, payload + off - fragchain->min); + serdata_default_append_blob (&d, 1, fragchain->maxp1 - off, payload + off - fragchain->min); off = fragchain->maxp1; } fragchain = fragchain->nextfrag; } - /* FIXME: assignment here is because of reallocs, but doing it this way is a bit hacky */ - d = st.data; - dds_stream_t is; dds_stream_from_serdata_default (&is, d); dds_stream_read_keyhash (&is, &d->keyhash, (const dds_topic_descriptor_t *)tp->type, kind == SDK_KEY); - return fix_serdata_default (d, tp->c.iid); + return fix_serdata_default (d, tp->c.serdata_basehash); } struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash) +{ + /* FIXME: not quite sure this is correct, though a check against a specially hacked OpenSplice suggests it is */ + if (!(tpcmn->status_cb_entity->m_descriptor->m_flagset & DDS_TOPIC_FIXED_KEY)) + { + /* keyhash is MD5 of a key value, so impossible to turn into a key value */ + return NULL; + } + else + { + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; + struct ddsi_serdata_default *d = serdata_default_new(tp, SDK_KEY); + d->hdr.identifier = CDR_BE; + serdata_default_append_blob (&d, 1, sizeof (keyhash->value), keyhash->value); + memcpy (d->keyhash.m_hash, keyhash->value, sizeof (d->keyhash.m_hash)); + d->keyhash.m_set = 1; + d->keyhash.m_iskey = 1; + return fix_serdata_default(d, tp->c.serdata_basehash); + } +} + +struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr_nokey (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash) { const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; struct ddsi_serdata_default *d = serdata_default_new(tp, SDK_KEY); - struct serstate st = { .data = d }; - /* FIXME: not quite sure this is correct */ - ddsi_serstate_append_blob (&st, 1, sizeof (keyhash->value), keyhash->value); - /* FIXME: assignment here is because of reallocs, but doing it this way is a bit hacky */ - d = st.data; - return fix_serdata_default(d, tp->c.iid); + (void)keyhash; + d->keyhash.m_set = 1; + d->keyhash.m_iskey = 1; + d->c.hash = tp->c.serdata_basehash; + return (struct ddsi_serdata *)d; } static struct ddsi_serdata *serdata_default_from_sample_cdr (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample) @@ -318,7 +320,7 @@ static struct ddsi_serdata *serdata_default_from_sample_cdr (const struct ddsi_s break; } dds_stream_add_to_serdata_default (&os, &d); - return fix_serdata_default (d, tp->c.iid); + return fix_serdata_default (d, tp->c.serdata_basehash); } static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample) @@ -327,9 +329,7 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; const struct ddsi_plist_sample *sample = vsample; struct ddsi_serdata_default *d = serdata_default_new(tp, kind); - struct serstate st = { .data = d }; - ddsi_serstate_append_blob (&st, 1, sample->size, sample->blob); - d = st.data; + serdata_default_append_blob (&d, 1, sample->size, sample->blob); const unsigned char *rawkey = nn_plist_findparam_native_unchecked (sample->blob, sample->keyparam); #ifndef NDEBUG size_t keysize; @@ -339,11 +339,11 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi case PID_PARTICIPANT_GUID: case PID_ENDPOINT_GUID: case PID_GROUP_GUID: - d->keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH; - d->keyhash.m_key_len = 16; - memcpy (&d->keyhash.m_hash, rawkey, d->keyhash.m_key_len); + d->keyhash.m_set = 1; + d->keyhash.m_iskey = 1; + memcpy (&d->keyhash.m_hash, rawkey, 16); #ifndef NDEBUG - keysize = d->keyhash.m_key_len; + keysize = 16; #endif break; @@ -354,13 +354,13 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi md5_state_t md5st; md5_byte_t digest[16]; topic_name_sz = (uint32_t) strlen (topic_name) + 1; - d->keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET; - d->keyhash.m_key_len = 16; + d->keyhash.m_set = 1; + d->keyhash.m_iskey = 0; md5_init (&md5st); md5_append (&md5st, (const md5_byte_t *) &topic_name_sz_BE, sizeof (topic_name_sz_BE)); md5_append (&md5st, (const md5_byte_t *) topic_name, topic_name_sz); md5_finish (&md5st, digest); - memcpy (&d->keyhash.m_hash, digest, d->keyhash.m_key_len); + memcpy (&d->keyhash.m_hash, digest, 16); #ifndef NDEBUG keysize = sizeof (uint32_t) + topic_name_sz; #endif @@ -371,10 +371,10 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi abort(); } - /* if we're it is supposed to be just a key, rawkey must be be the first field and followed only by a sentinel */ + /* if it is supposed to be just a key, rawkey must be be the first field and followed only by a sentinel */ assert (kind != SDK_KEY || rawkey == (const unsigned char *)sample->blob + sizeof (nn_parameter_t)); assert (kind != SDK_KEY || sample->size == sizeof (nn_parameter_t) + alignup_size (keysize, 4) + sizeof (nn_parameter_t)); - return fix_serdata_default (d, tp->c.iid); + return fix_serdata_default (d, tp->c.serdata_basehash); } static struct ddsi_serdata *serdata_default_from_sample_rawcdr (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample) @@ -383,15 +383,46 @@ static struct ddsi_serdata *serdata_default_from_sample_rawcdr (const struct dds const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; const struct ddsi_rawcdr_sample *sample = vsample; struct ddsi_serdata_default *d = serdata_default_new(tp, kind); - struct serstate st = { .data = d }; assert (sample->keysize <= 16); - ddsi_serstate_append_blob (&st, 1, sample->size, sample->blob); - d = st.data; - d->keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH; - d->keyhash.m_key_len = (uint32_t) sample->keysize; + serdata_default_append_blob (&d, 1, sample->size, sample->blob); + d->keyhash.m_set = 1; + d->keyhash.m_iskey = 1; if (sample->keysize > 0) memcpy (&d->keyhash.m_hash, sample->key, sample->keysize); - return fix_serdata_default (d, tp->c.iid); + return fix_serdata_default (d, tp->c.serdata_basehash); +} + +static struct ddsi_serdata *serdata_default_to_topicless (const struct ddsi_serdata *serdata_common) +{ + const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)d->c.topic; + struct ddsi_serdata_default *d_tl = serdata_default_new(tp, SDK_KEY); + d_tl->c.topic = NULL; + d_tl->c.hash = d->c.hash; + d_tl->c.timestamp.v = INT64_MIN; + d_tl->keyhash = d->keyhash; + /* These things are used for the key-to-instance map and only subject to eq, free and conversion to an invalid + sample of some topic for topics that can end up in a RHC, so, of the four kinds we have, only for CDR-with-key + the payload is of interest. */ + if (d->c.ops == &ddsi_serdata_ops_cdr) + { + if (d->c.kind == SDK_KEY) + { + d_tl->hdr.identifier = d->hdr.identifier; + serdata_default_append_blob (&d_tl, 1, d->pos, d->data); + } + else + { + /* One big hack ... read_sample_write_key goes via keyhash generation ... */ + dds_stream_t is, os; + dds_stream_from_serdata_default (&is, d); + dds_stream_from_serdata_default (&os, d_tl); + dds_stream_read_sample_write_key (&os, &is, tp); + dds_stream_add_to_serdata_default (&os, &d_tl); + d_tl->hdr.identifier = os.m_endian ? CDR_LE : CDR_BE; + } + } + return (struct ddsi_serdata *)d_tl; } /* Fill buffer with 'size' bytes of serialised data, starting from 'off'; 0 <= off < off+sz <= alignup4(size(d)) */ @@ -400,7 +431,6 @@ static void serdata_default_to_ser (const struct ddsi_serdata *serdata_common, s const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; assert (off < d->pos + sizeof(struct CDRHeader)); assert (sz <= alignup_size (d->pos + sizeof(struct CDRHeader), 4) - off); - /* FIXME: maybe I should pull the header out ... */ memcpy (buf, (char *)&d->hdr + off, sz); } @@ -410,7 +440,7 @@ static struct ddsi_serdata *serdata_default_to_ser_ref (const struct ddsi_serdat assert (off < d->pos + sizeof(struct CDRHeader)); assert (sz <= alignup_size (d->pos + sizeof(struct CDRHeader), 4) - off); ref->iov_base = (char *)&d->hdr + off; - ref->iov_len = sz; + ref->iov_len = (ddsi_iov_len_t)sz; return ddsi_serdata_ref(serdata_common); } @@ -433,38 +463,29 @@ static bool serdata_default_to_sample_cdr (const struct ddsi_serdata *serdata_co return true; /* FIXME: can't conversion to sample fail? */ } -static bool serdata_default_to_sample_plist (const struct ddsi_serdata *serdata_common, void *vsample, void **bufptr, void *buflim) +static bool serdata_default_topicless_to_sample_cdr (const struct ddsi_sertopic *topic, const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim) { -#if 0 const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; - struct ddsi_plist_sample *sample = vsample; - /* output of to_sample for normal samples is a copy, and so it should be for this one; only for native format (like the inverse) */ + dds_stream_t is; + assert (d->c.topic == NULL); + assert (d->c.kind == SDK_KEY); + assert (d->c.ops == topic->serdata_ops); if (bufptr) abort(); else { (void)buflim; } /* FIXME: haven't implemented that bit yet! */ - assert (d->hdr.identifier == PLATFORM_IS_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE); - sample->size = d->pos; - sample->blob = os_malloc (sample->size); - memcpy (sample->blob, (char *)&d->hdr + sizeof(struct CDRHeader), sample->size); - sample->keyparam = PID_PAD; - return true; -#else - /* I don't think I need this */ - (void)serdata_common; (void)vsample; (void)bufptr; (void)buflim; - abort(); - return false; -#endif + dds_stream_from_serdata_default(&is, d); + dds_stream_read_key (&is, sample, (const dds_topic_descriptor_t*) ((struct ddsi_sertopic_default *)topic)->type); + return true; /* FIXME: can't conversion to sample fail? */ } -static bool serdata_default_to_sample_rawcdr (const struct ddsi_serdata *serdata_common, void *vsample, void **bufptr, void *buflim) +static bool serdata_default_topicless_to_sample_cdr_nokey (const struct ddsi_sertopic *topic, const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim) { - /* I don't think I need this */ - (void)serdata_common; (void)vsample; (void)bufptr; (void)buflim; - abort(); - return false; + (void)topic; (void)sample; (void)bufptr; (void)buflim; + assert (serdata_common->topic == NULL); + assert (serdata_common->kind == SDK_KEY); + return true; } const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { .get_size = serdata_default_get_size, - .cmpkey = 0, .eqkey = serdata_default_eqkey, .free = serdata_default_free, .from_ser = serdata_default_from_ser, @@ -473,33 +494,52 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { .to_ser = serdata_default_to_ser, .to_sample = serdata_default_to_sample_cdr, .to_ser_ref = serdata_default_to_ser_ref, - .to_ser_unref = serdata_default_to_ser_unref + .to_ser_unref = serdata_default_to_ser_unref, + .to_topicless = serdata_default_to_topicless, + .topicless_to_sample = serdata_default_topicless_to_sample_cdr +}; + +const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey = { + .get_size = serdata_default_get_size, + .eqkey = serdata_default_eqkey_nokey, + .free = serdata_default_free, + .from_ser = serdata_default_from_ser, + .from_keyhash = ddsi_serdata_from_keyhash_cdr_nokey, + .from_sample = serdata_default_from_sample_cdr, + .to_ser = serdata_default_to_ser, + .to_sample = serdata_default_to_sample_cdr, + .to_ser_ref = serdata_default_to_ser_ref, + .to_ser_unref = serdata_default_to_ser_unref, + .to_topicless = serdata_default_to_topicless, + .topicless_to_sample = serdata_default_topicless_to_sample_cdr_nokey }; const struct ddsi_serdata_ops ddsi_serdata_ops_plist = { .get_size = serdata_default_get_size, - .cmpkey = 0, .eqkey = serdata_default_eqkey, .free = serdata_default_free, .from_ser = serdata_default_from_ser, - .from_keyhash = 0, /* q_ddsi_discovery.c takes care of it internally */ + .from_keyhash = 0, .from_sample = serdata_default_from_sample_plist, .to_ser = serdata_default_to_ser, - .to_sample = serdata_default_to_sample_plist, + .to_sample = 0, .to_ser_ref = serdata_default_to_ser_ref, - .to_ser_unref = serdata_default_to_ser_unref + .to_ser_unref = serdata_default_to_ser_unref, + .to_topicless = serdata_default_to_topicless, + .topicless_to_sample = 0 }; const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr = { .get_size = serdata_default_get_size, - .cmpkey = 0, .eqkey = serdata_default_eqkey, .free = serdata_default_free, .from_ser = serdata_default_from_ser, - .from_keyhash = 0, /* q_ddsi_discovery.c takes care of it internally */ + .from_keyhash = 0, .from_sample = serdata_default_from_sample_rawcdr, .to_ser = serdata_default_to_ser, - .to_sample = serdata_default_to_sample_rawcdr, + .to_sample = 0, .to_ser_ref = serdata_default_to_ser_ref, - .to_ser_unref = serdata_default_to_ser_unref + .to_ser_unref = serdata_default_to_ser_unref, + .to_topicless = serdata_default_to_topicless, + .topicless_to_sample = 0 }; diff --git a/src/core/ddsi/src/ddsi_sertopic.c b/src/core/ddsi/src/ddsi_sertopic.c index 0dc2d10..2c415a6 100644 --- a/src/core/ddsi/src/ddsi_sertopic.c +++ b/src/core/ddsi/src/ddsi_sertopic.c @@ -21,6 +21,8 @@ #include "ddsi/q_config.h" #include "ddsi/q_freelist.h" #include "ddsi/ddsi_sertopic.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/q_md5.h" struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *sertopic_const) { @@ -44,3 +46,16 @@ void ddsi_sertopic_unref (struct ddsi_sertopic *sertopic) } } } + +uint32_t ddsi_sertopic_compute_serdata_basehash (const struct ddsi_serdata_ops *ops) +{ + md5_state_t md5st; + md5_byte_t digest[16]; + uint32_t res; + md5_init (&md5st); + md5_append (&md5st, (const md5_byte_t *) &ops, sizeof (ops)); + md5_append (&md5st, (const md5_byte_t *) ops, sizeof (*ops)); + md5_finish (&md5st, digest); + memcpy (&res, digest, sizeof (res)); + return res; +} diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index 3f653f0..688e6d7 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -767,8 +767,9 @@ static struct ddsi_sertopic *make_special_topic (uint16_t enc_id, const struct d os_atomic_st32 (&st->c.refc, 1); st->c.ops = &ddsi_sertopic_ops_default; st->c.serdata_ops = ops; - st->native_encoding_identifier = enc_id; + st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops); st->c.iid = ddsi_plugin.iidgen_fn(); + st->native_encoding_identifier = enc_id; st->nkeys = 1; return (struct ddsi_sertopic *)st; } @@ -1009,7 +1010,7 @@ int rtps_init (void) (ddsi_plugin.init_fn) (); gv.xmsgpool = nn_xmsgpool_new (); - gv.serpool = ddsi_serstatepool_new (); + gv.serpool = ddsi_serdatapool_new (); #ifdef DDSI_INCLUDE_ENCRYPTION if (q_security_plugin.new_decoder) @@ -1359,7 +1360,7 @@ err_unicast_sockets: nn_xqos_fini (&gv.default_xqos_wr); nn_xqos_fini (&gv.default_xqos_rd); nn_plist_fini (&gv.default_plist_pp); - ddsi_serstatepool_free (gv.serpool); + ddsi_serdatapool_free (gv.serpool); nn_xmsgpool_free (gv.xmsgpool); (ddsi_plugin.fini_fn) (); #ifdef DDSI_INCLUDE_NETWORK_PARTITIONS @@ -1654,7 +1655,7 @@ OS_WARNING_MSVC_ON(6001); os_free (gv.interfaces[i].name); } - ddsi_serstatepool_free (gv.serpool); + ddsi_serdatapool_free (gv.serpool); nn_xmsgpool_free (gv.xmsgpool); (ddsi_plugin.fini_fn) (); nn_log (LC_CONFIG, "Finis.\n"); diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index 5c3b69b..1fe232a 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -1842,9 +1842,10 @@ static struct ddsi_serdata *extract_sample_from_data failmsg = "no content"; else if (!(qos->present & PP_KEYHASH)) failmsg = "qos present but without keyhash"; + else if ((sample = ddsi_serdata_from_keyhash (topic, &qos->keyhash)) == NULL) + failmsg = "keyhash is MD5 and can't be converted to key value"; else { - sample = ddsi_serdata_from_keyhash (topic, &qos->keyhash); sample->statusinfo = statusinfo; sample->timestamp = tstamp; } diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index cbd8e39..3b87032 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -397,6 +397,7 @@ void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_sta static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struct ddsi_serdata *serdata, struct nn_xmsg **pmsg) { +#define TEST_KEYHASH 0 const size_t expected_inline_qos_size = 4+8+20+4 + 32; struct nn_xmsg_marker sm_marker; unsigned char contentflag; @@ -408,7 +409,11 @@ static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struc contentflag = 0; break; case SDK_KEY: +#if TEST_KEYHASH + contentflag = wr->include_keyhash ? 0 : DATA_FLAG_KEYFLAG; +#else contentflag = DATA_FLAG_KEYFLAG; +#endif break; case SDK_DATA: contentflag = DATA_FLAG_DATAFLAG; @@ -452,7 +457,12 @@ static int create_fragment_message_simple (struct writer *wr, seqno_t seq, struc data->x.smhdr.flags |= DATAFRAG_FLAG_INLINE_QOS; } +#if TEST_KEYHASH + if (serdata->kind != SDK_KEY || !wr->include_keyhash) + nn_xmsg_serdata (*pmsg, serdata, 0, ddsi_serdata_size (serdata)); +#else nn_xmsg_serdata (*pmsg, serdata, 0, ddsi_serdata_size (serdata)); +#endif nn_xmsg_submsg_setnext (*pmsg, sm_marker); return 0; } From 259e4676dc5d40294d4d717c5ada43ad9e5ff07a Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Sun, 28 Oct 2018 13:40:41 +0800 Subject: [PATCH 07/13] fix sequencing of internal liveliness monitoring and rtps init/term liveliness monitoring requires rtps stack initialised if initially deaf, so starting the monitoring thread must happen after rtps_init Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_init.c | 25 +++++++++++++-------- src/core/ddsi/include/ddsi/q_servicelease.h | 1 + src/core/ddsi/src/ddsi_serdata_default.c | 2 +- src/core/ddsi/src/q_servicelease.c | 6 ++++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c index 7517006..f4d057d 100644 --- a/src/core/ddsc/src/dds_init.c +++ b/src/core/ddsc/src/dds_init.c @@ -131,11 +131,6 @@ dds_init(dds_domainid_t domain) ret = DDS_ERRNO(DDS_RETCODE_OUT_OF_RESOURCES, "Failed to create a servicelease."); goto fail_servicelease_new; } - if (nn_servicelease_start_renewing(gv.servicelease) < 0) - { - ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to start the servicelease."); - goto fail_servicelease_start; - } } if (rtps_init() < 0) @@ -143,6 +138,13 @@ dds_init(dds_domainid_t domain) ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to initialize RTPS."); goto fail_rtps_init; } + + if (gv.servicelease && nn_servicelease_start_renewing(gv.servicelease) < 0) + { + ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to start the servicelease."); + goto fail_servicelease_start; + } + upgrade_main_thread(); /* Set additional default participant properties */ @@ -175,11 +177,16 @@ skip: DDS_REPORT_FLUSH(false); return DDS_RETCODE_OK; -fail_rtps_init: fail_servicelease_start: if (gv.servicelease) + nn_servicelease_stop_renewing (gv.servicelease); + rtps_term (); +fail_rtps_init: + if (gv.servicelease) + { nn_servicelease_free (gv.servicelease); - gv.servicelease = NULL; + gv.servicelease = NULL; + } fail_servicelease_new: thread_states_fini(); fail_rtps_config: @@ -200,8 +207,6 @@ fail_handleserver: return ret; } - - extern void dds_fini (void) { os_mutex *init_mutex; @@ -213,6 +218,8 @@ extern void dds_fini (void) { dds__builtin_fini(); + if (gv.servicelease) + nn_servicelease_stop_renewing (gv.servicelease); rtps_term (); if (gv.servicelease) nn_servicelease_free (gv.servicelease); diff --git a/src/core/ddsi/include/ddsi/q_servicelease.h b/src/core/ddsi/include/ddsi/q_servicelease.h index c4e8be3..bc9c15d 100644 --- a/src/core/ddsi/include/ddsi/q_servicelease.h +++ b/src/core/ddsi/include/ddsi/q_servicelease.h @@ -20,6 +20,7 @@ struct nn_servicelease; struct nn_servicelease *nn_servicelease_new (void (*renew_cb) (void *arg), void *renew_arg); int nn_servicelease_start_renewing (struct nn_servicelease *sl); +void nn_servicelease_stop_renewing (struct nn_servicelease *sl); void nn_servicelease_free (struct nn_servicelease *sl); void nn_servicelease_statechange_barrier (struct nn_servicelease *sl); diff --git a/src/core/ddsi/src/ddsi_serdata_default.c b/src/core/ddsi/src/ddsi_serdata_default.c index a933626..4f333b7 100644 --- a/src/core/ddsi/src/ddsi_serdata_default.c +++ b/src/core/ddsi/src/ddsi_serdata_default.c @@ -478,7 +478,7 @@ static bool serdata_default_topicless_to_sample_cdr (const struct ddsi_sertopic static bool serdata_default_topicless_to_sample_cdr_nokey (const struct ddsi_sertopic *topic, const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim) { - (void)topic; (void)sample; (void)bufptr; (void)buflim; + (void)topic; (void)sample; (void)bufptr; (void)buflim; (void)serdata_common; assert (serdata_common->topic == NULL); assert (serdata_common->kind == SDK_KEY); return true; diff --git a/src/core/ddsi/src/q_servicelease.c b/src/core/ddsi/src/q_servicelease.c index 72eae90..3dac20e 100644 --- a/src/core/ddsi/src/q_servicelease.c +++ b/src/core/ddsi/src/q_servicelease.c @@ -230,7 +230,7 @@ void nn_servicelease_statechange_barrier (struct nn_servicelease *sl) os_mutexUnlock (&sl->lock); } -void nn_servicelease_free (struct nn_servicelease *sl) +void nn_servicelease_stop_renewing (struct nn_servicelease *sl) { if (sl->keepgoing != -1) { @@ -240,6 +240,10 @@ void nn_servicelease_free (struct nn_servicelease *sl) os_mutexUnlock (&sl->lock); join_thread (sl->ts); } +} + +void nn_servicelease_free (struct nn_servicelease *sl) +{ os_condDestroy (&sl->cond); os_mutexDestroy (&sl->lock); os_free (sl->av_ary); From 7cb80e7851e423af48c8edfb9398a2ddd0f0212e Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Oct 2018 13:24:07 +0800 Subject: [PATCH 08/13] minor refactor of CDR-to-key/keyhash generation Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds__stream.h | 2 +- src/core/ddsc/src/dds_stream.c | 39 +++++------------------- src/core/ddsi/src/ddsi_serdata_default.c | 17 +++++++++-- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/src/core/ddsc/src/dds__stream.h b/src/core/ddsc/src/dds__stream.h index 56350b9..fc0d62f 100644 --- a/src/core/ddsc/src/dds__stream.h +++ b/src/core/ddsc/src/dds__stream.h @@ -37,7 +37,7 @@ void dds_stream_from_serdata_default (dds_stream_t * s, const struct ddsi_serdat void dds_stream_add_to_serdata_default (dds_stream_t * s, struct ddsi_serdata_default **d); void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct ddsi_sertopic_default * topic); -void dds_stream_read_sample_write_key (dds_stream_t *os, dds_stream_t *is, const struct ddsi_sertopic_default *topic); +uint32_t dds_stream_extract_key (dds_stream_t *is, dds_stream_t *os, const uint32_t *ops, const bool just_key); void dds_stream_read_key ( dds_stream_t * is, diff --git a/src/core/ddsc/src/dds_stream.c b/src/core/ddsc/src/dds_stream.c index e7371d2..927d56d 100644 --- a/src/core/ddsc/src/dds_stream.c +++ b/src/core/ddsc/src/dds_stream.c @@ -1259,13 +1259,7 @@ void dds_stream_write_key (dds_stream_t * os, const char * sample, const struct of key hash. Input stream may contain full sample of just key data. */ -static uint32_t dds_stream_get_keyhash -( - dds_stream_t * is, - dds_stream_t * os, - const uint32_t * ops, - const bool just_key -) +uint32_t dds_stream_extract_key (dds_stream_t *is, dds_stream_t *os, const uint32_t *ops, const bool just_key) { uint32_t align; uint32_t op; @@ -1404,7 +1398,7 @@ static uint32_t dds_stream_get_keyhash const uint32_t jmp = DDS_OP_ADR_JMP (ops[1]); while (num--) { - dds_stream_get_keyhash (is, NULL, jsr_ops, just_key); + dds_stream_extract_key (is, NULL, jsr_ops, just_key); } ops += jmp ? (jmp - 2) : 2; break; @@ -1464,7 +1458,7 @@ static uint32_t dds_stream_get_keyhash const uint32_t jmp = DDS_OP_ADR_JMP (*ops); while (num--) { - dds_stream_get_keyhash (is, NULL, jsr_ops, just_key); + dds_stream_extract_key (is, NULL, jsr_ops, just_key); } ops += jmp ? (jmp - 3) : 2; break; @@ -1540,7 +1534,7 @@ static uint32_t dds_stream_get_keyhash } default: { - dds_stream_get_keyhash (is, NULL, jeq_op + DDS_OP_ADR_JSR (jeq_op[0]), just_key); + dds_stream_extract_key (is, NULL, jeq_op + DDS_OP_ADR_JSR (jeq_op[0]), just_key); break; } } @@ -1561,7 +1555,7 @@ static uint32_t dds_stream_get_keyhash } case DDS_OP_JSR: /* Implies nested type */ { - dds_stream_get_keyhash (is, os, ops + DDS_OP_JUMP (op), just_key); + dds_stream_extract_key (is, os, ops + DDS_OP_JUMP (op), just_key); ops++; break; } @@ -1571,25 +1565,6 @@ static uint32_t dds_stream_get_keyhash return os->m_index - origin; } -void dds_stream_read_sample_write_key (dds_stream_t *os, dds_stream_t *is, const struct ddsi_sertopic_default *topic) -{ - const struct dds_topic_descriptor *desc = (const struct dds_topic_descriptor *) topic->type; - uint32_t nbytes; - os->m_endian = 0; - if (os->m_size < is->m_size) - { - os->m_buffer.p8 = dds_realloc (os->m_buffer.p8, is->m_size); - os->m_size = is->m_size; - } - nbytes = dds_stream_get_keyhash (is, os, desc->m_ops, false); - os->m_index += nbytes; - if (os->m_index < os->m_size) - { - os->m_buffer.p8 = dds_realloc (os->m_buffer.p8, os->m_index); - os->m_size = os->m_index; - } -} - #ifndef NDEBUG static bool keyhash_is_reset(const dds_key_hash_t *kh) { @@ -1619,7 +1594,7 @@ void dds_stream_read_keyhash os.m_buffer.pv = kh->m_hash; os.m_size = 16; os.m_endian = 0; - ncheck = dds_stream_get_keyhash (is, &os, desc->m_ops, just_key); + ncheck = dds_stream_extract_key (is, &os, desc->m_ops, just_key); assert(ncheck <= 16); (void)ncheck; } @@ -1630,7 +1605,7 @@ void dds_stream_read_keyhash kh->m_iskey = 0; dds_stream_init (&os, 0); os.m_endian = 0; - dds_stream_get_keyhash (is, &os, desc->m_ops, just_key); + dds_stream_extract_key (is, &os, desc->m_ops, just_key); md5_init (&md5st); md5_append (&md5st, os.m_buffer.p8, os.m_index); md5_finish (&md5st, (unsigned char *) kh->m_hash); diff --git a/src/core/ddsi/src/ddsi_serdata_default.c b/src/core/ddsi/src/ddsi_serdata_default.c index 4f333b7..1d1e45e 100644 --- a/src/core/ddsi/src/ddsi_serdata_default.c +++ b/src/core/ddsi/src/ddsi_serdata_default.c @@ -411,15 +411,26 @@ static struct ddsi_serdata *serdata_default_to_topicless (const struct ddsi_serd d_tl->hdr.identifier = d->hdr.identifier; serdata_default_append_blob (&d_tl, 1, d->pos, d->data); } + else if (d->keyhash.m_iskey) + { + d_tl->hdr.identifier = CDR_BE; + serdata_default_append_blob (&d_tl, 1, sizeof (d->keyhash.m_hash), d->keyhash.m_hash); + } else { - /* One big hack ... read_sample_write_key goes via keyhash generation ... */ + const struct dds_topic_descriptor *desc = tp->type; dds_stream_t is, os; + uint32_t nbytes; dds_stream_from_serdata_default (&is, d); dds_stream_from_serdata_default (&os, d_tl); - dds_stream_read_sample_write_key (&os, &is, tp); + nbytes = dds_stream_extract_key (&is, &os, desc->m_ops, false); + os.m_index += nbytes; + if (os.m_index < os.m_size) + { + os.m_buffer.p8 = dds_realloc (os.m_buffer.p8, os.m_index); + os.m_size = os.m_index; + } dds_stream_add_to_serdata_default (&os, &d_tl); - d_tl->hdr.identifier = os.m_endian ? CDR_LE : CDR_BE; } } return (struct ddsi_serdata *)d_tl; From 3e343d032a95ca6f064b49ef6472ba4df038f039 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Oct 2018 13:26:24 +0800 Subject: [PATCH 09/13] reduce dependency on sertopic->status_cb_entity Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_rhc.c | 18 +++++++----------- src/core/ddsc/src/dds_stream.c | 4 ++-- src/core/ddsi/include/ddsi/ddsi_serdata.h | 1 + .../ddsi/include/ddsi/ddsi_serdata_default.h | 18 +++++++----------- src/core/ddsi/include/ddsi/ddsi_sertopic.h | 12 ++++++++++++ src/core/ddsi/src/ddsi_serdata_default.c | 4 ++-- src/core/ddsi/src/ddsi_sertopic.c | 5 ++++- src/core/ddsi/src/ddsi_sertopic_default.c | 11 +++++++++-- 8 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/core/ddsc/src/dds_rhc.c b/src/core/ddsc/src/dds_rhc.c index b9d9cb5..6f85b4d 100644 --- a/src/core/ddsc/src/dds_rhc.c +++ b/src/core/ddsc/src/dds_rhc.c @@ -653,7 +653,7 @@ static bool add_sample rhc->n_vsamples++; } - s->sample = ddsi_serdata_ref ((struct ddsi_serdata *) sample); /* drops const (tho refcount does change) */ + s->sample = ddsi_serdata_ref (sample); /* drops const (tho refcount does change) */ s->wr_iid = pwr_info->iid; s->isread = false; s->disposed_gen = inst->disposed_gen; @@ -663,19 +663,17 @@ static bool add_sample return true; } -static bool content_filter_accepts (const struct ddsi_sertopic * sertopic, const struct ddsi_serdata *sample) +static bool content_filter_accepts (const struct ddsi_sertopic *sertopic, const struct ddsi_serdata *sample) { bool ret = true; const struct dds_topic *tp = sertopic->status_cb_entity; if (tp->filter_fn) { const dds_topic_descriptor_t * desc = tp->m_descriptor; - char *tmp = os_malloc (desc->m_size); - memset (tmp, 0, desc->m_size); + char *tmp = dds_alloc (desc->m_size); ddsi_serdata_to_sample (sample, tmp, NULL, NULL); ret = (tp->filter_fn) (tmp, tp->filter_ctx); - dds_sample_free(tmp, desc, DDS_FREE_CONTENTS_BIT); - os_free (tmp); + ddsi_sertopic_free_sample (tp->m_stopic, tmp, DDS_FREE_ALL); } return ret; } @@ -1632,7 +1630,6 @@ static int dds_rhc_read_w_qminv { bool trigger_waitsets = false; uint32_t n = 0; - const struct dds_topic_descriptor * desc = rhc->topic->status_cb_entity->m_descriptor; if (lock) { @@ -1691,7 +1688,7 @@ static int dds_rhc_read_w_qminv else { /* The filter didn't match, so free the deserialised copy. */ - dds_sample_free(values[n], desc, DDS_FREE_CONTENTS); + ddsi_sertopic_free_sample (rhc->topic, values[n], DDS_FREE_CONTENTS); } } sample = sample->next; @@ -1760,7 +1757,6 @@ static int dds_rhc_take_w_qminv bool trigger_waitsets = false; uint64_t iid; uint32_t n = 0; - const struct dds_topic_descriptor * desc = rhc->topic->status_cb_entity->m_descriptor; if (lock) { @@ -1839,7 +1835,7 @@ static int dds_rhc_take_w_qminv else { /* The filter didn't match, so free the deserialised copy. */ - dds_sample_free(values[n], desc, DDS_FREE_CONTENTS); + ddsi_sertopic_free_sample (rhc->topic, values[n], DDS_FREE_CONTENTS); } } sample = sample1; @@ -2256,7 +2252,7 @@ static bool update_conditions_locked if (tmp) { - dds_sample_free (tmp, desc, DDS_FREE_CONTENTS_BIT); + ddsi_sertopic_free_sample (rhc->topic, tmp, DDS_FREE_CONTENTS); os_free (tmp); } return trigger; diff --git a/src/core/ddsc/src/dds_stream.c b/src/core/ddsc/src/dds_stream.c index 927d56d..69c6bcd 100644 --- a/src/core/ddsc/src/dds_stream.c +++ b/src/core/ddsc/src/dds_stream.c @@ -380,7 +380,7 @@ void dds_stream_read_buffer (dds_stream_t * is, uint8_t * buffer, uint32_t len) void dds_stream_read_sample (dds_stream_t * is, void * data, const struct ddsi_sertopic_default * topic) { - const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) topic->type; + const struct dds_topic_descriptor * desc = topic->type; /* Check if can copy directly from stream buffer */ if (topic->opt_size && DDS_IS_OK (is, desc->m_size) && (is->m_endian == DDS_ENDIAN)) { @@ -1171,7 +1171,7 @@ static void dds_stream_read (dds_stream_t * is, char * data, const uint32_t * op void dds_stream_write_sample (dds_stream_t * os, const void * data, const struct ddsi_sertopic_default * topic) { - const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) topic->type; + const struct dds_topic_descriptor * desc = topic->type; if (topic->opt_size && DDS_CDR_ALIGNED (os, desc->m_align)) { diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata.h b/src/core/ddsi/include/ddsi/ddsi_serdata.h index 4b2c8ba..5688332 100644 --- a/src/core/ddsi/include/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata.h @@ -82,6 +82,7 @@ typedef void (*ddsi_serdata_to_ser_unref_t) (struct ddsi_serdata *d, const ddsi_ otherwise malloc() is to be used for those. (This allows read/take to be given a block of memory by the caller.) */ typedef bool (*ddsi_serdata_to_sample_t) (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); + typedef bool (*ddsi_serdata_topicless_to_sample_t) (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); /* Test key values of two serdatas for equality (with the same ddsi_serdata_ops, but not necessarily diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata_default.h b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h index 61b0712..5614ff1 100644 --- a/src/core/ddsi/include/ddsi/ddsi_serdata_default.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h @@ -41,27 +41,23 @@ #define CDR_LE 0x0001 #endif -struct CDRHeader -{ +struct CDRHeader { unsigned short identifier; unsigned short options; }; -struct serdatapool /* FIXME: now a serdatapool */ -{ +struct serdatapool { struct nn_freelist freelist; }; -typedef struct dds_key_hash -{ +typedef struct dds_key_hash { char m_hash [16]; /* Key hash value. Also possibly key. Suitably aligned for accessing as uint32_t's */ unsigned m_set : 1; /* has it been initialised? */ unsigned m_iskey : 1; /* m_hash is key value */ } dds_key_hash_t; -struct ddsi_serdata_default -{ +struct ddsi_serdata_default { struct ddsi_serdata c; uint32_t pos; uint32_t size; @@ -82,18 +78,18 @@ struct ddsi_serdata_default }; struct dds_key_descriptor; +struct dds_topic_descriptor; #ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED #define DDS_TOPIC_INTERN_FILTER_FN_DEFINED typedef bool (*dds_topic_intern_filter_fn) (const void * sample, void *ctx); #endif -struct ddsi_sertopic_default -{ +struct ddsi_sertopic_default { struct ddsi_sertopic c; uint16_t native_encoding_identifier; /* (PL_)?CDR_(LE|BE) */ - void * type; + struct dds_topic_descriptor * type; unsigned nkeys; uint32_t flags; diff --git a/src/core/ddsi/include/ddsi/ddsi_sertopic.h b/src/core/ddsi/include/ddsi/ddsi_sertopic.h index 09b2048..fe1d68f 100644 --- a/src/core/ddsi/include/ddsi/ddsi_sertopic.h +++ b/src/core/ddsi/include/ddsi/ddsi_sertopic.h @@ -13,6 +13,7 @@ #define DDSI_SERTOPIC_H #include "util/ut_avl.h" +#include "ddsc/dds_public_alloc.h" struct ddsi_serdata; struct ddsi_serdata_ops; @@ -39,12 +40,23 @@ struct ddsi_sertopic { typedef void (*ddsi_sertopic_deinit_t) (struct ddsi_sertopic *tp); +/* Release any memory allocated by ddsi_sertopic_to_sample */ +typedef void (*ddsi_sertopic_free_sample_t) (const struct ddsi_sertopic *d, void *sample, dds_free_op_t op); + struct ddsi_sertopic_ops { ddsi_sertopic_deinit_t deinit; + ddsi_sertopic_free_sample_t free_sample; }; struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *tp); void ddsi_sertopic_unref (struct ddsi_sertopic *tp); uint32_t ddsi_sertopic_compute_serdata_basehash (const struct ddsi_serdata_ops *ops); +inline void ddsi_sertopic_deinit (struct ddsi_sertopic *tp) { + tp->ops->deinit (tp); +} +inline void ddsi_sertopic_free_sample (const struct ddsi_sertopic *tp, void *sample, dds_free_op_t op) { + tp->ops->free_sample (tp, sample, op); +} + #endif diff --git a/src/core/ddsi/src/ddsi_serdata_default.c b/src/core/ddsi/src/ddsi_serdata_default.c index 1d1e45e..ea17fc3 100644 --- a/src/core/ddsi/src/ddsi_serdata_default.c +++ b/src/core/ddsi/src/ddsi_serdata_default.c @@ -272,14 +272,14 @@ static struct ddsi_serdata *serdata_default_from_ser (const struct ddsi_sertopic struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash) { /* FIXME: not quite sure this is correct, though a check against a specially hacked OpenSplice suggests it is */ - if (!(tpcmn->status_cb_entity->m_descriptor->m_flagset & DDS_TOPIC_FIXED_KEY)) + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; + if (!(tp->type->m_flagset & DDS_TOPIC_FIXED_KEY)) { /* keyhash is MD5 of a key value, so impossible to turn into a key value */ return NULL; } else { - const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; struct ddsi_serdata_default *d = serdata_default_new(tp, SDK_KEY); d->hdr.identifier = CDR_BE; serdata_default_append_blob (&d, 1, sizeof (keyhash->value), keyhash->value); diff --git a/src/core/ddsi/src/ddsi_sertopic.c b/src/core/ddsi/src/ddsi_sertopic.c index 2c415a6..3a5687b 100644 --- a/src/core/ddsi/src/ddsi_sertopic.c +++ b/src/core/ddsi/src/ddsi_sertopic.c @@ -38,7 +38,7 @@ void ddsi_sertopic_unref (struct ddsi_sertopic *sertopic) { if (os_atomic_dec32_ov (&sertopic->refc) == 1) { - sertopic->ops->deinit (sertopic); + ddsi_sertopic_deinit (sertopic); os_free (sertopic->name_typename); os_free (sertopic->name); os_free (sertopic->typename); @@ -59,3 +59,6 @@ uint32_t ddsi_sertopic_compute_serdata_basehash (const struct ddsi_serdata_ops * memcpy (&res, digest, sizeof (res)); return res; } + +extern inline void ddsi_sertopic_deinit (struct ddsi_sertopic *tp); +extern inline void ddsi_sertopic_free_sample (const struct ddsi_sertopic *tp, void *sample, dds_free_op_t op); diff --git a/src/core/ddsi/src/ddsi_sertopic_default.c b/src/core/ddsi/src/ddsi_sertopic_default.c index 56a3650..e906d26 100644 --- a/src/core/ddsi/src/ddsi_sertopic_default.c +++ b/src/core/ddsi/src/ddsi_sertopic_default.c @@ -25,11 +25,18 @@ /* FIXME: sertopic /= ddstopic so a lot of stuff needs to be moved here from dds_topic.c and the free function needs to be implemented properly */ -static void deinit_sertopic_default (struct ddsi_sertopic *tp) +static void sertopic_default_deinit (struct ddsi_sertopic *tp) { (void)tp; } +static void sertopic_default_free_sample (const struct ddsi_sertopic *sertopic_common, void *sample, dds_free_op_t op) +{ + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)sertopic_common; + dds_sample_free (sample, tp->type, op); +} + const struct ddsi_sertopic_ops ddsi_sertopic_ops_default = { - .deinit = deinit_sertopic_default + .deinit = sertopic_default_deinit, + .free_sample = sertopic_default_free_sample }; From f2f436bde3cf225a6beaef8bb87ac24bec75b46c Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Oct 2018 13:27:13 +0800 Subject: [PATCH 10/13] wrap indirect calls to WHC in inline functions Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_whc.c | 107 ++++++++++++++--------------- src/core/ddsi/CMakeLists.txt | 1 + src/core/ddsi/include/ddsi/q_whc.h | 43 +++++++++++- src/core/ddsi/src/q_debmon.c | 2 +- src/core/ddsi/src/q_entity.c | 18 ++--- src/core/ddsi/src/q_receive.c | 16 ++--- src/core/ddsi/src/q_transmit.c | 12 ++-- src/core/ddsi/src/q_whc.c | 28 ++++++++ src/core/ddsi/src/q_xevent.c | 6 +- 9 files changed, 151 insertions(+), 82 deletions(-) create mode 100644 src/core/ddsi/src/q_whc.c diff --git a/src/core/ddsc/src/dds_whc.c b/src/core/ddsc/src/dds_whc.c index 19f9680..8e06b22 100644 --- a/src/core/ddsc/src/dds_whc.c +++ b/src/core/ddsc/src/dds_whc.c @@ -96,7 +96,7 @@ struct whc_impl { }; struct whc_sample_iter_impl { - struct whc_impl *whc; + struct whc_sample_iter_base c; bool first; }; @@ -135,39 +135,39 @@ static struct whc_node *whc_findseq (const struct whc_impl *whc, seqno_t seq); static void insert_whcn_in_hash (struct whc_impl *whc, struct whc_node *whcn); static void whc_delete_one (struct whc_impl *whc, struct whc_node *whcn); static int compare_seq (const void *va, const void *vb); -static unsigned whc_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list); static void free_deferred_free_list (struct whc_impl *whc, struct whc_node *deferred_free_list); static void get_state_locked(const struct whc_impl *whc, struct whc_state *st); -static unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); -static void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); -static void whc_get_state(const struct whc *whc, struct whc_state *st); -static int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); -static seqno_t whc_next_seq (const struct whc *whc, seqno_t seq); -static bool whc_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); -static bool whc_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); -static void whc_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info); -static unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st); -static void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it); -static bool whc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample); -static void whc_free (struct whc *whc); +static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list); +static unsigned whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); +static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); +static void whc_default_get_state(const struct whc *whc, struct whc_state *st); +static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq); +static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); +static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); +static void whc_default_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info); +static unsigned whc_default_downgrade_to_volatile (struct whc *whc, struct whc_state *st); +static void whc_default_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it); +static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample); +static void whc_default_free (struct whc *whc); static const ut_avlTreedef_t whc_seq_treedef = UT_AVL_TREEDEF_INITIALIZER (offsetof (struct whc_intvnode, avlnode), offsetof (struct whc_intvnode, min), compare_seq, 0); static const struct whc_ops whc_ops = { - .insert = whc_insert, - .remove_acked_messages = whc_remove_acked_messages, - .free_deferred_free_list = whc_free_deferred_free_list, - .get_state = whc_get_state, - .next_seq = whc_next_seq, - .borrow_sample = whc_borrow_sample, - .borrow_sample_key = whc_borrow_sample_key, - .return_sample = whc_return_sample, - .sample_iter_init = whc_sample_iter_init, - .sample_iter_borrow_next = whc_sample_iter_borrow_next, - .downgrade_to_volatile = whc_downgrade_to_volatile, - .free = whc_free + .insert = whc_default_insert, + .remove_acked_messages = whc_default_remove_acked_messages, + .free_deferred_free_list = whc_default_free_deferred_free_list, + .get_state = whc_default_get_state, + .next_seq = whc_default_next_seq, + .borrow_sample = whc_default_borrow_sample, + .borrow_sample_key = whc_default_borrow_sample_key, + .return_sample = whc_default_return_sample, + .sample_iter_init = whc_default_sample_iter_init, + .sample_iter_borrow_next = whc_default_sample_iter_borrow_next, + .downgrade_to_volatile = whc_default_downgrade_to_volatile, + .free = whc_default_free }; #if USE_EHH @@ -405,7 +405,7 @@ static void free_whc_node_contents (struct whc_node *whcn) } } -void whc_free (struct whc *whc_generic) +void whc_default_free (struct whc *whc_generic) { /* Freeing stuff without regards for maintaining data structures */ struct whc_impl * const whc = (struct whc_impl *)whc_generic; @@ -467,7 +467,7 @@ static void get_state_locked(const struct whc_impl *whc, struct whc_state *st) } } -static void whc_get_state(const struct whc *whc_generic, struct whc_state *st) +static void whc_default_get_state(const struct whc *whc_generic, struct whc_state *st) { const struct whc_impl * const whc = (const struct whc_impl *)whc_generic; os_mutexLock ((struct os_mutex *)&whc->lock); @@ -518,7 +518,7 @@ static struct whc_node *find_nextseq_intv (struct whc_intvnode **p_intv, const s } } -static seqno_t whc_next_seq (const struct whc *whc_generic, seqno_t seq) +static seqno_t whc_default_next_seq (const struct whc *whc_generic, seqno_t seq) { const struct whc_impl * const whc = (const struct whc_impl *)whc_generic; struct whc_node *n; @@ -596,7 +596,7 @@ static int whcn_in_tlidx (const struct whc_impl *whc, const struct whc_idxnode * } } -static unsigned whc_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st) +static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st) { struct whc_impl * const whc = (struct whc_impl *)whc_generic; seqno_t old_max_drop_seq; @@ -638,8 +638,8 @@ static unsigned whc_downgrade_to_volatile (struct whc *whc_generic, struct whc_s them all. */ old_max_drop_seq = whc->max_drop_seq; whc->max_drop_seq = 0; - cnt = whc_remove_acked_messages_full (whc, old_max_drop_seq, &deferred_free_list); - whc_free_deferred_free_list (whc_generic, deferred_free_list); + cnt = whc_default_remove_acked_messages_full (whc, old_max_drop_seq, &deferred_free_list); + whc_default_free_deferred_free_list (whc_generic, deferred_free_list); assert (whc->max_drop_seq == old_max_drop_seq); get_state_locked(whc, st); os_mutexUnlock (&whc->lock); @@ -789,13 +789,13 @@ static void free_deferred_free_list (struct whc_impl *whc, struct whc_node *defe } } -static void whc_free_deferred_free_list (struct whc *whc_generic, struct whc_node *deferred_free_list) +static void whc_default_free_deferred_free_list (struct whc *whc_generic, struct whc_node *deferred_free_list) { struct whc_impl * const whc = (struct whc_impl *)whc_generic; free_deferred_free_list(whc, deferred_free_list); } -static unsigned whc_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list) +static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list) { struct whc_intvnode *intv; struct whc_node *whcn; @@ -871,7 +871,7 @@ static unsigned whc_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t m return ndropped; } -static unsigned whc_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list) +static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list) { struct whc_intvnode *intv; struct whc_node *whcn; @@ -1005,7 +1005,7 @@ static unsigned whc_remove_acked_messages_full (struct whc_impl *whc, seqno_t ma return ndropped; } -static unsigned whc_remove_acked_messages (struct whc *whc_generic, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list) +static unsigned whc_default_remove_acked_messages (struct whc *whc_generic, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list) { struct whc_impl * const whc = (struct whc_impl *)whc_generic; unsigned cnt; @@ -1018,7 +1018,7 @@ static unsigned whc_remove_acked_messages (struct whc *whc_generic, seqno_t max_ { struct whc_state tmp; get_state_locked(whc, &tmp); - TRACE_WHC(("whc_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq)); + TRACE_WHC(("whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq)); TRACE_WHC((" whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n", tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth)); } @@ -1026,15 +1026,15 @@ static unsigned whc_remove_acked_messages (struct whc *whc_generic, seqno_t max_ check_whc (whc); if (whc->idxdepth == 0) - cnt = whc_remove_acked_messages_noidx (whc, max_drop_seq, deferred_free_list); + cnt = whc_default_remove_acked_messages_noidx (whc, max_drop_seq, deferred_free_list); else - cnt = whc_remove_acked_messages_full (whc, max_drop_seq, deferred_free_list); + cnt = whc_default_remove_acked_messages_full (whc, max_drop_seq, deferred_free_list); get_state_locked(whc, whcst); os_mutexUnlock (&whc->lock); return cnt; } -static struct whc_node *whc_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata) +static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata) { struct whc_node *newn = NULL; @@ -1095,7 +1095,7 @@ static struct whc_node *whc_insert_seq (struct whc_impl *whc, seqno_t max_drop_s return newn; } -static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) +static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) { struct whc_impl * const whc = (struct whc_impl *)whc_generic; struct whc_node *newn = NULL; @@ -1112,7 +1112,7 @@ static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t se { struct whc_state whcst; get_state_locked(whc, &whcst); - TRACE_WHC(("whc_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash)); + TRACE_WHC(("whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash)); TRACE_WHC((" whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n", whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth)); } @@ -1126,7 +1126,7 @@ static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t se assert (whc->seq_size == 0 || seq > whc->maxseq_node->seq); /* Always insert in seq admin */ - newn = whc_insert_seq (whc, max_drop_seq, seq, plist, serdata); + newn = whc_default_insert_seq (whc, max_drop_seq, seq, plist, serdata); TRACE_WHC((" whcn %p:", (void*)newn)); @@ -1179,7 +1179,7 @@ static int whc_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t se /* Special case for dropping everything beyond T-L history when the new sample is being auto-acknowledged (for lack of reliable readers), and the keep-last T-L history is shallower than the keep-last regular history (normal path handles this via pruning in - whc_remove_acked_messages, but that never happens when there are no readers). */ + whc_default_remove_acked_messages, but that never happens when there are no readers). */ if (seq <= max_drop_seq && whc->tldepth > 0 && whc->idxdepth > whc->tldepth) { unsigned pos = idxn->headidx + whc->idxdepth - whc->tldepth; @@ -1246,7 +1246,7 @@ static void make_borrowed_sample(struct whc_borrowed_sample *sample, struct whc_ sample->last_rexmit_ts = whcn->last_rexmit_ts; } -static bool whc_borrow_sample (const struct whc *whc_generic, seqno_t seq, struct whc_borrowed_sample *sample) +static bool whc_default_borrow_sample (const struct whc *whc_generic, seqno_t seq, struct whc_borrowed_sample *sample) { const struct whc_impl * const whc = (const struct whc_impl *)whc_generic; struct whc_node *whcn; @@ -1263,7 +1263,7 @@ static bool whc_borrow_sample (const struct whc *whc_generic, seqno_t seq, struc return found; } -static bool whc_borrow_sample_key (const struct whc *whc_generic, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample) +static bool whc_default_borrow_sample_key (const struct whc *whc_generic, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample) { const struct whc_impl * const whc = (const struct whc_impl *)whc_generic; struct whc_node *whcn; @@ -1304,7 +1304,7 @@ static void return_sample_locked (struct whc_impl *whc, struct whc_borrowed_samp } } -static void whc_return_sample (struct whc *whc_generic, struct whc_borrowed_sample *sample, bool update_retransmit_info) +static void whc_default_return_sample (struct whc *whc_generic, struct whc_borrowed_sample *sample, bool update_retransmit_info) { struct whc_impl * const whc = (struct whc_impl *)whc_generic; os_mutexLock (&whc->lock); @@ -1312,18 +1312,17 @@ static void whc_return_sample (struct whc *whc_generic, struct whc_borrowed_samp os_mutexUnlock (&whc->lock); } -static void whc_sample_iter_init (const struct whc *whc_generic, struct whc_sample_iter *opaque_it) +static void whc_default_sample_iter_init (const struct whc *whc_generic, struct whc_sample_iter *opaque_it) { - const struct whc_impl * const whc = (const struct whc_impl *)whc_generic; - struct whc_sample_iter_impl *it = (struct whc_sample_iter_impl *)opaque_it->opaque.opaque; - it->whc = (struct whc_impl *)whc; + struct whc_sample_iter_impl *it = (struct whc_sample_iter_impl *)opaque_it; + it->c.whc = (struct whc *)whc_generic; it->first = true; } -static bool whc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample) +static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample) { - struct whc_sample_iter_impl * const it = (struct whc_sample_iter_impl *)opaque_it->opaque.opaque; - struct whc_impl * const whc = it->whc; + struct whc_sample_iter_impl * const it = (struct whc_sample_iter_impl *)opaque_it; + struct whc_impl * const whc = (struct whc_impl *)it->c.whc; struct whc_node *whcn; struct whc_intvnode *intv; seqno_t seq; diff --git a/src/core/ddsi/CMakeLists.txt b/src/core/ddsi/CMakeLists.txt index d7707f2..c8d062b 100644 --- a/src/core/ddsi/CMakeLists.txt +++ b/src/core/ddsi/CMakeLists.txt @@ -54,6 +54,7 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src" q_time.c q_transmit.c q_inverse_uint32_set.c + q_whc.c q_xevent.c q_xmsg.c q_freelist.c diff --git a/src/core/ddsi/include/ddsi/q_whc.h b/src/core/ddsi/include/ddsi/q_whc.h index c9cfa55..1a99e65 100644 --- a/src/core/ddsi/include/ddsi/q_whc.h +++ b/src/core/ddsi/include/ddsi/q_whc.h @@ -42,8 +42,12 @@ struct whc_state { an iter on the stack without specifying an implementation. If future changes or implementations require more, these can be adjusted. An implementation should check things fit at compile time. */ -#define WHC_SAMPLE_ITER_SIZE (2*sizeof(void *)) +#define WHC_SAMPLE_ITER_SIZE (1*sizeof(void *)) +struct whc_sample_iter_base { + struct whc *whc; +}; struct whc_sample_iter { + struct whc_sample_iter_base c; union { char opaque[WHC_SAMPLE_ITER_SIZE]; /* cover alignment requirements: */ @@ -90,6 +94,43 @@ struct whc { const struct whc_ops *ops; }; +inline seqno_t whc_next_seq (const struct whc *whc, seqno_t seq) { + return whc->ops->next_seq (whc, seq); +} +inline void whc_get_state (const struct whc *whc, struct whc_state *st) { + whc->ops->get_state (whc, st); +} +inline bool whc_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample) { + return whc->ops->borrow_sample (whc, seq, sample); +} +inline bool whc_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample) { + return whc->ops->borrow_sample_key (whc, serdata_key, sample); +} +inline void whc_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info) { + whc->ops->return_sample (whc, sample, update_retransmit_info); +} +inline void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *it) { + whc->ops->sample_iter_init (whc, it); +} +inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_borrowed_sample *sample) { + return it->c.whc->ops->sample_iter_borrow_next (it, sample); +} +inline void whc_free (struct whc *whc) { + whc->ops->free (whc); +} +inline int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) { + return whc->ops->insert (whc, max_drop_seq, seq, plist, serdata, tk); +} +inline unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st) { + return whc->ops->downgrade_to_volatile (whc, st); +} +inline unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list) { + return whc->ops->remove_acked_messages (whc, max_drop_seq, whcst, deferred_free_list); +} +inline void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list) { + whc->ops->free_deferred_free_list (whc, deferred_free_list); +} + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsi/src/q_debmon.c b/src/core/ddsi/src/q_debmon.c index 4b1f839..6671cac 100644 --- a/src/core/ddsi/src/q_debmon.c +++ b/src/core/ddsi/src/q_debmon.c @@ -188,7 +188,7 @@ static int print_participants (struct thread_state1 *self, ddsi_tran_conn_t conn continue; os_mutexLock (&w->e.lock); print_endpoint_common (conn, "wr", &w->e, &w->c, w->xqos, w->topic); - w->whc->ops->get_state(w->whc, &whcst); + whc_get_state(w->whc, &whcst); x += cpf (conn, " whc [%lld,%lld] unacked %"PRIuSIZE"%s [%u,%u] seq %lld seq_xmit %lld cs_seq %lld\n", whcst.min_seq, whcst.max_seq, whcst.unacked_bytes, w->throttling ? " THROTTLING" : "", diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 0e61baf..d9d6de9 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -1314,7 +1314,7 @@ static void writer_drop_connection (const struct nn_guid * wr_guid, const struct } } os_mutexUnlock (&wr->e.lock); - wr->whc->ops->free_deferred_free_list (wr->whc, deferred_free_list); + whc_free_deferred_free_list (wr->whc, deferred_free_list); free_wr_prd_match (m); } } @@ -1606,8 +1606,8 @@ static void writer_add_local_connection (struct writer *wr, struct reader *rd) { struct whc_sample_iter it; struct whc_borrowed_sample sample; - wr->whc->ops->sample_iter_init(wr->whc, &it); - while (wr->whc->ops->sample_iter_borrow_next(&it, &sample)) + whc_sample_iter_init(wr->whc, &it); + while (whc_sample_iter_borrow_next(&it, &sample)) { struct proxy_writer_info pwr_info; struct ddsi_serdata *payload = sample.serdata; @@ -2540,7 +2540,7 @@ unsigned remove_acked_messages (struct writer *wr, struct whc_state *whcst, stru unsigned n; assert (wr->e.guid.entityid.u != NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER); ASSERT_MUTEX_HELD (&wr->e.lock); - n = wr->whc->ops->remove_acked_messages (wr->whc, writer_max_drop_seq (wr), whcst, deferred_free_list); + n = whc_remove_acked_messages (wr->whc, writer_max_drop_seq (wr), whcst, deferred_free_list); /* when transitioning from >= low-water to < low-water, signal anyone waiting in throttle_writer() */ if (wr->throttling && whcst->unacked_bytes <= wr->whc_low) @@ -2854,7 +2854,7 @@ static void gc_delete_writer (struct gcreq *gcreq) (wr->status_cb) (wr->status_cb_entity, NULL); } - wr->whc->ops->free (wr->whc); + whc_free (wr->whc); #ifdef DDSI_INCLUDE_SSM if (wr->ssm_as) unref_addrset (wr->ssm_as); @@ -2950,7 +2950,7 @@ int delete_writer (const struct nn_guid *guid) be the usual case), do it immediately. If more data is still coming in (which can't really happen at the moment, but might again in the future) it'll potentially be discarded. */ - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); if (whcst.unacked_bytes == 0) { nn_log (LC_DISCOVERY, "delete_writer(guid %x:%x:%x:%x) - no unack'ed samples\n", PGUID (*guid)); @@ -2982,12 +2982,12 @@ void writer_exit_startup_mode (struct writer *wr) struct whc_state whcst; wr->startup_mode = 0; cnt += remove_acked_messages (wr, &whcst, &deferred_free_list); - cnt += wr->whc->ops->downgrade_to_volatile (wr->whc, &whcst); + cnt += whc_downgrade_to_volatile (wr->whc, &whcst); writer_clear_retransmitting (wr); nn_log (LC_DISCOVERY, " %x:%x:%x:%x: dropped %u samples\n", PGUID(wr->e.guid), cnt); } os_mutexUnlock (&wr->e.lock); - wr->whc->ops->free_deferred_free_list (wr->whc, deferred_free_list); + whc_free_deferred_free_list (wr->whc, deferred_free_list); } uint64_t writer_instance_id (const struct nn_guid *guid) @@ -4316,7 +4316,7 @@ static void proxy_reader_set_delete_and_ack_all_messages (struct proxy_reader *p writer_clear_retransmitting (wr); } os_mutexUnlock (&wr->e.lock); - wr->whc->ops->free_deferred_free_list (wr->whc, deferred_free_list); + whc_free_deferred_free_list (wr->whc, deferred_free_list); } wrguid = wrguid_next; diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index 1fe232a..bf5846d 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -638,7 +638,7 @@ static void force_heartbeat_to_peer (struct writer *wr, const struct whc_state * static seqno_t grow_gap_to_next_seq (const struct writer *wr, seqno_t seq) { - seqno_t next_seq = wr->whc->ops->next_seq (wr->whc, seq - 1); + seqno_t next_seq = whc_next_seq (wr->whc, seq - 1); seqno_t seq_xmit = READ_SEQ_XMIT(wr); if (next_seq == MAX_SEQ_NUMBER) /* no next sample */ return seq_xmit + 1; @@ -835,7 +835,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac else { /* There's actually no guarantee that we need this information */ - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); } /* If this reader was marked as "non-responsive" in the past, it's now responding again, @@ -944,7 +944,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac { seqno_t seq = seqbase + i; struct whc_borrowed_sample sample; - if (wr->whc->ops->borrow_sample (wr->whc, seq, &sample)) + if (whc_borrow_sample (wr->whc, seq, &sample)) { if (!wr->retransmitting && sample.unacked) writer_set_retransmitting (wr); @@ -982,7 +982,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac } } - wr->whc->ops->return_sample(wr->whc, &sample, true); + whc_return_sample(wr->whc, &sample, true); } else if (gapstart == -1) { @@ -1076,7 +1076,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac TRACE ((")")); out: os_mutexUnlock (&wr->e.lock); - wr->whc->ops->free_deferred_free_list (wr->whc, deferred_free_list); + whc_free_deferred_free_list (wr->whc, deferred_free_list); return 1; } @@ -1498,7 +1498,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N /* Resend the requested fragments if we still have the sample, send a Gap if we don't have them anymore. */ - if (wr->whc->ops->borrow_sample (wr->whc, seq, &sample)) + if (whc_borrow_sample (wr->whc, seq, &sample)) { const unsigned base = msg->fragmentNumberState.bitmap_base - 1; int enqueued = 1; @@ -1514,7 +1514,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N enqueued = qxev_msg_rexmit_wrlock_held (wr->evq, reply, 0); } } - wr->whc->ops->return_sample (wr->whc, &sample, false); + whc_return_sample (wr->whc, &sample, false); } else { @@ -1541,7 +1541,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N to give the reader a chance to nack the rest and make sure hearbeats will go out at a reasonably high rate for a while */ struct whc_state whcst; - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); force_heartbeat_to_peer (wr, &whcst, prd, 1); writer_hbcontrol_note_asyncwrite (wr, now_mt ()); } diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index 3b87032..c6243b4 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -884,7 +884,7 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist if (!do_insert) res = 0; - else if ((insres = wr->whc->ops->insert (wr->whc, writer_max_drop_seq (wr), seq, plist, serdata, tk)) < 0) + else if ((insres = whc_insert (wr->whc, writer_max_drop_seq (wr), seq, plist, serdata, tk)) < 0) res = insres; else res = 1; @@ -893,7 +893,7 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist if (wr->e.guid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) { struct whc_state whcst; - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); if (WHCST_ISEMPTY(&whcst)) assert (wr->c.pp->builtins_deleted); } @@ -947,7 +947,7 @@ static os_result throttle_writer (struct nn_xpack *xp, struct writer *wr) nn_mtime_t tnow = now_mt (); const nn_mtime_t abstimeout = add_duration_to_mtime (tnow, nn_from_ddsi_duration (wr->xqos->reliability.max_blocking_time)); struct whc_state whcst; - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); { #ifndef NDEBUG @@ -992,7 +992,7 @@ static os_result throttle_writer (struct nn_xpack *xp, struct writer *wr) thread_state_asleep (lookup_thread_state()); result = os_condTimedWait (&wr->throttle_cond, &wr->e.lock, &timeout); thread_state_awake (lookup_thread_state()); - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); } if (result == os_resultTimeout) { @@ -1064,7 +1064,7 @@ static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_p /* If WHC overfull, block. */ { struct whc_state whcst; - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); if (whcst.unacked_bytes > wr->whc_high) { os_result ores; @@ -1119,7 +1119,7 @@ static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_p { struct whc_state whcst; if (wr->heartbeat_xevent) - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); /* Note the subtlety of enqueueing with the lock held but transmitting without holding the lock. Still working on diff --git a/src/core/ddsi/src/q_whc.c b/src/core/ddsi/src/q_whc.c new file mode 100644 index 0000000..dd7e95c --- /dev/null +++ b/src/core/ddsi/src/q_whc.c @@ -0,0 +1,28 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include "os/os.h" +#include "ddsi/q_rtps.h" +#include "ddsi/q_time.h" +#include "ddsi/q_whc.h" + +extern inline seqno_t whc_next_seq (const struct whc *whc, seqno_t seq); +extern inline void whc_get_state (const struct whc *whc, struct whc_state *st); +extern inline bool whc_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); +extern inline bool whc_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); +extern inline void whc_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info); +extern inline void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *it); +extern inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_borrowed_sample *sample); +extern inline void whc_free (struct whc *whc); +extern int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +extern unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st); +extern unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); +extern void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index 97f7f6a..9a3729d 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -607,7 +607,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt assert (wr->reliable); os_mutexLock (&wr->e.lock); - wr->whc->ops->get_state(wr->whc, &whcst); + whc_get_state(wr->whc, &whcst); if (!writer_must_have_hb_scheduled (wr, &whcst)) { hbansreq = 1; /* just for trace */ @@ -1023,7 +1023,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e nn_xmsg_free (mpayload); os_mutexLock (&spdp_wr->e.lock); - if (spdp_wr->whc->ops->borrow_sample_key (spdp_wr->whc, sd, &sample)) + if (whc_borrow_sample_key (spdp_wr->whc, sd, &sample)) { /* Claiming it is new rather than a retransmit so that the rexmit limiting won't kick in. It is best-effort and therefore the @@ -1031,7 +1031,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e place anyway. Nor is it necessary to fiddle with heartbeat control stuff. */ enqueue_sample_wrlock_held (spdp_wr, sample.seq, sample.plist, sample.serdata, prd, 1); - spdp_wr->whc->ops->return_sample(spdp_wr->whc, &sample, false); + whc_return_sample(spdp_wr->whc, &sample, false); #ifndef NDEBUG sample_found = true; #endif From b34cbdcf0c9bc80571de472937b7392e19a3c49d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Oct 2018 13:38:16 +0800 Subject: [PATCH 11/13] sockaddr_compare should really be ipaddr_compare Signed-off-by: Erik Boasson --- src/core/ddsi/include/ddsi/ddsi_ipaddr.h | 1 + src/core/ddsi/src/ddsi_ipaddr.c | 36 +++++++++++++++++++++++- src/core/ddsi/src/ddsi_tcp.c | 3 +- src/os/include/os/os_socket.h | 18 ------------ src/os/src/os_socket.c | 4 +-- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/core/ddsi/include/ddsi/ddsi_ipaddr.h b/src/core/ddsi/include/ddsi/ddsi_ipaddr.h index 0fa1b44..35bdc44 100644 --- a/src/core/ddsi/include/ddsi/ddsi_ipaddr.h +++ b/src/core/ddsi/include/ddsi/ddsi_ipaddr.h @@ -16,6 +16,7 @@ enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[]); enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str, int32_t kind); +int ddsi_ipaddr_compare (const os_sockaddr *const sa1, const os_sockaddr *const sa2); char *ddsi_ipaddr_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port); void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr *src, int32_t kind); void ddsi_ipaddr_from_loc (os_sockaddr_storage *dst, const nn_locator_t *src); diff --git a/src/core/ddsi/src/ddsi_ipaddr.c b/src/core/ddsi/src/ddsi_ipaddr.c index 96766da..fb8a69e 100644 --- a/src/core/ddsi/src/ddsi_ipaddr.c +++ b/src/core/ddsi/src/ddsi_ipaddr.c @@ -16,6 +16,40 @@ #include "ddsi/q_nwif.h" #include "ddsi/q_config.h" +int ddsi_ipaddr_compare (const os_sockaddr *const sa1, const os_sockaddr *const sa2) +{ + int eq; + size_t sz; + + if ((eq = sa1->sa_family - sa2->sa_family) == 0) { + switch(sa1->sa_family) { +#if (OS_SOCKET_HAS_IPV6 == 1) + case AF_INET6: { + os_sockaddr_in6 *sin61, *sin62; + sin61 = (os_sockaddr_in6 *)sa1; + sin62 = (os_sockaddr_in6 *)sa2; + sz = sizeof(sin61->sin6_addr); + eq = memcmp(&sin61->sin6_addr, &sin62->sin6_addr, sz); + break; + } +#endif /* OS_SOCKET_HAS_IPV6 */ + case AF_INET: { + os_sockaddr_in *sin1, *sin2; + sin1 = (os_sockaddr_in *)sa1; + sin2 = (os_sockaddr_in *)sa2; + sz = sizeof(sin1->sin_addr); + eq = memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(sz)); + break; + } + default: { + assert(0); + } + } + } + + return eq; +} + enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[]) { os_sockaddr_storage tmp, iftmp, nmtmp, ownip; @@ -29,7 +63,7 @@ enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory ddsi_ipaddr_from_loc(&ownip, &gv.ownloc); if (os_sockaddrSameSubnet ((os_sockaddr *) &tmp, (os_sockaddr *) &iftmp, (os_sockaddr *) &nmtmp)) { - if (os_sockaddr_compare((os_sockaddr *)&iftmp, (os_sockaddr *)&ownip) == 0) + if (ddsi_ipaddr_compare((os_sockaddr *)&iftmp, (os_sockaddr *)&ownip) == 0) return DNAR_SAME; else return DNAR_LOCAL; diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c index b2b1f9e..b4ac620 100644 --- a/src/core/ddsi/src/ddsi_tcp.c +++ b/src/core/ddsi/src/ddsi_tcp.c @@ -91,8 +91,7 @@ static int ddsi_tcp_cmp_conn (const ddsi_tcp_conn_t c1, const ddsi_tcp_conn_t c2 return (a1s->sa_family < a2s->sa_family) ? -1 : 1; else if (c1->m_peer_port != c2->m_peer_port) return (c1->m_peer_port < c2->m_peer_port) ? -1 : 1; - - return os_sockaddr_compare(a1s, a2s); + return ddsi_ipaddr_compare (a1s, a2s); } typedef struct ddsi_tcp_node diff --git a/src/os/include/os/os_socket.h b/src/os/include/os/os_socket.h index 511c1b4..24a67b3 100644 --- a/src/os/include/os/os_socket.h +++ b/src/os/include/os/os_socket.h @@ -271,24 +271,6 @@ extern "C" { OSAPI_EXPORT uint16_t os_sockaddr_get_port(const os_sockaddr *const sa) __nonnull_all__; - /** - * Compare two IP addresses for equality - does not consider port number. - * This is a 'straight' compare i.e. family must match and address bytes - * must correspond. It does not consider the possibility of IPv6 mapped - * IPv4 addresses or anything arcane like that. - * @param sa1 First socket address - * @param sa2 Second socket address. - * @return true if equal, false otherwise. - * @return Integer less than, equal to, or greater than zero if sa1 is - * found, respectively, to be less than, to match, or be greater - * than sa2. - * @pre both sa1 and sa2 are valid os_sockaddr pointers. - */ - OSAPI_EXPORT int - os_sockaddr_compare( - const os_sockaddr *const sa1, - const os_sockaddr *const sa2) __nonnull_all__ __attribute_pure__; - /** * Check if IP address of given socket address is unspecified. * @param sa Socket address diff --git a/src/os/src/os_socket.c b/src/os/src/os_socket.c index 5cb7b71..b6525f0 100644 --- a/src/os/src/os_socket.c +++ b/src/os/src/os_socket.c @@ -104,7 +104,7 @@ uint16_t os_sockaddr_get_port(const os_sockaddr *const sa) return port; } -int os_sockaddr_compare( +static int os_sockaddr_compare( const os_sockaddr *const sa1, const os_sockaddr *const sa2) { @@ -142,7 +142,7 @@ int os_sockaddr_compare( sin1 = (os_sockaddr_in *)sa1; sin2 = (os_sockaddr_in *)sa2; sz = sizeof(sin1->sin_addr); - eq = memcmp(sin1, sin2, sizeof(*sin1)); + eq = memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(sz)); } break; } From e3874c3c277872cc13b90f8203201857e33398b0 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Oct 2018 21:04:26 +0800 Subject: [PATCH 12/13] add some missing details in comments for serdata operations Signed-off-by: Erik Boasson --- src/core/ddsi/include/ddsi/ddsi_serdata.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata.h b/src/core/ddsi/include/ddsi/ddsi_serdata.h index 5688332..4d1dc95 100644 --- a/src/core/ddsi/include/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata.h @@ -83,10 +83,15 @@ typedef void (*ddsi_serdata_to_ser_unref_t) (struct ddsi_serdata *d, const ddsi_ by the caller.) */ typedef bool (*ddsi_serdata_to_sample_t) (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); +/* Create a sample from a topicless serdata, as returned by serdata_to_topicless. This sample + obviously has just the key fields filled in, and is used for generating invalid samples. */ typedef bool (*ddsi_serdata_topicless_to_sample_t) (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); -/* Test key values of two serdatas for equality (with the same ddsi_serdata_ops, but not necessarily - of the same topic) */ +/* Test key values of two serdatas for equality. The two will have the same ddsi_serdata_ops, + but are not necessarily of the same topic (one can decide to never consider them equal if they + are of different topics, of course; but the nice thing about _not_ doing that is that all + instances with a certain key value with have the same instance id, and that in turn makes + computing equijoins across topics much simpler). */ typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct ddsi_serdata *b); struct ddsi_serdata_ops { From 4a4f4e22d1c5b9923b1e986011e66edfa9012e9d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Oct 2018 21:37:06 +0800 Subject: [PATCH 13/13] dds_stream_extract_key: reserve space in destination before calling dds_stream_read_fixed_buffer Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_stream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ddsc/src/dds_stream.c b/src/core/ddsc/src/dds_stream.c index 69c6bcd..d98d580 100644 --- a/src/core/ddsc/src/dds_stream.c +++ b/src/core/ddsc/src/dds_stream.c @@ -1434,6 +1434,7 @@ uint32_t dds_stream_extract_key (dds_stream_t *is, dds_stream_t *os, const uint3 { char *dst; DDS_CDR_ALIGNTO (os, align); + DDS_CDR_RESIZE (os, num * align); dst = DDS_CDR_ADDRESS(os, char); dds_stream_read_fixed_buffer (is, dst, num, align, is->m_endian); os->m_index += num * align;