Merge pull request #31 from eboasson/builtintopics
Refactor sample representation (along with a few small other details)
This commit is contained in:
commit
2e2224daea
62 changed files with 1963 additions and 1623 deletions
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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;
|
||||
|
@ -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)))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,21 @@ 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);
|
||||
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,
|
||||
|
|
|
@ -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);
|
||||
_Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample);
|
||||
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, const struct ddsi_sertopic *topic, _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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -38,7 +38,7 @@ struct dds_readcond;
|
|||
struct dds_guardcond;
|
||||
struct dds_statuscond;
|
||||
|
||||
struct sertopic;
|
||||
struct ddsi_sertopic;
|
||||
struct rhc;
|
||||
|
||||
/* Internal entity status flags */
|
||||
|
@ -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 sertopic * m_stopic;
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 <ddsi/q_config.h>
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -286,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");
|
||||
|
@ -384,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");
|
||||
|
@ -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;
|
||||
|
@ -456,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");
|
||||
|
|
|
@ -13,101 +13,28 @@
|
|||
#include <string.h>
|
||||
#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"
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
@ -26,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();
|
||||
|
||||
|
@ -40,18 +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) {
|
||||
if (t->m_stopic->filter_sample == NULL) {
|
||||
t->m_stopic->filter_sample = dds_alloc(t->m_descriptor->m_size);
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -148,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 ******
|
||||
|
@ -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 (sample); /* drops const (tho refcount does change) */
|
||||
s->wr_iid = pwr_info->iid;
|
||||
s->isread = false;
|
||||
s->disposed_gen = inst->disposed_gen;
|
||||
|
@ -662,14 +663,17 @@ 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 *sertopic, const struct ddsi_serdata *sample)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
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 = dds_alloc (desc->m_size);
|
||||
ddsi_serdata_to_sample (sample, tmp, NULL, NULL);
|
||||
ret = (tp->filter_fn) (tmp, tp->filter_ctx);
|
||||
ddsi_sertopic_free_sample (tp->m_stopic, tmp, DDS_FREE_ALL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -683,16 +687,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 +1023,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 +1033,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 +1042,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 +1052,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 +1125,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 +1197,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 +1286,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 +1330,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 +1586,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 +1630,6 @@ static int dds_rhc_read_w_qminv
|
|||
{
|
||||
bool trigger_waitsets = false;
|
||||
uint32_t n = 0;
|
||||
const struct dds_topic_descriptor * desc = (const struct dds_topic_descriptor *) rhc->topic->type;
|
||||
|
||||
if (lock)
|
||||
{
|
||||
|
@ -1664,7 +1667,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])))
|
||||
|
@ -1685,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;
|
||||
|
@ -1696,7 +1699,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_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0);
|
||||
if (!inst->inv_isread)
|
||||
{
|
||||
inst->inv_isread = 1;
|
||||
|
@ -1754,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 = (const struct dds_topic_descriptor *) rhc->topic->type;
|
||||
|
||||
if (lock)
|
||||
{
|
||||
|
@ -1799,7 +1801,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])))
|
||||
|
@ -1833,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;
|
||||
|
@ -1843,7 +1845,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_topicless_to_sample (rhc->topic, inst->tk->m_sample, values[n], 0, 0);
|
||||
inst_clear_invsample (rhc, inst);
|
||||
++n;
|
||||
}
|
||||
|
@ -1912,7 +1914,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 +2161,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 +2169,8 @@ static bool update_conditions_locked
|
|||
dds_readcond * iter;
|
||||
int m_pre;
|
||||
int m_post;
|
||||
bool deserialised = (rhc->topic->filter_fn != NULL);
|
||||
const struct dds_topic_descriptor *desc = rhc->topic->status_cb_entity->m_descriptor;
|
||||
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,
|
||||
|
@ -2210,16 +2213,17 @@ 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))
|
||||
{
|
||||
deserialize_into ((char*)rhc->topic->filter_sample, sample);
|
||||
deserialised = true;
|
||||
tmp = os_malloc (desc->m_size);
|
||||
memset (tmp, 0, desc->m_size);
|
||||
ddsi_serdata_to_sample (sample, tmp, NULL, NULL);
|
||||
}
|
||||
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"));
|
||||
|
@ -2246,6 +2250,11 @@ static bool update_conditions_locked
|
|||
iter = iter->m_rhc_next;
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
ddsi_sertopic_free_sample (rhc->topic, tmp, DDS_FREE_CONTENTS);
|
||||
os_free (tmp);
|
||||
}
|
||||
return trigger;
|
||||
}
|
||||
|
||||
|
@ -2286,7 +2295,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);
|
||||
|
|
|
@ -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] =
|
||||
|
@ -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;
|
||||
|
||||
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))
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,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,
|
||||
|
@ -1162,9 +1169,9 @@ 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;
|
||||
const struct dds_topic_descriptor * desc = topic->type;
|
||||
|
||||
if (topic->opt_size && DDS_CDR_ALIGNED (os, desc->m_align))
|
||||
{
|
||||
|
@ -1176,16 +1183,17 @@ 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;
|
||||
assert (d->hdr.identifier == CDR_LE || d->hdr.identifier == CDR_BE);
|
||||
s->m_endian = (d->hdr.identifier == CDR_LE);
|
||||
}
|
||||
|
||||
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 +1201,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;
|
||||
|
@ -1255,13 +1259,7 @@ void dds_stream_write_key
|
|||
of key hash. Input stream may contain full sample of just key data.
|
||||
*/
|
||||
|
||||
static uint32_t dds_stream_get_keyhash
|
||||
(
|
||||
dds_stream_t * is,
|
||||
char * dst,
|
||||
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;
|
||||
|
@ -1269,9 +1267,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)
|
||||
{
|
||||
|
@ -1280,7 +1278,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)
|
||||
|
@ -1313,43 +1311,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:
|
||||
|
@ -1360,11 +1344,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
|
||||
|
@ -1417,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;
|
||||
|
@ -1451,8 +1432,12 @@ static uint32_t dds_stream_get_keyhash
|
|||
align = dds_op_size[subtype];
|
||||
if (is_key)
|
||||
{
|
||||
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);
|
||||
dst += num * align;
|
||||
os->m_index += num * align;
|
||||
}
|
||||
is->m_index += num * align;
|
||||
}
|
||||
|
@ -1474,7 +1459,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;
|
||||
|
@ -1550,7 +1535,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;
|
||||
}
|
||||
}
|
||||
|
@ -1571,21 +1556,21 @@ 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_extract_key (is, os, ops + DDS_OP_JUMP (op), just_key);
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
return (uint32_t) (dst - origin);
|
||||
return os->m_index - origin;
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
|
@ -1597,44 +1582,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_extract_key (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_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);
|
||||
dds_stream_fini (&os);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,17 +107,18 @@ 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;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const struct ddsi_sertopic *topic;
|
||||
uint64_t m_iid;
|
||||
void * m_sample;
|
||||
bool m_ret;
|
||||
|
@ -189,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)
|
||||
{
|
||||
deserialize_into (arg->m_sample, tk->m_sample);
|
||||
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);
|
||||
|
@ -243,7 +185,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,9 +193,7 @@ struct tkmap_instance * dds_tkmap_find(
|
|||
struct tkmap_instance * tk;
|
||||
struct tkmap * map = gv.m_tkmap;
|
||||
|
||||
assert(sd->v.keyhash.m_flags & DDS_KEY_HASH_SET);
|
||||
dummy.m_sample = sd;
|
||||
|
||||
retry:
|
||||
if ((tk = ut_chhLookup(map->m_hh, &dummy)) != NULL)
|
||||
{
|
||||
|
@ -279,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 ();
|
||||
|
@ -294,22 +234,15 @@ retry:
|
|||
|
||||
if (tk && rd)
|
||||
{
|
||||
TRACE (("tk=%p iid=%"PRIx64"", &tk, tk->m_iid));
|
||||
TRACE (("tk=%p iid=%"PRIx64" ", &tk, tk->m_iid));
|
||||
}
|
||||
return tk;
|
||||
}
|
||||
|
||||
_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
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -337,7 +270,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);
|
||||
|
|
|
@ -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,34 @@ 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 = 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;
|
||||
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 +449,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);
|
||||
|
@ -506,17 +506,11 @@ dds_topic_mod_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 {
|
||||
|
@ -544,8 +538,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
|
||||
|
|
|
@ -14,10 +14,9 @@
|
|||
#include <string.h>
|
||||
|
||||
#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 {
|
||||
|
@ -97,7 +96,7 @@ struct whc_impl {
|
|||
};
|
||||
|
||||
struct whc_sample_iter_impl {
|
||||
struct whc_impl *whc;
|
||||
struct whc_sample_iter_base c;
|
||||
bool first;
|
||||
};
|
||||
|
||||
|
@ -136,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, serdata_t 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 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
|
||||
|
@ -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;
|
||||
|
@ -406,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;
|
||||
|
@ -468,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);
|
||||
|
@ -519,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;
|
||||
|
@ -597,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;
|
||||
|
@ -639,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);
|
||||
|
@ -790,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;
|
||||
|
@ -872,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;
|
||||
|
@ -1006,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;
|
||||
|
@ -1019,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));
|
||||
}
|
||||
|
@ -1027,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, serdata_t 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;
|
||||
|
||||
|
@ -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_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;
|
||||
|
@ -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_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));
|
||||
}
|
||||
|
@ -1127,12 +1126,12 @@ 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));
|
||||
|
||||
/* 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);
|
||||
|
@ -1180,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;
|
||||
|
@ -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]));
|
||||
|
@ -1247,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;
|
||||
|
@ -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_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;
|
||||
|
@ -1305,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);
|
||||
|
@ -1313,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;
|
||||
|
|
|
@ -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,16 +192,16 @@ 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");
|
||||
}
|
||||
|
||||
/* 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;
|
||||
if (wr->m_topic->filter_fn && ! writekey) {
|
||||
if (!(wr->m_topic->filter_fn) (data, wr->m_topic->filter_ctx)) {
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,16 +210,12 @@ dds_write_impl(
|
|||
}
|
||||
|
||||
/* 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 +243,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,12 +260,10 @@ 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;
|
||||
|
||||
/* Check for topic filter */
|
||||
if (ddsi_wr->topic->filter_fn && ! writekey) {
|
||||
if (wr->m_topic->filter_fn) {
|
||||
abort();
|
||||
}
|
||||
|
||||
|
@ -278,10 +272,10 @@ dds_writecdr_impl(
|
|||
}
|
||||
|
||||
/* 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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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 <assert.h>
|
||||
#include <string.h>
|
||||
#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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
@ -51,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
|
||||
|
@ -60,7 +64,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 +71,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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,190 +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 DDSI_SER_H
|
||||
#define DDSI_SER_H
|
||||
|
||||
#include "os/os.h"
|
||||
#include "ddsi/q_plist.h" /* for nn_prismtech_writer_info */
|
||||
#include "ddsi/q_freelist.h"
|
||||
#include "util/ut_avl.h"
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "ddsc/dds.h"
|
||||
#include "dds__topic.h"
|
||||
|
||||
#ifndef PLATFORM_IS_LITTLE_ENDIAN
|
||||
# if OS_ENDIANNESS == OS_BIG_ENDIAN
|
||||
# define PLATFORM_IS_LITTLE_ENDIAN 0
|
||||
# elif OS_ENDIANNESS == OS_LITTLE_ENDIAN
|
||||
# define PLATFORM_IS_LITTLE_ENDIAN 1
|
||||
# else
|
||||
# error "invalid endianness setting"
|
||||
# endif
|
||||
#endif /* PLATFORM_IS_LITTLE_ENDIAN */
|
||||
|
||||
#if PLATFORM_IS_LITTLE_ENDIAN
|
||||
#define CDR_BE 0x0000
|
||||
#define CDR_LE 0x0100
|
||||
#else
|
||||
#define CDR_BE 0x0000
|
||||
#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 nn_freelist freelist;
|
||||
};
|
||||
|
||||
|
||||
#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. */
|
||||
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) */
|
||||
}
|
||||
dds_key_hash_t;
|
||||
|
||||
struct serdata_base
|
||||
{
|
||||
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 */
|
||||
dds_key_hash_t keyhash;
|
||||
bool bswap; /* Whether state is native endian or requires swapping */
|
||||
};
|
||||
|
||||
struct serdata
|
||||
{
|
||||
struct serdata_base v;
|
||||
/* 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)];
|
||||
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
|
||||
{
|
||||
ut_avlNode_t avlnode;
|
||||
char * name_typename;
|
||||
char * name;
|
||||
char * typename;
|
||||
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;
|
||||
|
||||
/*
|
||||
Array of keys, represented as offset in the OpenSplice internal
|
||||
format data blob. Keys must be stored in the order visited by
|
||||
serializer (so that the serializer can simply compare the current
|
||||
offset with the next key offset). Also: keys[nkeys].off =def=
|
||||
~0u, which won't equal any real offset so that there is no need
|
||||
to test for the end of the array.
|
||||
|
||||
Offsets work 'cos only primitive types, enums and strings are
|
||||
accepted as keys. So there is no ambiguity if a key happens to
|
||||
be inside a nested struct.
|
||||
*/
|
||||
};
|
||||
|
||||
serstatepool_t ddsi_serstatepool_new (void);
|
||||
void ddsi_serstatepool_free (serstatepool_t pool);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
OSAPI_EXPORT void ddsi_serdata_getblob (void **raw, size_t *sz, serdata_t serdata);
|
||||
|
||||
#endif
|
169
src/core/ddsi/include/ddsi/ddsi_serdata.h
Normal file
169
src/core/ddsi/include/ddsi/ddsi_serdata.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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. 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 {
|
||||
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;
|
||||
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_to_topicless_t to_topicless;
|
||||
ddsi_serdata_topicless_to_sample_t topicless_to_sample;
|
||||
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 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);
|
||||
}
|
||||
|
||||
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 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) {
|
||||
return a->ops->eqkey (a, b);
|
||||
}
|
||||
|
||||
#endif
|
139
src/core/ddsi/include/ddsi/ddsi_serdata_default.h
Normal file
139
src/core/ddsi/include/ddsi/ddsi_serdata_default.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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_SER_H
|
||||
#define DDSI_SER_H
|
||||
|
||||
#include "os/os.h"
|
||||
#include "ddsi/q_plist.h" /* for nn_prismtech_writer_info */
|
||||
#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"
|
||||
|
||||
#ifndef PLATFORM_IS_LITTLE_ENDIAN
|
||||
# if OS_ENDIANNESS == OS_BIG_ENDIAN
|
||||
# define PLATFORM_IS_LITTLE_ENDIAN 0
|
||||
# elif OS_ENDIANNESS == OS_LITTLE_ENDIAN
|
||||
# define PLATFORM_IS_LITTLE_ENDIAN 1
|
||||
# else
|
||||
# error "invalid endianness setting"
|
||||
# endif
|
||||
#endif /* PLATFORM_IS_LITTLE_ENDIAN */
|
||||
|
||||
#if PLATFORM_IS_LITTLE_ENDIAN
|
||||
#define CDR_BE 0x0000
|
||||
#define CDR_LE 0x0100
|
||||
#else
|
||||
#define CDR_BE 0x0000
|
||||
#define CDR_LE 0x0001
|
||||
#endif
|
||||
|
||||
struct CDRHeader {
|
||||
unsigned short identifier;
|
||||
unsigned short options;
|
||||
};
|
||||
|
||||
struct serdatapool {
|
||||
struct nn_freelist freelist;
|
||||
};
|
||||
|
||||
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 c;
|
||||
uint32_t pos;
|
||||
uint32_t size;
|
||||
#ifndef NDEBUG
|
||||
bool fixed;
|
||||
#endif
|
||||
dds_key_hash_t keyhash;
|
||||
|
||||
struct serdatapool *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 ddsi_serdata) + 4) % 8)];
|
||||
struct CDRHeader hdr;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
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 c;
|
||||
uint16_t native_encoding_identifier; /* (PL_)?CDR_(LE|BE) */
|
||||
|
||||
struct dds_topic_descriptor * type;
|
||||
unsigned nkeys;
|
||||
|
||||
uint32_t flags;
|
||||
size_t opt_size;
|
||||
dds_topic_intern_filter_fn filter_fn;
|
||||
void * filter_sample;
|
||||
void * filter_ctx;
|
||||
const struct dds_key_descriptor * keys;
|
||||
|
||||
/*
|
||||
Array of keys, represented as offset in the OpenSplice internal
|
||||
format data blob. Keys must be stored in the order visited by
|
||||
serializer (so that the serializer can simply compare the current
|
||||
offset with the next key offset). Also: keys[nkeys].off =def=
|
||||
~0u, which won't equal any real offset so that there is no need
|
||||
to test for the end of the array.
|
||||
|
||||
Offsets work 'cos only primitive types, enums and strings are
|
||||
accepted as keys. So there is no ambiguity if a key happens to
|
||||
be inside a nested struct.
|
||||
*/
|
||||
};
|
||||
|
||||
struct ddsi_plist_sample {
|
||||
void *blob;
|
||||
size_t size;
|
||||
nn_parameterid_t keyparam;
|
||||
};
|
||||
|
||||
struct ddsi_rawcdr_sample {
|
||||
void *blob;
|
||||
size_t size;
|
||||
void *key;
|
||||
size_t keysize;
|
||||
};
|
||||
|
||||
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 serdatapool * ddsi_serdatapool_new (void);
|
||||
void ddsi_serdatapool_free (struct serdatapool * pool);
|
||||
|
||||
#endif
|
62
src/core/ddsi/include/ddsi/ddsi_sertopic.h
Normal file
62
src/core/ddsi/include/ddsi/ddsi_sertopic.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "ddsc/dds_public_alloc.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;
|
||||
uint32_t serdata_basehash;
|
||||
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);
|
||||
|
||||
/* 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
|
|
@ -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;
|
||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct nn_xmsgpool;
|
||||
struct serstatepool;
|
||||
struct serdatapool;
|
||||
struct nn_dqueue;
|
||||
struct nn_reorder;
|
||||
struct nn_defrag;
|
||||
|
@ -275,8 +275,10 @@ 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 */
|
||||
|
||||
/* Network ID needed by v_groupWrite -- FIXME: might as well pass it
|
||||
to the receive thread instead of making it global (and that would
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
@ -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: */
|
||||
|
@ -56,7 +60,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 +70,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);
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
49
src/core/ddsi/src/ddsi_serdata.c
Normal file
49
src/core/ddsi/src/ddsi_serdata.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#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 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 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);
|
556
src/core/ddsi/src/ddsi_serdata_default.c
Normal file
556
src/core/ddsi/src/ddsi_serdata_default.c
Normal file
|
@ -0,0 +1,556 @@
|
|||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#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 <assert.h>
|
||||
#include <string.h>
|
||||
#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 serdatapool * ddsi_serdatapool_new (void)
|
||||
{
|
||||
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 serdata_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_serdatapool_free (struct serdatapool * pool)
|
||||
{
|
||||
TRACE (("ddsi_serdatapool_free(%p)\n", pool));
|
||||
nn_freelist_fini (&pool->freelist, serdata_free_wrap);
|
||||
os_free (pool);
|
||||
}
|
||||
|
||||
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 void *serdata_default_append (struct ddsi_serdata_default **d, size_t n)
|
||||
{
|
||||
char *p;
|
||||
if ((*d)->pos + n > (*d)->size)
|
||||
{
|
||||
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 ((*d)->pos + n <= (*d)->size);
|
||||
p = (*d)->data + (*d)->pos;
|
||||
(*d)->pos += (uint32_t)n;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *serdata_default_append_aligned (struct ddsi_serdata_default **d, size_t n, size_t a)
|
||||
{
|
||||
#if CLEAR_PADDING
|
||||
size_t pos0 = st->pos;
|
||||
#endif
|
||||
char *p;
|
||||
assert (ispowerof2_size (a));
|
||||
(*d)->pos = (uint32_t) alignup_size ((*d)->pos, a);
|
||||
p = serdata_default_append (d, n);
|
||||
#if CLEAR_PADDING
|
||||
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
|
||||
#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, uint32_t basehash)
|
||||
{
|
||||
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) ^ basehash;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
memset (d->keyhash.m_hash, 0, sizeof (d->keyhash.m_hash));
|
||||
d->keyhash.m_set = 0;
|
||||
d->keyhash.m_iskey = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
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 */
|
||||
|
||||
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));
|
||||
assert (d->hdr.identifier == CDR_LE || d->hdr.identifier == CDR_BE);
|
||||
|
||||
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));
|
||||
serdata_default_append_blob (&d, 1, fragchain->maxp1 - off, payload + off - fragchain->min);
|
||||
off = fragchain->maxp1;
|
||||
}
|
||||
fragchain = fragchain->nextfrag;
|
||||
}
|
||||
|
||||
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.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 */
|
||||
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
|
||||
{
|
||||
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);
|
||||
(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)
|
||||
{
|
||||
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.serdata_basehash);
|
||||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
#endif
|
||||
switch (sample->keyparam)
|
||||
{
|
||||
case PID_PARTICIPANT_GUID:
|
||||
case PID_ENDPOINT_GUID:
|
||||
case PID_GROUP_GUID:
|
||||
d->keyhash.m_set = 1;
|
||||
d->keyhash.m_iskey = 1;
|
||||
memcpy (&d->keyhash.m_hash, rawkey, 16);
|
||||
#ifndef NDEBUG
|
||||
keysize = 16;
|
||||
#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_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, 16);
|
||||
#ifndef NDEBUG
|
||||
keysize = sizeof (uint32_t) + topic_name_sz;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/* 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.serdata_basehash);
|
||||
}
|
||||
|
||||
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);
|
||||
assert (sample->keysize <= 16);
|
||||
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.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 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
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
return (struct ddsi_serdata *)d_tl;
|
||||
}
|
||||
|
||||
/* 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 <= alignup_size (d->pos + sizeof(struct CDRHeader), 4) - off);
|
||||
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 <= alignup_size (d->pos + sizeof(struct CDRHeader), 4) - off);
|
||||
ref->iov_base = (char *)&d->hdr + off;
|
||||
ref->iov_len = (ddsi_iov_len_t)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_topicless_to_sample_cdr (const struct ddsi_sertopic *topic, 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;
|
||||
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! */
|
||||
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_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)serdata_common;
|
||||
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,
|
||||
.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,
|
||||
.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,
|
||||
.eqkey = serdata_default_eqkey,
|
||||
.free = serdata_default_free,
|
||||
.from_ser = serdata_default_from_ser,
|
||||
.from_keyhash = 0,
|
||||
.from_sample = serdata_default_from_sample_plist,
|
||||
.to_ser = serdata_default_to_ser,
|
||||
.to_sample = 0,
|
||||
.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 = 0
|
||||
};
|
||||
|
||||
const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr = {
|
||||
.get_size = serdata_default_get_size,
|
||||
.eqkey = serdata_default_eqkey,
|
||||
.free = serdata_default_free,
|
||||
.from_ser = serdata_default_from_ser,
|
||||
.from_keyhash = 0,
|
||||
.from_sample = serdata_default_from_sample_rawcdr,
|
||||
.to_ser = serdata_default_to_ser,
|
||||
.to_sample = 0,
|
||||
.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 = 0
|
||||
};
|
64
src/core/ddsi/src/ddsi_sertopic.c
Normal file
64
src/core/ddsi/src/ddsi_sertopic.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#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.h"
|
||||
#include "ddsi/q_md5.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)
|
||||
{
|
||||
ddsi_sertopic_deinit (sertopic);
|
||||
os_free (sertopic->name_typename);
|
||||
os_free (sertopic->name);
|
||||
os_free (sertopic->typename);
|
||||
os_free (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;
|
||||
}
|
||||
|
||||
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);
|
42
src/core/ddsi/src/ddsi_sertopic_default.c
Normal file
42
src/core/ddsi/src/ddsi_sertopic_default.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#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 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 = sertopic_default_deinit,
|
||||
.free_sample = sertopic_default_free_sample
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -189,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" : "",
|
||||
|
|
|
@ -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);
|
||||
|
@ -1315,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);
|
||||
}
|
||||
}
|
||||
|
@ -1607,11 +1606,11 @@ 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;
|
||||
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)
|
||||
{
|
||||
|
@ -2541,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)
|
||||
|
@ -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;
|
||||
|
@ -2861,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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -2957,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));
|
||||
|
@ -2989,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)
|
||||
|
@ -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);
|
||||
|
@ -4329,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;
|
||||
|
|
|
@ -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,40 @@ 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->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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -978,7 +1012,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)
|
||||
|
@ -1000,6 +1034,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 ();
|
||||
|
@ -1311,6 +1347,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);
|
||||
|
@ -1325,7 +1362,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
|
||||
|
@ -1588,6 +1625,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);
|
||||
|
@ -1619,7 +1657,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");
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
@ -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 ());
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -1888,14 +1842,12 @@ static serdata_t 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
|
||||
{
|
||||
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->statusinfo = statusinfo;
|
||||
sample->timestamp = tstamp;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1943,20 +1895,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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,31 @@ 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)
|
||||
{
|
||||
#define TEST_KEYHASH 0
|
||||
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:
|
||||
#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;
|
||||
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 +432,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,20 +449,25 @@ 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);
|
||||
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;
|
||||
}
|
||||
|
||||
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 +488,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 +505,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 +534,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 +542,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 +564,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 +586,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 +619,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 +701,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 +746,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 +757,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 +785,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 +798,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 +852,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 +870,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);
|
||||
|
@ -855,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;
|
||||
|
@ -864,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);
|
||||
}
|
||||
|
@ -918,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
|
||||
|
@ -963,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)
|
||||
{
|
||||
|
@ -999,7 +1028,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;
|
||||
|
@ -1035,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;
|
||||
|
@ -1061,7 +1090,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)
|
||||
|
@ -1090,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
|
||||
|
@ -1135,17 +1164,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 +1184,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;
|
||||
|
|
28
src/core/ddsi/src/q_whc.c
Normal file
28
src/core/ddsi/src/q_whc.c
Normal file
|
@ -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);
|
|
@ -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"
|
||||
|
@ -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 */
|
||||
|
@ -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,18 +1006,24 @@ 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))
|
||||
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
|
||||
|
@ -1024,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
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue