Eliminate domain-specific global variables

This commit moves all but a handful of the global variables into the
domain object, in particular including the DDSI configuration, globals
and all transport internal state.

The goal of this commit is not to produce the nicest code possible, but
to get a working version that can support multiple simultaneous domains.
Various choices are driven by this desire and it is expected that some
of the changes will have to be undone.  (E.g., passing the DDSI globals
into address set operations and locator printing because there is no
other way to figure out what transport to use for a given locator;
storing the transport pointer inside the locator would solve that.)

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-07-04 20:49:22 +02:00 committed by eboasson
parent 8a591fdc9b
commit c1f3ad8a22
93 changed files with 2802 additions and 2915 deletions

View file

@ -147,6 +147,9 @@ static dds_entity_t prepare_dds(dds_entity_t *writer, const char *partitionName)
if (participant < 0)
DDS_FATAL("dds_create_participant: %s\n", dds_strretcode(-participant));
/* Enable write batching */
dds_write_set_batch (true);
/* A topic is created for our sample type on the domain participant. */
topic = dds_create_topic (participant, &ThroughputModule_DataType_desc, "Throughput", NULL, NULL);
if (topic < 0)
@ -171,9 +174,6 @@ static dds_entity_t prepare_dds(dds_entity_t *writer, const char *partitionName)
DDS_FATAL("dds_create_writer: %s\n", dds_strretcode(-*writer));
dds_delete_qos (dwQos);
/* Enable write batching */
dds_write_set_batch (true);
return participant;
}

View file

@ -28,10 +28,6 @@ dds_entity_t dds__get_builtin_subscriber (dds_entity_t e);
/* Checks whether the reader QoS is valid for use with built-in topic TOPIC */
bool dds__validate_builtin_reader_qos (const dds_domain *dom, dds_entity_t topic, const dds_qos_t *qos);
/* Init/fini for builtin-topic support that is global across domains */
void dds__builtin_init_global (void);
void dds__builtin_fini_global (void);
void dds__builtin_init (struct dds_domain *dom);
void dds__builtin_fini (struct dds_domain *dom);

View file

@ -20,6 +20,7 @@ struct dds_rhc;
struct dds_reader;
struct ddsi_sertopic;
DDS_EXPORT struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_tkmap *tkmap, const struct ddsi_sertopic *topic, bool xchecks);
DDS_EXPORT struct dds_rhc *dds_rhc_default_new (struct dds_reader *reader, const struct ddsi_sertopic *topic);
#if defined (__cplusplus)

View file

@ -33,15 +33,17 @@ enum ddsi_sertopic_builtintopic_type {
DSBT_WRITER
};
struct q_globals;
struct ddsi_sertopic_builtintopic {
struct ddsi_sertopic c;
enum ddsi_sertopic_builtintopic_type type;
struct q_globals *gv;
};
extern const struct ddsi_sertopic_ops ddsi_sertopic_ops_builtintopic;
extern const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic;
struct ddsi_sertopic *new_sertopic_builtintopic (enum ddsi_sertopic_builtintopic_type type, const char *name, const char *typename);
struct ddsi_sertopic *new_sertopic_builtintopic (enum ddsi_sertopic_builtintopic_type type, const char *name, const char *typename, struct q_globals *gv);
#if defined (__cplusplus)
}

View file

@ -17,6 +17,7 @@
#include "dds/dds.h"
#include "dds/ddsrt/sync.h"
#include "dds/ddsi/q_rtps.h"
#include "dds/ddsi/q_globals.h"
#include "dds/ddsrt/avl.h"
#include "dds/ddsi/ddsi_builtin_topic_if.h"
#include "dds__handles.h"
@ -97,15 +98,20 @@ typedef struct dds_domain {
ddsrt_avl_node_t m_node;
dds_domainid_t m_id;
ddsrt_avl_tree_t m_topics;
struct dds_entity *ppants;
ddsrt_avl_tree_t m_ppants;
uint32_t m_refc;
struct cfgst *cfgst;
struct ddsi_sertopic *builtin_participant_topic;
struct ddsi_sertopic *builtin_reader_topic;
struct ddsi_sertopic *builtin_writer_topic;
struct local_orphan_writer *builtintopic_writer_participant;
struct local_orphan_writer *builtintopic_writer_publications;
struct local_orphan_writer *builtintopic_writer_subscriptions;
struct ddsi_builtin_topic_interface btif;
struct q_globals gv;
} dds_domain;
struct dds_entity;
@ -242,6 +248,7 @@ typedef struct dds_writer {
struct nn_xpack *m_xp;
struct writer *m_wr;
struct whc *m_whc; /* FIXME: ownership still with underlying DDSI writer (cos of DDSI built-in writers )*/
bool whc_batch; /* FIXME: channels + latency budget */
/* Status metrics */
@ -311,10 +318,6 @@ typedef struct dds_globals {
uint32_t threadmon_count;
struct ddsi_threadmon *threadmon;
struct ddsi_sertopic *builtin_participant_topic;
struct ddsi_sertopic *builtin_reader_topic;
struct ddsi_sertopic *builtin_writer_topic;
} dds_globals;
DDS_EXPORT extern dds_globals dds_global;

View file

@ -18,7 +18,8 @@
extern "C" {
#endif
struct whc *whc_new (int is_transient_local, uint32_t hdepth, uint32_t tldepth);
struct q_globals;
struct whc *whc_new (struct q_globals *gv, int is_transient_local, uint32_t hdepth, uint32_t tldepth);
#if defined (__cplusplus)
}

View file

@ -19,7 +19,7 @@
extern "C" {
#endif
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type);
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type, const struct ephash *guid_hash);
#if defined (__cplusplus)
}

View file

@ -31,7 +31,7 @@ typedef enum {
dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t tstamp, dds_write_action action);
dds_return_t dds_writecdr_impl (dds_writer *wr, struct ddsi_serdata *d, dds_time_t tstamp, dds_write_action action);
dds_return_t dds_writecdr_impl_lowlevel (struct writer *ddsi_wr, struct nn_xpack *xp, struct ddsi_serdata *d);
dds_return_t dds_writecdr_impl_lowlevel (struct writer *ddsi_wr, struct nn_xpack *xp, struct ddsi_serdata *d, bool flush);
#if defined (__cplusplus)
}

View file

@ -54,13 +54,13 @@ dds_entity_t dds__get_builtin_topic (dds_entity_t entity, dds_entity_t topic)
switch (topic)
{
case DDS_BUILTIN_TOPIC_DCPSPARTICIPANT:
sertopic = dds_global.builtin_participant_topic;
sertopic = e->m_domain->builtin_participant_topic;
break;
case DDS_BUILTIN_TOPIC_DCPSPUBLICATION:
sertopic = dds_global.builtin_writer_topic;
sertopic = e->m_domain->builtin_writer_topic;
break;
case DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION:
sertopic = dds_global.builtin_reader_topic;
sertopic = e->m_domain->builtin_reader_topic;
break;
default:
assert (0);
@ -165,14 +165,14 @@ static bool dds__builtin_is_visible (const nn_guid_t *guid, nn_vendorid_t vendor
static struct ddsi_tkmap_instance *dds__builtin_get_tkmap_entry (const struct nn_guid *guid, void *vdomain)
{
struct dds_domain *domain = vdomain;
struct ddsi_tkmap_instance *tk;
struct ddsi_serdata *sd;
struct nn_keyhash kh;
(void) vdomain;
memcpy (&kh, guid, sizeof (kh));
/* any random builtin topic will do (provided it has a GUID for a key), because what matters is the "class" of the topic, not the actual topic; also, this is called early in the initialisation of the entity with this GUID, which simply causes serdata_from_keyhash to create a key-only serdata because the key lookup fails. */
sd = ddsi_serdata_from_keyhash (dds_global.builtin_participant_topic, &kh);
tk = ddsi_tkmap_find (sd, false, true);
sd = ddsi_serdata_from_keyhash (domain->builtin_participant_topic, &kh);
tk = ddsi_tkmap_find (domain->gv.m_tkmap, sd, false, true);
ddsi_serdata_unref (sd);
return tk;
}
@ -180,6 +180,7 @@ static struct ddsi_tkmap_instance *dds__builtin_get_tkmap_entry (const struct nn
struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, nn_wctime_t timestamp, bool alive)
{
/* initialize to avoid gcc warning ultimately caused by C's horrible type system */
struct dds_domain *dom = e->gv->builtin_topic_interface->arg;
struct ddsi_sertopic *topic = NULL;
struct ddsi_serdata *serdata;
struct nn_keyhash keyhash;
@ -187,15 +188,15 @@ struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, nn
{
case EK_PARTICIPANT:
case EK_PROXY_PARTICIPANT:
topic = dds_global.builtin_participant_topic;
topic = dom->builtin_participant_topic;
break;
case EK_WRITER:
case EK_PROXY_WRITER:
topic = dds_global.builtin_writer_topic;
topic = dom->builtin_writer_topic;
break;
case EK_READER:
case EK_PROXY_READER:
topic = dds_global.builtin_reader_topic;
topic = dom->builtin_reader_topic;
break;
}
assert (topic != NULL);
@ -230,24 +231,10 @@ static void dds__builtin_write (const struct entity_common *e, nn_wctime_t times
bwr = dom->builtintopic_writer_subscriptions;
break;
}
dds_writecdr_impl_lowlevel (&bwr->wr, NULL, serdata);
dds_writecdr_impl_lowlevel (&bwr->wr, NULL, serdata, true);
}
}
void dds__builtin_init_global (void)
{
dds_global.builtin_participant_topic = new_sertopic_builtintopic (DSBT_PARTICIPANT, "DCPSParticipant", "org::eclipse::cyclonedds::builtin::DCPSParticipant");
dds_global.builtin_reader_topic = new_sertopic_builtintopic (DSBT_READER, "DCPSSubscription", "org::eclipse::cyclonedds::builtin::DCPSSubscription");
dds_global.builtin_writer_topic = new_sertopic_builtintopic (DSBT_WRITER, "DCPSPublication", "org::eclipse::cyclonedds::builtin::DCPSPublication");
}
void dds__builtin_fini_global (void)
{
ddsi_sertopic_unref (dds_global.builtin_participant_topic);
ddsi_sertopic_unref (dds_global.builtin_reader_topic);
ddsi_sertopic_unref (dds_global.builtin_writer_topic);
}
void dds__builtin_init (struct dds_domain *dom)
{
dds_qos_t *qos = dds__create_builtin_qos ();
@ -257,11 +244,16 @@ void dds__builtin_init (struct dds_domain *dom)
dom->btif.builtintopic_is_builtintopic = dds__builtin_is_builtintopic;
dom->btif.builtintopic_is_visible = dds__builtin_is_visible;
dom->btif.builtintopic_write = dds__builtin_write;
gv.builtin_topic_interface = &dom->btif;
dom->gv.builtin_topic_interface = &dom->btif;
dom->builtintopic_writer_participant = new_local_orphan_writer (to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER), dds_global.builtin_participant_topic, qos, builtintopic_whc_new (DSBT_PARTICIPANT));
dom->builtintopic_writer_publications = new_local_orphan_writer (to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER), dds_global.builtin_writer_topic, qos, builtintopic_whc_new (DSBT_WRITER));
dom->builtintopic_writer_subscriptions = new_local_orphan_writer (to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), dds_global.builtin_reader_topic, qos, builtintopic_whc_new (DSBT_READER));
dom->builtin_participant_topic = new_sertopic_builtintopic (DSBT_PARTICIPANT, "DCPSParticipant", "org::eclipse::cyclonedds::builtin::DCPSParticipant", &dom->gv);
dom->builtin_reader_topic = new_sertopic_builtintopic (DSBT_READER, "DCPSSubscription", "org::eclipse::cyclonedds::builtin::DCPSSubscription", &dom->gv);
dom->builtin_writer_topic = new_sertopic_builtintopic (DSBT_WRITER, "DCPSPublication", "org::eclipse::cyclonedds::builtin::DCPSPublication", &dom->gv);
const struct ephash *gh = dom->gv.guid_hash;
dom->builtintopic_writer_participant = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER), dom->builtin_participant_topic, qos, builtintopic_whc_new (DSBT_PARTICIPANT, gh));
dom->builtintopic_writer_publications = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER), dom->builtin_writer_topic, qos, builtintopic_whc_new (DSBT_WRITER, gh));
dom->builtintopic_writer_subscriptions = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), dom->builtin_reader_topic, qos, builtintopic_whc_new (DSBT_READER, gh));
dds_delete_qos (qos);
}
@ -269,9 +261,13 @@ void dds__builtin_init (struct dds_domain *dom)
void dds__builtin_fini (struct dds_domain *dom)
{
/* No more sources for builtin topic samples */
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), &dom->gv);
delete_local_orphan_writer (dom->builtintopic_writer_participant);
delete_local_orphan_writer (dom->builtintopic_writer_publications);
delete_local_orphan_writer (dom->builtintopic_writer_subscriptions);
thread_state_asleep (lookup_thread_state ());
ddsi_sertopic_unref (dom->builtin_participant_topic);
ddsi_sertopic_unref (dom->builtin_reader_topic);
ddsi_sertopic_unref (dom->builtin_writer_topic);
}

View file

@ -49,10 +49,10 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
domain->m_refc = 1;
ddsrt_avl_init (&dds_topictree_def, &domain->m_topics);
gv.tstart = now ();
domain->gv.tstart = now ();
(void) ddsrt_getenv ("CYCLONEDDS_URI", &uri);
domain->cfgst = config_init (uri, &config);
domain->cfgst = config_init (uri, &domain->gv.config);
if (domain->cfgst == NULL)
{
DDS_LOG (DDS_LC_CONFIG, "Failed to parse configuration XML file %s\n", uri);
@ -69,23 +69,23 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
ret = DDS_RETCODE_ERROR;
goto fail_config_domainid;
}
else if (config.domainId.isdefault)
else if (domain->gv.config.domainId.isdefault)
{
config.domainId.value = domain_id;
domain->gv.config.domainId.value = domain_id;
}
else if (domain_id != config.domainId.value)
else if (domain_id != domain->gv.config.domainId.value)
{
DDS_ERROR ("requested domain id %"PRId32" is inconsistent with configured value %"PRId32"\n", domain_id, config.domainId.value);
DDS_ERROR ("requested domain id %"PRId32" is inconsistent with configured value %"PRId32"\n", domain_id, domain->gv.config.domainId.value);
ret = DDS_RETCODE_ERROR;
goto fail_config_domainid;
}
}
/* FIXME: The config.domainId can change internally in DDSI. So, remember what the
/* FIXME: The gv.config.domainId can change internally in DDSI. So, remember what the
* main configured domain id is. */
domain->m_id = config.domainId.value;
domain->m_id = domain->gv.config.domainId.value;
if (rtps_config_prep (domain->cfgst) != 0)
if (rtps_config_prep (&domain->gv, domain->cfgst) != 0)
{
DDS_LOG (DDS_LC_CONFIG, "Failed to configure RTPS\n");
ret = DDS_RETCODE_ERROR;
@ -93,11 +93,11 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
}
/* Start monitoring the liveliness of all threads. */
if (config.liveliness_monitoring)
if (domain->gv.config.liveliness_monitoring)
{
if (++dds_global.threadmon_count == 0)
{
dds_global.threadmon = ddsi_threadmon_new ();
dds_global.threadmon = ddsi_threadmon_new (domain->gv.config.liveliness_monitoring_interval, domain->gv.config.noprogress_log_stacktraces);
if (dds_global.threadmon == NULL)
{
DDS_ERROR ("Failed to create a thread liveliness monitor\n");
@ -107,7 +107,7 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
}
}
if (rtps_init () < 0)
if (rtps_init (&domain->gv) < 0)
{
DDS_LOG (DDS_LC_CONFIG, "Failed to initialize RTPS\n");
ret = DDS_RETCODE_ERROR;
@ -116,16 +116,17 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
dds__builtin_init (domain);
if (rtps_start () < 0)
if (rtps_start (&domain->gv) < 0)
{
DDS_LOG (DDS_LC_CONFIG, "Failed to start RTPS\n");
ret = DDS_RETCODE_ERROR;
goto fail_rtps_start;
}
if (config.liveliness_monitoring && dds_global.threadmon_count == 1)
if (domain->gv.config.liveliness_monitoring && dds_global.threadmon_count == 1)
{
if (ddsi_threadmon_start (dds_global.threadmon) < 0)
const char *name = "threadmon";
if (ddsi_threadmon_start (dds_global.threadmon, name, lookup_thread_properties (&domain->gv.config, name)) < 0)
{
DDS_ERROR ("Failed to start the thread liveliness monitor\n");
ret = DDS_RETCODE_ERROR;
@ -137,31 +138,31 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
char progname[50] = "UNKNOWN"; /* FIXME: once retrieving process names is back in */
char hostname[64];
gv.default_plist_pp.process_id = (unsigned) ddsrt_getpid();
gv.default_plist_pp.present |= PP_PRISMTECH_PROCESS_ID;
gv.default_plist_pp.exec_name = dds_string_alloc(32);
(void) snprintf (gv.default_plist_pp.exec_name, 32, "CycloneDDS: %u", gv.default_plist_pp.process_id);
len = (uint32_t) (13 + strlen (gv.default_plist_pp.exec_name));
gv.default_plist_pp.present |= PP_PRISMTECH_EXEC_NAME;
domain->gv.default_plist_pp.process_id = (unsigned) ddsrt_getpid();
domain->gv.default_plist_pp.present |= PP_PRISMTECH_PROCESS_ID;
domain->gv.default_plist_pp.exec_name = dds_string_alloc(32);
(void) snprintf (domain->gv.default_plist_pp.exec_name, 32, "CycloneDDS: %u", domain->gv.default_plist_pp.process_id);
len = (uint32_t) (13 + strlen (domain->gv.default_plist_pp.exec_name));
domain->gv.default_plist_pp.present |= PP_PRISMTECH_EXEC_NAME;
if (ddsrt_gethostname (hostname, sizeof (hostname)) == DDS_RETCODE_OK)
{
gv.default_plist_pp.node_name = dds_string_dup (hostname);
gv.default_plist_pp.present |= PP_PRISMTECH_NODE_NAME;
domain->gv.default_plist_pp.node_name = dds_string_dup (hostname);
domain->gv.default_plist_pp.present |= PP_PRISMTECH_NODE_NAME;
}
gv.default_plist_pp.entity_name = dds_alloc (len);
(void) snprintf (gv.default_plist_pp.entity_name, len, "%s<%u>", progname, gv.default_plist_pp.process_id);
gv.default_plist_pp.present |= PP_ENTITY_NAME;
domain->gv.default_plist_pp.entity_name = dds_alloc (len);
(void) snprintf (domain->gv.default_plist_pp.entity_name, len, "%s<%u>", progname, domain->gv.default_plist_pp.process_id);
domain->gv.default_plist_pp.present |= PP_ENTITY_NAME;
return DDS_RETCODE_OK;
fail_threadmon_start:
if (config.liveliness_monitoring && dds_global.threadmon_count == 1)
if (domain->gv.config.liveliness_monitoring && dds_global.threadmon_count == 1)
ddsi_threadmon_stop (dds_global.threadmon);
rtps_stop ();
rtps_stop (&domain->gv);
fail_rtps_start:
rtps_fini ();
rtps_fini (&domain->gv);
fail_rtps_init:
if (config.liveliness_monitoring)
if (domain->gv.config.liveliness_monitoring)
{
if (--dds_global.threadmon_count == 0)
{
@ -181,12 +182,12 @@ fail_config:
static void dds_domain_fini (struct dds_domain *domain)
{
if (config.liveliness_monitoring && dds_global.threadmon_count == 1)
if (domain->gv.config.liveliness_monitoring && dds_global.threadmon_count == 1)
ddsi_threadmon_stop (dds_global.threadmon);
rtps_stop ();
rtps_stop (&domain->gv);
dds__builtin_fini (domain);
rtps_fini ();
if (config.liveliness_monitoring)
rtps_fini (&domain->gv);
if (domain->gv.config.liveliness_monitoring)
{
if (--dds_global.threadmon_count == 0)
{
@ -259,15 +260,73 @@ void dds_domain_free (dds_domain *domain)
ddsrt_mutex_lock (&dds_global.m_mutex);
if (--domain->m_refc != 0)
{
//fprintf(stderr, "domain_free %d %p refcount > 0\n", (int)domain->m_id, domain);
ddsrt_mutex_unlock (&dds_global.m_mutex);
}
else
{
//fprintf(stderr, "domain_free %d %p\n", (int)domain->m_id, domain);
ddsrt_avl_delete (&dds_domaintree_def, &dds_global.m_domains, domain);
ddsrt_mutex_unlock (&dds_global.m_mutex);
dds_domain_fini (domain);
dds_free (domain);
}
}
#include "dds__entity.h"
static void pushdown_set_batch (struct dds_entity *e, bool enable)
{
/* e is pinned, no locks held */
dds_instance_handle_t last_iid = 0;
struct dds_entity *c;
ddsrt_mutex_lock (&e->m_mutex);
while ((c = ddsrt_avl_lookup_succ (&dds_entity_children_td, &e->m_children, &last_iid)) != NULL)
{
struct dds_entity *x;
last_iid = c->m_iid;
if (dds_entity_pin (c->m_hdllink.hdl, &x) < 0)
continue;
assert (x == c);
ddsrt_mutex_unlock (&e->m_mutex);
if (c->m_kind == DDS_KIND_PARTICIPANT)
pushdown_set_batch (c, enable);
else if (c->m_kind == DDS_KIND_WRITER)
{
struct dds_writer *w = (struct dds_writer *) c;
w->whc_batch = enable;
}
ddsrt_mutex_lock (&e->m_mutex);
dds_entity_unpin (c);
}
ddsrt_mutex_unlock (&e->m_mutex);
}
void dds_write_set_batch (bool enable)
{
/* FIXME: get channels + latency budget working and get rid of this; in the mean time, any ugly hack will do. */
struct dds_domain *dom;
dds_domainid_t last_id = -1;
dds_init ();
ddsrt_mutex_lock (&dds_global.m_mutex);
while ((dom = ddsrt_avl_lookup_succ (&dds_domaintree_def, &dds_global.m_domains, &last_id)) != NULL)
{
last_id = dom->m_id;
dom->gv.config.whc_batch = enable;
dds_instance_handle_t last_iid = 0;
struct dds_entity *e;
while (dom && (e = ddsrt_avl_lookup_succ (&dds_entity_children_td, &dom->m_ppants, &last_iid)) != NULL)
{
struct dds_entity *x;
last_iid = e->m_iid;
if (dds_entity_pin (e->m_hdllink.hdl, &x) < 0)
continue;
assert (x == e);
ddsrt_mutex_unlock (&dds_global.m_mutex);
pushdown_set_batch (e, enable);
ddsrt_mutex_lock (&dds_global.m_mutex);
dds_entity_unpin (e);
dom = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &last_id);
}
}
ddsrt_mutex_unlock (&dds_global.m_mutex);
dds_fini ();
}

View file

@ -35,8 +35,6 @@
#define DOMAIN_ID_MIN 0
#define DOMAIN_ID_MAX 230
struct q_globals gv;
dds_globals dds_global;
dds_return_t dds_init (void)
@ -57,7 +55,6 @@ dds_return_t dds_init (void)
thread_states_init_static ();
thread_states_init (64);
upgrade_main_thread ();
dds__builtin_init_global ();
if (dds_handle_server_init () != DDS_RETCODE_OK)
{
@ -85,7 +82,6 @@ extern void dds_fini (void)
if (--dds_global.m_init_count == 0)
{
dds_handle_server_fini ();
dds__builtin_fini_global ();
downgrade_main_thread ();
thread_states_fini ();
ddsi_iid_fini ();

View file

@ -41,16 +41,16 @@ dds_return_t dds_dispose_ih (dds_entity_t writer, dds_instance_handle_t handle)
static struct ddsi_tkmap_instance *dds_instance_find (const dds_topic *topic, const void *data, const bool create)
{
struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
struct ddsi_tkmap_instance *inst = ddsi_tkmap_find (sd, false, create);
struct ddsi_tkmap_instance *inst = ddsi_tkmap_find (topic->m_entity.m_domain->gv.m_tkmap, sd, false, create);
ddsi_serdata_unref (sd);
return inst;
}
static void dds_instance_remove (const dds_topic *topic, const void *data, dds_instance_handle_t handle)
static void dds_instance_remove (struct dds_domain *dom, const dds_topic *topic, const void *data, dds_instance_handle_t handle)
{
struct ddsi_tkmap_instance *inst;
if (handle != DDS_HANDLE_NIL)
inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
inst = ddsi_tkmap_find_by_id (dom->gv.m_tkmap, handle);
else
{
assert (data);
@ -58,7 +58,7 @@ static void dds_instance_remove (const dds_topic *topic, const void *data, dds_i
}
if (inst)
{
ddsi_tkmap_instance_unref (inst);
ddsi_tkmap_instance_unref (dom->gv.m_tkmap, inst);
}
}
@ -74,7 +74,7 @@ dds_return_t dds_register_instance (dds_entity_t writer, dds_instance_handle_t *
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
return ret;
thread_state_awake (ts1);
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
struct ddsi_tkmap_instance * const inst = dds_instance_find (wr->m_topic, data, true);
if (inst == NULL)
ret = DDS_RETCODE_ERROR;
@ -115,10 +115,10 @@ dds_return_t dds_unregister_instance_ts (dds_entity_t writer, const void *data,
if (wr->m_entity.m_qos)
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
thread_state_awake (ts1);
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
if (autodispose)
{
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
dds_instance_remove (wr->m_entity.m_domain, wr->m_topic, data, DDS_HANDLE_NIL);
action |= DDS_WR_DISPOSE_BIT;
}
ret = dds_write_impl (wr, data, timestamp, action);
@ -142,20 +142,20 @@ dds_return_t dds_unregister_instance_ih_ts (dds_entity_t writer, dds_instance_ha
if (wr->m_entity.m_qos)
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
thread_state_awake (ts1);
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
if (autodispose)
{
dds_instance_remove (wr->m_topic, NULL, handle);
dds_instance_remove (wr->m_entity.m_domain, wr->m_topic, NULL, handle);
action |= DDS_WR_DISPOSE_BIT;
}
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) == NULL)
if ((tk = ddsi_tkmap_find_by_id (wr->m_entity.m_domain->gv.m_tkmap, handle)) == NULL)
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
else
{
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (wr->m_entity.m_domain->gv.m_tkmap, tk);
ret = dds_write_impl (wr, sample, timestamp, action);
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
}
@ -173,9 +173,9 @@ dds_return_t dds_writedispose_ts (dds_entity_t writer, const void *data, dds_tim
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
return ret;
thread_state_awake (ts1);
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
if ((ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_WRITE_DISPOSE)) == DDS_RETCODE_OK)
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
dds_instance_remove (wr->m_entity.m_domain, wr->m_topic, data, DDS_HANDLE_NIL);
thread_state_asleep (ts1);
dds_writer_unlock (wr);
return ret;
@ -188,7 +188,7 @@ static dds_return_t dds_dispose_impl (dds_writer *wr, const void *data, dds_inst
dds_return_t ret;
assert (thread_is_awake ());
if ((ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_DISPOSE)) == DDS_RETCODE_OK)
dds_instance_remove (wr->m_topic, data, handle);
dds_instance_remove (wr->m_entity.m_domain, wr->m_topic, data, handle);
return ret;
}
@ -204,7 +204,7 @@ dds_return_t dds_dispose_ts (dds_entity_t writer, const void *data, dds_time_t t
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
return ret;
thread_state_awake (ts1);
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
ret = dds_dispose_impl (wr, data, DDS_HANDLE_NIL, timestamp);
thread_state_asleep (ts1);
dds_writer_unlock(wr);
@ -221,15 +221,15 @@ dds_return_t dds_dispose_ih_ts (dds_entity_t writer, dds_instance_handle_t handl
return ret;
struct ddsi_tkmap_instance *tk;
thread_state_awake (ts1);
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) == NULL)
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
if ((tk = ddsi_tkmap_find_by_id (wr->m_entity.m_domain->gv.m_tkmap, handle)) == NULL)
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
else
{
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (wr->m_entity.m_domain->gv.m_tkmap, tk);
ret = dds_dispose_impl (wr, sample, handle, timestamp);
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
}
@ -264,9 +264,9 @@ dds_instance_handle_t dds_lookup_instance (dds_entity_t entity, const void *data
return DDS_HANDLE_NIL;
}
thread_state_awake (ts1);
thread_state_awake (ts1, &w_or_r->m_domain->gv);
sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
ih = ddsi_tkmap_lookup (gv.m_tkmap, sd);
ih = ddsi_tkmap_lookup (w_or_r->m_domain->gv.m_tkmap, sd);
ddsi_serdata_unref (sd);
thread_state_asleep (ts1);
dds_entity_unlock (w_or_r);
@ -308,14 +308,14 @@ dds_return_t dds_instance_get_key (dds_entity_t entity, dds_instance_handle_t ih
return DDS_RETCODE_ILLEGAL_OPERATION;
}
thread_state_awake (ts1);
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, ih)) == NULL)
thread_state_awake (ts1, &e->m_domain->gv);
if ((tk = ddsi_tkmap_find_by_id (e->m_domain->gv.m_tkmap, ih)) == NULL)
ret = DDS_RETCODE_BAD_PARAMETER;
else
{
ddsi_sertopic_zero_sample (topic->m_stopic, data);
ddsi_serdata_topicless_to_sample (topic->m_stopic, tk->m_sample, data, NULL, NULL);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (e->m_domain->gv.m_tkmap, tk);
ret = DDS_RETCODE_OK;
}
thread_state_asleep (ts1);

View file

@ -33,18 +33,19 @@ dds_return_t dds_get_matched_subscriptions (dds_entity_t writer, dds_instance_ha
return rc;
else
{
const struct ephash *gh = wr->m_entity.m_domain->gv.guid_hash;
const int32_t nrds_max = (nrds > INT32_MAX) ? INT32_MAX : (int32_t) nrds;
int32_t nrds_act = 0;
ddsrt_avl_iter_t it;
/* FIXME: this ought not be so tightly coupled to the lower layer */
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), &wr->m_entity.m_domain->gv);
ddsrt_mutex_lock (&wr->m_wr->e.lock);
for (const struct wr_prd_match *m = ddsrt_avl_iter_first (&wr_readers_treedef, &wr->m_wr->readers, &it);
m != NULL;
m = ddsrt_avl_iter_next (&it))
{
struct proxy_reader *prd;
if ((prd = ephash_lookup_proxy_reader_guid (&m->prd_guid)) != NULL)
if ((prd = ephash_lookup_proxy_reader_guid (gh, &m->prd_guid)) != NULL)
{
if (nrds_act < nrds_max)
rds[nrds_act] = prd->e.iid;
@ -56,7 +57,7 @@ dds_return_t dds_get_matched_subscriptions (dds_entity_t writer, dds_instance_ha
m = ddsrt_avl_iter_next (&it))
{
struct reader *rd;
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL)
if ((rd = ephash_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
{
if (nrds_act < nrds_max)
rds[nrds_act] = rd->e.iid;
@ -80,18 +81,19 @@ dds_return_t dds_get_matched_publications (dds_entity_t reader, dds_instance_han
return rc;
else
{
const struct ephash *gh = rd->m_entity.m_domain->gv.guid_hash;
const int32_t nwrs_max = (nwrs > INT32_MAX) ? INT32_MAX : (int32_t) nwrs;
int32_t nwrs_act = 0;
ddsrt_avl_iter_t it;
/* FIXME: this ought not be so tightly coupled to the lower layer */
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), &rd->m_entity.m_domain->gv);
ddsrt_mutex_lock (&rd->m_rd->e.lock);
for (const struct rd_pwr_match *m = ddsrt_avl_iter_first (&rd_writers_treedef, &rd->m_rd->writers, &it);
m != NULL;
m = ddsrt_avl_iter_next (&it))
{
struct proxy_writer *pwr;
if ((pwr = ephash_lookup_proxy_writer_guid (&m->pwr_guid)) != NULL)
if ((pwr = ephash_lookup_proxy_writer_guid (gh, &m->pwr_guid)) != NULL)
{
if (nwrs_act < nwrs_max)
wrs[nwrs_act] = pwr->e.iid;
@ -103,7 +105,7 @@ dds_return_t dds_get_matched_publications (dds_entity_t reader, dds_instance_han
m = ddsrt_avl_iter_next (&it))
{
struct writer *wr;
if ((wr = ephash_lookup_writer_guid (&m->wr_guid)) != NULL)
if ((wr = ephash_lookup_writer_guid (gh, &m->wr_guid)) != NULL)
{
if (nwrs_act < nwrs_max)
wrs[nwrs_act] = wr->e.iid;
@ -142,17 +144,18 @@ dds_builtintopic_endpoint_t *dds_get_matched_subscription_data (dds_entity_t wri
return NULL;
else
{
const struct ephash *gh = wr->m_entity.m_domain->gv.guid_hash;
dds_builtintopic_endpoint_t *ret = NULL;
ddsrt_avl_iter_t it;
/* FIXME: this ought not be so tightly coupled to the lower layer, and not be so inefficient besides */
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), &wr->m_entity.m_domain->gv);
ddsrt_mutex_lock (&wr->m_wr->e.lock);
for (const struct wr_prd_match *m = ddsrt_avl_iter_first (&wr_readers_treedef, &wr->m_wr->readers, &it);
m != NULL && ret == NULL;
m = ddsrt_avl_iter_next (&it))
{
struct proxy_reader *prd;
if ((prd = ephash_lookup_proxy_reader_guid (&m->prd_guid)) != NULL)
if ((prd = ephash_lookup_proxy_reader_guid (gh, &m->prd_guid)) != NULL)
{
if (prd->e.iid == ih)
ret = make_builtintopic_endpoint (&prd->e.guid, &prd->c.proxypp->e.guid, prd->c.proxypp->e.iid, prd->c.xqos);
@ -163,7 +166,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_subscription_data (dds_entity_t wri
m = ddsrt_avl_iter_next (&it))
{
struct reader *rd;
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL)
if ((rd = ephash_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
{
if (rd->e.iid == ih)
ret = make_builtintopic_endpoint (&rd->e.guid, &rd->c.pp->e.guid, rd->c.pp->e.iid, rd->xqos);
@ -184,17 +187,18 @@ dds_builtintopic_endpoint_t *dds_get_matched_publication_data (dds_entity_t read
return NULL;
else
{
const struct ephash *gh = rd->m_entity.m_domain->gv.guid_hash;
dds_builtintopic_endpoint_t *ret = NULL;
ddsrt_avl_iter_t it;
/* FIXME: this ought not be so tightly coupled to the lower layer, and not be so inefficient besides */
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), &rd->m_entity.m_domain->gv);
ddsrt_mutex_lock (&rd->m_rd->e.lock);
for (const struct rd_pwr_match *m = ddsrt_avl_iter_first (&rd_writers_treedef, &rd->m_rd->writers, &it);
m != NULL && ret == NULL;
m = ddsrt_avl_iter_next (&it))
{
struct proxy_writer *pwr;
if ((pwr = ephash_lookup_proxy_writer_guid (&m->pwr_guid)) != NULL)
if ((pwr = ephash_lookup_proxy_writer_guid (gh, &m->pwr_guid)) != NULL)
{
if (pwr->e.iid == ih)
ret = make_builtintopic_endpoint (&pwr->e.guid, &pwr->c.proxypp->e.guid, pwr->c.proxypp->e.iid, pwr->c.xqos);
@ -205,7 +209,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_publication_data (dds_entity_t read
m = ddsrt_avl_iter_next (&it))
{
struct writer *wr;
if ((wr = ephash_lookup_writer_guid (&m->wr_guid)) != NULL)
if ((wr = ephash_lookup_writer_guid (gh, &m->wr_guid)) != NULL)
{
if (wr->e.iid == ih)
ret = make_builtintopic_endpoint (&wr->e.guid, &wr->c.pp->e.guid, wr->c.pp->e.iid, wr->xqos);

View file

@ -36,26 +36,14 @@ static dds_return_t dds_participant_delete (dds_entity *e) ddsrt_nonnull_all;
static dds_return_t dds_participant_delete (dds_entity *e)
{
struct dds_domain *dom;
dds_return_t ret;
dds_entity *prev, *iter;
assert (dds_entity_kind (e) == DDS_KIND_PARTICIPANT);
thread_state_awake (lookup_thread_state ());
if ((ret = delete_participant (&e->m_guid)) < 0)
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
if ((ret = delete_participant (&e->m_domain->gv, &e->m_guid)) < 0)
DDS_ERROR ("dds_participant_delete: internal error %"PRId32"\n", ret);
ddsrt_mutex_lock (&dds_global.m_mutex);
dom = e->m_domain;
for (iter = dom->ppants, prev = NULL; iter; prev = iter, iter = iter->m_next)
{
if (iter == e)
break;
}
assert (iter);
if (prev)
prev->m_next = iter->m_next;
else
dom->ppants = iter->m_next;
ddsrt_avl_delete (&dds_entity_children_td, &e->m_domain->m_ppants, e);
ddsrt_mutex_unlock (&dds_global.m_mutex);
thread_state_asleep (lookup_thread_state ());
@ -71,8 +59,8 @@ static dds_return_t dds_participant_qos_set (dds_entity *e, const dds_qos_t *qos
if (enabled)
{
struct participant *pp;
thread_state_awake (lookup_thread_state ());
if ((pp = ephash_lookup_participant_guid (&e->m_guid)) != NULL)
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
if ((pp = ephash_lookup_participant_guid (e->m_domain->gv.guid_hash, &e->m_guid)) != NULL)
{
nn_plist_t plist;
nn_plist_init_empty (&plist);
@ -111,7 +99,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
new_qos = dds_create_qos ();
if (qos != NULL)
nn_xqos_mergein_missing (new_qos, qos, DDS_PARTICIPANT_QOS_MASK);
nn_xqos_mergein_missing (new_qos, &gv.default_plist_pp.qos, ~(uint64_t)0);
nn_xqos_mergein_missing (new_qos, &dom->gv.default_plist_pp.qos, ~(uint64_t)0);
if ((ret = nn_xqos_valid (new_qos)) < 0)
goto err_qos_validation;
@ -119,8 +107,8 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
nn_plist_init_empty (&plist);
dds_merge_qos (&plist.qos, new_qos);
thread_state_awake (lookup_thread_state ());
ret = new_participant (&guid, 0, &plist);
thread_state_awake (lookup_thread_state (), &dom->gv);
ret = new_participant (&guid, &dom->gv, 0, &plist);
thread_state_asleep (lookup_thread_state ());
nn_plist_fini (&plist);
if (ret < 0)
@ -134,14 +122,13 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
goto err_entity_init;
pp->m_entity.m_guid = guid;
pp->m_entity.m_iid = get_entity_instance_id (&guid);
pp->m_entity.m_iid = get_entity_instance_id (&dom->gv, &guid);
pp->m_entity.m_domain = dom;
pp->m_builtin_subscriber = 0;
/* Add participant to extent */
ddsrt_mutex_lock (&dds_global.m_mutex);
pp->m_entity.m_next = pp->m_entity.m_domain->ppants;
pp->m_entity.m_domain->ppants = &pp->m_entity;
ddsrt_avl_insert (&dds_entity_children_td, &dom->m_ppants, &pp->m_entity);
ddsrt_mutex_unlock (&dds_global.m_mutex);
return ret;
@ -176,10 +163,11 @@ dds_entity_t dds_lookup_participant (dds_domainid_t domain_id, dds_entity_t *par
ddsrt_mutex_lock (&dds_global.m_mutex);
if ((dom = dds_domain_find_locked (domain_id)) != NULL)
{
for (dds_entity *iter = dom->ppants; iter; iter = iter->m_next)
ddsrt_avl_iter_t it;
for (dds_entity *e = ddsrt_avl_iter_first (&dds_entity_children_td, &dom->m_ppants, &it); e != NULL; e = ddsrt_avl_iter_next (&it))
{
if ((size_t) ret < size)
participants[ret] = iter->m_hdllink.hdl;
participants[ret] = e->m_hdllink.hdl;
ret++;
}
}

View file

@ -52,21 +52,19 @@ dds_entity_t dds_create_publisher (dds_entity_t participant, const dds_qos_t *qo
dds_qos_t *new_qos;
dds_return_t ret;
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
return ret;
new_qos = dds_create_qos ();
if (qos)
nn_xqos_mergein_missing (new_qos, qos, DDS_PUBLISHER_QOS_MASK);
nn_xqos_mergein_missing (new_qos, &gv.default_xqos_pub, ~(uint64_t)0);
nn_xqos_mergein_missing (new_qos, &par->m_entity.m_domain->gv.default_xqos_pub, ~(uint64_t)0);
if ((ret = nn_xqos_valid (new_qos)) != DDS_RETCODE_OK)
{
dds_delete_qos (new_qos);
dds_participant_unlock (par);
return ret;
}
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
{
dds_delete_qos (new_qos);
return ret;
}
pub = dds_alloc (sizeof (*pub));
hdl = dds_entity_init (&pub->m_entity, &par->m_entity, DDS_KIND_PUBLISHER, new_qos, listener, DDS_PUBLISHER_STATUS_MASK);
pub->m_entity.m_iid = ddsi_iid_gen ();

View file

@ -43,27 +43,27 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
if (buf == NULL || si == NULL || maxs == 0 || bufsz == 0 || bufsz < maxs)
return DDS_RETCODE_BAD_PARAMETER;
thread_state_awake (ts1);
if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) {
goto fail_awake;
goto fail;
} else if (dds_entity_kind (entity) == DDS_KIND_READER) {
rd = (dds_reader *) entity;
cond = NULL;
} else if (only_reader) {
ret = DDS_RETCODE_ILLEGAL_OPERATION;
goto fail_awake_pinned;
goto fail_pinned;
} else if (dds_entity_kind (entity) != DDS_KIND_COND_READ && dds_entity_kind (entity) != DDS_KIND_COND_QUERY) {
ret = DDS_RETCODE_ILLEGAL_OPERATION;
goto fail_awake_pinned;
goto fail_pinned;
} else {
rd = (dds_reader *) entity->m_parent;
cond = (dds_readcond *) entity;
}
thread_state_awake (ts1, &entity->m_domain->gv);
if (hand != DDS_HANDLE_NIL)
{
if (ddsi_tkmap_find_by_id (gv.m_tkmap, hand) == NULL) {
if (ddsi_tkmap_find_by_id (entity->m_domain->gv.m_tkmap, hand) == NULL) {
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail_awake_pinned;
}
@ -144,9 +144,10 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
#undef NC_RESET_BUF
fail_awake_pinned:
dds_entity_unpin (entity);
fail_awake:
thread_state_asleep (ts1);
fail_pinned:
dds_entity_unpin (entity);
fail:
return ret;
}
@ -164,20 +165,19 @@ static dds_return_t dds_readcdr_impl (bool take, dds_entity_t reader_or_conditio
assert (maxs > 0);
(void)take;
thread_state_awake (ts1);
if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) {
goto fail_awake;
return ret;
} else if (dds_entity_kind (entity) == DDS_KIND_READER) {
rd = (dds_reader *) entity;
} else if (dds_entity_kind (entity) != DDS_KIND_COND_READ && dds_entity_kind (entity) != DDS_KIND_COND_QUERY) {
dds_entity_unpin (entity);
ret = DDS_RETCODE_ILLEGAL_OPERATION;
goto fail_awake;
return DDS_RETCODE_ILLEGAL_OPERATION;
} else {
rd = (dds_reader *) entity->m_parent;
}
thread_state_awake (ts1, &entity->m_domain->gv);
/* read/take resets data available status -- must reset before reading because
the actual writing is protected by RHC lock, not by rd->m_entity.m_lock */
dds_entity_status_reset (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
@ -188,8 +188,6 @@ static dds_return_t dds_readcdr_impl (bool take, dds_entity_t reader_or_conditio
ret = dds_rhc_takecdr (rd->m_rhc, lock, buf, si, maxs, mask & DDS_ANY_SAMPLE_STATE, mask & DDS_ANY_VIEW_STATE, mask & DDS_ANY_INSTANCE_STATE, hand);
dds_entity_unpin (entity);
fail_awake:
thread_state_asleep (ts1);
return ret;
}

View file

@ -45,8 +45,8 @@ static dds_return_t dds_reader_close (dds_entity *e) ddsrt_nonnull_all;
static dds_return_t dds_reader_close (dds_entity *e)
{
dds_return_t ret = DDS_RETCODE_OK;
thread_state_awake (lookup_thread_state ());
if (delete_reader (&e->m_guid) != 0)
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
if (delete_reader (&e->m_domain->gv, &e->m_guid) != 0)
ret = DDS_RETCODE_ERROR;
thread_state_asleep (lookup_thread_state ());
return ret;
@ -76,8 +76,8 @@ static dds_return_t dds_reader_qos_set (dds_entity *e, const dds_qos_t *qos, boo
if (enabled)
{
struct reader *rd;
thread_state_awake (lookup_thread_state ());
if ((rd = ephash_lookup_reader_guid (&e->m_guid)) != NULL)
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
if ((rd = ephash_lookup_reader_guid (e->m_domain->gv.guid_hash, &e->m_guid)) != NULL)
update_reader_qos (rd, qos);
thread_state_asleep (lookup_thread_state ());
}
@ -347,6 +347,7 @@ dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_enti
goto err_tp_lock;
}
assert (tp->m_stopic);
/* FIXME: domain check */
assert (sub->m_entity.m_domain == tp->m_entity.m_domain);
/* Merge qos from topic and subscriber, dds_copy_qos only fails when it is passed a null
@ -358,7 +359,7 @@ dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_enti
nn_xqos_mergein_missing (rqos, sub->m_entity.m_qos, ~(uint64_t)0);
if (tp->m_entity.m_qos)
nn_xqos_mergein_missing (rqos, tp->m_entity.m_qos, ~(uint64_t)0);
nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd, ~(uint64_t)0);
nn_xqos_mergein_missing (rqos, &sub->m_entity.m_domain->gv.default_xqos_rd, ~(uint64_t)0);
if ((ret = nn_xqos_valid (rqos)) != DDS_RETCODE_OK)
{
@ -392,14 +393,14 @@ dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_enti
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
ddsrt_mutex_unlock (&sub->m_entity.m_mutex);
thread_state_awake (lookup_thread_state ());
ret = new_reader (&rd->m_rd, &rd->m_entity.m_guid, NULL, &sub->m_entity.m_participant->m_guid, tp->m_stopic, rqos, &rd->m_rhc->common.rhc, dds_reader_status_cb, rd);
thread_state_awake (lookup_thread_state (), &sub->m_entity.m_domain->gv);
ret = new_reader (&rd->m_rd, &rd->m_entity.m_domain->gv, &rd->m_entity.m_guid, NULL, &sub->m_entity.m_participant->m_guid, tp->m_stopic, rqos, &rd->m_rhc->common.rhc, dds_reader_status_cb, rd);
ddsrt_mutex_lock (&sub->m_entity.m_mutex);
ddsrt_mutex_lock (&tp->m_entity.m_mutex);
assert (ret == DDS_RETCODE_OK); /* FIXME: can be out-of-resources at the very least */
thread_state_asleep (lookup_thread_state ());
rd->m_entity.m_iid = get_entity_instance_id (&rd->m_entity.m_guid);
rd->m_entity.m_iid = get_entity_instance_id (&rd->m_entity.m_domain->gv, &rd->m_entity.m_guid);
dds_entity_register_child (&sub->m_entity, &rd->m_entity);
dds_topic_unlock (tp);
@ -460,7 +461,7 @@ void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb
pwrguid_next.entityid.u = (pwrguid_next.entityid.u & ~(uint32_t)0xff) | NN_ENTITYID_KIND_WRITER_NO_KEY;
}
ddsrt_mutex_unlock (&rd->e.lock);
if ((pwr = ephash_lookup_proxy_writer_guid (&pwrguid)) != NULL)
if ((pwr = ephash_lookup_proxy_writer_guid (dds_entity->m_domain->gv.guid_hash, &pwrguid)) != NULL)
{
ddsrt_mutex_lock (&pwr->e.lock);
pwr->ddsi2direct_cb = cb;

View file

@ -302,8 +302,10 @@ struct dds_rhc_default {
bool by_source_ordering; /* true if BY_SOURCE, false if BY_RECEPTION */
bool exclusive_ownership; /* true if EXCLUSIVE, false if SHARED */
bool reliable; /* true if reliability RELIABLE */
bool xchecks; /* whether to do expensive checking if checking at all */
dds_reader *reader; /* reader */
dds_reader *reader; /* reader -- may be NULL (used by rhc_torture) */
struct ddsi_tkmap *tkmap; /* back pointer to tkmap */
const struct ddsi_sertopic *topic; /* topic description */
uint32_t history_depth; /* depth, 1 for KEEP_LAST_1, 2**32-1 for KEEP_ALL */
@ -521,7 +523,7 @@ static void remove_inst_from_nonempty_list (struct dds_rhc_default *rhc, struct
rhc->n_nonempty_instances--;
}
struct dds_rhc *dds_rhc_default_new (dds_reader *reader, const struct ddsi_sertopic *topic)
struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_tkmap *tkmap, const struct ddsi_sertopic *topic, bool xchecks)
{
struct dds_rhc_default *rhc = ddsrt_malloc (sizeof (*rhc));
memset (rhc, 0, sizeof (*rhc));
@ -532,10 +534,17 @@ struct dds_rhc *dds_rhc_default_new (dds_reader *reader, const struct ddsi_serto
rhc->instances = ddsrt_hh_new (1, instance_iid_hash, instance_iid_eq);
rhc->topic = topic;
rhc->reader = reader;
rhc->tkmap = tkmap;
rhc->xchecks = xchecks;
return &rhc->common;
}
struct dds_rhc *dds_rhc_default_new (dds_reader *reader, const struct ddsi_sertopic *topic)
{
return dds_rhc_default_new_xchecks (reader, reader->m_entity.m_domain->gv.m_tkmap, topic, (reader->m_entity.m_domain->gv.config.enabled_xchecks & DDS_XCHECK_RHC) != 0);
}
static void dds_rhc_default_set_qos (struct dds_rhc_default * rhc, const dds_qos_t * qos)
{
/* Set read related QoS */
@ -635,10 +644,10 @@ static void inst_set_invsample (struct dds_rhc_default *rhc, struct rhc_instance
}
}
static void free_empty_instance (struct rhc_instance *inst)
static void free_empty_instance (struct rhc_instance *inst, struct dds_rhc_default *rhc)
{
assert (inst_is_empty (inst));
ddsi_tkmap_instance_unref (inst->tk);
ddsi_tkmap_instance_unref (rhc->tkmap, inst->tk);
ddsrt_free (inst);
}
@ -667,7 +676,7 @@ static void free_instance_rhc_free (struct rhc_instance *inst, struct dds_rhc_de
{
remove_inst_from_nonempty_list (rhc, inst);
}
ddsi_tkmap_instance_unref (inst->tk);
ddsi_tkmap_instance_unref (rhc->tkmap, inst->tk);
ddsrt_free (inst);
}
@ -926,7 +935,7 @@ static void drop_instance_noupdate_no_writers (struct dds_rhc_default *rhc, stru
assert (ret);
(void) ret;
free_empty_instance (inst);
free_empty_instance (inst, rhc);
}
static void dds_rhc_register (struct dds_rhc_default *rhc, struct rhc_instance *inst, uint64_t wr_iid, bool iid_update)
@ -1259,7 +1268,7 @@ static rhc_store_result_t rhc_store_new_instance (struct rhc_instance **out_inst
{
if (!add_sample (rhc, inst, pwr_info, sample, cb_data, trig_qc))
{
free_empty_instance (inst);
free_empty_instance (inst, rhc);
return RHC_REJECTED;
}
}
@ -2638,7 +2647,7 @@ static int dds_rhc_default_takecdr (struct dds_rhc_default *rhc, bool lock, stru
#define CHECK_MAX_CONDS 64
static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_conds, bool check_qcmask)
{
if (!(config.enabled_xchecks & DDS_XCHECK_RHC))
if (!rhc->xchecks)
return 1;
const uint32_t ncheck = rhc->nconds < CHECK_MAX_CONDS ? rhc->nconds : CHECK_MAX_CONDS;

View file

@ -131,7 +131,7 @@ static struct ddsi_serdata *ddsi_serdata_builtin_from_keyhash (const struct ddsi
/* FIXME: not quite elegant to manage the creation of a serdata for a built-in topic via this function, but I also find it quite unelegant to let from_sample read straight from the underlying internal entity, and to_sample convert to the external format ... I could claim the internal entity is the "serialised form", but that forces wrapping it in a fragchain in one way or another, which, though possible, is also a bit lacking in elegance. */
const struct ddsi_sertopic_builtintopic *tp = (const struct ddsi_sertopic_builtintopic *)tpcmn;
/* keyhash must in host format (which the GUIDs always are internally) */
const struct entity_common *entity = ephash_lookup_guid_untyped ((const nn_guid_t *) keyhash->value);
const struct entity_common *entity = ephash_lookup_guid_untyped (tp->gv->guid_hash, (const nn_guid_t *) keyhash->value);
struct ddsi_serdata_builtintopic *d = serdata_builtin_new(tp, entity ? SDK_DATA : SDK_KEY);
memcpy (&d->key, keyhash->value, sizeof (d->key));
if (entity)

View file

@ -26,7 +26,7 @@
/* 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 */
struct ddsi_sertopic *new_sertopic_builtintopic (enum ddsi_sertopic_builtintopic_type type, const char *name, const char *typename)
struct ddsi_sertopic *new_sertopic_builtintopic (enum ddsi_sertopic_builtintopic_type type, const char *name, const char *typename, struct q_globals *gv)
{
struct ddsi_sertopic_builtintopic *tp = ddsrt_malloc (sizeof (*tp));
tp->c.iid = ddsi_iid_gen();
@ -40,6 +40,7 @@ struct ddsi_sertopic *new_sertopic_builtintopic (enum ddsi_sertopic_builtintopic
tp->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (tp->c.serdata_ops);
ddsrt_atomic_st32 (&tp->c.refc, 1);
tp->type = type;
tp->gv = gv;
return &tp->c;
}

View file

@ -55,7 +55,7 @@ dds_entity_t dds__create_subscriber_l (dds_participant *participant, const dds_q
new_qos = dds_create_qos ();
if (qos)
nn_xqos_mergein_missing (new_qos, qos, DDS_SUBSCRIBER_QOS_MASK);
nn_xqos_mergein_missing (new_qos, &gv.default_xqos_sub, ~(uint64_t)0);
nn_xqos_mergein_missing (new_qos, &participant->m_entity.m_domain->gv.default_xqos_sub, ~(uint64_t)0);
if ((ret = nn_xqos_valid (new_qos)) != DDS_RETCODE_OK)
{
dds_delete_qos (new_qos);

View file

@ -426,8 +426,8 @@ dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_s
top->m_stopic = sertopic;
/* Publish Topic */
thread_state_awake (lookup_thread_state ());
ddsi_pp = ephash_lookup_participant_guid (&par->m_entity.m_guid);
thread_state_awake (lookup_thread_state (), &par->m_entity.m_domain->gv);
ddsi_pp = ephash_lookup_participant_guid (par->m_entity.m_domain->gv.guid_hash, &par->m_entity.m_guid);
assert (ddsi_pp);
if (sedp_plist)
{
@ -461,10 +461,15 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
nn_plist_t plist;
dds_entity_t hdl;
size_t keysz;
struct dds_entity *ppent;
dds_return_t ret;
if (desc == NULL || name == NULL || !is_valid_name (name))
return DDS_RETCODE_BAD_PARAMETER;
if ((ret = dds_entity_pin (participant, &ppent)) < 0)
return ret;
typename = desc->m_typename;
keysz = strlen (name) + strlen (typename) + 2;
key = dds_alloc (keysz);
@ -481,7 +486,7 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
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 = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? CDR_LE : CDR_BE);
st->serpool = ppent->m_domain->gv.serpool;
st->type = (void*) desc;
st->nkeys = desc->m_nkeys;
st->keys = desc->m_keys;
@ -513,6 +518,7 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
hdl = dds_create_topic_arbitrary (participant, &st->c, qos, listener, &plist);
ddsi_sertopic_unref (&st->c);
dds_entity_unpin (ppent);
nn_plist_fini (&plist);
return hdl;
}

View file

@ -76,8 +76,11 @@ struct whc_impl {
uint32_t seq_size;
size_t unacked_bytes;
size_t sample_overhead;
uint32_t fragment_size;
uint64_t total_bytes; /* total number of bytes pushed in */
unsigned is_transient_local: 1;
unsigned xchecks: 1;
struct ddsi_tkmap *tkmap;
uint32_t hdepth; /* 0 = unlimited */
uint32_t tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
uint32_t idxdepth; /* = max (hdepth, tldepth) */
@ -264,7 +267,7 @@ static void check_whc (const struct whc_impl *whc)
assert (whc->maxseq_node == whc_findmax_procedurally (whc));
#if !defined (NDEBUG)
if (config.enabled_xchecks & DDS_XCHECK_WHC)
if (whc->xchecks)
{
struct whc_intvnode *firstintv;
struct whc_node *cur;
@ -332,7 +335,7 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
} template;
struct whc_idxnode *n;
check_whc (whc);
template.idxn.iid = ddsi_tkmap_lookup (gv.m_tkmap, serdata_key);
template.idxn.iid = ddsi_tkmap_lookup (whc->tkmap, serdata_key);
n = ddsrt_hh_lookup (whc->idx_hash, &template.idxn);
if (n == NULL)
return NULL;
@ -343,7 +346,7 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
}
}
struct whc *whc_new (int is_transient_local, uint32_t hdepth, uint32_t tldepth)
struct whc *whc_new (struct q_globals *gv, int is_transient_local, uint32_t hdepth, uint32_t tldepth)
{
size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */
struct whc_impl *whc;
@ -355,6 +358,8 @@ struct whc *whc_new (int is_transient_local, uint32_t hdepth, uint32_t tldepth)
whc->common.ops = &whc_ops;
ddsrt_mutex_init (&whc->lock);
whc->is_transient_local = is_transient_local ? 1 : 0;
whc->xchecks = (gv->config.enabled_xchecks & DDS_XCHECK_WHC) != 0;
whc->tkmap = gv->m_tkmap;
whc->hdepth = hdepth;
whc->tldepth = tldepth;
whc->idxdepth = hdepth > tldepth ? hdepth : tldepth;
@ -363,6 +368,7 @@ struct whc *whc_new (int is_transient_local, uint32_t hdepth, uint32_t tldepth)
whc->unacked_bytes = 0;
whc->total_bytes = 0;
whc->sample_overhead = sample_overhead;
whc->fragment_size = gv->config.fragment_size;
#if USE_EHH
whc->seq_hash = ddsrt_ehh_new (sizeof (struct whc_seq_entry), 32, whc_seq_entry_hash, whc_seq_entry_eq);
#else
@ -550,7 +556,7 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w
#endif
if (!ddsrt_hh_remove (whc->idx_hash, idxn))
assert (0);
ddsi_tkmap_instance_unref (idxn->tk);
ddsi_tkmap_instance_unref (whc->tkmap, idxn->tk);
ddsrt_free (idxn);
}
whcn->idxnode = NULL;
@ -647,7 +653,7 @@ static uint32_t whc_default_downgrade_to_volatile (struct whc *whc_generic, stru
static size_t whcn_size (const struct whc_impl *whc, const struct whc_node *whcn)
{
size_t sz = ddsi_serdata_size (whcn->serdata);
return sz + ((sz + config.fragment_size - 1) / config.fragment_size) * whc->sample_overhead;
return sz + ((sz + whc->fragment_size - 1) / whc->fragment_size) * whc->sample_overhead;
}
static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_intv, struct whc_node **p_whcn)

View file

@ -28,6 +28,7 @@
struct bwhc {
struct whc common;
enum ddsi_sertopic_builtintopic_type type;
const struct ephash *guid_hash;
};
enum bwhc_iter_state {
@ -63,7 +64,7 @@ static void bwhc_sample_iter_init (const struct whc *whc_generic, struct whc_sam
static bool is_visible (const struct entity_common *e)
{
const nn_vendorid_t vendorid = get_entity_vendorid (e);
return builtintopic_is_visible (gv.builtin_topic_interface, &e->guid, vendorid);
return builtintopic_is_visible (e->gv->builtin_topic_interface, &e->guid, vendorid);
}
static bool bwhc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample)
@ -91,7 +92,7 @@ static bool bwhc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, str
case DSBT_READER: kind = EK_READER; break;
}
assert (whc->type == DSBT_PARTICIPANT || kind != EK_PARTICIPANT);
ephash_enum_init (&it->it, kind);
ephash_enum_init (&it->it, whc->guid_hash, kind);
it->st = BIS_LOCAL;
/* FALLS THROUGH */
case BIS_LOCAL:
@ -114,7 +115,7 @@ static bool bwhc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, str
case DSBT_READER: kind = EK_PROXY_READER; break;
}
assert (kind != EK_PARTICIPANT);
ephash_enum_init (&it->it, kind);
ephash_enum_init (&it->it, whc->guid_hash, kind);
it->st = BIS_PROXY;
/* FALLS THROUGH */
case BIS_PROXY:
@ -191,10 +192,11 @@ static const struct whc_ops bwhc_ops = {
.free = bwhc_free
};
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type)
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type, const struct ephash *guid_hash)
{
struct bwhc *whc = ddsrt_malloc (sizeof (*whc));
whc->common.ops = &bwhc_ops;
whc->type = type;
whc->guid_hash = guid_hash;
return (struct whc *) whc;
}

View file

@ -24,6 +24,7 @@
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_radmin.h"
#include "dds/ddsi/q_globals.h"
dds_return_t dds_write (dds_entity_t writer, const void *data)
{
@ -121,6 +122,7 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
ddsrt_avl_iter_t it;
struct pwr_rd_match *m;
struct proxy_writer_info pwr_info;
const struct ephash *gh = wr->e.gv->guid_hash;
dds_duration_t max_block_ms = wr->xqos->reliability.max_blocking_time;
ddsrt_mutex_unlock (&wr->rdary.rdary_lock);
make_proxy_writer_info (&pwr_info, &wr->e, wr->xqos);
@ -128,7 +130,7 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
for (m = ddsrt_avl_iter_first (&wr_local_readers_treedef, &wr->local_readers, &it); m != NULL; m = ddsrt_avl_iter_next (&it))
{
struct reader *rd;
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL)
if ((rd = ephash_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
{
DDS_TRACE ("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
/* Copied the return value ignore from DDSI deliver_user_data () function. */
@ -159,7 +161,7 @@ dds_return_t dds_write_impl (dds_writer *wr, const void * data, dds_time_t tstam
if (! wr->m_topic->filter_fn (data, wr->m_topic->filter_ctx))
return DDS_RETCODE_OK;
thread_state_awake (ts1);
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
/* Serialize and write data or key */
d = ddsi_serdata_from_sample (ddsi_wr->topic, writekey ? SDK_KEY : SDK_DATA, data);
@ -167,12 +169,12 @@ dds_return_t dds_write_impl (dds_writer *wr, const void * data, dds_time_t tstam
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0));
d->timestamp.v = tstamp;
ddsi_serdata_ref (d);
tk = ddsi_tkmap_lookup_instance_ref (d);
tk = ddsi_tkmap_lookup_instance_ref (wr->m_entity.m_domain->gv.m_tkmap, d);
w_rc = write_sample_gc (ts1, wr->m_xp, ddsi_wr, d, tk);
if (w_rc >= 0) {
/* Flush out write unless configured to batch */
if (!config.whc_batch)
if (!wr->whc_batch)
nn_xpack_send (wr->m_xp, false);
ret = DDS_RETCODE_OK;
} else if (w_rc == DDS_RETCODE_TIMEOUT) {
@ -185,25 +187,25 @@ dds_return_t dds_write_impl (dds_writer *wr, const void * data, dds_time_t tstam
if (ret == DDS_RETCODE_OK)
ret = deliver_locally (ddsi_wr, d, tk);
ddsi_serdata_unref (d);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (wr->m_entity.m_domain->gv.m_tkmap, tk);
thread_state_asleep (ts1);
return ret;
}
dds_return_t dds_writecdr_impl_lowlevel (struct writer *ddsi_wr, struct nn_xpack *xp, struct ddsi_serdata *d)
dds_return_t dds_writecdr_impl_lowlevel (struct writer *ddsi_wr, struct nn_xpack *xp, struct ddsi_serdata *d, bool flush)
{
struct thread_state1 * const ts1 = lookup_thread_state ();
struct ddsi_tkmap_instance * tk;
int ret = DDS_RETCODE_OK;
int w_rc;
thread_state_awake (ts1);
thread_state_awake (ts1, ddsi_wr->e.gv);
ddsi_serdata_ref (d);
tk = ddsi_tkmap_lookup_instance_ref (d);
tk = ddsi_tkmap_lookup_instance_ref (ddsi_wr->e.gv->m_tkmap, d);
w_rc = write_sample_gc (ts1, xp, ddsi_wr, d, tk);
if (w_rc >= 0) {
/* Flush out write unless configured to batch */
if (!config.whc_batch && xp != NULL)
if (flush && xp != NULL)
nn_xpack_send (xp, false);
ret = DDS_RETCODE_OK;
} else if (w_rc == DDS_RETCODE_TIMEOUT) {
@ -217,7 +219,7 @@ dds_return_t dds_writecdr_impl_lowlevel (struct writer *ddsi_wr, struct nn_xpack
if (ret == DDS_RETCODE_OK)
ret = deliver_locally (ddsi_wr, d, tk);
ddsi_serdata_unref (d);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (ddsi_wr->e.gv->m_tkmap, tk);
thread_state_asleep (ts1);
return ret;
}
@ -230,12 +232,7 @@ dds_return_t dds_writecdr_impl (dds_writer *wr, struct ddsi_serdata *d, dds_time
d->statusinfo = (((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) |
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0));
d->timestamp.v = tstamp;
return dds_writecdr_impl_lowlevel (wr->m_wr, wr->m_xp, d);
}
void dds_write_set_batch (bool enable)
{
config.whc_batch = enable ? 1 : 0;
return dds_writecdr_impl_lowlevel (wr->m_wr, wr->m_xp, d, !wr->whc_batch);
}
void dds_write_flush (dds_entity_t writer)
@ -243,11 +240,11 @@ void dds_write_flush (dds_entity_t writer)
struct thread_state1 * const ts1 = lookup_thread_state ();
dds_writer *wr;
dds_return_t rc;
thread_state_awake (ts1);
if ((rc = dds_writer_lock (writer, &wr)) == DDS_RETCODE_OK)
{
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
nn_xpack_send (wr->m_xp, true);
thread_state_asleep (ts1);
dds_writer_unlock (wr);
}
thread_state_asleep (ts1);
}

View file

@ -172,9 +172,9 @@ static dds_return_t dds_writer_close (dds_entity *e)
{
dds_writer * const wr = (dds_writer *) e;
dds_return_t ret;
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
nn_xpack_send (wr->m_xp, false);
if ((ret = delete_writer (&e->m_guid)) < 0)
if ((ret = delete_writer (&e->m_domain->gv, &e->m_guid)) < 0)
ret = DDS_RETCODE_ERROR;
thread_state_asleep (lookup_thread_state ());
return ret;
@ -187,7 +187,7 @@ static dds_return_t dds_writer_delete (dds_entity *e)
dds_writer * const wr = (dds_writer *) e;
dds_return_t ret;
/* FIXME: not freeing WHC here because it is owned by the DDSI entity */
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
nn_xpack_free (wr->m_xp);
thread_state_asleep (lookup_thread_state ());
if ((ret = dds_delete (wr->m_topic->m_entity.m_hdllink.hdl)) == DDS_RETCODE_OK)
@ -205,15 +205,15 @@ static dds_return_t dds_writer_qos_set (dds_entity *e, const dds_qos_t *qos, boo
if (enabled)
{
struct writer *wr;
thread_state_awake (lookup_thread_state ());
if ((wr = ephash_lookup_writer_guid (&e->m_guid)) != NULL)
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
if ((wr = ephash_lookup_writer_guid (e->m_domain->gv.guid_hash, &e->m_guid)) != NULL)
update_writer_qos (wr, qos);
thread_state_asleep (lookup_thread_state ());
}
return DDS_RETCODE_OK;
}
static struct whc *make_whc (const dds_qos_t *qos)
static struct whc *make_whc (struct dds_domain *dom, const dds_qos_t *qos)
{
bool handle_as_transient_local;
uint32_t hdepth, tldepth;
@ -234,7 +234,7 @@ static struct whc *make_whc (const dds_qos_t *qos)
else
tldepth = (unsigned) qos->durability_service.history.depth;
}
return whc_new (handle_as_transient_local, hdepth, tldepth);
return whc_new (&dom->gv, handle_as_transient_local, hdepth, tldepth);
}
const struct dds_entity_deriver dds_entity_deriver_writer = {
@ -253,7 +253,6 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
dds_publisher *pub = NULL;
dds_topic *tp;
dds_entity_t publisher;
ddsi_tran_conn_t conn = gv.data_conn_uc;
{
dds_entity *p_or_p;
@ -269,6 +268,7 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
if ((rc = dds_publisher_lock (publisher, &pub)) != DDS_RETCODE_OK)
return rc;
ddsi_tran_conn_t conn = pub->m_entity.m_domain->gv.data_conn_uc;
if (publisher != participant_or_publisher)
pub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
@ -286,7 +286,7 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
nn_xqos_mergein_missing (wqos, pub->m_entity.m_qos, ~(uint64_t)0);
if (tp->m_entity.m_qos)
nn_xqos_mergein_missing (wqos, tp->m_entity.m_qos, ~(uint64_t)0);
nn_xqos_mergein_missing (wqos, &gv.default_xqos_wr, ~(uint64_t)0);
nn_xqos_mergein_missing (wqos, &pub->m_entity.m_domain->gv.default_xqos_wr, ~(uint64_t)0);
if ((rc = nn_xqos_valid (wqos)) < 0)
{
@ -300,8 +300,9 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
wr->m_topic = tp;
dds_entity_add_ref_locked (&tp->m_entity);
wr->m_xp = nn_xpack_new (conn, get_bandwidth_limit (wqos->transport_priority), config.xpack_send_async);
wr->m_whc = make_whc (wqos);
wr->m_xp = nn_xpack_new (conn, get_bandwidth_limit (wqos->transport_priority), pub->m_entity.m_domain->gv.config.xpack_send_async);
wr->m_whc = make_whc (pub->m_entity.m_domain, wqos);
wr->whc_batch = pub->m_entity.m_domain->gv.config.whc_batch;
/* Extra claim of this writer to make sure that the delete waits until DDSI
* has deleted its writer as well. This can be known through the callback. */
@ -310,14 +311,14 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
ddsrt_mutex_unlock (&pub->m_entity.m_mutex);
thread_state_awake (lookup_thread_state ());
rc = new_writer (&wr->m_wr, &wr->m_entity.m_guid, NULL, &pub->m_entity.m_participant->m_guid, tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
thread_state_awake (lookup_thread_state (), &pub->m_entity.m_domain->gv);
rc = new_writer (&wr->m_wr, &wr->m_entity.m_domain->gv, &wr->m_entity.m_guid, NULL, &pub->m_entity.m_participant->m_guid, tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
ddsrt_mutex_lock (&pub->m_entity.m_mutex);
ddsrt_mutex_lock (&tp->m_entity.m_mutex);
assert(rc == DDS_RETCODE_OK);
thread_state_asleep (lookup_thread_state ());
wr->m_entity.m_iid = get_entity_instance_id (&wr->m_entity.m_guid);
wr->m_entity.m_iid = get_entity_instance_id (&wr->m_entity.m_domain->gv, &wr->m_entity.m_guid);
dds_entity_register_child (&pub->m_entity, &wr->m_entity);
dds_topic_unlock (tp);

View file

@ -18,7 +18,7 @@
extern "C" {
#endif
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_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, const nn_locator_t *ownloc, 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 struct sockaddr *const sa1, const struct 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);

View file

@ -22,10 +22,10 @@ struct nn_group_membership;
struct nn_group_membership *new_group_membership (void);
void free_group_membership (struct nn_group_membership *mship);
int ddsi_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcip, const nn_locator_t *mcip);
int ddsi_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcip, const nn_locator_t *mcip);
void ddsi_transfer_group_membership (ddsi_tran_conn_t conn, ddsi_tran_conn_t newconn);
int ddsi_rejoin_transferred_mcgroups (ddsi_tran_conn_t conn);
int ddsi_join_mc (const struct q_globals *gv, struct nn_group_membership *mship, ddsi_tran_conn_t conn, const nn_locator_t *srcip, const nn_locator_t *mcip);
int ddsi_leave_mc (const struct q_globals *gv, struct nn_group_membership *mship, ddsi_tran_conn_t conn, const nn_locator_t *srcip, const nn_locator_t *mcip);
void ddsi_transfer_group_membership (struct nn_group_membership *mship, ddsi_tran_conn_t conn, ddsi_tran_conn_t newconn);
int ddsi_rejoin_transferred_mcgroups (const struct q_globals *gv, struct nn_group_membership *mship, ddsi_tran_conn_t conn);
#if defined (__cplusplus)
}

View file

@ -16,7 +16,7 @@
extern "C" {
#endif
int ddsi_raweth_init (void);
int ddsi_raweth_init (struct q_globals *gv);
#if defined (__cplusplus)
}

View file

@ -67,7 +67,7 @@ typedef struct dds_keyhash {
uint32_t size; \
DDSI_SERDATA_DEFAULT_DEBUG_FIELDS \
dds_keyhash_t keyhash; \
struct serdatapool *pool; \
struct serdatapool *serpool; \
struct ddsi_serdata_default *next /* in pool->freelist */
#define DDSI_SERDATA_DEFAULT_POSTPAD \
struct CDRHeader hdr; \

View file

@ -24,7 +24,7 @@ extern "C" {
struct ddsi_ssl_plugins
{
bool (*init) (void);
bool (*init) (struct q_globals *gv);
void (*fini) (void);
void (*ssl_free) (SSL *ssl);
void (*bio_vfree) (BIO *bio);
@ -39,13 +39,13 @@ struct ddsi_ssl_plugins
}
#endif
#endif
#endif /* DDSI_INCLUDE_SSL */
#if defined (__cplusplus)
extern "C" {
#endif
int ddsi_tcp_init (void);
int ddsi_tcp_init (struct q_globals *gv);
#if defined (__cplusplus)
}

View file

@ -17,9 +17,10 @@ extern "C" {
#endif
struct ddsi_threadmon;
struct config_thread_properties_listelem;
struct ddsi_threadmon *ddsi_threadmon_new (void);
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl);
struct ddsi_threadmon *ddsi_threadmon_new (int64_t liveliness_monitoring_interval, bool noprogress_log_stacktraces);
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl, const char *name, const struct config_thread_properties_listelem *tprops);
void ddsi_threadmon_stop (struct ddsi_threadmon *sl);
void ddsi_threadmon_free (struct ddsi_threadmon *sl);

View file

@ -22,22 +22,23 @@ extern "C" {
struct ddsi_tkmap;
struct ddsi_serdata;
struct dds_topic;
struct q_globals;
struct ddsi_tkmap_instance
{
struct ddsi_serdata * m_sample;
struct ddsi_serdata *m_sample;
uint64_t m_iid;
ddsrt_atomic_uint32_t m_refc;
};
DDS_EXPORT struct ddsi_tkmap * ddsi_tkmap_new (void);
DDS_EXPORT struct ddsi_tkmap *ddsi_tkmap_new (struct q_globals *gv);
DDS_EXPORT void ddsi_tkmap_free (struct ddsi_tkmap *tkmap);
DDS_EXPORT void ddsi_tkmap_instance_ref (struct ddsi_tkmap_instance *tk);
DDS_EXPORT uint64_t ddsi_tkmap_lookup (struct ddsi_tkmap *tkmap, const struct ddsi_serdata *serdata);
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_find(struct ddsi_serdata *sd, const bool rd, const bool create);
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_find(struct ddsi_tkmap *map, struct ddsi_serdata *sd, const bool rd, const bool create);
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_find_by_id (struct ddsi_tkmap *map, uint64_t iid);
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (struct ddsi_serdata * sd);
DDS_EXPORT void ddsi_tkmap_instance_unref (struct ddsi_tkmap_instance *tk);
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (struct ddsi_tkmap *map, struct ddsi_serdata * sd);
DDS_EXPORT void ddsi_tkmap_instance_unref (struct ddsi_tkmap *map, struct ddsi_tkmap_instance *tk);
#if defined (__cplusplus)
}

View file

@ -17,6 +17,7 @@
#include "dds/ddsrt/ifaddrs.h"
#include "dds/ddsrt/atomics.h"
#include "dds/ddsi/q_protocol.h"
#include "dds/ddsi/q_config.h"
#if defined (__cplusplus)
extern "C" {
@ -51,16 +52,16 @@ typedef struct ddsi_tran_qos * ddsi_tran_qos_t;
typedef ssize_t (*ddsi_tran_read_fn_t) (ddsi_tran_conn_t, unsigned char *, size_t, bool, nn_locator_t *);
typedef ssize_t (*ddsi_tran_write_fn_t) (ddsi_tran_conn_t, const nn_locator_t *, size_t, const ddsrt_iovec_t *, uint32_t);
typedef int (*ddsi_tran_locator_fn_t) (ddsi_tran_base_t, nn_locator_t *);
typedef bool (*ddsi_tran_supports_fn_t) (int32_t);
typedef int (*ddsi_tran_locator_fn_t) (ddsi_tran_factory_t, ddsi_tran_base_t, nn_locator_t *);
typedef bool (*ddsi_tran_supports_fn_t) (const struct ddsi_tran_factory *, int32_t);
typedef ddsrt_socket_t (*ddsi_tran_handle_fn_t) (ddsi_tran_base_t);
typedef int (*ddsi_tran_listen_fn_t) (ddsi_tran_listener_t);
typedef void (*ddsi_tran_free_fn_t) (void);
typedef void (*ddsi_tran_free_fn_t) (ddsi_tran_factory_t);
typedef void (*ddsi_tran_peer_locator_fn_t) (ddsi_tran_conn_t, nn_locator_t *);
typedef void (*ddsi_tran_disable_multiplexing_fn_t) (ddsi_tran_conn_t);
typedef ddsi_tran_conn_t (*ddsi_tran_accept_fn_t) (ddsi_tran_listener_t);
typedef ddsi_tran_conn_t (*ddsi_tran_create_conn_fn_t) (uint32_t, ddsi_tran_qos_t);
typedef ddsi_tran_listener_t (*ddsi_tran_create_listener_fn_t) (int port, ddsi_tran_qos_t);
typedef ddsi_tran_conn_t (*ddsi_tran_create_conn_fn_t) (ddsi_tran_factory_t fact, uint32_t, ddsi_tran_qos_t);
typedef ddsi_tran_listener_t (*ddsi_tran_create_listener_fn_t) (ddsi_tran_factory_t fact, int port, ddsi_tran_qos_t);
typedef void (*ddsi_tran_release_conn_fn_t) (ddsi_tran_conn_t);
typedef void (*ddsi_tran_close_conn_fn_t) (ddsi_tran_conn_t);
typedef void (*ddsi_tran_unblock_listener_fn_t) (ddsi_tran_listener_t);
@ -76,7 +77,7 @@ enum ddsi_nearby_address_result {
DNAR_SAME
};
typedef enum ddsi_nearby_address_result (*ddsi_is_nearby_address_fn_t) (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface *interf);
typedef enum ddsi_nearby_address_result (*ddsi_is_nearby_address_fn_t) (ddsi_tran_factory_t tran, const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface *interf);
enum ddsi_locator_from_string_result {
AFSR_OK, /* conversion succeeded */
@ -89,10 +90,10 @@ typedef enum ddsi_locator_from_string_result (*ddsi_locator_from_string_fn_t) (d
typedef char * (*ddsi_locator_to_string_fn_t) (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port);
typedef int (*ddsi_enumerate_interfaces_fn_t) (ddsi_tran_factory_t tran, ddsrt_ifaddrs_t **interfs);
typedef int (*ddsi_enumerate_interfaces_fn_t) (ddsi_tran_factory_t tran, enum transport_selector transport_selector, ddsrt_ifaddrs_t **interfs);
/* Data types */
struct q_globals;
struct ddsi_tran_base
{
/* Data */
@ -100,10 +101,10 @@ struct ddsi_tran_base
uint32_t m_port;
uint32_t m_trantype;
bool m_multicast;
struct q_globals *gv;
/* Functions */
ddsi_tran_locator_fn_t m_locator_fn;
ddsi_tran_handle_fn_t m_handle_fn;
};
@ -117,6 +118,7 @@ struct ddsi_tran_conn
ddsi_tran_write_fn_t m_write_fn;
ddsi_tran_peer_locator_fn_t m_peer_locator_fn;
ddsi_tran_disable_multiplexing_fn_t m_disable_multiplexing_fn;
ddsi_tran_locator_fn_t m_locator_fn;
/* Data */
@ -141,6 +143,7 @@ struct ddsi_tran_listener
ddsi_tran_listen_fn_t m_listen_fn;
ddsi_tran_accept_fn_t m_accept_fn;
ddsi_tran_locator_fn_t m_locator_fn;
/* Relationships */
@ -173,10 +176,11 @@ struct ddsi_tran_factory
/* Data */
int32_t m_kind;
const char * m_typename;
const char * m_default_spdp_address;
const char *m_typename;
const char *m_default_spdp_address;
bool m_connless;
bool m_stream;
struct q_globals *gv;
/* Relationships */
@ -191,21 +195,21 @@ struct ddsi_tran_qos
int m_diffserv;
};
void ddsi_tran_factories_fini (void);
void ddsi_factory_add (ddsi_tran_factory_t factory);
void ddsi_tran_factories_fini (struct q_globals *gv);
void ddsi_factory_add (struct q_globals *gv, ddsi_tran_factory_t factory);
void ddsi_factory_free (ddsi_tran_factory_t factory);
ddsi_tran_factory_t ddsi_factory_find (const char * type);
ddsi_tran_factory_t ddsi_factory_find_supported_kind (int32_t kind);
void ddsi_factory_conn_init (ddsi_tran_factory_t factory, ddsi_tran_conn_t conn);
ddsi_tran_factory_t ddsi_factory_find (const struct q_globals *gv, const char * type);
ddsi_tran_factory_t ddsi_factory_find_supported_kind (const struct q_globals *gv, int32_t kind);
void ddsi_factory_conn_init (const struct ddsi_tran_factory *factory, ddsi_tran_conn_t conn);
inline bool ddsi_factory_supports (ddsi_tran_factory_t factory, int32_t kind) {
return factory->m_supports_fn (kind);
inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int32_t kind) {
return factory->m_supports_fn (factory, kind);
}
inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos) {
return factory->m_create_conn_fn (port, qos);
return factory->m_create_conn_fn (factory, port, qos);
}
inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, int port, ddsi_tran_qos_t qos) {
return factory->m_create_listener_fn (port, qos);
return factory->m_create_listener_fn (factory, port, qos);
}
void ddsi_tran_free (ddsi_tran_base_t base);
@ -214,10 +218,6 @@ ddsi_tran_qos_t ddsi_tran_create_qos (void);
inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base) {
return base->m_handle_fn (base);
}
inline int ddsi_tran_locator (ddsi_tran_base_t base, nn_locator_t * loc) {
return base->m_locator_fn (base, loc);
}
inline ddsrt_socket_t ddsi_conn_handle (ddsi_tran_conn_t conn) {
return conn->m_base.m_handle_fn (&conn->m_base);
}
@ -228,7 +228,7 @@ inline uint32_t ddsi_conn_port (ddsi_tran_conn_t conn) {
return conn->m_base.m_port;
}
inline int ddsi_conn_locator (ddsi_tran_conn_t conn, nn_locator_t * loc) {
return conn->m_base.m_locator_fn (&conn->m_base, loc);
return conn->m_locator_fn (conn->m_factory, &conn->m_base, loc);
}
inline ssize_t ddsi_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags) {
return conn->m_closed ? -1 : (conn->m_write_fn) (conn, dst, niov, iov, flags);
@ -244,11 +244,11 @@ int ddsi_conn_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcip, const n
int ddsi_conn_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcip, const nn_locator_t *mcip, const struct nn_interface *interf);
void ddsi_conn_transfer_group_membership (ddsi_tran_conn_t conn, ddsi_tran_conn_t newconn);
int ddsi_conn_rejoin_transferred_mcgroups (ddsi_tran_conn_t conn);
int ddsi_is_mcaddr (const nn_locator_t *loc);
int ddsi_is_ssm_mcaddr (const nn_locator_t *loc);
enum ddsi_nearby_address_result ddsi_is_nearby_address (const nn_locator_t *loc, size_t ninterf, const struct nn_interface *interf);
int ddsi_is_mcaddr (const struct q_globals *gv, const nn_locator_t *loc);
int ddsi_is_ssm_mcaddr (const struct q_globals *gv, const nn_locator_t *loc);
enum ddsi_nearby_address_result ddsi_is_nearby_address (const struct q_globals *gv, const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface *interf);
enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc, const char *str);
enum ddsi_locator_from_string_result ddsi_locator_from_string (const struct q_globals *gv, nn_locator_t *loc, const char *str, ddsi_tran_factory_t default_factory);
/* 8 for transport/
1 for [
@ -261,13 +261,13 @@ enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc
*/
#define DDSI_LOCSTRLEN 70
char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc);
char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_locator_t *loc);
char *ddsi_locator_to_string (const struct q_globals *gv, char *dst, size_t sizeof_dst, const nn_locator_t *loc);
char *ddsi_locator_to_string_no_port (const struct q_globals *gv, char *dst, size_t sizeof_dst, const nn_locator_t *loc);
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, ddsrt_ifaddrs_t **interfs);
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, enum transport_selector transport_selector, ddsrt_ifaddrs_t **interfs);
inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc) {
return listener->m_base.m_locator_fn (&listener->m_base, loc);
inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t *loc) {
return listener->m_locator_fn (listener->m_factory, &listener->m_base, loc);
}
inline int ddsi_listener_listen (ddsi_tran_listener_t listener) {
return listener->m_listen_fn (listener);

View file

@ -16,16 +16,15 @@
extern "C" {
#endif
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;
uint8_t base;
uint8_t count;
uint8_t idx; /* must be last: then sorting will put them consecutively */
} nn_udpv4mcgen_address_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;
uint8_t base;
uint8_t count;
uint8_t idx; /* must be last: then sorting will put them consecutively */
} nn_udpv4mcgen_address_t;
int ddsi_udp_init (void);
int ddsi_udp_init (struct q_globals *gv);
#if defined (__cplusplus)
}

View file

@ -39,16 +39,16 @@ typedef ssize_t (*addrset_forone_fun_t) (const nn_locator_t *loc, void *arg);
struct addrset *new_addrset (void);
struct addrset *ref_addrset (struct addrset *as);
void unref_addrset (struct addrset *as);
void add_to_addrset (struct addrset *as, const nn_locator_t *loc);
void remove_from_addrset (struct addrset *as, const nn_locator_t *loc);
void add_to_addrset (const struct q_globals *gv, struct addrset *as, const nn_locator_t *loc);
void remove_from_addrset (const struct q_globals *gv, struct addrset *as, const nn_locator_t *loc);
int addrset_purge (struct addrset *as);
int compare_locators (const nn_locator_t *a, const nn_locator_t *b);
/* These lock ASADD, then lock/unlock AS any number of times, then
unlock ASADD */
void copy_addrset_into_addrset_uc (struct addrset *as, const struct addrset *asadd);
void copy_addrset_into_addrset_mc (struct addrset *as, const struct addrset *asadd);
void copy_addrset_into_addrset (struct addrset *as, const struct addrset *asadd);
void copy_addrset_into_addrset_uc (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd);
void copy_addrset_into_addrset_mc (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd);
void copy_addrset_into_addrset (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd);
size_t addrset_count (const struct addrset *as);
size_t addrset_count_uc (const struct addrset *as);
@ -63,7 +63,7 @@ int addrset_any_mc (const struct addrset *as, nn_locator_t *dst);
int addrset_forone (struct addrset *as, addrset_forone_fun_t f, void *arg);
void addrset_forall (struct addrset *as, addrset_forall_fun_t f, void *arg);
size_t addrset_forall_count (struct addrset *as, addrset_forall_fun_t f, void *arg);
void nn_log_addrset (uint32_t tf, const char *prefix, const struct addrset *as);
void nn_log_addrset (struct q_globals *gv, uint32_t tf, const char *prefix, const struct addrset *as);
/* Tries to lock A then B for a decent check, returning false if
trylock B fails */
@ -72,15 +72,15 @@ int addrset_eq_onesidederr (const struct addrset *a, const struct addrset *b);
int is_unspec_locator (const nn_locator_t *loc);
void set_unspec_locator (nn_locator_t *loc);
int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc);
struct q_globals;
int add_addresses_to_addrset (const struct q_globals *gv, struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc);
#ifdef DDSI_INCLUDE_SSM
int addrset_contains_ssm (const struct addrset *as);
int addrset_any_ssm (const struct addrset *as, nn_locator_t *dst);
int addrset_any_non_ssm_mc (const struct addrset *as, nn_locator_t *dst);
void copy_addrset_into_addrset_no_ssm_mc (struct addrset *as, const struct addrset *asadd);
void copy_addrset_into_addrset_no_ssm (struct addrset *as, const struct addrset *asadd);
void addrset_pruge_ssm (struct addrset *as);
int addrset_contains_ssm (const struct q_globals *gv, const struct addrset *as);
int addrset_any_ssm (const struct q_globals *gv, const struct addrset *as, nn_locator_t *dst);
int addrset_any_non_ssm_mc (const struct q_globals *gv, const struct addrset *as, nn_locator_t *dst);
void copy_addrset_into_addrset_no_ssm_mc (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd);
void copy_addrset_into_addrset_no_ssm (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd);
#endif
#if defined (__cplusplus)

View file

@ -18,7 +18,6 @@
#include "dds/ddsi/q_security.h"
#endif /* DDSI_INCLUDE_ENCRYPTION */
#include "dds/ddsi/q_xqos.h"
#include "dds/ddsi/ddsi_tran.h"
#include "dds/ddsi/q_feature_check.h"
#if defined (__cplusplus)
@ -37,8 +36,8 @@ enum nn_standards_conformance {
NN_SC_LAX
};
#define NN_PEDANTIC_P (config.standards_conformance <= NN_SC_PEDANTIC)
#define NN_STRICT_P (config.standards_conformance <= NN_SC_STRICT)
#define NN_PEDANTIC_P(config) ((config).standards_conformance <= NN_SC_PEDANTIC)
#define NN_STRICT_P(config) ((config).standards_conformance <= NN_SC_STRICT)
enum besmode {
BESMODE_FULL,
@ -392,8 +391,6 @@ struct config
struct prune_deleted_ppant prune_deleted_ppant;
};
extern struct config DDS_EXPORT config;
struct cfgst;
struct cfgst *config_init (const char *configfile, struct config *cfg);

View file

@ -35,8 +35,6 @@ int sedp_dispose_unregister_reader (struct reader *rd);
int sedp_write_topic (struct participant *pp, const struct nn_plist *datap);
int sedp_write_cm_participant (struct participant *pp, int alive);
int sedp_write_cm_publisher (const struct nn_plist *datap, int alive);
int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive);
int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, void *qarg);

View file

@ -20,7 +20,7 @@ struct debug_monitor;
typedef int (*debug_monitor_cpf_t) (ddsi_tran_conn_t conn, const char *fmt, ...);
typedef int (*debug_monitor_plugin_t) (ddsi_tran_conn_t conn, debug_monitor_cpf_t cpf, void *arg);
struct debug_monitor *new_debug_monitor (int port);
struct debug_monitor *new_debug_monitor (struct q_globals *gv, int port);
void add_debug_monitor_plugin (struct debug_monitor *dm, debug_monitor_plugin_t fn, void *arg);
void free_debug_monitor (struct debug_monitor *dm);

View file

@ -141,6 +141,7 @@ struct entity_common {
struct ddsi_tkmap_instance *tk;
ddsrt_mutex_t lock;
bool onlylocal;
struct q_globals *gv;
};
struct local_reader_ary {
@ -387,7 +388,7 @@ extern const ddsrt_avl_treedef_t deleted_participants_treedef;
#define DPG_LOCAL 1
#define DPG_REMOTE 2
struct deleted_participants_admin;
struct deleted_participants_admin *deleted_participants_admin_new (void);
struct deleted_participants_admin *deleted_participants_admin_new (int64_t delay);
void deleted_participants_admin_free (struct deleted_participants_admin *admin);
int is_deleted_participant_guid (struct deleted_participants_admin *admin, const struct nn_guid *guid, unsigned for_what);
@ -477,7 +478,7 @@ nn_vendorid_t get_entity_vendorid (const struct entity_common *e);
* @retval DDS_RETCODE_OUT_OF_RESOURCES
* The configured maximum number of participants has been reached.
*/
dds_return_t new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const struct nn_plist *plist);
dds_return_t new_participant_guid (const nn_guid_t *ppguid, struct q_globals *gv, unsigned flags, const struct nn_plist *plist);
/**
* @brief Create a new participant in the domain. See also new_participant_guid.
@ -501,7 +502,7 @@ dds_return_t new_participant_guid (const nn_guid_t *ppguid, unsigned flags, cons
* @retval DDS_RETCODE_OUT_OF_RESOURCES
* The configured maximum number of participants has been reached.
*/
dds_return_t new_participant (struct nn_guid *ppguid, unsigned flags, const struct nn_plist *plist);
dds_return_t new_participant (struct nn_guid *ppguid, struct q_globals *gv, unsigned flags, const struct nn_plist *plist);
/**
* @brief Initiate the deletion of the participant:
@ -527,9 +528,9 @@ dds_return_t new_participant (struct nn_guid *ppguid, unsigned flags, const stru
* @retval DDS_RETCODE_BAD_PARAMETER
* ppguid lookup failed.
*/
dds_return_t delete_participant (const struct nn_guid *ppguid);
dds_return_t delete_participant (struct q_globals *gv, const struct nn_guid *ppguid);
void update_participant_plist (struct participant *pp, const struct nn_plist *plist);
uint64_t get_entity_instance_id (const struct nn_guid *guid);
uint64_t get_entity_instance_id (const struct q_globals *gv, const struct nn_guid *guid);
/* To obtain the builtin writer to be used for publishing SPDP, SEDP,
PMD stuff for PP and its endpoints, given the entityid. If PP has
@ -540,9 +541,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. */
dds_return_t new_writer (struct writer **wr_out, struct nn_guid *wrguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg);
dds_return_t new_writer (struct writer **wr_out, struct q_globals *gv, struct nn_guid *wrguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg);
dds_return_t new_reader (struct reader **rd_out, struct nn_guid *rdguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct rhc * rhc, status_cb_t status_cb, void *status_cb_arg);
dds_return_t new_reader (struct reader **rd_out, struct q_globals *gv, struct nn_guid *rdguid, const struct nn_guid *group_guid, const struct nn_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct rhc * rhc, status_cb_t status_cb, void *status_cb_arg);
void update_reader_qos (struct reader *rd, const struct dds_qos *xqos);
void update_writer_qos (struct writer *wr, const struct dds_qos *xqos);
@ -555,16 +556,16 @@ int writer_must_have_hb_scheduled (const struct writer *wr, const struct whc_sta
void writer_set_retransmitting (struct writer *wr);
void writer_clear_retransmitting (struct writer *wr);
dds_return_t delete_writer (const struct nn_guid *guid);
dds_return_t delete_writer_nolinger (const struct nn_guid *guid);
dds_return_t delete_writer (struct q_globals *gv, const struct nn_guid *guid);
dds_return_t delete_writer_nolinger (struct q_globals *gv, const struct nn_guid *guid);
dds_return_t delete_writer_nolinger_locked (struct writer *wr);
dds_return_t delete_reader (const struct nn_guid *guid);
dds_return_t delete_reader (struct q_globals *gv, const struct nn_guid *guid);
struct local_orphan_writer {
struct writer wr;
};
struct local_orphan_writer *new_local_orphan_writer (nn_entityid_t entityid, struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc *whc);
struct local_orphan_writer *new_local_orphan_writer (struct q_globals *gv, nn_entityid_t entityid, struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc *whc);
void delete_local_orphan_writer (struct local_orphan_writer *wr);
/* To create or delete a new proxy participant: "guid" MUST have the
@ -591,8 +592,8 @@ void delete_local_orphan_writer (struct local_orphan_writer *wr);
/* Set when this proxy participant is not to be announced on the built-in topics yet */
#define CF_PROXYPP_NO_SPDP (1 << 3)
void new_proxy_participant (const struct nn_guid *guid, unsigned bes, unsigned prismtech_bes, const struct nn_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct nn_plist *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, nn_wctime_t timestamp, seqno_t seq);
int delete_proxy_participant_by_guid (const struct nn_guid * guid, nn_wctime_t timestamp, int isimplicit);
void new_proxy_participant (struct q_globals *gv, const struct nn_guid *guid, unsigned bes, unsigned prismtech_bes, const struct nn_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct nn_plist *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, nn_wctime_t timestamp, seqno_t seq);
int delete_proxy_participant_by_guid (struct q_globals *gv, const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit);
enum update_proxy_participant_source {
UPD_PROXYPP_SPDP,
@ -603,12 +604,12 @@ int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, se
int update_proxy_participant_plist (struct proxy_participant *proxypp, seqno_t seq, const struct nn_plist *datap, enum update_proxy_participant_source source, nn_wctime_t timestamp);
void proxy_participant_reassign_lease (struct proxy_participant *proxypp, struct lease *newlease);
void purge_proxy_participants (const nn_locator_t *loc, bool delete_from_as_disc);
void purge_proxy_participants (struct q_globals *gv, const nn_locator_t *loc, bool delete_from_as_disc);
/* To create a new proxy writer or reader; the proxy participant is
determined from the GUID and must exist. */
int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist, struct nn_dqueue *dqueue, struct xeventq *evq, nn_wctime_t timestamp);
int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist, nn_wctime_t timestamp
int new_proxy_writer (struct q_globals *gv, const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist, struct nn_dqueue *dqueue, struct xeventq *evq, nn_wctime_t timestamp);
int new_proxy_reader (struct q_globals *gv, const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist, nn_wctime_t timestamp
#ifdef DDSI_INCLUDE_SSM
, int favours_ssm
#endif
@ -619,18 +620,18 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid,
reader or writer. Actual deletion is scheduled in the future, when
no outstanding references may still exist (determined by checking
thread progress, &c.). */
int delete_proxy_writer (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit);
int delete_proxy_reader (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit);
int delete_proxy_writer (struct q_globals *gv, const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit);
int delete_proxy_reader (struct q_globals *gv, const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit);
void update_proxy_reader (struct proxy_reader *prd, struct addrset *as, const struct dds_qos *xqos, nn_wctime_t timestamp);
void update_proxy_writer (struct proxy_writer *pwr, struct addrset *as, const struct dds_qos *xqos, nn_wctime_t timestamp);
int new_proxy_group (const struct nn_guid *guid, const char *name, const struct dds_qos *xqos, nn_wctime_t timestamp);
void delete_proxy_group (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit);
void delete_proxy_group (struct ephash *guid_hash, const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit);
/* Call this to empty all address sets of all writers to stop all outgoing traffic, or to
rebuild them all (which only makes sense after previously having emptied them all). */
void rebuild_or_clear_writer_addrsets(int rebuild);
void rebuild_or_clear_writer_addrsets(struct q_globals *gv, int rebuild);
void local_reader_ary_setfastpath_ok (struct local_reader_ary *x, bool fastpath_ok);

View file

@ -62,32 +62,33 @@ struct ephash_enum
at the protocol level slightly before the network reader can use it
to transmit data. */
struct ephash *ephash_new (void);
struct q_globals;
struct ephash *ephash_new (struct q_globals *gv);
void ephash_free (struct ephash *ephash);
void ephash_insert_participant_guid (struct participant *pp);
void ephash_insert_proxy_participant_guid (struct proxy_participant *proxypp);
void ephash_insert_writer_guid (struct writer *wr);
void ephash_insert_reader_guid (struct reader *rd);
void ephash_insert_proxy_writer_guid (struct proxy_writer *pwr);
void ephash_insert_proxy_reader_guid (struct proxy_reader *prd);
void ephash_insert_participant_guid (struct ephash *eh, struct participant *pp);
void ephash_insert_proxy_participant_guid (struct ephash *eh, struct proxy_participant *proxypp);
void ephash_insert_writer_guid (struct ephash *eh, struct writer *wr);
void ephash_insert_reader_guid (struct ephash *eh, struct reader *rd);
void ephash_insert_proxy_writer_guid (struct ephash *eh, struct proxy_writer *pwr);
void ephash_insert_proxy_reader_guid (struct ephash *eh, struct proxy_reader *prd);
void ephash_remove_participant_guid (struct participant *pp);
void ephash_remove_proxy_participant_guid (struct proxy_participant *proxypp);
void ephash_remove_writer_guid (struct writer *wr);
void ephash_remove_reader_guid (struct reader *rd);
void ephash_remove_proxy_writer_guid (struct proxy_writer *pwr);
void ephash_remove_proxy_reader_guid (struct proxy_reader *prd);
void ephash_remove_participant_guid (struct ephash *eh, struct participant *pp);
void ephash_remove_proxy_participant_guid (struct ephash *eh, struct proxy_participant *proxypp);
void ephash_remove_writer_guid (struct ephash *eh, struct writer *wr);
void ephash_remove_reader_guid (struct ephash *eh, struct reader *rd);
void ephash_remove_proxy_writer_guid (struct ephash *eh, struct proxy_writer *pwr);
void ephash_remove_proxy_reader_guid (struct ephash *eh, struct proxy_reader *prd);
void *ephash_lookup_guid_untyped (const struct nn_guid *guid);
void *ephash_lookup_guid (const struct nn_guid *guid, enum entity_kind kind);
void *ephash_lookup_guid_untyped (const struct ephash *eh, const struct nn_guid *guid);
void *ephash_lookup_guid (const struct ephash *eh, const struct nn_guid *guid, enum entity_kind kind);
struct participant *ephash_lookup_participant_guid (const struct nn_guid *guid);
struct proxy_participant *ephash_lookup_proxy_participant_guid (const struct nn_guid *guid);
struct writer *ephash_lookup_writer_guid (const struct nn_guid *guid);
struct reader *ephash_lookup_reader_guid (const struct nn_guid *guid);
struct proxy_writer *ephash_lookup_proxy_writer_guid (const struct nn_guid *guid);
struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct nn_guid *guid);
struct participant *ephash_lookup_participant_guid (const struct ephash *eh, const struct nn_guid *guid);
struct proxy_participant *ephash_lookup_proxy_participant_guid (const struct ephash *eh, const struct nn_guid *guid);
struct writer *ephash_lookup_writer_guid (const struct ephash *eh, const struct nn_guid *guid);
struct reader *ephash_lookup_reader_guid (const struct ephash *eh, const struct nn_guid *guid);
struct proxy_writer *ephash_lookup_proxy_writer_guid (const struct ephash *eh, const struct nn_guid *guid);
struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct ephash *eh, const struct nn_guid *guid);
/* Enumeration of entries in the hash table:
@ -110,16 +111,16 @@ struct ephash_enum_proxy_participant { struct ephash_enum st; };
struct ephash_enum_proxy_writer { struct ephash_enum st; };
struct ephash_enum_proxy_reader { struct ephash_enum st; };
void ephash_enum_init (struct ephash_enum *st, enum entity_kind kind);
void ephash_enum_init (struct ephash_enum *st, const struct ephash *eh, enum entity_kind kind);
void *ephash_enum_next (struct ephash_enum *st);
void ephash_enum_fini (struct ephash_enum *st);
void ephash_enum_writer_init (struct ephash_enum_writer *st);
void ephash_enum_reader_init (struct ephash_enum_reader *st);
void ephash_enum_proxy_writer_init (struct ephash_enum_proxy_writer *st);
void ephash_enum_proxy_reader_init (struct ephash_enum_proxy_reader *st);
void ephash_enum_participant_init (struct ephash_enum_participant *st);
void ephash_enum_proxy_participant_init (struct ephash_enum_proxy_participant *st);
void ephash_enum_writer_init (struct ephash_enum_writer *st, const struct ephash *eh);
void ephash_enum_reader_init (struct ephash_enum_reader *st, const struct ephash *eh);
void ephash_enum_proxy_writer_init (struct ephash_enum_proxy_writer *st, const struct ephash *eh);
void ephash_enum_proxy_reader_init (struct ephash_enum_proxy_reader *st, const struct ephash *eh);
void ephash_enum_participant_init (struct ephash_enum_participant *st, const struct ephash *eh);
void ephash_enum_proxy_participant_init (struct ephash_enum_proxy_participant *st, const struct ephash *eh);
struct writer *ephash_enum_writer_next (struct ephash_enum_writer *st);
struct reader *ephash_enum_reader_next (struct ephash_enum_reader *st);

View file

@ -21,6 +21,7 @@ extern "C" {
struct gcreq;
struct gcreq_queue;
struct q_globals;
struct writer;
struct reader;
@ -43,7 +44,7 @@ struct gcreq {
struct idx_vtime vtimes[];
};
DDS_EXPORT struct gcreq_queue *gcreq_queue_new (void);
DDS_EXPORT struct gcreq_queue *gcreq_queue_new (struct q_globals *gv);
DDS_EXPORT void gcreq_queue_drain (struct gcreq_queue *q);
DDS_EXPORT void gcreq_queue_free (struct gcreq_queue *q);

View file

@ -24,6 +24,7 @@
#include "dds/ddsi/q_protocol.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsi/q_sockwaitset.h"
#include "dds/ddsi/q_config.h"
#ifdef DDSI_INCLUDE_ENCRYPTION
#include "dds/ddsi/q_security.h" /* for q_securityDecoderSet */
@ -71,6 +72,7 @@ enum recv_thread_mode {
struct recv_thread_arg {
enum recv_thread_mode mode;
struct nn_rbufpool *rbpool;
struct q_globals *gv;
union {
struct {
const nn_locator_t *loc;
@ -89,6 +91,8 @@ struct q_globals {
volatile int deaf;
volatile int mute;
struct config config;
struct ddsi_tkmap * m_tkmap;
/* Hash tables for participants, readers, writers, proxy
@ -106,9 +110,9 @@ struct q_globals {
ddsrt_mutex_t leaseheap_lock;
ddsrt_fibheap_t leaseheap;
/* Transport factory */
struct ddsi_tran_factory * m_factory;
/* Transport factories & selected factory */
struct ddsi_tran_factory *ddsi_tran_factories;
struct ddsi_tran_factory *m_factory;
/* Connections for multicast discovery & data, and those that correspond
to the one DDSI participant index that the DDSI2 service uses. The
@ -298,8 +302,6 @@ struct q_globals {
struct nn_group_membership *mship;
};
extern struct q_globals DDS_EXPORT gv;
#if defined (__cplusplus)
}
#endif

View file

@ -16,8 +16,8 @@
extern "C" {
#endif
int create_multicast_sockets(void);
int joinleave_spdp_defmcip (int dojoin);
int create_multicast_sockets (struct q_globals *gv);
int joinleave_spdp_defmcip (struct q_globals *gv, int dojoin);
#if defined (__cplusplus)
}

View file

@ -22,15 +22,16 @@ struct receiver_state;
struct participant;
struct lease;
struct entity_common;
struct q_globals; /* FIXME: make a special for the lease admin */
void lease_management_init (void);
void lease_management_term (void);
void lease_management_init (struct q_globals *gv);
void lease_management_term (struct q_globals *gv);
struct lease *lease_new (nn_etime_t texpire, int64_t tdur, struct entity_common *e);
void lease_register (struct lease *l);
void lease_free (struct lease *l);
void lease_renew (struct lease *l, nn_etime_t tnow);
void lease_set_expiry (struct lease *l, nn_etime_t when);
int64_t check_and_handle_lease_expiration (nn_etime_t tnow);
int64_t check_and_handle_lease_expiration (struct q_globals *gv, nn_etime_t tnow);
void handle_PMD (const struct receiver_state *rst, nn_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len);

View file

@ -22,6 +22,8 @@
extern "C" {
#endif
struct q_globals;
#define MAX_INTERFACES 128
struct nn_interface {
nn_locator_t loc;
@ -33,8 +35,8 @@ struct nn_interface {
char *name;
};
int make_socket (ddsrt_socket_t *socket, uint16_t port, bool stream, bool reuse);
int find_own_ip (const char *requested_address);
int make_socket (ddsrt_socket_t *socket, uint16_t port, bool stream, bool reuse, const struct q_globals *gv);
int find_own_ip (struct q_globals *gv, const char *requested_address);
uint32_t locator_to_hopefully_unique_uint32 (const nn_locator_t *src);
#if defined (__cplusplus)

View file

@ -23,24 +23,9 @@ struct msghdr;
FILE * new_pcap_file (const char *name);
void write_pcap_received
(
FILE * fp,
nn_wctime_t tstamp,
const struct sockaddr_storage * src,
const struct sockaddr_storage * dst,
unsigned char * buf,
size_t sz
);
void write_pcap_sent
(
FILE * fp,
nn_wctime_t tstamp,
const struct sockaddr_storage * src,
const ddsrt_msghdr_t * hdr,
size_t sz
);
void write_pcap_received (struct q_globals *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz);
void write_pcap_sent (struct q_globals *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src,
const ddsrt_msghdr_t *hdr, size_t sz);
#if defined (__cplusplus)
}

View file

@ -14,7 +14,7 @@
#include "dds/ddsi/q_feature_check.h"
#include "dds/ddsi/q_xqos.h"
#include "dds/ddsi/ddsi_tran.h" /* FIXME: eliminate */
#if defined (__cplusplus)
extern "C" {
@ -167,13 +167,14 @@ typedef struct nn_plist {
/***/
typedef struct nn_plist_src {
nn_protocol_version_t protocol_version;
nn_vendorid_t vendorid;
int encoding;
const unsigned char *buf;
size_t bufsz;
bool strict;
ddsi_tran_factory_t factory; /* eliminate this */
} nn_plist_src_t;
void nn_plist_init_tables (void);

View file

@ -107,6 +107,7 @@ struct receiver_state {
nn_protocol_version_t protocol_version; /* 2 => 44/48 */
ddsi_tran_conn_t conn; /* Connection for request */
nn_locator_t srcloc;
struct q_globals *gv;
};
struct nn_rsample_info {
@ -215,7 +216,7 @@ struct nn_rsample *nn_defrag_rsample (struct nn_defrag *defrag, struct nn_rdata
void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1);
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set_header *map, uint32_t *mapbits, uint32_t maxsz);
struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples);
struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples, bool late_ack_mode);
void nn_reorder_free (struct nn_reorder *r);
struct nn_rsample *nn_reorder_rsample_dup_first (struct nn_rmsg *rmsg, struct nn_rsample *rsampleiv);
struct nn_rdata *nn_rsample_fragchain (struct nn_rsample *rsample);
@ -225,7 +226,7 @@ int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t seq);
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail);
seqno_t nn_reorder_next_seq (const struct nn_reorder *reorder);
struct nn_dqueue *nn_dqueue_new (const char *name, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg);
struct nn_dqueue *nn_dqueue_new (const char *name, const struct q_globals *gv, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg);
void nn_dqueue_free (struct nn_dqueue *q);
bool nn_dqueue_enqueue_deferred_wakeup (struct nn_dqueue *q, struct nn_rsample_chain *sc, nn_reorder_result_t rres);
void dd_dqueue_enqueue_trigger (struct nn_dqueue *q);

View file

@ -22,7 +22,7 @@ struct nn_rdata;
struct ddsi_tran_listener;
struct recv_thread_arg;
void trigger_recv_threads (void);
void trigger_recv_threads (const struct q_globals *gv);
uint32_t recv_thread (void *vrecv_thread_arg);
uint32_t listen_thread (struct ddsi_tran_listener * listener);
int user_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, void *qarg);

View file

@ -74,12 +74,13 @@ typedef int64_t seqno_t;
#define NN_ENTITYID_ALLOCSTEP 0x100
struct cfgst;
int rtps_config_prep (struct cfgst *cfgst);
int rtps_config_open (void);
int rtps_init (void);
int rtps_start (void);
void rtps_stop (void);
void rtps_fini (void);
struct q_globals;
int rtps_config_prep (struct q_globals *config, struct cfgst *cfgst);
int rtps_config_open (struct q_globals *config);
int rtps_init (struct q_globals *config);
int rtps_start (struct q_globals *config);
void rtps_stop (struct q_globals *config);
void rtps_fini (struct q_globals *config);
#if defined (__cplusplus)
}

View file

@ -54,6 +54,8 @@ enum thread_state {
THREAD_STATE_ALIVE /* known to be alive - for Cyclone internal threads */
};
struct q_globals;
struct config;
struct logbuf;
/*
@ -62,9 +64,13 @@ struct logbuf;
* vtime is updated without using atomic operations: only the owning thread updates
* them, and the garbage collection mechanism and the liveliness monitoring only
* observe the value
*
* gv is constant for internal threads, i.e., for threads with state = ALIVE
* gv is non-NULL for internal threads except thread liveliness monitoring
*/
#define THREAD_BASE \
ddsrt_atomic_uint32_t vtime; \
ddsrt_atomic_voidp_t gv; \
enum thread_state state; \
ddsrt_thread_t tid; \
ddsrt_thread_t extTid; \
@ -98,8 +104,9 @@ DDS_EXPORT void thread_states_fini (void);
DDS_EXPORT void upgrade_main_thread (void);
DDS_EXPORT void downgrade_main_thread (void);
DDS_EXPORT const struct config_thread_properties_listelem *lookup_thread_properties (const char *name);
DDS_EXPORT dds_return_t create_thread (struct thread_state1 **ts, const char *name, uint32_t (*f) (void *arg), void *arg);
DDS_EXPORT const struct config_thread_properties_listelem *lookup_thread_properties (const struct config *config, const char *name);
DDS_EXPORT dds_return_t create_thread_with_properties (struct thread_state1 **ts1, struct config_thread_properties_listelem const * const tprops, const char *name, uint32_t (*f) (void *arg), void *arg);
DDS_EXPORT dds_return_t create_thread (struct thread_state1 **ts, const struct q_globals *gv, const char *name, uint32_t (*f) (void *arg), void *arg);
DDS_EXPORT struct thread_state1 *lookup_thread_state_real (void);
DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1);
DDS_EXPORT void log_stack_traces (void);
@ -157,15 +164,36 @@ DDS_EXPORT inline void thread_state_asleep (struct thread_state1 *ts1)
ddsrt_atomic_st32 (&ts1->vtime, vt);
}
DDS_EXPORT inline void thread_state_awake (struct thread_state1 *ts1)
DDS_EXPORT inline void thread_state_awake (struct thread_state1 *ts1, const struct q_globals *gv)
{
vtime_t vt = ddsrt_atomic_ld32 (&ts1->vtime);
assert ((vt & VTIME_NEST_MASK) < VTIME_NEST_MASK);
assert (gv != NULL);
assert (ts1->state != THREAD_STATE_ALIVE || gv == ddsrt_atomic_ldvoidp (&ts1->gv));
ddsrt_atomic_stvoidp (&ts1->gv, (struct q_globals *) gv);
ddsrt_atomic_fence_stst ();
ddsrt_atomic_st32 (&ts1->vtime, vt + 1u);
/* nested calls a rare and an extra fence doesn't break things */
ddsrt_atomic_fence_acq ();
}
DDS_EXPORT inline void thread_state_awake_domain_ok (struct thread_state1 *ts1)
{
vtime_t vt = ddsrt_atomic_ld32 (&ts1->vtime);
assert ((vt & VTIME_NEST_MASK) < VTIME_NEST_MASK);
assert (ddsrt_atomic_ldvoidp (&ts1->gv) != NULL);
ddsrt_atomic_st32 (&ts1->vtime, vt + 1u);
/* nested calls a rare and an extra fence doesn't break things */
ddsrt_atomic_fence_acq ();
}
DDS_EXPORT inline void thread_state_awake_fixed_domain (struct thread_state1 *ts1)
{
/* fixed domain -> must be an internal thread */
assert (ts1->state == THREAD_STATE_ALIVE);
thread_state_awake_domain_ok (ts1);
}
DDS_EXPORT inline void thread_state_awake_to_awake_no_nest (struct thread_state1 *ts1)
{
vtime_t vt = ddsrt_atomic_ld32 (&ts1->vtime);

View file

@ -59,12 +59,12 @@ DDS_EXPORT int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched);
DDS_EXPORT struct xevent *qxev_heartbeat (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *wr_guid);
DDS_EXPORT struct xevent *qxev_acknack (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *pwr_guid, const nn_guid_t *rd_guid);
DDS_EXPORT struct xevent *qxev_spdp (nn_mtime_t tsched, const nn_guid_t *pp_guid, const nn_guid_t *proxypp_guid);
DDS_EXPORT struct xevent *qxev_pmd_update (nn_mtime_t tsched, const nn_guid_t *pp_guid);
DDS_EXPORT struct xevent *qxev_delete_writer (nn_mtime_t tsched, const nn_guid_t *guid);
DDS_EXPORT struct xevent *qxev_spdp (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *pp_guid, const nn_guid_t *proxypp_guid);
DDS_EXPORT struct xevent *qxev_pmd_update (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *pp_guid);
DDS_EXPORT struct xevent *qxev_delete_writer (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *guid);
/* cb will be called with now = T_NEVER if the event is still enqueued when when xeventq_free starts cleaning up */
DDS_EXPORT struct xevent *qxev_callback (nn_mtime_t tsched, void (*cb) (struct xevent *xev, void *arg, nn_mtime_t now), void *arg);
DDS_EXPORT struct xevent *qxev_callback (struct xeventq *evq, nn_mtime_t tsched, void (*cb) (struct xevent *xev, void *arg, nn_mtime_t now), void *arg);
#if defined (__cplusplus)
}

View file

@ -92,7 +92,7 @@ void nn_xmsg_set_data_readerId (struct nn_xmsg *m, nn_entityid_t *readerId);
Returns 1 if merge was successful, else 0. On failure, neither
message will have been changed and both should be sent as if there
had been no merging. */
int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct nn_xmsg *m, const struct nn_xmsg *madd);
int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct nn_xmsg *m, const struct nn_xmsg *madd);
/* To set writer ids for updating last transmitted sequence number;
wrfragid is 0 based, unlike DDSI but like other places where
@ -135,10 +135,10 @@ int64_t nn_xpack_maxdelay (const struct nn_xpack *xp);
unsigned nn_xpack_packetid (const struct nn_xpack *xp);
/* SENDQ */
void nn_xpack_sendq_init (void);
void nn_xpack_sendq_start (void);
void nn_xpack_sendq_stop (void);
void nn_xpack_sendq_fini (void);
void nn_xpack_sendq_init (struct q_globals *gv);
void nn_xpack_sendq_start (struct q_globals *gv);
void nn_xpack_sendq_stop (struct q_globals *gv);
void nn_xpack_sendq_fini (struct q_globals *gv);
#if defined (__cplusplus)
}

View file

@ -10,21 +10,20 @@
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "ddsi_eth.h"
#include "dds/ddsi/q_config.h"
int ddsi_eth_enumerate_interfaces(ddsi_tran_factory_t fact, ddsrt_ifaddrs_t **ifs)
int ddsi_eth_enumerate_interfaces (ddsi_tran_factory_t fact, enum transport_selector transport_selector, ddsrt_ifaddrs_t **ifs)
{
int afs[] = { AF_INET, DDSRT_AF_TERM };
(void)fact;
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_TCP6 ||
config.transport_selector == TRANS_UDP6)
if (transport_selector == TRANS_TCP6 ||
transport_selector == TRANS_UDP6)
{
afs[0] = AF_INET6;
}
#endif /* DDSRT_HAVE_IPV6 */
return -ddsrt_getifaddrs(ifs, afs);
return ddsrt_getifaddrs(ifs, afs);
}

View file

@ -13,12 +13,13 @@
#define DDSI_ETH_H
#include "dds/ddsi/ddsi_tran.h"
#include "dds/ddsi/q_config.h"
#if defined (__cplusplus)
extern "C" {
#endif
int ddsi_eth_enumerate_interfaces(ddsi_tran_factory_t fact, ddsrt_ifaddrs_t **ifs);
int ddsi_eth_enumerate_interfaces(ddsi_tran_factory_t fact, enum transport_selector transport_selector, ddsrt_ifaddrs_t **ifs);
#if defined (__cplusplus)
}

View file

@ -54,7 +54,7 @@ int ddsi_ipaddr_compare (const struct sockaddr *const sa1, const struct sockaddr
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[])
enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface interf[])
{
struct sockaddr_storage tmp, iftmp, nmtmp, ownip;
size_t i;
@ -64,7 +64,7 @@ enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory
{
ddsi_ipaddr_from_loc(&iftmp, &interf[i].loc);
ddsi_ipaddr_from_loc(&nmtmp, &interf[i].netmask);
ddsi_ipaddr_from_loc(&ownip, &gv.ownloc);
ddsi_ipaddr_from_loc(&ownip, ownloc);
if (ddsrt_sockaddr_insamesubnet ((struct sockaddr *) &tmp, (struct sockaddr *) &iftmp, (struct sockaddr *) &nmtmp))
{
if (ddsi_ipaddr_compare((struct sockaddr *)&iftmp, (struct sockaddr *)&ownip) == 0)
@ -120,38 +120,43 @@ enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_
char *ddsi_ipaddr_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port)
{
struct sockaddr_storage src;
size_t pos;
(void)tran;
assert (sizeof_dst > 1);
ddsi_ipaddr_from_loc(&src, loc);
switch (src.ss_family)
if (loc->kind == NN_LOCATOR_KIND_INVALID)
snprintf (dst, sizeof_dst, "(invalid)");
else
{
case AF_INET:
ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst, sizeof_dst);
if (with_port) {
pos = strlen (dst);
assert(pos <= sizeof_dst);
snprintf (dst + pos, sizeof_dst - pos, ":%"PRIu32, loc->port);
}
break;
struct sockaddr_storage src;
size_t pos;
ddsi_ipaddr_from_loc(&src, loc);
switch (src.ss_family)
{
case AF_INET:
ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst, sizeof_dst);
if (with_port) {
pos = strlen (dst);
assert(pos <= sizeof_dst);
snprintf (dst + pos, sizeof_dst - pos, ":%"PRIu32, loc->port);
}
break;
#if DDSRT_HAVE_IPV6
case AF_INET6:
dst[0] = '[';
ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst + 1, sizeof_dst);
pos = strlen (dst);
if (with_port) {
assert(pos <= sizeof_dst);
snprintf (dst + pos, sizeof_dst - pos, "]:%"PRIu32, loc->port);
} else {
snprintf (dst + pos, sizeof_dst - pos, "]");
}
break;
case AF_INET6:
dst[0] = '[';
ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst + 1, sizeof_dst);
pos = strlen (dst);
if (with_port) {
assert(pos <= sizeof_dst);
snprintf (dst + pos, sizeof_dst - pos, "]:%"PRIu32, loc->port);
} else {
snprintf (dst + pos, sizeof_dst - pos, "]");
}
break;
#endif
default:
assert(0);
dst[0] = 0;
break;
default:
assert(0);
dst[0] = 0;
break;
}
}
return dst;
}
@ -209,11 +214,7 @@ void ddsi_ipaddr_from_loc (struct sockaddr_storage *dst, const nn_locator_t *src
switch (src->kind)
{
case NN_LOCATOR_KIND_INVALID:
#if DDSRT_HAVE_IPV6
dst->ss_family = (config.transport_selector == TRANS_UDP6 || config.transport_selector == TRANS_TCP6) ? AF_INET6 : AF_INET;
#else
dst->ss_family = AF_INET;
#endif
assert (0);
break;
case NN_LOCATOR_KIND_UDPv4:
case NN_LOCATOR_KIND_TCPv4:
@ -234,7 +235,7 @@ void ddsi_ipaddr_from_loc (struct sockaddr_storage *dst, const nn_locator_t *src
memcpy (&x->sin6_addr.s6_addr, src->address, 16);
if (IN6_IS_ADDR_LINKLOCAL (&x->sin6_addr))
{
x->sin6_scope_id = gv.interfaceNo;
x->sin6_scope_id = 0;//FIXME: gv.interfaceNo;
}
break;
}

View file

@ -136,14 +136,14 @@ static char *make_joinleave_msg (char *buf, size_t bufsz, ddsi_tran_conn_t conn,
int n;
#ifdef DDSI_INCLUDE_SSM
if (srcloc) {
ddsi_locator_to_string_no_port(srcstr, sizeof(srcstr), srcloc);
ddsi_locator_to_string_no_port(conn->m_base.gv, srcstr, sizeof(srcstr), srcloc);
}
#else
DDSRT_UNUSED_ARG (srcloc);
#endif
ddsi_locator_to_string_no_port (mcstr, sizeof(mcstr), mcloc);
ddsi_locator_to_string_no_port (conn->m_base.gv, mcstr, sizeof(mcstr), mcloc);
if (interf)
ddsi_locator_to_string_no_port(interfstr, sizeof(interfstr), &interf->loc);
ddsi_locator_to_string_no_port(conn->m_base.gv, interfstr, sizeof(interfstr), &interf->loc);
else
(void) snprintf (interfstr, sizeof (interfstr), "(default)");
n = err ? snprintf (buf, bufsz, "error %d in ", err) : 0;
@ -166,10 +166,10 @@ static int joinleave_mcgroup (ddsi_tran_conn_t conn, int join, const nn_locator_
return err ? -1 : 0;
}
static int interface_in_recvips_p (const struct nn_interface *interf)
static int interface_in_recvips_p (const struct config_in_addr_node *recvips, const struct nn_interface *interf)
{
struct config_in_addr_node *nodeaddr;
for (nodeaddr = gv.recvips; nodeaddr; nodeaddr = nodeaddr->next)
const struct config_in_addr_node *nodeaddr;
for (nodeaddr = recvips; nodeaddr; nodeaddr = nodeaddr->next)
{
if (locator_compare_no_port(&nodeaddr->loc, &interf->loc) == 0)
return 1;
@ -177,10 +177,10 @@ static int interface_in_recvips_p (const struct nn_interface *interf)
return 0;
}
static int joinleave_mcgroups (ddsi_tran_conn_t conn, int join, const nn_locator_t *srcloc, const nn_locator_t *mcloc)
static int joinleave_mcgroups (const struct q_globals *gv, ddsi_tran_conn_t conn, int join, const nn_locator_t *srcloc, const nn_locator_t *mcloc)
{
int rc;
switch (gv.recvips_mode)
switch (gv->recvips_mode)
{
case RECVIPS_MODE_NONE:
break;
@ -190,20 +190,20 @@ static int joinleave_mcgroups (ddsi_tran_conn_t conn, int join, const nn_locator
return rc;
break;
case RECVIPS_MODE_PREFERRED:
if (gv.interfaces[gv.selected_interface].mc_capable)
return joinleave_mcgroup (conn, join, srcloc, mcloc, &gv.interfaces[gv.selected_interface]);
if (gv->interfaces[gv->selected_interface].mc_capable)
return joinleave_mcgroup (conn, join, srcloc, mcloc, &gv->interfaces[gv->selected_interface]);
return 0;
case RECVIPS_MODE_ALL:
case RECVIPS_MODE_SOME:
{
int i, fails = 0, oks = 0;
for (i = 0; i < gv.n_interfaces; i++)
for (i = 0; i < gv->n_interfaces; i++)
{
if (gv.interfaces[i].mc_capable)
if (gv->interfaces[i].mc_capable)
{
if (gv.recvips_mode == RECVIPS_MODE_ALL || interface_in_recvips_p (&gv.interfaces[i]))
if (gv->recvips_mode == RECVIPS_MODE_ALL || interface_in_recvips_p (gv->recvips, &gv->interfaces[i]))
{
if ((rc = joinleave_mcgroup (conn, join, srcloc, mcloc, &gv.interfaces[i])) < 0)
if ((rc = joinleave_mcgroup (conn, join, srcloc, mcloc, &gv->interfaces[i])) < 0)
fails++;
else
oks++;
@ -223,11 +223,12 @@ static int joinleave_mcgroups (ddsi_tran_conn_t conn, int join, const nn_locator
return 0;
}
int ddsi_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc)
int ddsi_join_mc (const struct q_globals *gv, struct nn_group_membership *mship, ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc)
{
/* FIXME: gv to be reduced; perhaps mship, recvips, interfaces, ownloc should be combined into a single struct */
int ret;
ddsrt_mutex_lock (&gv.mship->lock);
if (!reg_group_membership (gv.mship, conn, srcloc, mcloc))
ddsrt_mutex_lock (&mship->lock);
if (!reg_group_membership (mship, conn, srcloc, mcloc))
{
char buf[256];
DDS_TRACE("%s: already joined\n", make_joinleave_msg (buf, sizeof(buf), conn, 1, srcloc, mcloc, NULL, 0));
@ -235,17 +236,17 @@ int ddsi_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_lo
}
else
{
ret = joinleave_mcgroups (conn, 1, srcloc, mcloc);
ret = joinleave_mcgroups (gv, conn, 1, srcloc, mcloc);
}
ddsrt_mutex_unlock (&gv.mship->lock);
ddsrt_mutex_unlock (&mship->lock);
return ret;
}
int ddsi_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc)
int ddsi_leave_mc (const struct q_globals *gv, struct nn_group_membership *mship, ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc)
{
int ret;
ddsrt_mutex_lock (&gv.mship->lock);
if (!unreg_group_membership (gv.mship, conn, srcloc, mcloc))
ddsrt_mutex_lock (&mship->lock);
if (!unreg_group_membership (mship, conn, srcloc, mcloc))
{
char buf[256];
DDS_TRACE("%s: not leaving yet\n", make_joinleave_msg (buf, sizeof(buf), conn, 0, srcloc, mcloc, NULL, 0));
@ -253,13 +254,13 @@ int ddsi_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_l
}
else
{
ret = joinleave_mcgroups (conn, 0, srcloc, mcloc);
ret = joinleave_mcgroups (gv, conn, 0, srcloc, mcloc);
}
ddsrt_mutex_unlock (&gv.mship->lock);
ddsrt_mutex_unlock (&mship->lock);
return ret;
}
void ddsi_transfer_group_membership (ddsi_tran_conn_t conn, ddsi_tran_conn_t newconn)
void ddsi_transfer_group_membership (struct nn_group_membership *mship, ddsi_tran_conn_t conn, ddsi_tran_conn_t newconn)
{
struct nn_group_membership_node *n, min, max;
memset(&min, 0, sizeof(min));
@ -268,34 +269,35 @@ void ddsi_transfer_group_membership (ddsi_tran_conn_t conn, ddsi_tran_conn_t new
/* ordering is on socket, then src IP, then mc IP; IP compare checks family first and AF_INET, AF_INET6
are neither 0 nor maximum representable, min and max define the range of key values that relate to
oldsock */
ddsrt_mutex_lock (&gv.mship->lock);
n = ddsrt_avl_lookup_succ_eq (&mship_td, &gv.mship->mships, &min);
ddsrt_mutex_lock (&mship->lock);
n = ddsrt_avl_lookup_succ_eq (&mship_td, &mship->mships, &min);
while (n != NULL && cmp_group_membership (n, &max) <= 0)
{
struct nn_group_membership_node * const nn = ddsrt_avl_find_succ (&mship_td, &gv.mship->mships, n);
ddsrt_avl_delete (&mship_td, &gv.mship->mships, n);
struct nn_group_membership_node * const nn = ddsrt_avl_find_succ (&mship_td, &mship->mships, n);
ddsrt_avl_delete (&mship_td, &mship->mships, n);
n->conn = newconn;
ddsrt_avl_insert (&mship_td, &gv.mship->mships, n);
ddsrt_avl_insert (&mship_td, &mship->mships, n);
n = nn;
}
ddsrt_mutex_unlock (&gv.mship->lock);
ddsrt_mutex_unlock (&mship->lock);
}
int ddsi_rejoin_transferred_mcgroups (ddsi_tran_conn_t conn)
int ddsi_rejoin_transferred_mcgroups (const struct q_globals *gv, struct nn_group_membership *mship, ddsi_tran_conn_t conn)
{
/* FIXME: see gv should be reduced; perhaps recvips, ownloc, mship, interfaces should be a single struct */
struct nn_group_membership_node *n, min, max;
ddsrt_avl_iter_t it;
int ret = 0;
memset(&min, 0, sizeof(min));
memset(&max, 0xff, sizeof(max));
min.conn = max.conn = conn;
ddsrt_mutex_lock (&gv.mship->lock);
for (n = ddsrt_avl_iter_succ_eq (&mship_td, &gv.mship->mships, &it, &min); n != NULL && ret >= 0 && cmp_group_membership(n, &max) <= 0; n = ddsrt_avl_iter_next (&it))
ddsrt_mutex_lock (&mship->lock);
for (n = ddsrt_avl_iter_succ_eq (&mship_td, &mship->mships, &it, &min); n != NULL && ret >= 0 && cmp_group_membership(n, &max) <= 0; n = ddsrt_avl_iter_next (&it))
{
int have_srcloc = (memcmp(&n->srcloc, &min.srcloc, sizeof(n->srcloc)) != 0);
assert (n->conn == conn);
ret = joinleave_mcgroups (conn, 1, have_srcloc ? &n->srcloc : NULL, &n->mcloc);
ret = joinleave_mcgroups (gv, conn, 1, have_srcloc ? &n->srcloc : NULL, &n->mcloc);
}
ddsrt_mutex_unlock (&gv.mship->lock);
ddsrt_mutex_unlock (&mship->lock);
return ret;
}

View file

@ -32,25 +32,11 @@
#include <stdlib.h>
#include <errno.h>
typedef struct ddsi_tran_factory * ddsi_raweth_factory_t;
typedef struct ddsi_raweth_config
{
struct nn_group_membership *mship;
}
* ddsi_raweth_config_t;
typedef struct ddsi_raweth_conn
{
typedef struct ddsi_raweth_conn {
struct ddsi_tran_conn m_base;
ddsrt_socket_t m_sock;
int m_ifindex;
}
* ddsi_raweth_conn_t;
static struct ddsi_raweth_config ddsi_raweth_config_g;
static struct ddsi_tran_factory ddsi_raweth_factory_g;
static ddsrt_atomic_uint32_t init_g = DDSRT_ATOMIC_UINT32_INIT(0);
} *ddsi_raweth_conn_t;
static char *ddsi_raweth_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port)
{
@ -168,26 +154,28 @@ static ddsrt_socket_t ddsi_raweth_conn_handle (ddsi_tran_base_t base)
return ((ddsi_raweth_conn_t) base)->m_sock;
}
static bool ddsi_raweth_supports (int32_t kind)
static bool ddsi_raweth_supports (const struct ddsi_tran_factory *fact, int32_t kind)
{
(void) fact;
return (kind == NN_LOCATOR_KIND_RAWETH);
}
static int ddsi_raweth_conn_locator (ddsi_tran_base_t base, nn_locator_t *loc)
static int ddsi_raweth_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t base, nn_locator_t *loc)
{
ddsi_raweth_conn_t uc = (ddsi_raweth_conn_t) base;
int ret = -1;
(void) fact;
if (uc->m_sock != DDSRT_INVALID_SOCKET)
{
loc->kind = NN_LOCATOR_KIND_RAWETH;
loc->port = uc->m_base.m_base.m_port;
memcpy(loc->address, gv.extloc.address, sizeof (loc->address));
memcpy(loc->address, uc->m_base.m_base.gv->extloc.address, sizeof (loc->address));
ret = 0;
}
return ret;
}
static ddsi_tran_conn_t ddsi_raweth_create_conn (uint32_t port, ddsi_tran_qos_t qos)
static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint32_t port, ddsi_tran_qos_t qos)
{
ddsrt_socket_t sock;
dds_return_t rc;
@ -213,7 +201,7 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (uint32_t port, ddsi_tran_qos_t
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons((uint16_t)port);
addr.sll_ifindex = (int)gv.interfaceNo;
addr.sll_ifindex = (int)fact->gv->interfaceNo;
addr.sll_pkttype = PACKET_HOST | PACKET_BROADCAST | PACKET_MULTICAST;
rc = ddsrt_bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if (rc != DDS_RETCODE_OK)
@ -227,12 +215,12 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (uint32_t port, ddsi_tran_qos_t
memset (uc, 0, sizeof (*uc));
uc->m_sock = sock;
uc->m_ifindex = addr.sll_ifindex;
ddsi_factory_conn_init (&ddsi_raweth_factory_g, &uc->m_base);
ddsi_factory_conn_init (fact, &uc->m_base);
uc->m_base.m_base.m_port = port;
uc->m_base.m_base.m_trantype = DDSI_TRAN_CONN;
uc->m_base.m_base.m_multicast = mcast;
uc->m_base.m_base.m_handle_fn = ddsi_raweth_conn_handle;
uc->m_base.m_base.m_locator_fn = ddsi_raweth_conn_locator;
uc->m_base.m_locator_fn = ddsi_raweth_conn_locator;
uc->m_base.m_read_fn = ddsi_raweth_conn_read;
uc->m_base.m_write_fn = ddsi_raweth_conn_write;
uc->m_base.m_disable_multiplexing_fn = 0;
@ -314,10 +302,11 @@ static int ddsi_raweth_is_ssm_mcaddr (const ddsi_tran_factory_t tran, const nn_l
return 0;
}
static enum ddsi_nearby_address_result ddsi_raweth_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[])
static enum ddsi_nearby_address_result ddsi_raweth_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface interf[])
{
(void) tran;
(void) loc;
(void) ownloc;
(void) ninterf;
(void) interf;
return DNAR_LOCAL;
@ -350,55 +339,48 @@ static enum ddsi_locator_from_string_result ddsi_raweth_address_from_string (dds
return AFSR_OK;
}
static void ddsi_raweth_deinit(void)
static void ddsi_raweth_deinit(ddsi_tran_factory_t fact)
{
if (ddsrt_atomic_dec32_nv(&init_g) == 0) {
if (ddsi_raweth_config_g.mship)
free_group_membership(ddsi_raweth_config_g.mship);
DDS_LOG(DDS_LC_CONFIG, "raweth de-initialized\n");
}
ddsrt_free (fact);
DDS_LOG(DDS_LC_CONFIG, "raweth de-initialized\n");
}
static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t factory, ddsrt_ifaddrs_t **interfs)
static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t fact, enum transport_selector transport_selector, ddsrt_ifaddrs_t **ifs)
{
int afs[] = { AF_PACKET, DDSRT_AF_TERM };
(void)factory;
return -ddsrt_getifaddrs(interfs, afs);
(void)fact;
(void)transport_selector;
return ddsrt_getifaddrs(ifs, afs);
}
int ddsi_raweth_init (void)
int ddsi_raweth_init (struct q_globals *gv)
{
if (ddsrt_atomic_inc32_nv(&init_g) == 1) {
memset (&ddsi_raweth_factory_g, 0, sizeof (ddsi_raweth_factory_g));
ddsi_raweth_factory_g.m_free_fn = ddsi_raweth_deinit;
ddsi_raweth_factory_g.m_kind = NN_LOCATOR_KIND_RAWETH;
ddsi_raweth_factory_g.m_typename = "raweth";
ddsi_raweth_factory_g.m_default_spdp_address = "raweth/ff:ff:ff:ff:ff:ff";
ddsi_raweth_factory_g.m_connless = 1;
ddsi_raweth_factory_g.m_supports_fn = ddsi_raweth_supports;
ddsi_raweth_factory_g.m_create_conn_fn = ddsi_raweth_create_conn;
ddsi_raweth_factory_g.m_release_conn_fn = ddsi_raweth_release_conn;
ddsi_raweth_factory_g.m_join_mc_fn = ddsi_raweth_join_mc;
ddsi_raweth_factory_g.m_leave_mc_fn = ddsi_raweth_leave_mc;
ddsi_raweth_factory_g.m_is_mcaddr_fn = ddsi_raweth_is_mcaddr;
ddsi_raweth_factory_g.m_is_ssm_mcaddr_fn = ddsi_raweth_is_ssm_mcaddr;
ddsi_raweth_factory_g.m_is_nearby_address_fn = ddsi_raweth_is_nearby_address;
ddsi_raweth_factory_g.m_locator_from_string_fn = ddsi_raweth_address_from_string;
ddsi_raweth_factory_g.m_locator_to_string_fn = ddsi_raweth_to_string;
ddsi_raweth_factory_g.m_enumerate_interfaces_fn = ddsi_raweth_enumerate_interfaces;
ddsi_factory_add (&ddsi_raweth_factory_g);
ddsi_raweth_config_g.mship = new_group_membership();
DDS_LOG(DDS_LC_CONFIG, "raweth initialized\n");
}
struct ddsi_tran_factory *fact = ddsrt_malloc (sizeof (*fact));
memset (fact, 0, sizeof (*fact));
fact->gv = gv;
fact->m_free_fn = ddsi_raweth_deinit;
fact->m_kind = NN_LOCATOR_KIND_RAWETH;
fact->m_typename = "raweth";
fact->m_default_spdp_address = "raweth/ff:ff:ff:ff:ff:ff";
fact->m_connless = 1;
fact->m_supports_fn = ddsi_raweth_supports;
fact->m_create_conn_fn = ddsi_raweth_create_conn;
fact->m_release_conn_fn = ddsi_raweth_release_conn;
fact->m_join_mc_fn = ddsi_raweth_join_mc;
fact->m_leave_mc_fn = ddsi_raweth_leave_mc;
fact->m_is_mcaddr_fn = ddsi_raweth_is_mcaddr;
fact->m_is_ssm_mcaddr_fn = ddsi_raweth_is_ssm_mcaddr;
fact->m_is_nearby_address_fn = ddsi_raweth_is_nearby_address;
fact->m_locator_from_string_fn = ddsi_raweth_address_from_string;
fact->m_locator_to_string_fn = ddsi_raweth_to_string;
fact->m_enumerate_interfaces_fn = ddsi_raweth_enumerate_interfaces;
ddsi_factory_add (gv, fact);
DDS_LOG(DDS_LC_CONFIG, "raweth initialized\n");
return 0;
}
#else
int ddsi_raweth_init (void) { return 0; }
int ddsi_raweth_init (struct q_globals *gv) { (void) gv; return 0; }
#endif /* defined __linux */

View file

@ -216,7 +216,7 @@ static void serdata_default_free(struct ddsi_serdata *dcmn)
{
struct ddsi_serdata_default *d = (struct ddsi_serdata_default *)dcmn;
assert(ddsrt_atomic_ld32(&d->c.refc) == 0);
if (d->size > MAX_SIZE_FOR_POOL || !nn_freelist_push (&gv.serpool->freelist, d))
if (d->size > MAX_SIZE_FOR_POOL || !nn_freelist_push (&d->serpool->freelist, d))
dds_free (d);
}
@ -234,20 +234,20 @@ static void serdata_default_init(struct ddsi_serdata_default *d, const struct dd
d->keyhash.m_iskey = 0;
}
static struct ddsi_serdata_default *serdata_default_allocnew (struct serdatapool *pool, uint32_t init_size)
static struct ddsi_serdata_default *serdata_default_allocnew (struct serdatapool *serpool, uint32_t init_size)
{
struct ddsi_serdata_default *d = ddsrt_malloc (offsetof (struct ddsi_serdata_default, data) + init_size);
d->size = init_size;
d->pool = pool;
d->serpool = serpool;
return d;
}
static struct ddsi_serdata_default *serdata_default_new_size (const struct ddsi_sertopic_default *tp, enum ddsi_serdata_kind kind, uint32_t size)
{
struct ddsi_serdata_default *d;
if (size <= MAX_SIZE_FOR_POOL && (d = nn_freelist_pop (&gv.serpool->freelist)) != NULL)
if (size <= MAX_SIZE_FOR_POOL && (d = nn_freelist_pop (&tp->serpool->freelist)) != NULL)
ddsrt_atomic_st32 (&d->c.refc, 1);
else if ((d = serdata_default_allocnew (gv.serpool, size)) == NULL)
else if ((d = serdata_default_allocnew (tp->serpool, size)) == NULL)
return NULL;
serdata_default_init (d, tp, kind);
return d;

View file

@ -28,8 +28,10 @@
#include "dds/ddsrt/sockets.h"
#include "dds/ddsrt/sync.h"
#include "dds/ddsrt/threads.h"
#include "dds/ddsi/q_globals.h"
static SSL_CTX *ddsi_ssl_ctx = NULL;
static bool ddsi_ssl_allow_self_signed_hack = false;
static SSL *ddsi_ssl_new (void)
{
@ -52,7 +54,7 @@ static int ddsi_ssl_verify (int ok, X509_STORE_CTX *store)
int err = X509_STORE_CTX_get_error (store);
/* Check if allowing self-signed certificates */
if (config.ssl_self_signed && ((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) || (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)))
if (ddsi_ssl_allow_self_signed_hack && ((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) || (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)))
ok = 1;
else
{
@ -176,76 +178,80 @@ static void ddsi_ssl_dynlock_destroy (CRYPTO_dynlock_value *lock, const char *fi
static int ddsi_ssl_password (char *buf, int num, int rwflag, void *udata)
{
struct q_globals *gv = udata;
(void) rwflag;
(void) udata;
if (num < 0 || (size_t) num < strlen (config.ssl_key_pass) + 1)
if (num < 0 || (size_t) num < strlen (gv->config.ssl_key_pass) + 1)
return 0;
DDSRT_WARNING_MSVC_OFF(4996);
strcpy (buf, config.ssl_key_pass);
strcpy (buf, gv->config.ssl_key_pass);
DDSRT_WARNING_MSVC_ON(4996);
return (int) strlen (config.ssl_key_pass);
return (int) strlen (gv->config.ssl_key_pass);
}
static SSL_CTX *ddsi_ssl_ctx_init (void)
static SSL_CTX *ddsi_ssl_ctx_init (struct q_globals *gv)
{
SSL_CTX *ctx = SSL_CTX_new (SSLv23_method ());
unsigned disallow_TLSv1_2;
/* Load certificates */
if (! SSL_CTX_use_certificate_file (ctx, config.ssl_keystore, SSL_FILETYPE_PEM))
if (! SSL_CTX_use_certificate_file (ctx, gv->config.ssl_keystore, SSL_FILETYPE_PEM))
{
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load certificate from file: %s\n", config.ssl_keystore);
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load certificate from file: %s\n", gv->config.ssl_keystore);
goto fail;
}
/* Set password and callback */
SSL_CTX_set_default_passwd_cb (ctx, ddsi_ssl_password);
SSL_CTX_set_default_passwd_cb_userdata (ctx, gv);
/* Get private key */
if (! SSL_CTX_use_PrivateKey_file (ctx, config.ssl_keystore, SSL_FILETYPE_PEM))
if (! SSL_CTX_use_PrivateKey_file (ctx, gv->config.ssl_keystore, SSL_FILETYPE_PEM))
{
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load private key from file: %s\n", config.ssl_keystore);
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load private key from file: %s\n", gv->config.ssl_keystore);
goto fail;
}
/* Load CAs */
if (! SSL_CTX_load_verify_locations (ctx, config.ssl_keystore, 0))
if (! SSL_CTX_load_verify_locations (ctx, gv->config.ssl_keystore, 0))
{
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load CA from file: %s\n", config.ssl_keystore);
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load CA from file: %s\n", gv->config.ssl_keystore);
goto fail;
}
/* Set ciphers */
if (! SSL_CTX_set_cipher_list (ctx, config.ssl_ciphers))
if (! SSL_CTX_set_cipher_list (ctx, gv->config.ssl_ciphers))
{
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to set ciphers: %s\n", config.ssl_ciphers);
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to set ciphers: %s\n", gv->config.ssl_ciphers);
goto fail;
}
/* Load randomness from file (optional) */
if (config.ssl_rand_file[0] != '\0')
if (gv->config.ssl_rand_file[0] != '\0')
{
if (! RAND_load_file (config.ssl_rand_file, 4096))
if (! RAND_load_file (gv->config.ssl_rand_file, 4096))
{
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load random seed from file: %s\n", config.ssl_rand_file);
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load random seed from file: %s\n", gv->config.ssl_rand_file);
goto fail;
}
}
/* Set certificate verification policy from configuration */
if (!config.ssl_verify)
if (!gv->config.ssl_verify)
SSL_CTX_set_verify (ctx, SSL_VERIFY_NONE, NULL);
else
{
int i = SSL_VERIFY_PEER;
if (config.ssl_verify_client)
if (gv->config.ssl_verify_client)
i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
/* FIXME: whether or not self-signed is allowed is per-config, SSL_set_ex_data can fix that (or hashing ctx) */
if (gv->config.ssl_self_signed)
ddsi_ssl_allow_self_signed_hack = true;
SSL_CTX_set_verify (ctx, i, ddsi_ssl_verify);
}
switch (config.ssl_min_version.major)
switch (gv->config.ssl_min_version.major)
{
case 1:
switch (config.ssl_min_version.minor)
switch (gv->config.ssl_min_version.minor)
{
case 2:
disallow_TLSv1_2 = 0;
@ -254,17 +260,17 @@ static SSL_CTX *ddsi_ssl_ctx_init (void)
#ifdef SSL_OP_NO_TLSv1_2
disallow_TLSv1_2 = SSL_OP_NO_TLSv1_2;
#else
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: openssl version does not support disabling TLSv1.2 as required by config\n");
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: openssl version does not support disabling TLSv1.2 as required by gv->config\n");
goto fail;
#endif
break;
default:
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", config.ssl_min_version.major, config.ssl_min_version.minor);
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", gv->config.ssl_min_version.major, gv->config.ssl_min_version.minor);
goto fail;
}
break;
default:
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", config.ssl_min_version.major, config.ssl_min_version.minor);
DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", gv->config.ssl_min_version.major, gv->config.ssl_min_version.minor);
goto fail;
}
SSL_CTX_set_options (ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | disallow_TLSv1_2);
@ -344,8 +350,9 @@ static SSL *ddsi_ssl_accept (BIO *bio, ddsrt_socket_t *sock)
return ssl;
}
static bool ddsi_ssl_init (void)
static bool ddsi_ssl_init (struct q_globals *gv)
{
/* FIXME: allocate this stuff ... don't copy gv into a global variable ... */
ERR_load_BIO_strings ();
SSL_load_error_strings ();
SSL_library_init ();
@ -368,7 +375,7 @@ static bool ddsi_ssl_init (void)
CRYPTO_set_dynlock_create_callback (ddsi_ssl_dynlock_create);
CRYPTO_set_dynlock_lock_callback (ddsi_ssl_dynlock_lock);
CRYPTO_set_dynlock_destroy_callback (ddsi_ssl_dynlock_destroy);
ddsi_ssl_ctx = ddsi_ssl_ctx_init ();
ddsi_ssl_ctx = ddsi_ssl_ctx_init (gv);
return (ddsi_ssl_ctx != NULL);
}

View file

@ -29,15 +29,6 @@
#define INVALID_PORT (~0u)
typedef struct ddsi_tran_factory * ddsi_tcp_factory_g_t;
static ddsrt_atomic_uint32_t ddsi_tcp_init_g = DDSRT_ATOMIC_UINT32_INIT(0);
#ifdef DDSI_INCLUDE_SSL
static struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin;
#endif
static const char * ddsi_name = "tcp";
/*
ddsi_tcp_conn: TCP connection for reading and writing. Mutex prevents concurrent
writes to socket. Is reference counted. Peer port is actually contained in peer
@ -49,8 +40,7 @@ static const char * ddsi_name = "tcp";
wait set that manages their lifecycle.
*/
typedef struct ddsi_tcp_conn
{
typedef struct ddsi_tcp_conn {
struct ddsi_tran_conn m_base;
struct sockaddr_storage m_peer_addr;
uint32_t m_peer_port;
@ -59,22 +49,25 @@ typedef struct ddsi_tcp_conn
#ifdef DDSI_INCLUDE_SSL
SSL * m_ssl;
#endif
}
* ddsi_tcp_conn_t;
} *ddsi_tcp_conn_t;
typedef struct ddsi_tcp_listener
{
typedef struct ddsi_tcp_listener {
struct ddsi_tran_listener m_base;
ddsrt_socket_t m_sock;
#ifdef DDSI_INCLUDE_SSL
BIO * m_bio;
#endif
}
* ddsi_tcp_listener_t;
} *ddsi_tcp_listener_t;
/* Stateless singleton instance handed out as client connection */
static struct ddsi_tcp_conn ddsi_tcp_conn_client;
struct ddsi_tran_factory_tcp {
struct ddsi_tran_factory fact;
ddsrt_mutex_t ddsi_tcp_cache_lock_g;
ddsrt_avl_tree_t ddsi_tcp_cache_g;
struct ddsi_tcp_conn ddsi_tcp_conn_client;
#ifdef DDSI_INCLUDE_SSL
struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin;
#endif
};
static int ddsi_tcp_cmp_conn (const struct ddsi_tcp_conn *c1, const struct ddsi_tcp_conn *c2)
{
@ -92,12 +85,10 @@ static int ddsi_tcp_cmp_conn_wrap (const void *a, const void *b)
return ddsi_tcp_cmp_conn (a, b);
}
typedef struct ddsi_tcp_node
{
typedef struct ddsi_tcp_node {
ddsrt_avl_node_t m_avlnode;
ddsi_tcp_conn_t m_conn;
}
* ddsi_tcp_node_t;
} * ddsi_tcp_node_t;
static const ddsrt_avl_treedef_t ddsi_tcp_treedef = DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY
(
@ -107,17 +98,13 @@ static const ddsrt_avl_treedef_t ddsi_tcp_treedef = DDSRT_AVL_TREEDEF_INITIALIZE
0
);
static ddsrt_mutex_t ddsi_tcp_cache_lock_g;
static ddsrt_avl_tree_t ddsi_tcp_cache_g;
static struct ddsi_tran_factory ddsi_tcp_factory_g;
static ddsi_tcp_conn_t ddsi_tcp_new_conn (struct ddsi_tran_factory_tcp *fact, ddsrt_socket_t, bool, struct sockaddr *);
static ddsi_tcp_conn_t ddsi_tcp_new_conn (ddsrt_socket_t, bool, struct sockaddr *);
static char *sockaddr_to_string_with_port (char *dst, size_t sizeof_dst, const struct sockaddr *src)
static char *sockaddr_to_string_with_port (const struct q_globals *gv, char *dst, size_t sizeof_dst, const struct sockaddr *src)
{
nn_locator_t loc;
ddsi_ipaddr_to_loc(&loc, src, src->sa_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
ddsi_locator_to_string(dst, sizeof_dst, &loc);
ddsi_locator_to_string(gv, dst, sizeof_dst, &loc);
return dst;
}
@ -172,15 +159,15 @@ static void ddsi_tcp_sock_free (ddsrt_socket_t sock, const char * msg)
{
if (msg)
{
DDS_LOG(DDS_LC_TCP, "%s %s free socket %"PRIdSOCK"\n", ddsi_name, msg, sock);
DDS_LOG(DDS_LC_TCP, "tcp %s free socket %"PRIdSOCK"\n", msg, sock);
}
ddsrt_close (sock);
}
}
static void ddsi_tcp_sock_new (ddsrt_socket_t * sock, unsigned short port)
static void ddsi_tcp_sock_new (ddsrt_socket_t *sock, unsigned short port, const struct q_globals *gv)
{
if (make_socket (sock, port, true, true) != 0)
if (make_socket (sock, port, true, true, gv) != 0)
{
*sock = DDSRT_INVALID_SOCKET;
}
@ -195,11 +182,14 @@ static void ddsi_tcp_node_free (void * ptr)
static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t * msg)
{
#ifdef DDSI_INCLUDE_SSL
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
#endif
char buff[DDSI_LOCSTRLEN];
ddsrt_socket_t sock;
dds_return_t ret;
ddsi_tcp_sock_new (&sock, 0);
ddsi_tcp_sock_new (&sock, 0, conn->m_base.m_base.gv);
if (sock != DDSRT_INVALID_SOCKET)
{
/* Attempt to connect, expected that may fail */
@ -218,9 +208,9 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t *
ddsi_tcp_conn_set_socket (conn, sock);
#ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.connect)
if (fact->ddsi_tcp_ssl_plugin.connect)
{
conn->m_ssl = (ddsi_tcp_ssl_plugin.connect) (sock);
conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (sock);
if (conn->m_ssl == NULL)
{
ddsi_tcp_conn_set_socket (conn, DDSRT_INVALID_SOCKET);
@ -229,21 +219,21 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t *
}
#endif
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *) msg->msg_name);
DDS_LOG(DDS_LC_TCP, "%s connect socket %"PRIdSOCK" port %u to %s\n", ddsi_name, sock, get_socket_port (sock), buff);
sockaddr_to_string_with_port(conn->m_base.m_base.gv, buff, sizeof(buff), (struct sockaddr *) msg->msg_name);
DDS_LOG(DDS_LC_TCP, "tcp connect socket %"PRIdSOCK" port %u to %s\n", sock, get_socket_port (sock), buff);
/* Also may need to receive on connection so add to waitset */
(void)ddsrt_setsocknonblocking(conn->m_sock, true);
assert (gv.n_recv_threads > 0);
assert (gv.recv_threads[0].arg.mode == RTM_MANY);
os_sockWaitsetAdd (gv.recv_threads[0].arg.u.many.ws, &conn->m_base);
os_sockWaitsetTrigger (gv.recv_threads[0].arg.u.many.ws);
assert (conn->m_base.m_base.gv->n_recv_threads > 0);
assert (conn->m_base.m_base.gv->recv_threads[0].arg.mode == RTM_MANY);
os_sockWaitsetAdd (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws, &conn->m_base);
os_sockWaitsetTrigger (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws);
}
}
static void ddsi_tcp_cache_add (ddsi_tcp_conn_t conn, ddsrt_avl_ipath_t * path)
static void ddsi_tcp_cache_add (struct ddsi_tran_factory_tcp *fact, ddsi_tcp_conn_t conn, ddsrt_avl_ipath_t * path)
{
const char * action = "added";
ddsi_tcp_node_t node;
@ -256,11 +246,11 @@ static void ddsi_tcp_cache_add (ddsi_tcp_conn_t conn, ddsrt_avl_ipath_t * path)
{
node = ddsrt_malloc (sizeof (*node));
node->m_conn = conn;
ddsrt_avl_insert_ipath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node, path);
ddsrt_avl_insert_ipath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node, path);
}
else
{
node = ddsrt_avl_lookup (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, conn);
node = ddsrt_avl_lookup (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, conn);
if (node)
{
/* Replace connection in cache */
@ -273,30 +263,31 @@ static void ddsi_tcp_cache_add (ddsi_tcp_conn_t conn, ddsrt_avl_ipath_t * path)
{
node = ddsrt_malloc (sizeof (*node));
node->m_conn = conn;
ddsrt_avl_insert (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node);
ddsrt_avl_insert (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node);
}
}
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "%s cache %s %s socket %"PRIdSOCK" to %s\n", ddsi_name, action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "tcp cache %s %s socket %"PRIdSOCK" to %s\n", action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
}
static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
{
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
char buff[DDSI_LOCSTRLEN];
ddsi_tcp_node_t node;
ddsrt_avl_dpath_t path;
ddsrt_mutex_lock (&ddsi_tcp_cache_lock_g);
node = ddsrt_avl_lookup_dpath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, conn, &path);
ddsrt_mutex_lock (&fact->ddsi_tcp_cache_lock_g);
node = ddsrt_avl_lookup_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, conn, &path);
if (node)
{
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "%s cache removed socket %"PRIdSOCK" to %s\n", ddsi_name, conn->m_sock, buff);
ddsrt_avl_delete_dpath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node, &path);
sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "tcp cache removed socket %"PRIdSOCK" to %s\n", conn->m_sock, buff);
ddsrt_avl_delete_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node, &path);
ddsi_tcp_node_free (node);
}
ddsrt_mutex_unlock (&ddsi_tcp_cache_lock_g);
ddsrt_mutex_unlock (&fact->ddsi_tcp_cache_lock_g);
}
/*
@ -304,7 +295,7 @@ static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
create new connection.
*/
static ddsi_tcp_conn_t ddsi_tcp_cache_find (const ddsrt_msghdr_t * msg)
static ddsi_tcp_conn_t ddsi_tcp_cache_find (struct ddsi_tran_factory_tcp *fact, const ddsrt_msghdr_t * msg)
{
ddsrt_avl_ipath_t path;
ddsi_tcp_node_t node;
@ -317,13 +308,13 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (const ddsrt_msghdr_t * msg)
/* Check cache for existing connection to target */
ddsrt_mutex_lock (&ddsi_tcp_cache_lock_g);
node = ddsrt_avl_lookup_ipath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, &key, &path);
ddsrt_mutex_lock (&fact->ddsi_tcp_cache_lock_g);
node = ddsrt_avl_lookup_ipath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, &key, &path);
if (node)
{
if (node->m_conn->m_base.m_closed)
{
ddsrt_avl_delete (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node);
ddsrt_avl_delete (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node);
ddsi_tcp_node_free (node);
}
else
@ -333,10 +324,10 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (const ddsrt_msghdr_t * msg)
}
if (ret == NULL)
{
ret = ddsi_tcp_new_conn (DDSRT_INVALID_SOCKET, false, (struct sockaddr *)&key.m_peer_addr);
ddsi_tcp_cache_add (ret, &path);
ret = ddsi_tcp_new_conn (fact, DDSRT_INVALID_SOCKET, false, (struct sockaddr *)&key.m_peer_addr);
ddsi_tcp_cache_add (fact, ret, &path);
}
ddsrt_mutex_unlock (&ddsi_tcp_cache_lock_g);
ddsrt_mutex_unlock (&fact->ddsi_tcp_cache_lock_g);
return ret;
}
@ -354,17 +345,18 @@ static ssize_t ddsi_tcp_conn_read_plain (ddsi_tcp_conn_t tcp, void * buf, size_t
#ifdef DDSI_INCLUDE_SSL
static ssize_t ddsi_tcp_conn_read_ssl (ddsi_tcp_conn_t tcp, void * buf, size_t len, dds_return_t *rc)
{
return (ddsi_tcp_ssl_plugin.read) (tcp->m_ssl, buf, len, rc);
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) tcp->m_base.m_factory;
return (fact->ddsi_tcp_ssl_plugin.read) (tcp->m_ssl, buf, len, rc);
}
#endif
static bool ddsi_tcp_select (ddsrt_socket_t sock, bool read, size_t pos)
static bool ddsi_tcp_select (ddsrt_socket_t sock, bool read, size_t pos, int64_t timeout)
{
dds_return_t rc;
fd_set fds;
fd_set * rdset = read ? &fds : NULL;
fd_set * wrset = read ? NULL : &fds;
int64_t tval = read ? config.tcp_read_timeout : config.tcp_write_timeout;
fd_set *rdset = read ? &fds : NULL;
fd_set *wrset = read ? NULL : &fds;
int64_t tval = timeout;
int32_t ready = 0;
FD_ZERO (&fds);
@ -376,25 +368,24 @@ static bool ddsi_tcp_select (ddsrt_socket_t sock, bool read, size_t pos)
DDSRT_WARNING_GNUC_ON(sign-conversion)
#endif
DDS_LOG(DDS_LC_TCP, "%s blocked %s: sock %d\n", ddsi_name, read ? "read" : "write", (int) sock);
DDS_LOG(DDS_LC_TCP, "tcp blocked %s: sock %d\n", read ? "read" : "write", (int) sock);
do {
rc = ddsrt_select (sock + 1, rdset, wrset, NULL, tval, &ready);
} while (rc == DDS_RETCODE_INTERRUPTED);
if (rc != DDS_RETCODE_OK)
{
DDS_WARNING
(
"%s abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n",
ddsi_name, read ? "read" : "write", (int) sock, pos
);
DDS_WARNING ("tcp abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n", read ? "read" : "write", (int) sock, pos);
}
return (ready > 0);
}
static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
{
#ifdef DDSI_INCLUDE_SSL
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_factory;
#endif
dds_return_t rc;
ddsi_tcp_conn_t tcp = (ddsi_tcp_conn_t) conn;
ssize_t (*rd) (ddsi_tcp_conn_t, void *, size_t, dds_return_t * err) = ddsi_tcp_conn_read_plain;
@ -402,7 +393,7 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
ssize_t n;
#ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.read)
if (fact->ddsi_tcp_ssl_plugin.read)
{
rd = ddsi_tcp_conn_read_ssl;
}
@ -425,7 +416,7 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
}
else if (n == 0)
{
DDS_LOG(DDS_LC_TCP, "%s read: sock %"PRIdSOCK" closed-by-peer\n", ddsi_name, tcp->m_sock);
DDS_LOG(DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" closed-by-peer\n", tcp->m_sock);
break;
}
else
@ -436,12 +427,13 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
{
if (allow_spurious && pos == 0)
return 0;
else if (ddsi_tcp_select (tcp->m_sock, true, pos) == false)
const int64_t timeout = conn->m_base.gv->config.tcp_read_timeout;
if (ddsi_tcp_select (tcp->m_sock, true, pos, timeout) == false)
break;
}
else
{
DDS_LOG(DDS_LC_TCP, "%s read: sock %"PRIdSOCK" error %"PRId32"\n", ddsi_name, tcp->m_sock, rc);
DDS_LOG(DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" error %"PRId32"\n", tcp->m_sock, rc);
break;
}
}
@ -468,17 +460,12 @@ static ssize_t ddsi_tcp_conn_write_plain (ddsi_tcp_conn_t conn, const void * buf
#ifdef DDSI_INCLUDE_SSL
static ssize_t ddsi_tcp_conn_write_ssl (ddsi_tcp_conn_t conn, const void * buf, size_t len, dds_return_t *rc)
{
return (ddsi_tcp_ssl_plugin.write) (conn->m_ssl, buf, len, rc);
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
return (fact->ddsi_tcp_ssl_plugin.write) (conn->m_ssl, buf, len, rc);
}
#endif
static ssize_t ddsi_tcp_block_write
(
ssize_t (*wr) (ddsi_tcp_conn_t, const void *, size_t, dds_return_t *),
ddsi_tcp_conn_t conn,
const void * buf,
size_t sz
)
static ssize_t ddsi_tcp_block_write (ssize_t (*wr) (ddsi_tcp_conn_t, const void *, size_t, dds_return_t *), ddsi_tcp_conn_t conn, const void * buf, size_t sz)
{
/* Write all bytes of buf even in the presence of signals,
partial writes and blocking (typically write buffer full) */
@ -499,14 +486,15 @@ static ssize_t ddsi_tcp_block_write
{
if (rc == DDS_RETCODE_TRY_AGAIN)
{
if (ddsi_tcp_select (conn->m_sock, false, pos) == false)
const int64_t timeout = conn->m_base.m_base.gv->config.tcp_write_timeout;
if (ddsi_tcp_select (conn->m_sock, false, pos, timeout) == false)
{
break;
}
}
else
{
DDS_LOG(DDS_LC_TCP, "%s write: sock %"PRIdSOCK" error %"PRId32"\n", ddsi_name, conn->m_sock, rc);
DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" error %"PRId32"\n", conn->m_sock, rc);
break;
}
}
@ -519,9 +507,8 @@ static ssize_t ddsi_tcp_block_write
static size_t iovlen_sum (size_t niov, const ddsrt_iovec_t *iov)
{
size_t tot = 0;
while (niov--) {
while (niov--)
tot += iov++->iov_len;
}
return tot;
}
@ -533,6 +520,7 @@ static void set_msghdr_iov (ddsrt_msghdr_t *mhdr, ddsrt_iovec_t *iov, size_t iov
static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags)
{
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) base->m_factory;
#ifdef DDSI_INCLUDE_SSL
char msgbuf[4096]; /* stack buffer for merging smallish writes without requiring allocations */
ddsrt_iovec_t iovec; /* iovec used for msgbuf */
@ -556,7 +544,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
len = iovlen_sum (niov, iov);
(void) base;
conn = ddsi_tcp_cache_find (&msg);
conn = ddsi_tcp_cache_find (fact, &msg);
if (conn == NULL)
{
return -1;
@ -581,13 +569,13 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
if (!connect && ((flags & DDSI_TRAN_ON_CONNECT) != 0))
{
DDS_LOG(DDS_LC_TCP, "%s write: sock %"PRIdSOCK" message filtered\n", ddsi_name, conn->m_sock);
DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" message filtered\n", conn->m_sock);
ddsrt_mutex_unlock (&conn->m_mutex);
return (ssize_t) len;
}
#ifdef DDSI_INCLUDE_SSL
if (config.ssl_enable)
if (base->m_base.gv->config.ssl_enable)
{
/* SSL doesn't have sendmsg, ret = 0 so writing starts at first byte.
Rumor is that it is much better to merge small writes, which do here
@ -640,11 +628,11 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
{
case DDS_RETCODE_NO_CONNECTION:
case DDS_RETCODE_ILLEGAL_OPERATION:
DDS_LOG(DDS_LC_TCP, "%s write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", ddsi_name, conn->m_sock);
DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", conn->m_sock);
break;
default:
if (! conn->m_base.m_closed && (conn->m_sock != DDSRT_INVALID_SOCKET))
DDS_WARNING("%s write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", ddsi_name, conn->m_sock, rc);
DDS_WARNING("tcp write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", conn->m_sock, rc);
break;
}
}
@ -653,7 +641,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
{
if (ret == 0)
{
DDS_LOG(DDS_LC_TCP, "%s write: sock %"PRIdSOCK" eof\n", ddsi_name, conn->m_sock);
DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" eof\n", conn->m_sock);
}
piecewise = (ret > 0 && (size_t) ret < len);
}
@ -664,7 +652,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
ssize_t (*wr) (ddsi_tcp_conn_t, const void *, size_t, dds_return_t *) = ddsi_tcp_conn_write_plain;
int i = 0;
#ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.write)
if (fact->ddsi_tcp_ssl_plugin.write)
{
wr = ddsi_tcp_conn_write_ssl;
}
@ -707,35 +695,39 @@ static ddsrt_socket_t ddsi_tcp_conn_handle (ddsi_tran_base_t base)
}
ddsrt_attribute_no_sanitize (("thread"))
static bool ddsi_tcp_supports (int32_t kind)
static bool ddsi_tcp_supports (const struct ddsi_tran_factory *fact_cmn, int32_t kind)
{
return kind == ddsi_tcp_factory_g.m_kind;
return kind == fact_cmn->m_kind;
}
static int ddsi_tcp_locator (ddsi_tran_base_t base, nn_locator_t *loc)
static int ddsi_tcp_locator (struct ddsi_tran_factory *fact_cmn, ddsi_tran_base_t base, nn_locator_t *loc)
{
loc->kind = ddsi_tcp_factory_g.m_kind;
memcpy(loc->address, gv.extloc.address, sizeof(loc->address));
loc->kind = fact_cmn->m_kind;
memcpy(loc->address, base->gv->extloc.address, sizeof(loc->address));
loc->port = base->m_port;
return 0;
}
static ddsi_tran_conn_t ddsi_tcp_create_conn (uint32_t port, ddsi_tran_qos_t qos)
static ddsi_tran_conn_t ddsi_tcp_create_conn (struct ddsi_tran_factory *fact_cmn, uint32_t port, ddsi_tran_qos_t qos)
{
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn;
(void) qos;
(void) port;
return &ddsi_tcp_conn_client.m_base;
return &fact->ddsi_tcp_conn_client.m_base;
}
static int ddsi_tcp_listen (ddsi_tran_listener_t listener)
{
#ifdef DDSI_INCLUDE_SSL
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
#endif
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
int ret = listen (tl->m_sock, 4);
#ifdef DDSI_INCLUDE_SSL
if ((ret == 0) && ddsi_tcp_ssl_plugin.listen)
if ((ret == 0) && fact->ddsi_tcp_ssl_plugin.listen)
{
tl->m_bio = (ddsi_tcp_ssl_plugin.listen) (tl->m_sock);
tl->m_bio = (fact->ddsi_tcp_ssl_plugin.listen) (tl->m_sock);
}
#endif
@ -744,6 +736,7 @@ static int ddsi_tcp_listen (ddsi_tran_listener_t listener)
static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
{
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
ddsi_tcp_conn_t tcp = NULL;
ddsrt_socket_t sock = DDSRT_INVALID_SOCKET;
@ -758,9 +751,9 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
memset (&addr, 0, addrlen);
do {
#ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.accept)
if (fact->ddsi_tcp_ssl_plugin.accept)
{
ssl = (ddsi_tcp_ssl_plugin.accept) (tl->m_bio, &sock);
ssl = (fact->ddsi_tcp_ssl_plugin.accept) (tl->m_bio, &sock);
if (ssl == NULL) {
assert(sock == DDSRT_INVALID_SOCKET);
rc = DDS_RETCODE_ERROR;
@ -771,7 +764,7 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
{
rc = ddsrt_accept(tl->m_sock, NULL, NULL, &sock);
}
if (!ddsrt_atomic_ld32(&gv.rtps_keepgoing))
if (!ddsrt_atomic_ld32(&listener->m_base.gv->rtps_keepgoing))
{
ddsi_tcp_sock_free (sock, NULL);
return NULL;
@ -781,21 +774,21 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
if (sock == DDSRT_INVALID_SOCKET)
{
(void)ddsrt_getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen);
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_LOG((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, "%s accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", ddsi_name, tl->m_sock, buff, rc);
sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_LOG((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, "tcp accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", tl->m_sock, buff, rc);
}
else if (getpeername (sock, (struct sockaddr *) &addr, &addrlen) == -1)
{
DDS_WARNING("%s accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", ddsi_name, sock, tl->m_sock, rc);
DDS_WARNING("tcp accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", sock, tl->m_sock, rc);
ddsrt_close (sock);
}
else
{
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_LOG(DDS_LC_TCP, "%s accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", ddsi_name, sock, tl->m_sock, buff);
sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_LOG(DDS_LC_TCP, "tcp accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", sock, tl->m_sock, buff);
(void)ddsrt_setsocknonblocking (sock, true);
tcp = ddsi_tcp_new_conn (sock, true, (struct sockaddr *)&addr);
tcp = ddsi_tcp_new_conn (fact, sock, true, (struct sockaddr *)&addr);
#ifdef DDSI_INCLUDE_SSL
tcp->m_ssl = ssl;
#endif
@ -805,9 +798,9 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
/* Add connection to cache for bi-dir */
ddsrt_mutex_lock (&ddsi_tcp_cache_lock_g);
ddsi_tcp_cache_add (tcp, NULL);
ddsrt_mutex_unlock (&ddsi_tcp_cache_lock_g);
ddsrt_mutex_lock (&fact->ddsi_tcp_cache_lock_g);
ddsi_tcp_cache_add (fact, tcp, NULL);
ddsrt_mutex_unlock (&fact->ddsi_tcp_cache_lock_g);
}
return tcp ? &tcp->m_base : NULL;
}
@ -829,28 +822,28 @@ static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * lo
ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn;
assert (tc->m_sock != DDSRT_INVALID_SOCKET);
ddsi_ipaddr_to_loc (loc, (struct sockaddr *)&tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
ddsi_locator_to_string(buff, sizeof(buff), loc);
DDS_LOG(DDS_LC_TCP, "(%s EP:%s)", ddsi_name, buff);
ddsi_locator_to_string(conn->m_base.gv, buff, sizeof(buff), loc);
DDS_LOG(DDS_LC_TCP, "(tcp EP:%s)", buff);
}
static void ddsi_tcp_base_init (struct ddsi_tran_conn * base)
static void ddsi_tcp_base_init (const struct ddsi_tran_factory_tcp *fact, struct ddsi_tran_conn *base)
{
ddsi_factory_conn_init (&ddsi_tcp_factory_g, base);
ddsi_factory_conn_init (&fact->fact, base);
base->m_base.m_trantype = DDSI_TRAN_CONN;
base->m_base.m_handle_fn = ddsi_tcp_conn_handle;
base->m_base.m_locator_fn = ddsi_tcp_locator;
base->m_read_fn = ddsi_tcp_conn_read;
base->m_write_fn = ddsi_tcp_conn_write;
base->m_peer_locator_fn = ddsi_tcp_conn_peer_locator;
base->m_disable_multiplexing_fn = 0;
base->m_locator_fn = ddsi_tcp_locator;
}
static ddsi_tcp_conn_t ddsi_tcp_new_conn (ddsrt_socket_t sock, bool server, struct sockaddr * peer)
static ddsi_tcp_conn_t ddsi_tcp_new_conn (struct ddsi_tran_factory_tcp *fact, ddsrt_socket_t sock, bool server, struct sockaddr * peer)
{
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) ddsrt_malloc (sizeof (*conn));
memset (conn, 0, sizeof (*conn));
ddsi_tcp_base_init (&conn->m_base);
ddsi_tcp_base_init (fact, &conn->m_base);
ddsrt_mutex_init (&conn->m_mutex);
conn->m_sock = DDSRT_INVALID_SOCKET;
(void)memcpy(&conn->m_peer_addr, peer, ddsrt_sockaddr_get_size(peer));
@ -862,7 +855,7 @@ static ddsi_tcp_conn_t ddsi_tcp_new_conn (ddsrt_socket_t sock, bool server, stru
return conn;
}
static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t qos)
static ddsi_tran_listener_t ddsi_tcp_create_listener (ddsi_tran_factory_t fact, int port, ddsi_tran_qos_t qos)
{
char buff[DDSI_LOCSTRLEN];
ddsrt_socket_t sock;
@ -872,7 +865,7 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
(void) qos;
ddsi_tcp_sock_new (&sock, (unsigned short) port);
ddsi_tcp_sock_new (&sock, (unsigned short) port, fact->gv);
if (sock != DDSRT_INVALID_SOCKET)
{
@ -882,14 +875,15 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
tl->m_sock = sock;
tl->m_base.m_base.gv = fact->gv;
tl->m_base.m_listen_fn = ddsi_tcp_listen;
tl->m_base.m_accept_fn = ddsi_tcp_accept;
tl->m_base.m_factory = &ddsi_tcp_factory_g;
tl->m_base.m_factory = fact;
tl->m_base.m_base.m_port = get_socket_port (sock);
tl->m_base.m_base.m_trantype = DDSI_TRAN_LISTENER;
tl->m_base.m_base.m_handle_fn = ddsi_tcp_listener_handle;
tl->m_base.m_base.m_locator_fn = ddsi_tcp_locator;
tl->m_base.m_locator_fn = ddsi_tcp_locator;
ret = ddsrt_getsockname(sock, (struct sockaddr *)&addr, &addrlen);
if (ret != DDS_RETCODE_OK) {
@ -899,8 +893,8 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
return NULL;
}
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_LOG(DDS_LC_TCP, "%s create listener socket %"PRIdSOCK" on %s\n", ddsi_name, sock, buff);
sockaddr_to_string_with_port(fact->gv, buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_LOG(DDS_LC_TCP, "tcp create listener socket %"PRIdSOCK" on %s\n", sock, buff);
}
return tl ? &tl->m_base : NULL;
@ -908,14 +902,17 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
{
#ifdef DDSI_INCLUDE_SSL
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
#endif
char buff[DDSI_LOCSTRLEN];
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "%s free %s connnection on socket %"PRIdSOCK" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
sockaddr_to_string_with_port(conn->m_base.m_base.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "tcp free %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
#ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.ssl_free)
if (fact->ddsi_tcp_ssl_plugin.ssl_free)
{
(ddsi_tcp_ssl_plugin.ssl_free) (conn->m_ssl);
(fact->ddsi_tcp_ssl_plugin.ssl_free) (conn->m_ssl);
}
else
#endif
@ -928,23 +925,25 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
{
if (tc != &ddsi_tcp_conn_client.m_base)
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) tc->m_factory;
if (tc != &fact_tcp->ddsi_tcp_conn_client.m_base)
{
char buff[DDSI_LOCSTRLEN];
nn_locator_t loc;
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc;
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "%s close %s connnection on socket %"PRIdSOCK" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
sockaddr_to_string_with_port(tc->m_base.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
DDS_LOG(DDS_LC_TCP, "tcp close %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
(void) shutdown (conn->m_sock, 2);
ddsi_ipaddr_to_loc(&loc, (struct sockaddr *)&conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
loc.port = conn->m_peer_port;
purge_proxy_participants (&loc, conn->m_base.m_server);
purge_proxy_participants (conn->m_base.m_base.gv, &loc, conn->m_base.m_server);
}
}
static void ddsi_tcp_release_conn (ddsi_tran_conn_t conn)
{
if (conn != &ddsi_tcp_conn_client.m_base)
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) conn->m_factory;
if (conn != &fact_tcp->ddsi_tcp_conn_client.m_base)
{
ddsi_tcp_conn_delete ((ddsi_tcp_conn_t) conn);
}
@ -957,7 +956,7 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
dds_return_t ret;
/* Connect to own listener socket to wake listener from blocking 'accept()' */
ddsi_tcp_sock_new (&sock, 0);
ddsi_tcp_sock_new (&sock, 0, listener->m_base.gv);
if (sock != DDSRT_INVALID_SOCKET)
{
struct sockaddr_storage addr;
@ -965,7 +964,7 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
ret = ddsrt_getsockname(tl->m_sock, (struct sockaddr *)&addr, &addrlen);
if (ret != DDS_RETCODE_OK) {
DDS_WARNING("%s failed to get listener address error %"PRId32"\n", ddsi_name, ret);
DDS_WARNING("tcp failed to get listener address error %"PRId32"\n", ret);
} else {
switch (addr.ss_family) {
case AF_INET:
@ -994,8 +993,8 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
if (ret != DDS_RETCODE_OK)
{
char buff[DDSI_LOCSTRLEN];
sockaddr_to_string_with_port(buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_WARNING("%s failed to connect to own listener (%s) error %"PRId32"\n", ddsi_name, buff, ret);
sockaddr_to_string_with_port(listener->m_base.gv, buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_WARNING("tcp failed to connect to own listener (%s) error %"PRId32"\n", buff, ret);
}
}
ddsi_tcp_sock_free (sock, NULL);
@ -1006,33 +1005,34 @@ static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
{
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
#ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.bio_vfree)
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
if (fact->ddsi_tcp_ssl_plugin.bio_vfree)
{
(ddsi_tcp_ssl_plugin.bio_vfree) (tl->m_bio);
(fact->ddsi_tcp_ssl_plugin.bio_vfree) (tl->m_bio);
}
#endif
ddsi_tcp_sock_free (tl->m_sock, "listener");
ddsrt_free (tl);
}
static void ddsi_tcp_release_factory (void)
static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn)
{
if (ddsrt_atomic_dec32_nv (&ddsi_tcp_init_g) == 0) {
ddsrt_avl_free (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, ddsi_tcp_node_free);
ddsrt_mutex_destroy (&ddsi_tcp_cache_lock_g);
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn;
ddsrt_avl_free (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, ddsi_tcp_node_free);
ddsrt_mutex_destroy (&fact->ddsi_tcp_cache_lock_g);
#ifdef DDSI_INCLUDE_SSL
if (ddsi_tcp_ssl_plugin.fini)
{
(ddsi_tcp_ssl_plugin.fini) ();
}
#endif
DDS_LOG(DDS_LC_CONFIG, "tcp de-initialized\n");
if (fact->ddsi_tcp_ssl_plugin.fini)
{
(fact->ddsi_tcp_ssl_plugin.fini) ();
}
#endif
ddsrt_free (fact);
DDS_LOG(DDS_LC_CONFIG, "tcp de-initialized\n");
}
static enum ddsi_locator_from_string_result ddsi_tcp_address_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str)
static enum ddsi_locator_from_string_result ddsi_tcp_address_from_string (ddsi_tran_factory_t fact, nn_locator_t *loc, const char *str)
{
return ddsi_ipaddr_from_string(tran, loc, str, ddsi_tcp_factory_g.m_kind);
return ddsi_ipaddr_from_string(fact, loc, str, fact->m_kind);
}
static int ddsi_tcp_is_mcaddr (const ddsi_tran_factory_t tran, const nn_locator_t *loc)
@ -1049,64 +1049,63 @@ static int ddsi_tcp_is_ssm_mcaddr (const ddsi_tran_factory_t tran, const nn_loca
return 0;
}
static enum ddsi_nearby_address_result ddsi_tcp_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[])
static enum ddsi_nearby_address_result ddsi_tcp_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface interf[])
{
return ddsi_ipaddr_is_nearby_address(tran, loc, ninterf, interf);
return ddsi_ipaddr_is_nearby_address(tran, loc, ownloc, ninterf, interf);
}
int ddsi_tcp_init (void)
int ddsi_tcp_init (struct q_globals *gv)
{
if (ddsrt_atomic_inc32_nv (&ddsi_tcp_init_g) == 1)
{
memset (&ddsi_tcp_factory_g, 0, sizeof (ddsi_tcp_factory_g));
ddsi_tcp_factory_g.m_kind = NN_LOCATOR_KIND_TCPv4;
ddsi_tcp_factory_g.m_typename = "tcp";
ddsi_tcp_factory_g.m_stream = true;
ddsi_tcp_factory_g.m_connless = false;
ddsi_tcp_factory_g.m_supports_fn = ddsi_tcp_supports;
ddsi_tcp_factory_g.m_create_listener_fn = ddsi_tcp_create_listener;
ddsi_tcp_factory_g.m_create_conn_fn = ddsi_tcp_create_conn;
ddsi_tcp_factory_g.m_release_conn_fn = ddsi_tcp_release_conn;
ddsi_tcp_factory_g.m_close_conn_fn = ddsi_tcp_close_conn;
ddsi_tcp_factory_g.m_unblock_listener_fn = ddsi_tcp_unblock_listener;
ddsi_tcp_factory_g.m_release_listener_fn = ddsi_tcp_release_listener;
ddsi_tcp_factory_g.m_free_fn = ddsi_tcp_release_factory;
ddsi_tcp_factory_g.m_locator_from_string_fn = ddsi_tcp_address_from_string;
ddsi_tcp_factory_g.m_locator_to_string_fn = ddsi_ipaddr_to_string;
ddsi_tcp_factory_g.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
ddsi_tcp_factory_g.m_is_mcaddr_fn = ddsi_tcp_is_mcaddr;
ddsi_tcp_factory_g.m_is_ssm_mcaddr_fn = ddsi_tcp_is_ssm_mcaddr;
ddsi_tcp_factory_g.m_is_nearby_address_fn = ddsi_tcp_is_nearby_address;
ddsi_factory_add (&ddsi_tcp_factory_g);
struct ddsi_tran_factory_tcp *fact = ddsrt_malloc (sizeof (*fact));
memset (fact, 0, sizeof (*fact));
fact->fact.gv = gv;
fact->fact.m_kind = NN_LOCATOR_KIND_TCPv4;
fact->fact.m_typename = "tcp";
fact->fact.m_stream = true;
fact->fact.m_connless = false;
fact->fact.m_supports_fn = ddsi_tcp_supports;
fact->fact.m_create_listener_fn = ddsi_tcp_create_listener;
fact->fact.m_create_conn_fn = ddsi_tcp_create_conn;
fact->fact.m_release_conn_fn = ddsi_tcp_release_conn;
fact->fact.m_close_conn_fn = ddsi_tcp_close_conn;
fact->fact.m_unblock_listener_fn = ddsi_tcp_unblock_listener;
fact->fact.m_release_listener_fn = ddsi_tcp_release_listener;
fact->fact.m_free_fn = ddsi_tcp_release_factory;
fact->fact.m_locator_from_string_fn = ddsi_tcp_address_from_string;
fact->fact.m_locator_to_string_fn = ddsi_ipaddr_to_string;
fact->fact.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
fact->fact.m_is_mcaddr_fn = ddsi_tcp_is_mcaddr;
fact->fact.m_is_ssm_mcaddr_fn = ddsi_tcp_is_ssm_mcaddr;
fact->fact.m_is_nearby_address_fn = ddsi_tcp_is_nearby_address;
ddsi_factory_add (gv, &fact->fact);
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_TCP6)
{
ddsi_tcp_factory_g.m_kind = NN_LOCATOR_KIND_TCPv6;
ddsi_tcp_factory_g.m_typename = "tcp6";
}
if (gv->config.transport_selector == TRANS_TCP6)
{
fact->fact.m_kind = NN_LOCATOR_KIND_TCPv6;
fact->fact.m_typename = "tcp6";
}
#endif
memset (&ddsi_tcp_conn_client, 0, sizeof (ddsi_tcp_conn_client));
ddsi_tcp_base_init (&ddsi_tcp_conn_client.m_base);
memset (&fact->ddsi_tcp_conn_client, 0, sizeof (fact->ddsi_tcp_conn_client));
ddsi_tcp_base_init (fact, &fact->ddsi_tcp_conn_client.m_base);
#ifdef DDSI_INCLUDE_SSL
if (config.ssl_enable)
if (gv->config.ssl_enable)
{
ddsi_ssl_config_plugin (&fact->ddsi_tcp_ssl_plugin);
if (! fact->ddsi_tcp_ssl_plugin.init (gv))
{
ddsi_name = "tcp/ssl";
ddsi_ssl_config_plugin (&ddsi_tcp_ssl_plugin);
if (! ddsi_tcp_ssl_plugin.init ())
{
DDS_ERROR("Failed to initialize OpenSSL\n");
return -1;
}
DDS_ERROR("Failed to initialize OpenSSL\n");
return -1;
}
}
#endif
ddsrt_avl_init (&ddsi_tcp_treedef, &ddsi_tcp_cache_g);
ddsrt_mutex_init (&ddsi_tcp_cache_lock_g);
ddsrt_avl_init (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g);
ddsrt_mutex_init (&fact->ddsi_tcp_cache_lock_g);
DDS_LOG(DDS_LC_CONFIG, "%s initialized\n", ddsi_name);
}
DDS_LOG(DDS_LC_CONFIG, "tcp initialized\n");
return 0;
}

View file

@ -34,6 +34,8 @@ struct ddsi_threadmon {
struct alive_vt *av_ary;
void (*renew_cb) (void *arg);
void *renew_arg;
int64_t liveliness_monitoring_interval;
bool noprogress_log_stacktraces;
ddsrt_mutex_t lock;
ddsrt_cond_t cond;
@ -57,7 +59,7 @@ static uint32_t threadmon_thread (struct ddsi_threadmon *sl)
while (sl->keepgoing)
{
/* Guard against spurious wakeups by checking only when cond_waitfor signals a timeout */
if (ddsrt_cond_waitfor (&sl->cond, &sl->lock, config.liveliness_monitoring_interval))
if (ddsrt_cond_waitfor (&sl->cond, &sl->lock, sl->liveliness_monitoring_interval))
continue;
unsigned n_alive = 0, n_unused = 0;
@ -111,8 +113,13 @@ static uint32_t threadmon_thread (struct ddsi_threadmon *sl)
else
{
DDS_TRACE(": [%u] FAIL\n", n_alive);
if (was_alive)
log_stack_traces ();
if (was_alive && dds_get_log_mask () != 0)
{
if (!sl->noprogress_log_stacktraces)
DDS_LOG (~DDS_LC_FATAL, "-- stack traces requested, but traces disabled --\n");
else
log_stack_traces ();
}
was_alive = false;
}
@ -132,24 +139,20 @@ static uint32_t threadmon_thread (struct ddsi_threadmon *sl)
}
}
#endif /* DDSRT_HAVE_RUSAGE */
/* While deaf, we need to make sure the receive thread wakes up
every now and then to try recreating sockets & rejoining multicast
groups */
if (gv.deaf)
trigger_recv_threads ();
}
ddsrt_mutex_unlock (&sl->lock);
return 0;
}
struct ddsi_threadmon *ddsi_threadmon_new (void)
struct ddsi_threadmon *ddsi_threadmon_new (int64_t liveliness_monitoring_interval, bool noprogress_log_stacktraces)
{
struct ddsi_threadmon *sl;
sl = ddsrt_malloc (sizeof (*sl));
sl->keepgoing = -1;
sl->ts = NULL;
sl->liveliness_monitoring_interval = liveliness_monitoring_interval;
sl->noprogress_log_stacktraces = noprogress_log_stacktraces;
if ((sl->av_ary = ddsrt_malloc (thread_states.nthreads * sizeof (*sl->av_ary))) == NULL)
goto fail_vtimes;
@ -164,14 +167,14 @@ struct ddsi_threadmon *ddsi_threadmon_new (void)
return NULL;
}
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl)
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl, const char *name, const struct config_thread_properties_listelem *tprops)
{
ddsrt_mutex_lock (&sl->lock);
assert (sl->keepgoing == -1);
sl->keepgoing = 1;
ddsrt_mutex_unlock (&sl->lock);
if (create_thread (&sl->ts, "lease", (uint32_t (*) (void *)) threadmon_thread, sl) != DDS_RETCODE_OK)
if (create_thread_with_properties (&sl->ts, tprops, name, (uint32_t (*) (void *)) threadmon_thread, sl) != DDS_RETCODE_OK)
goto fail_thread;
return 0;

View file

@ -31,7 +31,8 @@
struct ddsi_tkmap
{
struct ddsrt_chh * m_hh;
struct ddsrt_chh *m_hh;
struct q_globals *gv;
ddsrt_mutex_t m_lock;
ddsrt_cond_t m_cond;
};
@ -42,9 +43,10 @@ static void gc_buckets_impl (struct gcreq *gcreq)
gcreq_free (gcreq);
}
static void gc_buckets (void *a)
static void gc_buckets (void *a, void *arg)
{
struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, gc_buckets_impl);
const struct ddsi_tkmap *tkmap = arg;
struct gcreq *gcreq = gcreq_new (tkmap->gv->gcreq_queue, gc_buckets_impl);
gcreq->arg = a;
gcreq_enqueue (gcreq);
}
@ -57,19 +59,19 @@ static void gc_tkmap_instance_impl (struct gcreq *gcreq)
gcreq_free (gcreq);
}
static void gc_tkmap_instance (struct ddsi_tkmap_instance *tk)
static void gc_tkmap_instance (struct ddsi_tkmap_instance *tk, struct gcreq_queue *gcreq_queue)
{
struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, gc_tkmap_instance_impl);
struct gcreq *gcreq = gcreq_new (gcreq_queue, gc_tkmap_instance_impl);
gcreq->arg = tk;
gcreq_enqueue (gcreq);
}
static uint32_t dds_tk_hash (const struct ddsi_tkmap_instance * inst)
static uint32_t dds_tk_hash (const struct ddsi_tkmap_instance *inst)
{
return inst->m_sample->hash;
}
static uint32_t dds_tk_hash_void (const void * inst)
static uint32_t dds_tk_hash_void (const void *inst)
{
return dds_tk_hash (inst);
}
@ -84,10 +86,11 @@ static int dds_tk_equals_void (const void *a, const void *b)
return dds_tk_equals (a, b);
}
struct ddsi_tkmap *ddsi_tkmap_new (void)
struct ddsi_tkmap *ddsi_tkmap_new (struct q_globals *gv)
{
struct ddsi_tkmap *tkmap = dds_alloc (sizeof (*tkmap));
tkmap->m_hh = ddsrt_chh_new (1, dds_tk_hash_void, dds_tk_equals_void, gc_buckets);
tkmap->m_hh = ddsrt_chh_new (1, dds_tk_hash_void, dds_tk_equals_void, gc_buckets, tkmap);
tkmap->gv = gv;
ddsrt_mutex_init (&tkmap->m_lock);
ddsrt_cond_init (&tkmap->m_cond);
return tkmap;
@ -137,7 +140,7 @@ struct ddsi_tkmap_instance *ddsi_tkmap_find_by_id (struct ddsi_tkmap *map, uint6
return tk;
else
/* Let key value lookup handle the possible CAS loop and the complicated cases */
return ddsi_tkmap_find (tk->m_sample, false, false);
return ddsi_tkmap_find (map, tk->m_sample, false, false);
}
/* Debug keyhash generation for debug and coverage builds */
@ -152,15 +155,10 @@ struct ddsi_tkmap_instance *ddsi_tkmap_find_by_id (struct ddsi_tkmap *map, uint6
#define DDS_DEBUG_KEYHASH 1
#endif
struct ddsi_tkmap_instance *
ddsi_tkmap_find(
struct ddsi_serdata * sd,
const bool rd,
const bool create)
struct ddsi_tkmap_instance *ddsi_tkmap_find (struct ddsi_tkmap *map, struct ddsi_serdata *sd, const bool rd, const bool create)
{
struct ddsi_tkmap_instance dummy;
struct ddsi_tkmap_instance * tk;
struct ddsi_tkmap * map = gv.m_tkmap;
struct ddsi_tkmap_instance *tk;
assert (thread_is_awake ());
dummy.m_sample = sd;
@ -208,9 +206,9 @@ retry:
return tk;
}
struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (struct ddsi_serdata * sd)
struct ddsi_tkmap_instance *ddsi_tkmap_lookup_instance_ref (struct ddsi_tkmap *map, struct ddsi_serdata *sd)
{
return ddsi_tkmap_find (sd, true, true);
return ddsi_tkmap_find (map, sd, true, true);
}
void ddsi_tkmap_instance_ref (struct ddsi_tkmap_instance *tk)
@ -218,7 +216,7 @@ void ddsi_tkmap_instance_ref (struct ddsi_tkmap_instance *tk)
ddsrt_atomic_inc32 (&tk->m_refc);
}
void ddsi_tkmap_instance_unref (struct ddsi_tkmap_instance * tk)
void ddsi_tkmap_instance_unref (struct ddsi_tkmap *map, struct ddsi_tkmap_instance *tk)
{
uint32_t old, new;
assert (thread_is_awake ());
@ -234,8 +232,6 @@ void ddsi_tkmap_instance_unref (struct ddsi_tkmap_instance * tk)
} while (!ddsrt_atomic_cas32(&tk->m_refc, old, new));
if (new == REFC_DELETE)
{
struct ddsi_tkmap *map = gv.m_tkmap;
/* Remove from hash table */
int removed = ddsrt_chh_remove(map->m_hh, tk);
assert (removed);
@ -248,6 +244,6 @@ void ddsi_tkmap_instance_unref (struct ddsi_tkmap_instance * tk)
/* Schedule freeing of memory until after all those who may have found a pointer have
progressed to where they no longer hold that pointer */
gc_tkmap_instance(tk);
gc_tkmap_instance(tk, map->gv->gcreq_queue);
}
}

View file

@ -21,33 +21,30 @@
#include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_globals.h"
static ddsi_tran_factory_t ddsi_tran_factories = NULL;
extern inline uint32_t ddsi_conn_type (ddsi_tran_conn_t conn);
extern inline uint32_t ddsi_conn_port (ddsi_tran_conn_t conn);
extern inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, int port, ddsi_tran_qos_t qos);
extern inline bool ddsi_factory_supports (ddsi_tran_factory_t factory, int32_t kind);
extern inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int32_t kind);
extern inline ddsrt_socket_t ddsi_conn_handle (ddsi_tran_conn_t conn);
extern inline int ddsi_conn_locator (ddsi_tran_conn_t conn, nn_locator_t * loc);
extern inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base);
extern inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos);
extern inline int ddsi_tran_locator (ddsi_tran_base_t base, nn_locator_t * loc);
extern inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc);
extern inline int ddsi_listener_listen (ddsi_tran_listener_t listener);
extern inline ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);
extern inline ssize_t ddsi_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, bool allow_spurious, nn_locator_t *srcloc);
extern inline ssize_t ddsi_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags);
void ddsi_factory_add (ddsi_tran_factory_t factory)
void ddsi_factory_add (struct q_globals *gv, ddsi_tran_factory_t factory)
{
factory->m_factory = ddsi_tran_factories;
ddsi_tran_factories = factory;
factory->m_factory = gv->ddsi_tran_factories;
gv->ddsi_tran_factories = factory;
}
ddsi_tran_factory_t ddsi_factory_find (const char * type)
ddsi_tran_factory_t ddsi_factory_find (const struct q_globals *gv, const char *type)
{
/* FIXME: should speed up */
ddsi_tran_factory_t factory = ddsi_tran_factories;
ddsi_tran_factory_t factory = gv->ddsi_tran_factories;
while (factory)
{
@ -61,23 +58,23 @@ ddsi_tran_factory_t ddsi_factory_find (const char * type)
return factory;
}
void ddsi_tran_factories_fini (void)
void ddsi_tran_factories_fini (struct q_globals *gv)
{
ddsi_tran_factory_t factory;
while ((factory = ddsi_tran_factories) != NULL)
while ((factory = gv->ddsi_tran_factories) != NULL)
{
/* Keep the factory in the list for the duration of "factory_free" so that
conversion of locator kind to factory remains possible. */
ddsi_tran_factory_t next = factory->m_factory;
ddsi_factory_free (factory);
ddsi_tran_factories = next;
gv->ddsi_tran_factories = next;
}
}
static ddsi_tran_factory_t ddsi_factory_find_with_len (const char * type, size_t len)
static ddsi_tran_factory_t ddsi_factory_find_with_len (const struct q_globals *gv, const char *type, size_t len)
{
/* FIXME: should speed up */
ddsi_tran_factory_t factory = ddsi_tran_factories;
ddsi_tran_factory_t factory = gv->ddsi_tran_factories;
while (factory)
{
@ -92,12 +89,12 @@ static ddsi_tran_factory_t ddsi_factory_find_with_len (const char * type, size_t
}
ddsrt_attribute_no_sanitize (("thread"))
ddsi_tran_factory_t ddsi_factory_find_supported_kind (int32_t kind)
ddsi_tran_factory_t ddsi_factory_find_supported_kind (const struct q_globals *gv, int32_t kind)
{
/* FIXME: MUST speed up */
ddsi_tran_factory_t factory;
for (factory = ddsi_tran_factories; factory; factory = factory->m_factory) {
if (factory->m_supports_fn(kind)) {
for (factory = gv->ddsi_tran_factories; factory; factory = factory->m_factory) {
if (factory->m_supports_fn(factory, kind)) {
return factory;
}
}
@ -108,7 +105,7 @@ void ddsi_factory_free (ddsi_tran_factory_t factory)
{
if (factory && factory->m_free_fn)
{
(factory->m_free_fn) ();
(factory->m_free_fn) (factory);
}
}
@ -122,19 +119,19 @@ void ddsi_conn_free (ddsi_tran_conn_t conn)
/* FIXME: rethink the socket waitset & the deleting of entries; the biggest issue is TCP handling that can open & close sockets at will and yet expects the waitset to wake up at the apprioriate times. (This pretty much works with the select-based version, but not the kqueue-based one.) TCP code can also have connections without a socket ... Calling sockWaitsetRemove here (where there shouldn't be any knowledge of it) at least ensures that it is removed in time and that there can't be aliasing of connections and sockets. */
if (ddsi_conn_handle (conn) != DDSRT_INVALID_SOCKET)
{
for (uint32_t i = 0; i < gv.n_recv_threads; i++)
for (uint32_t i = 0; i < conn->m_base.gv->n_recv_threads; i++)
{
if (!gv.recv_threads[i].ts)
assert (!ddsrt_atomic_ld32 (&gv.rtps_keepgoing));
if (!conn->m_base.gv->recv_threads[i].ts)
assert (!ddsrt_atomic_ld32 (&conn->m_base.gv->rtps_keepgoing));
else
{
switch (gv.recv_threads[i].arg.mode)
switch (conn->m_base.gv->recv_threads[i].arg.mode)
{
case RTM_MANY:
os_sockWaitsetRemove (gv.recv_threads[i].arg.u.many.ws, conn);
os_sockWaitsetRemove (conn->m_base.gv->recv_threads[i].arg.u.many.ws, conn);
break;
case RTM_SINGLE:
if (gv.recv_threads[i].arg.u.single.conn == conn)
if (conn->m_base.gv->recv_threads[i].arg.u.single.conn == conn)
abort();
break;
}
@ -158,19 +155,19 @@ void ddsi_conn_add_ref (ddsi_tran_conn_t conn)
ddsrt_atomic_inc32 (&conn->m_count);
}
void ddsi_factory_conn_init (ddsi_tran_factory_t factory, ddsi_tran_conn_t conn)
void ddsi_factory_conn_init (const struct ddsi_tran_factory *factory, ddsi_tran_conn_t conn)
{
ddsrt_atomic_st32 (&conn->m_count, 1);
conn->m_connless = factory->m_connless;
conn->m_stream = factory->m_stream;
conn->m_factory = factory;
conn->m_factory = (struct ddsi_tran_factory *) factory;
conn->m_base.gv = factory->gv;
}
void ddsi_conn_disable_multiplexing (ddsi_tran_conn_t conn)
{
if (conn->m_disable_multiplexing_fn) {
if (conn->m_disable_multiplexing_fn)
(conn->m_disable_multiplexing_fn) (conn);
}
}
bool ddsi_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * loc)
@ -238,27 +235,27 @@ void ddsi_listener_free (ddsi_tran_listener_t listener)
}
}
int ddsi_is_mcaddr (const nn_locator_t *loc)
int ddsi_is_mcaddr (const struct q_globals *gv, const nn_locator_t *loc)
{
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind (loc->kind);
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind (gv, loc->kind);
return tran ? tran->m_is_mcaddr_fn (tran, loc) : 0;
}
int ddsi_is_ssm_mcaddr (const nn_locator_t *loc)
int ddsi_is_ssm_mcaddr (const struct q_globals *gv, const nn_locator_t *loc)
{
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind);
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(gv, loc->kind);
if (tran && tran->m_is_ssm_mcaddr_fn != 0)
return tran->m_is_ssm_mcaddr_fn (tran, loc);
return 0;
}
enum ddsi_nearby_address_result ddsi_is_nearby_address (const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[])
enum ddsi_nearby_address_result ddsi_is_nearby_address (const struct q_globals *gv, const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface interf[])
{
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind);
return tran ? tran->m_is_nearby_address_fn (tran, loc, ninterf, interf) : DNAR_DISTANT;
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(gv, loc->kind);
return tran ? tran->m_is_nearby_address_fn (tran, loc, ownloc, ninterf, interf) : DNAR_DISTANT;
}
enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc, const char *str)
enum ddsi_locator_from_string_result ddsi_locator_from_string (const struct q_globals *gv, nn_locator_t *loc, const char *str, ddsi_tran_factory_t default_factory)
{
const char *sep = strchr(str, '/');
ddsi_tran_factory_t tran;
@ -269,21 +266,21 @@ enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc
while (cur-- > str)
if (!isalnum((unsigned char)*cur) && *cur != '_')
return AFSR_INVALID;
tran = ddsi_factory_find_with_len(str, (size_t)(sep - str));
tran = ddsi_factory_find_with_len(gv, str, (size_t)(sep - str));
if (tran == NULL)
return AFSR_UNKNOWN;
} else {
/* FIXME: am I happy with defaulting it like this? */
tran = gv.m_factory;
tran = default_factory;
}
return tran->m_locator_from_string_fn (tran, loc, sep ? sep + 1 : str);
}
char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc)
char *ddsi_locator_to_string (const struct q_globals *gv, char *dst, size_t sizeof_dst, const nn_locator_t *loc)
{
/* FIXME: should add a "factory" for INVALID locators */
if (loc->kind != NN_LOCATOR_KIND_INVALID) {
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind);
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(gv, loc->kind);
int pos = snprintf (dst, sizeof_dst, "%s/", tran->m_typename);
if (0 < pos && (size_t)pos < sizeof_dst)
(void) tran->m_locator_to_string_fn (tran, dst + (size_t)pos, sizeof_dst - (size_t)pos, loc, 1);
@ -293,10 +290,10 @@ char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *
return dst;
}
char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_locator_t *loc)
char *ddsi_locator_to_string_no_port (const struct q_globals *gv, char *dst, size_t sizeof_dst, const nn_locator_t *loc)
{
if (loc->kind != NN_LOCATOR_KIND_INVALID) {
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(loc->kind);
ddsi_tran_factory_t tran = ddsi_factory_find_supported_kind(gv, loc->kind);
int pos = snprintf (dst, sizeof_dst, "%s/", tran->m_typename);
if (0 < pos && (size_t)pos < sizeof_dst)
(void) tran->m_locator_to_string_fn (tran, dst + (size_t)pos, sizeof_dst - (size_t)pos, loc, 0);
@ -306,7 +303,7 @@ char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_loc
return dst;
}
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, ddsrt_ifaddrs_t **interfs)
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, enum transport_selector transport_selector, ddsrt_ifaddrs_t **interfs)
{
return factory->m_enumerate_interfaces_fn (factory, interfs);
return factory->m_enumerate_interfaces_fn (factory, transport_selector, interfs);
}

View file

@ -27,30 +27,14 @@
#include "dds/ddsi/q_pcap.h"
#include "dds/ddsi/q_globals.h"
extern void ddsi_factory_conn_init (ddsi_tran_factory_t factory, ddsi_tran_conn_t conn);
typedef struct ddsi_tran_factory * ddsi_udp_factory_t;
typedef struct ddsi_udp_config
{
struct nn_group_membership *mship;
}
* ddsi_udp_config_t;
typedef struct ddsi_udp_conn
{
typedef struct ddsi_udp_conn {
struct ddsi_tran_conn m_base;
ddsrt_socket_t m_sock;
#if defined _WIN32
WSAEVENT m_sockEvent;
#endif
int m_diffserv;
}
* ddsi_udp_conn_t;
static struct ddsi_udp_config ddsi_udp_config_g;
static struct ddsi_tran_factory ddsi_udp_factory_g;
static ddsrt_atomic_uint32_t ddsi_udp_init_g = DDSRT_ATOMIC_UINT32_INIT(0);
} *ddsi_udp_conn_t;
static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
{
@ -86,13 +70,13 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
if (srcloc)
ddsi_ipaddr_to_loc(srcloc, (struct sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
if(gv.pcap_fp)
if(conn->m_base.gv->pcap_fp)
{
struct sockaddr_storage dest;
socklen_t dest_len = sizeof (dest);
if (ddsrt_getsockname (((ddsi_udp_conn_t) conn)->m_sock, (struct sockaddr *) &dest, &dest_len) != DDS_RETCODE_OK)
memset(&dest, 0, sizeof(dest));
write_pcap_received(gv.pcap_fp, now(), &src, &dest, buf, (size_t) ret);
write_pcap_received(conn->m_base.gv, now(), &src, &dest, buf, (size_t) ret);
}
/* Check for udp packet truncation */
@ -105,7 +89,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
char addrbuf[DDSI_LOCSTRLEN];
nn_locator_t tmp;
ddsi_ipaddr_to_loc(&tmp, (struct sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
ddsi_locator_to_string(addrbuf, sizeof(addrbuf), &tmp);
ddsi_locator_to_string(conn->m_base.gv, addrbuf, sizeof(addrbuf), &tmp);
DDS_WARNING("%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
}
}
@ -165,13 +149,13 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *d
} while ((rc == DDS_RETCODE_INTERRUPTED) ||
(rc == DDS_RETCODE_TRY_AGAIN) ||
(rc == DDS_RETCODE_NOT_ALLOWED && retry-- > 0));
if (ret > 0 && gv.pcap_fp)
if (ret > 0 && conn->m_base.gv->pcap_fp)
{
struct sockaddr_storage sa;
socklen_t alen = sizeof (sa);
if (ddsrt_getsockname (((ddsi_udp_conn_t) conn)->m_sock, (struct sockaddr *) &sa, &alen) != DDS_RETCODE_OK)
memset(&sa, 0, sizeof(sa));
write_pcap_sent (gv.pcap_fp, now (), &sa, &msg, (size_t) ret);
write_pcap_sent (conn->m_base.gv, now (), &sa, &msg, (size_t) ret);
}
else if (rc != DDS_RETCODE_OK &&
rc != DDS_RETCODE_NOT_ALLOWED &&
@ -199,22 +183,20 @@ static ddsrt_socket_t ddsi_udp_conn_handle (ddsi_tran_base_t base)
return ((ddsi_udp_conn_t) base)->m_sock;
}
static bool ddsi_udp_supports (int32_t kind)
static bool ddsi_udp_supports (const struct ddsi_tran_factory *fact, int32_t kind)
{
return
kind == ddsi_udp_factory_g.m_kind ||
(kind == NN_LOCATOR_KIND_UDPv4MCGEN && ddsi_udp_factory_g.m_kind == NN_LOCATOR_KIND_UDPv4);
return kind == fact->m_kind || (kind == NN_LOCATOR_KIND_UDPv4MCGEN && fact->m_kind == NN_LOCATOR_KIND_UDPv4);
}
static int ddsi_udp_conn_locator (ddsi_tran_base_t base, nn_locator_t *loc)
static int ddsi_udp_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t base, nn_locator_t *loc)
{
int ret = -1;
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) base;
if (uc->m_sock != DDSRT_INVALID_SOCKET)
{
loc->kind = ddsi_udp_factory_g.m_kind;
loc->kind = fact->m_kind;
loc->port = uc->m_base.m_base.m_port;
memcpy(loc->address, gv.extloc.address, sizeof (loc->address));
memcpy(loc->address, uc->m_base.m_base.gv->extloc.address, sizeof (loc->address));
ret = 0;
}
return ret;
@ -236,11 +218,7 @@ static unsigned short get_socket_port (ddsrt_socket_t socket)
return ddsrt_sockaddr_get_port((struct sockaddr *)&addr);
}
static ddsi_tran_conn_t ddsi_udp_create_conn
(
uint32_t port,
ddsi_tran_qos_t qos
)
static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t port, ddsi_tran_qos_t qos)
{
int ret;
ddsrt_socket_t sock;
@ -249,13 +227,7 @@ static ddsi_tran_conn_t ddsi_udp_create_conn
/* If port is zero, need to create dynamic port */
ret = make_socket
(
&sock,
(unsigned short) port,
false,
mcast
);
ret = make_socket (&sock, (unsigned short) port, false, mcast, fact->gv);
if (ret == 0)
{
@ -269,16 +241,16 @@ static ddsi_tran_conn_t ddsi_udp_create_conn
WSAEventSelect(uc->m_sock, uc->m_sockEvent, FD_WRITE);
#endif
ddsi_factory_conn_init (&ddsi_udp_factory_g, &uc->m_base);
ddsi_factory_conn_init (fact, &uc->m_base);
uc->m_base.m_base.m_port = get_socket_port (sock);
uc->m_base.m_base.m_trantype = DDSI_TRAN_CONN;
uc->m_base.m_base.m_multicast = mcast;
uc->m_base.m_base.m_handle_fn = ddsi_udp_conn_handle;
uc->m_base.m_base.m_locator_fn = ddsi_udp_conn_locator;
uc->m_base.m_read_fn = ddsi_udp_conn_read;
uc->m_base.m_write_fn = ddsi_udp_conn_write;
uc->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing;
uc->m_base.m_locator_fn = ddsi_udp_conn_locator;
DDS_TRACE
(
@ -288,7 +260,7 @@ static ddsi_tran_conn_t ddsi_udp_create_conn
uc->m_base.m_base.m_port
);
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
if ((uc->m_diffserv != 0) && (ddsi_udp_factory_g.m_kind == NN_LOCATOR_KIND_UDPv4))
if ((uc->m_diffserv != 0) && (fact->m_kind == NN_LOCATOR_KIND_UDPv4))
{
dds_return_t rc;
rc = ddsrt_setsockopt(sock, IPPROTO_IP, IP_TOS, (char *)&uc->m_diffserv, sizeof(uc->m_diffserv));
@ -299,7 +271,7 @@ static ddsi_tran_conn_t ddsi_udp_create_conn
}
else
{
if (config.participantIndex != PARTICIPANT_INDEX_AUTO)
if (fact->gv->config.participantIndex != PARTICIPANT_INDEX_AUTO)
{
DDS_ERROR
(
@ -319,7 +291,7 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
struct sockaddr_storage mcip;
ddsi_ipaddr_from_loc(&mcip, mcloc);
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_UDP6)
if (mcloc->kind == NN_LOCATOR_KIND_UDPv6)
{
struct ipv6_mreq ipv6mreq;
memset (&ipv6mreq, 0, sizeof (ipv6mreq));
@ -349,7 +321,7 @@ static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
ddsi_ipaddr_from_loc(&mcip, mcloc);
ddsi_ipaddr_from_loc(&srcip, srcloc);
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_UDP6)
if (mcloc->kind == NN_LOCATOR_KIND_UDPv6)
{
struct group_source_req gsr;
memset (&gsr, 0, sizeof (gsr));
@ -466,7 +438,7 @@ static int ddsi_udp_is_ssm_mcaddr (const ddsi_tran_factory_t tran, const nn_loca
static enum ddsi_locator_from_string_result ddsi_udp_address_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str)
{
return ddsi_ipaddr_from_string(tran, loc, str, ddsi_udp_factory_g.m_kind);
return ddsi_ipaddr_from_string (tran, loc, str, tran->m_kind);
}
static char *ddsi_udp_locator_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port)
@ -497,56 +469,45 @@ static char *ddsi_udp_locator_to_string (ddsi_tran_factory_t tran, char *dst, si
}
}
static void ddsi_udp_fini (void)
static void ddsi_udp_fini (ddsi_tran_factory_t fact)
{
if (ddsrt_atomic_dec32_nv (&ddsi_udp_init_g) == 0) {
free_group_membership (ddsi_udp_config_g.mship);
memset (&ddsi_udp_factory_g, 0, sizeof (ddsi_udp_factory_g));
DDS_LOG (DDS_LC_CONFIG, "udp finalized\n");
}
DDS_LOG (DDS_LC_CONFIG, "udp finalized\n");
ddsrt_free (fact);
}
int ddsi_udp_init (void)
int ddsi_udp_init (struct q_globals *gv)
{
/* TODO: proper init_once. Either the call doesn't need it, in which case
* this can be removed. Or the call does, in which case it should be done right.
* The lack of locking suggests it isn't needed.
*/
if (ddsrt_atomic_inc32_nv (&ddsi_udp_init_g) == 1)
{
memset (&ddsi_udp_factory_g, 0, sizeof (ddsi_udp_factory_g));
ddsi_udp_factory_g.m_free_fn = ddsi_udp_fini;
ddsi_udp_factory_g.m_kind = NN_LOCATOR_KIND_UDPv4;
ddsi_udp_factory_g.m_typename = "udp";
ddsi_udp_factory_g.m_default_spdp_address = "udp/239.255.0.1";
ddsi_udp_factory_g.m_connless = true;
ddsi_udp_factory_g.m_supports_fn = ddsi_udp_supports;
ddsi_udp_factory_g.m_create_conn_fn = ddsi_udp_create_conn;
ddsi_udp_factory_g.m_release_conn_fn = ddsi_udp_release_conn;
ddsi_udp_factory_g.m_join_mc_fn = ddsi_udp_join_mc;
ddsi_udp_factory_g.m_leave_mc_fn = ddsi_udp_leave_mc;
ddsi_udp_factory_g.m_is_mcaddr_fn = ddsi_udp_is_mcaddr;
struct ddsi_tran_factory *fact = ddsrt_malloc (sizeof (*fact));
memset (fact, 0, sizeof (*fact));
fact->gv = gv;
fact->m_free_fn = ddsi_udp_fini;
fact->m_kind = NN_LOCATOR_KIND_UDPv4;
fact->m_typename = "udp";
fact->m_default_spdp_address = "udp/239.255.0.1";
fact->m_connless = true;
fact->m_supports_fn = ddsi_udp_supports;
fact->m_create_conn_fn = ddsi_udp_create_conn;
fact->m_release_conn_fn = ddsi_udp_release_conn;
fact->m_join_mc_fn = ddsi_udp_join_mc;
fact->m_leave_mc_fn = ddsi_udp_leave_mc;
fact->m_is_mcaddr_fn = ddsi_udp_is_mcaddr;
#ifdef DDSI_INCLUDE_SSM
ddsi_udp_factory_g.m_is_ssm_mcaddr_fn = ddsi_udp_is_ssm_mcaddr;
fact->m_is_ssm_mcaddr_fn = ddsi_udp_is_ssm_mcaddr;
#endif
ddsi_udp_factory_g.m_is_nearby_address_fn = ddsi_ipaddr_is_nearby_address;
ddsi_udp_factory_g.m_locator_from_string_fn = ddsi_udp_address_from_string;
ddsi_udp_factory_g.m_locator_to_string_fn = ddsi_udp_locator_to_string;
ddsi_udp_factory_g.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
fact->m_is_nearby_address_fn = ddsi_ipaddr_is_nearby_address;
fact->m_locator_from_string_fn = ddsi_udp_address_from_string;
fact->m_locator_to_string_fn = ddsi_udp_locator_to_string;
fact->m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_UDP6)
{
ddsi_udp_factory_g.m_kind = NN_LOCATOR_KIND_UDPv6;
ddsi_udp_factory_g.m_typename = "udp6";
ddsi_udp_factory_g.m_default_spdp_address = "udp6/ff02::ffff:239.255.0.1";
}
if (gv->config.transport_selector == TRANS_UDP6)
{
fact->m_kind = NN_LOCATOR_KIND_UDPv6;
fact->m_typename = "udp6";
fact->m_default_spdp_address = "udp6/ff02::ffff:239.255.0.1";
}
#endif
ddsi_udp_config_g.mship = new_group_membership();
ddsi_factory_add (&ddsi_udp_factory_g);
DDS_LOG(DDS_LC_CONFIG, "udp initialized\n");
}
ddsi_factory_add (gv, fact);
DDS_LOG(DDS_LC_CONFIG, "udp initialized\n");
return 0;
}

View file

@ -18,6 +18,7 @@
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/misc.h"
#include "dds/ddsrt/avl.h"
#include "dds/ddsi/ddsi_tran.h"
#include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_config.h"
@ -43,12 +44,12 @@ static int compare_locators_vwrap (const void *va, const void *vb);
static const ddsrt_avl_ctreedef_t addrset_treedef =
DDSRT_AVL_CTREEDEF_INITIALIZER (offsetof (struct addrset_node, avlnode), offsetof (struct addrset_node, loc), compare_locators_vwrap, 0);
static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int port_mode, const char *msgtag, int req_mc, int mcgen_base, int mcgen_count, int mcgen_idx)
static int add_addresses_to_addrset_1 (const struct q_globals *gv, struct addrset *as, const char *ip, int port_mode, const char *msgtag, int req_mc, int mcgen_base, int mcgen_count, int mcgen_idx)
{
char buf[DDSI_LOCSTRLEN];
nn_locator_t loc;
switch (ddsi_locator_from_string(&loc, ip))
switch (ddsi_locator_from_string(gv, &loc, ip, gv->m_factory))
{
case AFSR_OK:
break;
@ -63,7 +64,7 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
return -1;
}
if (req_mc && !ddsi_is_mcaddr (&loc))
if (req_mc && !ddsi_is_mcaddr (gv, &loc))
{
DDS_ERROR ("%s: %s: not a multicast address\n", msgtag, ip);
return -1;
@ -71,7 +72,7 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
if (mcgen_base == -1 && mcgen_count == -1 && mcgen_idx == -1)
;
else if (loc.kind == NN_LOCATOR_KIND_UDPv4 && ddsi_is_mcaddr(&loc) && mcgen_base >= 0 && mcgen_count > 0 && mcgen_base + mcgen_count < 28 && mcgen_idx >= 0 && mcgen_idx < mcgen_count)
else if (loc.kind == NN_LOCATOR_KIND_UDPv4 && ddsi_is_mcaddr(gv, &loc) && mcgen_base >= 0 && mcgen_count > 0 && mcgen_base + mcgen_count < 28 && mcgen_idx >= 0 && mcgen_idx < mcgen_count)
{
nn_udpv4mcgen_address_t x;
memset(&x, 0, sizeof(x));
@ -93,34 +94,34 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
if (port_mode >= 0)
{
loc.port = (unsigned) port_mode;
DDS_LOG(DDS_LC_CONFIG, "%s: add %s", msgtag, ddsi_locator_to_string(buf, sizeof(buf), &loc));
add_to_addrset (as, &loc);
DDS_LOG(DDS_LC_CONFIG, "%s: add %s", msgtag, ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
add_to_addrset (gv, as, &loc);
}
else
{
DDS_LOG(DDS_LC_CONFIG, "%s: add ", msgtag);
if (!ddsi_is_mcaddr (&loc))
if (!ddsi_is_mcaddr (gv, &loc))
{
int i;
for (i = 0; i <= config.maxAutoParticipantIndex; i++)
for (i = 0; i <= gv->config.maxAutoParticipantIndex; i++)
{
int port = config.port_base + config.port_dg * config.domainId.value + i * config.port_pg + config.port_d1;
int port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + i * gv->config.port_pg + gv->config.port_d1;
loc.port = (unsigned) port;
if (i == 0)
DDS_LOG(DDS_LC_CONFIG, "%s", ddsi_locator_to_string(buf, sizeof(buf), &loc));
DDS_LOG(DDS_LC_CONFIG, "%s", ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
else
DDS_LOG(DDS_LC_CONFIG, ", :%d", port);
add_to_addrset (as, &loc);
add_to_addrset (gv, as, &loc);
}
}
else
{
int port = port_mode;
if (port == -1)
port = config.port_base + config.port_dg * config.domainId.value + config.port_d0;
port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d0;
loc.port = (unsigned) port;
DDS_LOG(DDS_LC_CONFIG, "%s", ddsi_locator_to_string(buf, sizeof(buf), &loc));
add_to_addrset (as, &loc);
DDS_LOG(DDS_LC_CONFIG, "%s", ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
add_to_addrset (gv, as, &loc);
}
}
@ -128,7 +129,7 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
return 0;
}
int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc)
int add_addresses_to_addrset (const struct q_globals *gv, struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc)
{
/* port_mode: -1 => take from string, if 0 & unicast, add for a range of participant indices;
port_mode >= 0 => always set port to port_mode
@ -143,7 +144,7 @@ int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mo
{
int port = 0, pos;
int mcgen_base = -1, mcgen_count = -1, mcgen_idx = -1;
if (config.transport_selector == TRANS_UDP || config.transport_selector == TRANS_TCP)
if (gv->config.transport_selector == TRANS_UDP || gv->config.transport_selector == TRANS_TCP)
{
if (port_mode == -1 && sscanf (a, "%[^:]:%d%n", ip, &port, &pos) == 2 && a[pos] == 0)
; /* XYZ:PORT */
@ -169,7 +170,7 @@ int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mo
}
if ((port > 0 && port <= 65535) || (port_mode == -1 && port == -1)) {
if (add_addresses_to_addrset_1 (as, ip, port, msgtag, req_mc, mcgen_base, mcgen_count, mcgen_idx) < 0)
if (add_addresses_to_addrset_1 (gv, as, ip, port, msgtag, req_mc, mcgen_base, mcgen_count, mcgen_idx) < 0)
goto error;
} else {
DDS_ERROR("%s: %s: port %d invalid\n", msgtag, a, port);
@ -245,14 +246,14 @@ int is_unspec_locator (const nn_locator_t *loc)
}
#ifdef DDSI_INCLUDE_SSM
int addrset_contains_ssm (const struct addrset *as)
int addrset_contains_ssm (const struct q_globals *gv, const struct addrset *as)
{
struct addrset_node *n;
ddsrt_avl_citer_t it;
LOCK (as);
for (n = ddsrt_avl_citer_first (&addrset_treedef, &as->mcaddrs, &it); n; n = ddsrt_avl_citer_next (&it))
{
if (ddsi_is_ssm_mcaddr (&n->loc))
if (ddsi_is_ssm_mcaddr (gv, &n->loc))
{
UNLOCK (as);
return 1;
@ -262,14 +263,14 @@ int addrset_contains_ssm (const struct addrset *as)
return 0;
}
int addrset_any_ssm (const struct addrset *as, nn_locator_t *dst)
int addrset_any_ssm (const struct q_globals *gv, const struct addrset *as, nn_locator_t *dst)
{
struct addrset_node *n;
ddsrt_avl_citer_t it;
LOCK (as);
for (n = ddsrt_avl_citer_first (&addrset_treedef, &as->mcaddrs, &it); n; n = ddsrt_avl_citer_next (&it))
{
if (ddsi_is_ssm_mcaddr (&n->loc))
if (ddsi_is_ssm_mcaddr (gv, &n->loc))
{
*dst = n->loc;
UNLOCK (as);
@ -280,14 +281,14 @@ int addrset_any_ssm (const struct addrset *as, nn_locator_t *dst)
return 0;
}
int addrset_any_non_ssm_mc (const struct addrset *as, nn_locator_t *dst)
int addrset_any_non_ssm_mc (const struct q_globals *gv, const struct addrset *as, nn_locator_t *dst)
{
struct addrset_node *n;
ddsrt_avl_citer_t it;
LOCK (as);
for (n = ddsrt_avl_citer_first (&addrset_treedef, &as->mcaddrs, &it); n; n = ddsrt_avl_citer_next (&it))
{
if (!ddsi_is_ssm_mcaddr (&n->loc))
if (!ddsi_is_ssm_mcaddr (gv, &n->loc))
{
*dst = n->loc;
UNLOCK (as);
@ -308,12 +309,12 @@ int addrset_purge (struct addrset *as)
return 0;
}
void add_to_addrset (struct addrset *as, const nn_locator_t *loc)
void add_to_addrset (const struct q_globals *gv, struct addrset *as, const nn_locator_t *loc)
{
if (!is_unspec_locator (loc))
{
ddsrt_avl_ipath_t path;
ddsrt_avl_ctree_t *tree = ddsi_is_mcaddr (loc) ? &as->mcaddrs : &as->ucaddrs;
ddsrt_avl_ctree_t *tree = ddsi_is_mcaddr (gv, loc) ? &as->mcaddrs : &as->ucaddrs;
LOCK (as);
if (ddsrt_avl_clookup_ipath (&addrset_treedef, tree, loc, &path) == NULL)
{
@ -325,10 +326,10 @@ void add_to_addrset (struct addrset *as, const nn_locator_t *loc)
}
}
void remove_from_addrset (struct addrset *as, const nn_locator_t *loc)
void remove_from_addrset (const struct q_globals *gv, struct addrset *as, const nn_locator_t *loc)
{
ddsrt_avl_dpath_t path;
ddsrt_avl_ctree_t *tree = ddsi_is_mcaddr (loc) ? &as->mcaddrs : &as->ucaddrs;
ddsrt_avl_ctree_t *tree = ddsi_is_mcaddr (gv, loc) ? &as->mcaddrs : &as->ucaddrs;
struct addrset_node *n;
LOCK (as);
if ((n = ddsrt_avl_clookup_dpath (&addrset_treedef, tree, loc, &path)) != NULL)
@ -339,51 +340,51 @@ void remove_from_addrset (struct addrset *as, const nn_locator_t *loc)
UNLOCK (as);
}
void copy_addrset_into_addrset_uc (struct addrset *as, const struct addrset *asadd)
void copy_addrset_into_addrset_uc (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd)
{
struct addrset_node *n;
ddsrt_avl_citer_t it;
LOCK (asadd);
for (n = ddsrt_avl_citer_first (&addrset_treedef, &asadd->ucaddrs, &it); n; n = ddsrt_avl_citer_next (&it))
add_to_addrset (as, &n->loc);
add_to_addrset (gv, as, &n->loc);
UNLOCK (asadd);
}
void copy_addrset_into_addrset_mc (struct addrset *as, const struct addrset *asadd)
void copy_addrset_into_addrset_mc (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd)
{
struct addrset_node *n;
ddsrt_avl_citer_t it;
LOCK (asadd);
for (n = ddsrt_avl_citer_first (&addrset_treedef, &asadd->mcaddrs, &it); n; n = ddsrt_avl_citer_next (&it))
add_to_addrset (as, &n->loc);
add_to_addrset (gv, as, &n->loc);
UNLOCK (asadd);
}
void copy_addrset_into_addrset (struct addrset *as, const struct addrset *asadd)
void copy_addrset_into_addrset (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd)
{
copy_addrset_into_addrset_uc (as, asadd);
copy_addrset_into_addrset_mc (as, asadd);
copy_addrset_into_addrset_uc (gv, as, asadd);
copy_addrset_into_addrset_mc (gv, as, asadd);
}
#ifdef DDSI_INCLUDE_SSM
void copy_addrset_into_addrset_no_ssm_mc (struct addrset *as, const struct addrset *asadd)
void copy_addrset_into_addrset_no_ssm_mc (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd)
{
struct addrset_node *n;
ddsrt_avl_citer_t it;
LOCK (asadd);
for (n = ddsrt_avl_citer_first (&addrset_treedef, &asadd->mcaddrs, &it); n; n = ddsrt_avl_citer_next (&it))
{
if (!ddsi_is_ssm_mcaddr (&n->loc))
add_to_addrset (as, &n->loc);
if (!ddsi_is_ssm_mcaddr (gv, &n->loc))
add_to_addrset (gv, as, &n->loc);
}
UNLOCK (asadd);
}
void copy_addrset_into_addrset_no_ssm (struct addrset *as, const struct addrset *asadd)
void copy_addrset_into_addrset_no_ssm (const struct q_globals *gv, struct addrset *as, const struct addrset *asadd)
{
copy_addrset_into_addrset_uc (as, asadd);
copy_addrset_into_addrset_no_ssm_mc (as, asadd);
copy_addrset_into_addrset_uc (gv, as, asadd);
copy_addrset_into_addrset_no_ssm_mc (gv, as, asadd);
}
#endif
@ -548,6 +549,7 @@ int addrset_forone (struct addrset *as, addrset_forone_fun_t f, void *arg)
struct log_addrset_helper_arg
{
uint32_t tf;
struct q_globals *gv;
};
static void log_addrset_helper (const nn_locator_t *n, void *varg)
@ -555,15 +557,16 @@ static void log_addrset_helper (const nn_locator_t *n, void *varg)
const struct log_addrset_helper_arg *arg = varg;
char buf[DDSI_LOCSTRLEN];
if (dds_get_log_mask() & arg->tf)
DDS_LOG(arg->tf, " %s", ddsi_locator_to_string(buf, sizeof(buf), n));
DDS_LOG(arg->tf, " %s", ddsi_locator_to_string(arg->gv, buf, sizeof(buf), n));
}
void nn_log_addrset (uint32_t tf, const char *prefix, const struct addrset *as)
void nn_log_addrset (struct q_globals *gv, uint32_t tf, const char *prefix, const struct addrset *as)
{
if (dds_get_log_mask() & tf)
{
struct log_addrset_helper_arg arg;
arg.tf = tf;
arg.gv = gv;
DDS_LOG(tf, "%s", prefix);
addrset_forall ((struct addrset *) as, log_addrset_helper, &arg); /* drop const, we know it is */
}

View file

@ -843,8 +843,6 @@ static const struct cfgelem root_cfgelem = {
#undef ABSOFF
#undef CO
struct config config;
static const struct unit unittab_duration[] = {
{ "ns", 1 },
{ "us", 1000 },

View file

@ -43,7 +43,7 @@
#include "dds/ddsi/ddsi_serdata_default.h"
#include "dds/ddsi/q_feature_check.h"
static int get_locator (nn_locator_t *loc, const nn_locators_t *locs, int uc_same_subnet)
static int get_locator (const struct q_globals *gv, nn_locator_t *loc, const nn_locators_t *locs, int uc_same_subnet)
{
struct nn_locators_one *l;
nn_locator_t first, samenet;
@ -52,7 +52,7 @@ static int get_locator (nn_locator_t *loc, const nn_locators_t *locs, int uc_sam
memset (&samenet, 0, sizeof (samenet));
/* Special case UDPv4 MC address generators - there is a bit of an type mismatch between an address generator (i.e., a set of addresses) and an address ... Whoever uses them is supposed to know that that is what he wants, so we simply given them priority. */
if (ddsi_factory_supports (gv.m_factory, NN_LOCATOR_KIND_UDPv4))
if (ddsi_factory_supports (gv->m_factory, NN_LOCATOR_KIND_UDPv4))
{
for (l = locs->first; l != NULL; l = l->next)
{
@ -71,20 +71,20 @@ static int get_locator (nn_locator_t *loc, const nn_locators_t *locs, int uc_sam
{
/* Skip locators of the wrong kind */
if (! ddsi_factory_supports (gv.m_factory, l->loc.kind))
if (! ddsi_factory_supports (gv->m_factory, l->loc.kind))
{
continue;
}
if (l->loc.kind == NN_LOCATOR_KIND_UDPv4 && gv.extmask.kind != NN_LOCATOR_KIND_INVALID)
if (l->loc.kind == NN_LOCATOR_KIND_UDPv4 && gv->extmask.kind != NN_LOCATOR_KIND_INVALID)
{
/* If the examined locator is in the same subnet as our own
external IP address, this locator will be translated into one
in the same subnet as our own local ip and selected. */
struct in_addr tmp4 = *((struct in_addr *) (l->loc.address + 12));
const struct in_addr ownip = *((struct in_addr *) (gv.ownloc.address + 12));
const struct in_addr extip = *((struct in_addr *) (gv.extloc.address + 12));
const struct in_addr extmask = *((struct in_addr *) (gv.extmask.address + 12));
const struct in_addr ownip = *((struct in_addr *) (gv->ownloc.address + 12));
const struct in_addr extip = *((struct in_addr *) (gv->extloc.address + 12));
const struct in_addr extmask = *((struct in_addr *) (gv->extmask.address + 12));
if ((tmp4.s_addr & extmask.s_addr) == (extip.s_addr & extmask.s_addr))
{
@ -104,7 +104,7 @@ static int get_locator (nn_locator_t *loc, const nn_locators_t *locs, int uc_sam
addresses unles we're in "link-local" mode ourselves. Then
we just hope for the best. */
const struct in6_addr *ip6 = (const struct in6_addr *) l->loc.address;
if (!gv.ipv6_link_local && IN6_IS_ADDR_LINKLOCAL (ip6))
if (!gv->ipv6_link_local && IN6_IS_ADDR_LINKLOCAL (ip6))
continue;
}
#endif
@ -115,7 +115,7 @@ static int get_locator (nn_locator_t *loc, const nn_locators_t *locs, int uc_sam
first_set = 1;
}
switch (ddsi_is_nearby_address(&l->loc, (size_t)gv.n_interfaces, gv.interfaces))
switch (ddsi_is_nearby_address(gv, &l->loc, &gv->ownloc, (size_t) gv->n_interfaces, gv->interfaces))
{
case DNAR_DISTANT:
break;
@ -157,14 +157,14 @@ static int get_locator (nn_locator_t *loc, const nn_locators_t *locs, int uc_sam
***
*****************************************************************************/
static void maybe_add_pp_as_meta_to_as_disc (const struct addrset *as_meta)
static void maybe_add_pp_as_meta_to_as_disc (struct q_globals *gv, const struct addrset *as_meta)
{
if (addrset_empty_mc (as_meta) || !(config.allowMulticast & AMC_SPDP))
if (addrset_empty_mc (as_meta) || !(gv->config.allowMulticast & AMC_SPDP))
{
nn_locator_t loc;
if (addrset_any_uc (as_meta, &loc))
{
add_to_addrset (gv.as_disc, &loc);
add_to_addrset (gv, gv->as_disc, &loc);
}
}
}
@ -175,7 +175,7 @@ static int write_mpayload (struct writer *wr, int alive, nn_parameterid_t keypar
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 = ddsi_serdata_from_sample (wr->e.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 (ts1, NULL, wr, serdata);
@ -211,7 +211,7 @@ int spdp_write (struct participant *pp)
terribly important, the msg will grow as needed, address space is
essentially meaningless because we only use the message to
construct the payload. */
mpayload = nn_xmsg_new (gv.xmsgpool, &pp->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
nn_plist_init_empty (&ps);
ps.present |= PP_PARTICIPANT_GUID | PP_BUILTIN_ENDPOINT_SET |
@ -235,24 +235,24 @@ int spdp_write (struct participant *pp)
def_uni_loc_one.next = NULL;
meta_uni_loc_one.next = NULL;
if (config.many_sockets_mode == MSM_MANY_UNICAST)
if (pp->e.gv->config.many_sockets_mode == MSM_MANY_UNICAST)
{
def_uni_loc_one.loc = pp->m_locator;
meta_uni_loc_one.loc = pp->m_locator;
}
else
{
def_uni_loc_one.loc = gv.loc_default_uc;
meta_uni_loc_one.loc = gv.loc_meta_uc;
def_uni_loc_one.loc = pp->e.gv->loc_default_uc;
meta_uni_loc_one.loc = pp->e.gv->loc_meta_uc;
}
if (config.publish_uc_locators)
if (pp->e.gv->config.publish_uc_locators)
{
ps.present |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR;
ps.aliased |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR;
}
if (config.allowMulticast)
if (pp->e.gv->config.allowMulticast)
{
int include = 0;
#ifdef DDSI_INCLUDE_SSM
@ -260,12 +260,12 @@ int spdp_write (struct participant *pp)
we will simply advertise it. The recipients better understand
it means the writers will publish to address and the readers
favour SSM. */
if (ddsi_is_ssm_mcaddr (&gv.loc_default_mc))
include = (config.allowMulticast & AMC_SSM) != 0;
if (ddsi_is_ssm_mcaddr (pp->e.gv, &pp->e.gv->loc_default_mc))
include = (pp->e.gv->config.allowMulticast & AMC_SSM) != 0;
else
include = (config.allowMulticast & AMC_ASM) != 0;
include = (pp->e.gv->config.allowMulticast & AMC_ASM) != 0;
#else
if (config.allowMulticast & AMC_ASM)
if (pp->e.gv->config.allowMulticast & AMC_ASM)
include = 1;
#endif
if (include)
@ -279,9 +279,9 @@ int spdp_write (struct participant *pp)
ps.metatraffic_multicast_locators.first =
ps.metatraffic_multicast_locators.last = &meta_multi_loc_one;
def_multi_loc_one.next = NULL;
def_multi_loc_one.loc = gv.loc_default_mc;
def_multi_loc_one.loc = pp->e.gv->loc_default_mc;
meta_multi_loc_one.next = NULL;
meta_multi_loc_one.loc = gv.loc_meta_mc;
meta_multi_loc_one.loc = pp->e.gv->loc_meta_mc;
}
}
ps.participant_lease_duration = pp->lease_duration;
@ -295,12 +295,12 @@ int spdp_write (struct participant *pp)
NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG |
NN_PRISMTECH_FL_PTBES_FIXED_0 |
NN_PRISMTECH_FL_SUPPORTS_STATUSINFOX;
if (config.besmode == BESMODE_MINIMAL)
if (pp->e.gv->config.besmode == BESMODE_MINIMAL)
ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_MINIMAL_BES_MODE;
ddsrt_mutex_lock (&gv.privileged_pp_lock);
ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock);
if (pp->is_ddsi2_pp)
ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2;
ddsrt_mutex_unlock (&gv.privileged_pp_lock);
ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock);
ddsrt_gethostname(node, sizeof(node)-1);
node[sizeof(node)-1] = '\0';
@ -311,8 +311,8 @@ int spdp_write (struct participant *pp)
}
/* Participant QoS's insofar as they are set, different from the default, and mapped to the SPDP data, rather than to the PrismTech-specific CMParticipant endpoint. Currently, that means just USER_DATA. */
qosdiff = nn_xqos_delta (&pp->plist->qos, &gv.default_plist_pp.qos, QP_USER_DATA);
if (config.explicitly_publish_qos_set_to_default)
qosdiff = nn_xqos_delta (&pp->plist->qos, &pp->e.gv->default_plist_pp.qos, QP_USER_DATA);
if (pp->e.gv->config.explicitly_publish_qos_set_to_default)
qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
assert (ps.qos.present == 0);
@ -339,7 +339,7 @@ int spdp_dispose_unregister (struct participant *pp)
return 0;
}
mpayload = nn_xmsg_new (gv.xmsgpool, &pp->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
nn_plist_init_empty (&ps);
ps.present |= PP_PARTICIPANT_GUID;
ps.participant_guid = pp->e.guid;
@ -381,27 +381,27 @@ static unsigned pseudo_random_delay (const nn_guid_t *x, const nn_guid_t *y, nn_
return (unsigned) (m >> 32);
}
static void respond_to_spdp (const nn_guid_t *dest_proxypp_guid)
static void respond_to_spdp (const struct q_globals *gv, const nn_guid_t *dest_proxypp_guid)
{
struct ephash_enum_participant est;
struct participant *pp;
nn_mtime_t tnow = now_mt ();
ephash_enum_participant_init (&est);
ephash_enum_participant_init (&est, gv->guid_hash);
while ((pp = ephash_enum_participant_next (&est)) != NULL)
{
/* delay_base has 32 bits, so delay_norm is approximately 1s max;
delay_max <= 1s by config checks */
delay_max <= 1s by gv.config checks */
unsigned delay_base = pseudo_random_delay (&pp->e.guid, dest_proxypp_guid, tnow);
unsigned delay_norm = delay_base >> 2;
int64_t delay_max_ms = config.spdp_response_delay_max / 1000000;
int64_t delay_max_ms = gv->config.spdp_response_delay_max / 1000000;
int64_t delay = (int64_t) delay_norm * delay_max_ms / 1000;
nn_mtime_t tsched = add_duration_to_mtime (tnow, delay);
DDS_TRACE(" %"PRId64, delay);
if (!config.unicast_response_to_spdp_messages)
if (!pp->e.gv->config.unicast_response_to_spdp_messages)
/* pp can't reach gc_delete_participant => can safely reschedule */
resched_xevent_if_earlier (pp->spdp_xevent, tsched);
else
qxev_spdp (tsched, &pp->e.guid, dest_proxypp_guid);
qxev_spdp (gv->xevents, tsched, &pp->e.guid, dest_proxypp_guid);
}
ephash_enum_participant_fini (&est);
}
@ -418,7 +418,7 @@ static int handle_SPDP_dead (const struct receiver_state *rst, nn_wctime_t times
guid = datap->participant_guid;
DDS_LOG(DDS_LC_DISCOVERY, " %"PRIx32":%"PRIx32":%"PRIx32":%"PRIx32, PGUID (guid));
assert (guid.entityid.u == NN_ENTITYID_PARTICIPANT);
if (delete_proxy_participant_by_guid (&guid, timestamp, 0) < 0)
if (delete_proxy_participant_by_guid (rst->gv, &guid, timestamp, 0) < 0)
{
DDS_LOG(DDS_LC_DISCOVERY, " unknown");
}
@ -434,31 +434,31 @@ static int handle_SPDP_dead (const struct receiver_state *rst, nn_wctime_t times
return 1;
}
static void allowmulticast_aware_add_to_addrset (struct addrset *as, const nn_locator_t *loc)
static void allowmulticast_aware_add_to_addrset (const struct q_globals *gv, uint32_t allow_multicast, struct addrset *as, const nn_locator_t *loc)
{
#if DDSI_INCLUDE_SSM
if (ddsi_is_ssm_mcaddr (loc))
if (ddsi_is_ssm_mcaddr (gv, loc))
{
if (!(config.allowMulticast & AMC_SSM))
if (!(allow_multicast & AMC_SSM))
return;
}
else if (ddsi_is_mcaddr (loc))
else if (ddsi_is_mcaddr (gv, loc))
{
if (!(config.allowMulticast & AMC_ASM))
if (!(allow_multicast & AMC_ASM))
return;
}
#else
if (ddsi_is_mcaddr (loc) && !(config.allowMulticast & AMC_ASM))
if (ddsi_is_mcaddr (gv, loc) && !(allow_multicast & AMC_ASM))
return;
#endif
add_to_addrset (as, loc);
add_to_addrset (gv, as, loc);
}
static struct proxy_participant *find_ddsi2_proxy_participant (const nn_guid_t *ppguid)
static struct proxy_participant *find_ddsi2_proxy_participant (const struct ephash *guid_hash, const nn_guid_t *ppguid)
{
struct ephash_enum_proxy_participant it;
struct proxy_participant *pp;
ephash_enum_proxy_participant_init (&it);
ephash_enum_proxy_participant_init (&it, guid_hash);
while ((pp = ephash_enum_proxy_participant_next (&it)) != NULL)
{
if (vendor_is_eclipse_or_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ppguid->prefix.u[0] && pp->is_ddsi2_pp)
@ -468,15 +468,15 @@ static struct proxy_participant *find_ddsi2_proxy_participant (const nn_guid_t *
return pp;
}
static void make_participants_dependent_on_ddsi2 (const nn_guid_t *ddsi2guid, nn_wctime_t timestamp)
static void make_participants_dependent_on_ddsi2 (struct q_globals *gv, const nn_guid_t *ddsi2guid, nn_wctime_t timestamp)
{
struct ephash_enum_proxy_participant it;
struct proxy_participant *pp, *d2pp;
struct lease *d2pp_lease;
if ((d2pp = ephash_lookup_proxy_participant_guid (ddsi2guid)) == NULL)
if ((d2pp = ephash_lookup_proxy_participant_guid (gv->guid_hash, ddsi2guid)) == NULL)
return;
d2pp_lease = ddsrt_atomic_ldvoidp (&d2pp->lease);
ephash_enum_proxy_participant_init (&it);
ephash_enum_proxy_participant_init (&it, gv->guid_hash);
while ((pp = ephash_enum_proxy_participant_next (&it)) != NULL)
{
if (vendor_is_eclipse_or_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ddsi2guid->prefix.u[0] && !pp->is_ddsi2_pp)
@ -488,7 +488,7 @@ static void make_participants_dependent_on_ddsi2 (const nn_guid_t *ddsi2guid, nn
proxy_participant_reassign_lease (pp, d2pp_lease);
DDS_TRACE("\n");
if (ephash_lookup_proxy_participant_guid (ddsi2guid) == NULL)
if (ephash_lookup_proxy_participant_guid (gv->guid_hash, ddsi2guid) == NULL)
{
/* If DDSI2 has been deleted here (i.e., very soon after
having been created), we don't know whether pp will be
@ -502,7 +502,7 @@ static void make_participants_dependent_on_ddsi2 (const nn_guid_t *ddsi2guid, nn
if (pp != NULL)
{
DDS_TRACE("make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n", PGUID (*ddsi2guid), PGUID (pp->e.guid));
delete_proxy_participant_by_guid (&pp->e.guid, timestamp, 1);
delete_proxy_participant_by_guid (gv, &pp->e.guid, timestamp, 1);
}
}
@ -537,7 +537,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER))
!= (NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER |
NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER)) &&
config.assume_rti_has_pmd_endpoints)
rst->gv->config.assume_rti_has_pmd_endpoints)
{
DDS_LOG(DDS_LC_DISCOVERY, "data (SPDP, vendor %u.%u): assuming unadvertised PMD endpoints do exist\n",
rst->vendor.id[0], rst->vendor.id[1]);
@ -567,7 +567,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
consequently the looped back packet may appear to be from an
unknown participant. So we handle that, too. */
if (is_deleted_participant_guid (gv.deleted_participants, &datap->participant_guid, DPG_REMOTE))
if (is_deleted_participant_guid (rst->gv->deleted_participants, &datap->participant_guid, DPG_REMOTE))
{
DDS_LOG(DDS_LC_TRACE, "SPDP ST0 "PGUIDFMT" (recently deleted)", PGUID (datap->participant_guid));
return 1;
@ -575,7 +575,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
{
int islocal = 0;
if (ephash_lookup_participant_guid (&datap->participant_guid))
if (ephash_lookup_participant_guid (rst->gv->guid_hash, &datap->participant_guid))
islocal = 1;
if (islocal)
{
@ -584,12 +584,12 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
}
}
if ((proxypp = ephash_lookup_proxy_participant_guid (&datap->participant_guid)) != NULL)
if ((proxypp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &datap->participant_guid)) != NULL)
{
/* SPDP processing is so different from normal processing that we
are even skipping the automatic lease renewal. Therefore do it
regardless of
config.arrival_of_data_asserts_pp_and_ep_liveliness. */
gv.config.arrival_of_data_asserts_pp_and_ep_liveliness. */
DDS_LOG(DDS_LC_TRACE, "SPDP ST0 "PGUIDFMT" (known)", PGUID (datap->participant_guid));
lease_renew (ddsrt_atomic_ldvoidp (&proxypp->lease), now_et ());
ddsrt_mutex_lock (&proxypp->e.lock);
@ -656,7 +656,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
/* Non-DDSI2 participants are made dependent on DDSI2 (but DDSI2
itself need not be discovered yet) */
struct proxy_participant *ddsi2;
if ((ddsi2 = find_ddsi2_proxy_participant (&datap->participant_guid)) == NULL)
if ((ddsi2 = find_ddsi2_proxy_participant (rst->gv->guid_hash, &datap->participant_guid)) == NULL)
memset (&privileged_pp_guid.prefix, 0, sizeof (privileged_pp_guid.prefix));
else
{
@ -678,17 +678,17 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
as_default = new_addrset ();
as_meta = new_addrset ();
if ((datap->present & PP_DEFAULT_MULTICAST_LOCATOR) && (get_locator (&loc, &datap->default_multicast_locators, 0)))
allowmulticast_aware_add_to_addrset (as_default, &loc);
if ((datap->present & PP_METATRAFFIC_MULTICAST_LOCATOR) && (get_locator (&loc, &datap->metatraffic_multicast_locators, 0)))
allowmulticast_aware_add_to_addrset (as_meta, &loc);
if ((datap->present & PP_DEFAULT_MULTICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->default_multicast_locators, 0)))
allowmulticast_aware_add_to_addrset (rst->gv, rst->gv->config.allowMulticast, as_default, &loc);
if ((datap->present & PP_METATRAFFIC_MULTICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->metatraffic_multicast_locators, 0)))
allowmulticast_aware_add_to_addrset (rst->gv, rst->gv->config.allowMulticast, as_meta, &loc);
/* If no multicast locators or multicast TTL > 1, assume IP (multicast) routing can be relied upon to reach
the remote participant, else only accept nodes with an advertised unicast address in the same subnet to
protect against multicasts being received over an unexpected interface (which sometimes appears to occur) */
if (addrset_empty_mc (as_default) && addrset_empty_mc (as_meta))
uc_same_subnet = 0;
else if (config.multicast_ttl > 1)
else if (rst->gv->config.multicast_ttl > 1)
uc_same_subnet = 0;
else
{
@ -697,22 +697,22 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
}
/* 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);
if (!rst->gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_DEFAULT_UNICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->default_unicast_locators, uc_same_subnet)))
add_to_addrset (rst->gv, as_default, &loc);
else {
DDS_LOG(DDS_LC_DISCOVERY, " (srclocD)");
add_to_addrset (as_default, &rst->srcloc);
add_to_addrset (rst->gv, 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);
if (!rst->gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_METATRAFFIC_UNICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->metatraffic_unicast_locators, uc_same_subnet)))
add_to_addrset (rst->gv, as_meta, &loc);
else {
DDS_LOG(DDS_LC_DISCOVERY, " (srclocM)");
add_to_addrset (as_meta, &rst->srcloc);
add_to_addrset (rst->gv, as_meta, &rst->srcloc);
}
nn_log_addrset(DDS_LC_DISCOVERY, " (data", as_default);
nn_log_addrset(DDS_LC_DISCOVERY, " meta", as_meta);
nn_log_addrset(rst->gv, DDS_LC_DISCOVERY, " (data", as_default);
nn_log_addrset(rst->gv, DDS_LC_DISCOVERY, " meta", as_meta);
DDS_LOG(DDS_LC_DISCOVERY, ")");
}
@ -728,10 +728,11 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
nn_log_xqos(DDS_LC_DISCOVERY, &datap->qos);
DDS_LOG(DDS_LC_DISCOVERY, "}\n");
maybe_add_pp_as_meta_to_as_disc (as_meta);
maybe_add_pp_as_meta_to_as_disc (rst->gv, as_meta);
new_proxy_participant
(
rst->gv,
&datap->participant_guid,
builtin_endpoint_set,
prismtech_builtin_endpoint_set,
@ -755,7 +756,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
if (!have_dst)
{
DDS_LOG(DDS_LC_DISCOVERY, "broadcasted SPDP packet -> answering");
respond_to_spdp (&datap->participant_guid);
respond_to_spdp (rst->gv, &datap->participant_guid);
}
else
{
@ -767,17 +768,17 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
{
/* If we just discovered DDSI2, make sure any existing
participants served by it are made dependent on it */
make_participants_dependent_on_ddsi2 (&datap->participant_guid, timestamp);
make_participants_dependent_on_ddsi2 (rst->gv, &datap->participant_guid, timestamp);
}
else if (privileged_pp_guid.prefix.u[0] || privileged_pp_guid.prefix.u[1] || privileged_pp_guid.prefix.u[2])
{
/* If we just created a participant dependent on DDSI2, make sure
DDSI2 still exists. There is a risk of racing the lease expiry
of DDSI2. */
if (ephash_lookup_proxy_participant_guid (&privileged_pp_guid) == NULL)
if (ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &privileged_pp_guid) == NULL)
{
DDS_LOG(DDS_LC_DISCOVERY, "make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n", PGUID (privileged_pp_guid), PGUID (datap->participant_guid));
delete_proxy_participant_by_guid (&datap->participant_guid, timestamp, 1);
delete_proxy_participant_by_guid (rst->gv, &datap->participant_guid, timestamp, 1);
}
}
return 1;
@ -803,6 +804,8 @@ static void handle_SPDP (const struct receiver_state *rst, seqno_t seq, nn_wctim
src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4;
src.strict = NN_STRICT_P (rst->gv->config);
src.factory = rst->gv->m_factory;
if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{
if (plist_ret != DDS_RETCODE_UNSUPPORTED)
@ -828,9 +831,14 @@ static void handle_SPDP (const struct receiver_state *rst, seqno_t seq, nn_wctim
}
}
static void add_locator_to_ps (const nn_locator_t *loc, void *arg)
struct add_locator_to_ps_arg {
struct q_globals *gv;
nn_plist_t *ps;
};
static void add_locator_to_ps (const nn_locator_t *loc, void *varg)
{
nn_plist_t *ps = (nn_plist_t *) arg;
struct add_locator_to_ps_arg *arg = varg;
struct nn_locators_one *elem = ddsrt_malloc (sizeof (struct nn_locators_one));
struct nn_locators *locs;
unsigned present_flag;
@ -838,19 +846,19 @@ static void add_locator_to_ps (const nn_locator_t *loc, void *arg)
elem->loc = *loc;
elem->next = NULL;
if (ddsi_is_mcaddr (loc)) {
locs = &ps->multicast_locators;
if (ddsi_is_mcaddr (arg->gv, loc)) {
locs = &arg->ps->multicast_locators;
present_flag = PP_MULTICAST_LOCATOR;
} else {
locs = &ps->unicast_locators;
locs = &arg->ps->unicast_locators;
present_flag = PP_UNICAST_LOCATOR;
}
if (!(ps->present & present_flag))
if (!(arg->ps->present & present_flag))
{
locs->n = 0;
locs->first = locs->last = NULL;
ps->present |= present_flag;
arg->ps->present |= present_flag;
}
locs->n++;
if (locs->first)
@ -872,7 +880,7 @@ static int sedp_write_endpoint
const struct entity_common *common, const struct endpoint_common *epcommon,
const dds_qos_t *xqos, struct addrset *as)
{
const dds_qos_t *defqos = is_writer_entityid (epguid->entityid) ? &gv.default_xqos_wr : &gv.default_xqos_rd;
const dds_qos_t *defqos = is_writer_entityid (epguid->entityid) ? &wr->e.gv->default_xqos_wr : &wr->e.gv->default_xqos_rd;
struct nn_xmsg *mpayload;
uint64_t qosdiff;
nn_plist_t ps;
@ -917,7 +925,7 @@ static int sedp_write_endpoint
the default. */
if (!is_writer_entityid (epguid->entityid))
{
const struct reader *rd = ephash_lookup_reader_guid (epguid);
const struct reader *rd = ephash_lookup_reader_guid (wr->e.gv->guid_hash, epguid);
assert (rd);
if (rd->favours_ssm)
{
@ -928,12 +936,15 @@ static int sedp_write_endpoint
#endif
qosdiff = nn_xqos_delta (xqos, defqos, ~(uint64_t)0);
if (config.explicitly_publish_qos_set_to_default)
if (wr->e.gv->config.explicitly_publish_qos_set_to_default)
qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
if (as)
{
addrset_forall (as, add_locator_to_ps, &ps);
struct add_locator_to_ps_arg arg;
arg.gv = wr->e.gv;
arg.ps = &ps;
addrset_forall (as, add_locator_to_ps, &arg);
}
}
@ -941,7 +952,7 @@ static int sedp_write_endpoint
the QoS and other settings. So the header fields aren't really
important, except that they need to be set to reasonable things
or it'll crash */
mpayload = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
mpayload = nn_xmsg_new (wr->e.gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
if (xqos) nn_xqos_addtomsg (mpayload, xqos, qosdiff);
nn_xmsg_addpar_sentinel (mpayload);
@ -1023,7 +1034,7 @@ static const char *durability_to_string (dds_durability_kind_t k)
return "undefined-durability";
}
static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppguid, nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp, seqno_t seq)
static struct proxy_participant *implicitly_create_proxypp (struct q_globals *gv, const nn_guid_t *ppguid, nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp, seqno_t seq)
{
nn_guid_t privguid;
nn_plist_t pp_plist;
@ -1060,7 +1071,7 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg
doing anything about (1). That means we fall back to the legacy mode of locally generating
GIDs but leaving the system id unchanged if the remote is OSPL. */
actual_vendorid = (datap->present & PP_VENDORID) ? datap->vendorid : vendorid;
new_proxy_participant(ppguid, 0, 0, &privguid, new_addrset(), new_addrset(), &pp_plist, T_NEVER, actual_vendorid, CF_IMPLICITLY_CREATED_PROXYPP, timestamp, seq);
new_proxy_participant(gv, ppguid, 0, 0, &privguid, new_addrset(), new_addrset(), &pp_plist, T_NEVER, actual_vendorid, CF_IMPLICITLY_CREATED_PROXYPP, timestamp, seq);
}
else if (ppguid->prefix.u[0] == src_guid_prefix->u[0] && vendor_is_eclipse_or_opensplice (vendorid))
{
@ -1068,7 +1079,7 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg
readers or writers, only if remote ddsi2 is provably running
with a minimal built-in endpoint set */
struct proxy_participant *privpp;
if ((privpp = ephash_lookup_proxy_participant_guid (&privguid)) == NULL) {
if ((privpp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &privguid)) == NULL) {
DDS_TRACE(" unknown-src-proxypp?\n");
goto err;
} else if (!privpp->is_ddsi2_pp) {
@ -1094,13 +1105,13 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg
ddsrt_mutex_unlock (&privpp->e.lock);
pp_plist.prismtech_participant_version_info.flags &= ~NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2;
new_proxy_participant (ppguid, 0, 0, &privguid, as_default, as_meta, &pp_plist, T_NEVER, vendorid, CF_IMPLICITLY_CREATED_PROXYPP | CF_PROXYPP_NO_SPDP, timestamp, seq);
new_proxy_participant (gv, ppguid, 0, 0, &privguid, as_default, as_meta, &pp_plist, T_NEVER, vendorid, CF_IMPLICITLY_CREATED_PROXYPP | CF_PROXYPP_NO_SPDP, timestamp, seq);
}
}
err:
nn_plist_fini (&pp_plist);
return ephash_lookup_proxy_participant_guid (ppguid);
return ephash_lookup_proxy_participant_guid (gv->guid_hash, ppguid);
}
static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp)
@ -1126,10 +1137,10 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
ppguid.prefix = datap->endpoint_guid.prefix;
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
if (is_deleted_participant_guid (gv.deleted_participants, &ppguid, DPG_REMOTE))
if (is_deleted_participant_guid (rst->gv->deleted_participants, &ppguid, DPG_REMOTE))
E (" local dead pp?\n", err);
if (ephash_lookup_participant_guid (&ppguid) != NULL)
if (ephash_lookup_participant_guid (rst->gv->guid_hash, &ppguid) != NULL)
E (" local pp?\n", err);
if (is_builtin_entityid (datap->endpoint_guid.entityid, vendorid))
@ -1139,10 +1150,10 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
if (!(datap->qos.present & QP_TYPE_NAME))
E (" no typename?\n", err);
if ((pp = ephash_lookup_proxy_participant_guid (&ppguid)) == NULL)
if ((pp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &ppguid)) == NULL)
{
DDS_LOG(DDS_LC_DISCOVERY, " unknown-proxypp");
if ((pp = implicitly_create_proxypp (&ppguid, datap, src_guid_prefix, vendorid, timestamp, 0)) == NULL)
if ((pp = implicitly_create_proxypp (rst->gv, &ppguid, datap, src_guid_prefix, vendorid, timestamp, 0)) == NULL)
E ("?\n", err);
/* Repeat regular SEDP trace for convenience */
DDS_LOG(DDS_LC_DISCOVERY, "SEDP ST0 "PGUIDFMT" (cont)", PGUID (datap->endpoint_guid));
@ -1151,11 +1162,11 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
xqos = &datap->qos;
is_writer = is_writer_entityid (datap->endpoint_guid.entityid);
if (!is_writer)
nn_xqos_mergein_missing (xqos, &gv.default_xqos_rd, ~(uint64_t)0);
nn_xqos_mergein_missing (xqos, &rst->gv->default_xqos_rd, ~(uint64_t)0);
else if (vendor_is_eclipse_or_prismtech(vendorid))
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr, ~(uint64_t)0);
nn_xqos_mergein_missing (xqos, &rst->gv->default_xqos_wr, ~(uint64_t)0);
else
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr_nad, ~(uint64_t)0);
nn_xqos_mergein_missing (xqos, &rst->gv->default_xqos_wr_nad, ~(uint64_t)0);
/* After copy + merge, should have at least the ones present in the
input. Also verify reliability and durability are present,
@ -1181,11 +1192,11 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
if (is_writer)
{
pwr = ephash_lookup_proxy_writer_guid (&datap->endpoint_guid);
pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &datap->endpoint_guid);
}
else
{
prd = ephash_lookup_proxy_reader_guid (&datap->endpoint_guid);
prd = ephash_lookup_proxy_reader_guid (rst->gv->guid_hash, &datap->endpoint_guid);
}
if (pwr || prd)
{
@ -1212,21 +1223,21 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
{
nn_locator_t loc;
as = new_addrset ();
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)
if (!rst->gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_UNICAST_LOCATOR) && get_locator (rst->gv, &loc, &datap->unicast_locators, 0))
add_to_addrset (rst->gv, as, &loc);
else if (rst->gv->config.tcp_use_peeraddr_for_unicast)
{
DDS_LOG(DDS_LC_DISCOVERY, " (srcloc)");
add_to_addrset (as, &rst->srcloc);
add_to_addrset (rst->gv, as, &rst->srcloc);
}
else
{
copy_addrset_into_addrset_uc (as, pp->as_default);
copy_addrset_into_addrset_uc (rst->gv, as, pp->as_default);
}
if ((datap->present & PP_MULTICAST_LOCATOR) && get_locator (&loc, &datap->multicast_locators, 0))
allowmulticast_aware_add_to_addrset (as, &loc);
if ((datap->present & PP_MULTICAST_LOCATOR) && get_locator (rst->gv, &loc, &datap->multicast_locators, 0))
allowmulticast_aware_add_to_addrset (rst->gv, rst->gv->config.allowMulticast, as, &loc);
else
copy_addrset_into_addrset_mc (as, pp->as_default);
copy_addrset_into_addrset_mc (rst->gv, as, pp->as_default);
}
if (addrset_empty (as))
{
@ -1234,11 +1245,11 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
E (" no address", err);
}
nn_log_addrset(DDS_LC_DISCOVERY, " (as", as);
nn_log_addrset(rst->gv, DDS_LC_DISCOVERY, " (as", as);
#ifdef DDSI_INCLUDE_SSM
ssm = 0;
if (is_writer)
ssm = addrset_contains_ssm (as);
ssm = addrset_contains_ssm (rst->gv, as);
else if (datap->present & PP_READER_FAVOURS_SSM)
ssm = (datap->reader_favours_ssm.state != 0);
DDS_LOG(DDS_LC_DISCOVERY, " ssm=%u", ssm);
@ -1265,11 +1276,11 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
assert (!is_builtin_entityid (datap->endpoint_guid.entityid, vendorid));
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
{
struct config_channel_listelem *channel = find_channel (&config, xqos->transport_priority);
new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, channel->dqueue, channel->evq ? channel->evq : gv.xevents, timestamp);
struct config_channel_listelem *channel = find_channel (&rst->gv->config, xqos->transport_priority);
new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, channel->dqueue, channel->evq ? channel->evq : rst->gv->xevents, timestamp);
}
#else
new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, gv.user_dqueue, gv.xevents, timestamp);
new_proxy_writer (rst->gv, &ppguid, &datap->endpoint_guid, as, datap, rst->gv->user_dqueue, rst->gv->xevents, timestamp);
#endif
}
}
@ -1282,9 +1293,9 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
else
{
#ifdef DDSI_INCLUDE_SSM
new_proxy_reader (&ppguid, &datap->endpoint_guid, as, datap, timestamp, ssm);
new_proxy_reader (rst->gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, ssm);
#else
new_proxy_reader (&ppguid, &datap->endpoint_guid, as, datap, timestamp);
new_proxy_reader (rst->gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp);
#endif
}
}
@ -1298,7 +1309,7 @@ err:
#undef E
}
static void handle_SEDP_dead (nn_plist_t *datap, nn_wctime_t timestamp)
static void handle_SEDP_dead (const struct receiver_state *rst, nn_plist_t *datap, nn_wctime_t timestamp)
{
int res;
if (!(datap->present & PP_ENDPOINT_GUID))
@ -1309,11 +1320,11 @@ static void handle_SEDP_dead (nn_plist_t *datap, nn_wctime_t timestamp)
DDS_LOG(DDS_LC_DISCOVERY, " "PGUIDFMT, PGUID (datap->endpoint_guid));
if (is_writer_entityid (datap->endpoint_guid.entityid))
{
res = delete_proxy_writer (&datap->endpoint_guid, timestamp, 0);
res = delete_proxy_writer (rst->gv, &datap->endpoint_guid, timestamp, 0);
}
else
{
res = delete_proxy_reader (&datap->endpoint_guid, timestamp, 0);
res = delete_proxy_reader (rst->gv, &datap->endpoint_guid, timestamp, 0);
}
DDS_LOG(DDS_LC_DISCOVERY, " %s\n", (res < 0) ? " unknown" : " delete");
}
@ -1337,6 +1348,8 @@ static void handle_SEDP (const struct receiver_state *rst, nn_wctime_t timestamp
src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4;
src.strict = NN_STRICT_P (rst->gv->config);
src.factory = rst->gv->m_factory;
if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{
if (plist_ret != DDS_RETCODE_UNSUPPORTED)
@ -1353,7 +1366,7 @@ static void handle_SEDP (const struct receiver_state *rst, nn_wctime_t timestamp
case NN_STATUSINFO_DISPOSE:
case NN_STATUSINFO_UNREGISTER:
case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER):
handle_SEDP_dead (&decoded_data, timestamp);
handle_SEDP_dead (rst, &decoded_data, timestamp);
break;
}
@ -1383,9 +1396,9 @@ int sedp_write_topic (struct participant *pp, const struct nn_plist *datap)
sedp_wr = get_sedp_writer (pp, NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER);
mpayload = nn_xmsg_new (gv.xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
delta = nn_xqos_delta (&datap->qos, &gv.default_xqos_tp, ~(uint64_t)0);
if (config.explicitly_publish_qos_set_to_default)
mpayload = nn_xmsg_new (sedp_wr->e.gv->xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
delta = nn_xqos_delta (&datap->qos, &sedp_wr->e.gv->default_xqos_tp, ~(uint64_t)0);
if (sedp_wr->e.gv->config.explicitly_publish_qos_set_to_default)
delta |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
nn_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta);
nn_xmsg_addpar_sentinel (mpayload);
@ -1421,7 +1434,7 @@ int sedp_write_cm_participant (struct participant *pp, int alive)
the QoS and other settings. So the header fields aren't really
important, except that they need to be set to reasonable things
or it'll crash */
mpayload = nn_xmsg_new (gv.xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
mpayload = nn_xmsg_new (sedp_wr->e.gv->xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
nn_plist_init_empty (&ps);
ps.present = PP_PARTICIPANT_GUID;
ps.participant_guid = pp->e.guid;
@ -1464,6 +1477,8 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e
src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4;
src.strict = NN_STRICT_P (rst->gv->config);
src.factory = rst->gv->m_factory;
if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{
if (plist_ret != DDS_RETCODE_UNSUPPORTED)
@ -1479,8 +1494,8 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e
DDS_WARNING("SEDP_CM (vendor %u.%u): missing participant GUID\n", src.vendorid.id[0], src.vendorid.id[1]);
else
{
if ((proxypp = ephash_lookup_proxy_participant_guid (&decoded_data.participant_guid)) == NULL)
proxypp = implicitly_create_proxypp (&decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp, 0);
if ((proxypp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &decoded_data.participant_guid)) == NULL)
proxypp = implicitly_create_proxypp (rst->gv, &decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp, 0);
if (proxypp != NULL)
update_proxy_participant_plist (proxypp, 0, &decoded_data, UPD_PROXYPP_CM, timestamp);
}
@ -1491,165 +1506,6 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e
DDS_LOG(DDS_LC_DISCOVERY, "\n");
}
static struct participant *group_guid_to_participant (const nn_guid_t *group_guid)
{
nn_guid_t ppguid;
ppguid.prefix = group_guid->prefix;
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
return ephash_lookup_participant_guid (&ppguid);
}
int sedp_write_cm_publisher (const struct nn_plist *datap, int alive)
{
struct participant *pp;
struct writer *sedp_wr;
struct nn_xmsg *mpayload;
uint64_t delta;
int ret;
if ((pp = group_guid_to_participant (&datap->group_guid)) == NULL)
{
DDS_TRACE("sedp: write CMPublisher alive:%d for "PGUIDFMT" dropped: no participant\n",
alive, PGUID (datap->group_guid));
return 0;
}
sedp_wr = get_sedp_writer (pp, NN_ENTITYID_SEDP_BUILTIN_CM_PUBLISHER_WRITER);
/* The message is only a temporary thing, used only for encoding
the QoS and other settings. So the header fields aren't really
important, except that they need to be set to reasonable things
or it'll crash */
mpayload = nn_xmsg_new (gv.xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
if (!alive)
delta = 0;
else
{
delta = nn_xqos_delta (&datap->qos, &gv.default_xqos_pub, ~(uint64_t)0);
if (!config.explicitly_publish_qos_set_to_default)
delta |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
}
nn_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta);
nn_xmsg_addpar_sentinel (mpayload);
ret = write_mpayload (sedp_wr, alive, PID_GROUP_GUID ,mpayload);
nn_xmsg_free (mpayload);
return ret;
}
int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive)
{
struct participant *pp;
struct writer *sedp_wr;
struct nn_xmsg *mpayload;
uint64_t delta;
int ret;
if ((pp = group_guid_to_participant (&datap->group_guid)) == NULL)
{
DDS_LOG(DDS_LC_DISCOVERY, "sedp: write CMSubscriber alive:%d for "PGUIDFMT" dropped: no participant\n",
alive, PGUID (datap->group_guid));
return 0;
}
sedp_wr = get_sedp_writer (pp, NN_ENTITYID_SEDP_BUILTIN_CM_SUBSCRIBER_WRITER);
/* The message is only a temporary thing, used only for encoding
the QoS and other settings. So the header fields aren't really
important, except that they need to be set to reasonable things
or it'll crash */
mpayload = nn_xmsg_new (gv.xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
if (!alive)
delta = 0;
else
{
delta = nn_xqos_delta (&datap->qos, &gv.default_xqos_sub, ~(uint64_t)0);
if (!config.explicitly_publish_qos_set_to_default)
delta |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
}
nn_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta);
nn_xmsg_addpar_sentinel (mpayload);
ret = write_mpayload (sedp_wr, alive, PID_GROUP_GUID, mpayload);
nn_xmsg_free (mpayload);
return ret;
}
static void handle_SEDP_GROUP_alive (nn_plist_t *datap /* note: potentially modifies datap */, nn_wctime_t timestamp)
{
#define E(msg, lbl) do { DDS_LOG(DDS_LC_DISCOVERY, msg); goto lbl; } while (0)
nn_guid_t ppguid;
if (!(datap->present & PP_GROUP_GUID))
E (" no guid?\n", err);
DDS_LOG(DDS_LC_DISCOVERY, " %"PRIx32"%"PRIx32"%"PRIx32"%"PRIx32, PGUID (datap->group_guid));
ppguid.prefix = datap->group_guid.prefix;
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
if (ephash_lookup_proxy_participant_guid (&ppguid) == NULL)
E (" unknown proxy pp?\n", err);
DDS_LOG(DDS_LC_DISCOVERY, " alive\n");
{
char *name = (datap->present & PP_ENTITY_NAME) ? datap->entity_name : "";
new_proxy_group (&datap->group_guid, name, &datap->qos, timestamp);
}
err:
return;
#undef E
}
static void handle_SEDP_GROUP_dead (nn_plist_t *datap, nn_wctime_t timestamp)
{
if (!(datap->present & PP_GROUP_GUID))
{
DDS_LOG(DDS_LC_DISCOVERY, " no guid?\n");
return;
}
DDS_LOG(DDS_LC_DISCOVERY, " "PGUIDFMT"\n", PGUID (datap->group_guid));
delete_proxy_group (&datap->group_guid, timestamp, 0);
}
static void handle_SEDP_GROUP (const struct receiver_state *rst, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len)
{
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
DDS_LOG(DDS_LC_DISCOVERY, "SEDP_GROUP ST%x", statusinfo);
if (data == NULL)
{
DDS_LOG(DDS_LC_DISCOVERY, " no payload?\n");
return;
}
else
{
nn_plist_t decoded_data;
nn_plist_src_t src;
dds_return_t plist_ret;
src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor;
src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4;
if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{
if (plist_ret != DDS_RETCODE_UNSUPPORTED)
DDS_WARNING("SEDP_GROUP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
return;
}
switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
{
case 0:
handle_SEDP_GROUP_alive (&decoded_data, timestamp);
break;
case NN_STATUSINFO_DISPOSE:
case NN_STATUSINFO_UNREGISTER:
case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER):
handle_SEDP_GROUP_dead (&decoded_data, timestamp);
break;
}
nn_plist_fini (&decoded_data);
}
}
/******************************************************************************
*****************************************************************************/
@ -1749,6 +1605,8 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE;
src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset);
src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset;
src.strict = NN_STRICT_P (sampleinfo->rst->gv->config);
src.factory = sampleinfo->rst->gv->m_factory;
if ((plist_ret = nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH, 0, &src)) < 0)
{
if (plist_ret != DDS_RETCODE_UNSUPPORTED)
@ -1797,7 +1655,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
goto done_upd_deliv;
}
}
else if ((qos.present & PP_KEYHASH) && !NN_STRICT_P)
else if ((qos.present & PP_KEYHASH) && !NN_STRICT_P(pwr->e.gv->config))
{
/* For SPDP/SEDP, fake a parameter list with just a keyhash. For
PMD, just use the keyhash directly. Too hard to fix everything
@ -1872,10 +1730,6 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
case NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER:
handle_SEDP_CM (sampleinfo->rst, srcguid.entityid, timestamp, statusinfo, datap, datasz);
break;
case NN_ENTITYID_SEDP_BUILTIN_CM_PUBLISHER_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_CM_SUBSCRIBER_WRITER:
handle_SEDP_GROUP (sampleinfo->rst, timestamp, statusinfo, datap, datasz);
break;
default:
DDS_LOG (DDS_LC_DISCOVERY, "data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": not handled\n",
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],

View file

@ -52,6 +52,7 @@ struct debug_monitor {
ddsi_tran_listener_t servsock;
ddsrt_mutex_t lock;
ddsrt_cond_t cond;
struct q_globals *gv;
struct plugin *plugins;
int stop;
};
@ -85,7 +86,7 @@ static void print_address (const nn_locator_t *n, void *varg)
{
struct print_address_arg *arg = varg;
char buf[DDSI_LOCSTRLEN];
arg->count += cpf (arg->conn, " %s", ddsi_locator_to_string (buf, sizeof(buf), n));
arg->count += cpf (arg->conn, " %s", ddsi_locator_to_string (arg->conn->m_base.gv, buf, sizeof(buf), n));
}
static int print_addrset (ddsi_tran_conn_t conn, const char *prefix, struct addrset *as, const char *suffix)
@ -140,13 +141,13 @@ static int print_proxy_endpoint_common (ddsi_tran_conn_t conn, const char *label
}
static int print_participants (struct thread_state1 * const ts1, ddsi_tran_conn_t conn)
static int print_participants (struct thread_state1 * const ts1, struct q_globals *gv, ddsi_tran_conn_t conn)
{
struct ephash_enum_participant e;
struct participant *p;
int x = 0;
thread_state_awake (ts1);
ephash_enum_participant_init (&e);
thread_state_awake_fixed_domain (ts1);
ephash_enum_participant_init (&e, gv->guid_hash);
while ((p = ephash_enum_participant_next (&e)) != NULL)
{
ddsrt_mutex_lock (&p->e.lock);
@ -156,7 +157,7 @@ static int print_participants (struct thread_state1 * const ts1, ddsi_tran_conn_
{
struct ephash_enum_reader er;
struct reader *r;
ephash_enum_reader_init (&er);
ephash_enum_reader_init (&er, gv->guid_hash);
while ((r = ephash_enum_reader_next (&er)) != NULL)
{
ddsrt_avl_iter_t writ;
@ -178,7 +179,7 @@ static int print_participants (struct thread_state1 * const ts1, ddsi_tran_conn_
{
struct ephash_enum_writer ew;
struct writer *w;
ephash_enum_writer_init (&ew);
ephash_enum_writer_init (&ew, gv->guid_hash);
while ((w = ephash_enum_writer_next (&ew)) != NULL)
{
ddsrt_avl_iter_t rdit;
@ -225,13 +226,13 @@ static int print_participants (struct thread_state1 * const ts1, ddsi_tran_conn_
return x;
}
static int print_proxy_participants (struct thread_state1 * const ts1, ddsi_tran_conn_t conn)
static int print_proxy_participants (struct thread_state1 * const ts1, struct q_globals *gv, ddsi_tran_conn_t conn)
{
struct ephash_enum_proxy_participant e;
struct proxy_participant *p;
int x = 0;
thread_state_awake (ts1);
ephash_enum_proxy_participant_init (&e);
thread_state_awake_fixed_domain (ts1);
ephash_enum_proxy_participant_init (&e, gv->guid_hash);
while ((p = ephash_enum_proxy_participant_next (&e)) != NULL)
{
ddsrt_mutex_lock (&p->e.lock);
@ -243,7 +244,7 @@ static int print_proxy_participants (struct thread_state1 * const ts1, ddsi_tran
{
struct ephash_enum_proxy_reader er;
struct proxy_reader *r;
ephash_enum_proxy_reader_init (&er);
ephash_enum_proxy_reader_init (&er, gv->guid_hash);
while ((r = ephash_enum_proxy_reader_next (&er)) != NULL)
{
ddsrt_avl_iter_t writ;
@ -262,7 +263,7 @@ static int print_proxy_participants (struct thread_state1 * const ts1, ddsi_tran
{
struct ephash_enum_proxy_writer ew;
struct proxy_writer *w;
ephash_enum_proxy_writer_init (&ew);
ephash_enum_proxy_writer_init (&ew, gv->guid_hash);
while ((w = ephash_enum_proxy_writer_next (&ew)) != NULL)
{
ddsrt_avl_iter_t rdit;
@ -303,9 +304,9 @@ static void debmon_handle_connection (struct debug_monitor *dm, ddsi_tran_conn_t
struct thread_state1 * const ts1 = lookup_thread_state ();
struct plugin *p;
int r = 0;
r += print_participants (ts1, conn);
r += print_participants (ts1, dm->gv, conn);
if (r == 0)
r += print_proxy_participants (ts1, conn);
r += print_proxy_participants (ts1, dm->gv, conn);
/* Note: can only add plugins (at the tail) */
ddsrt_mutex_lock (&dm->lock);
@ -344,21 +345,22 @@ static uint32_t debmon_main (void *vdm)
return 0;
}
struct debug_monitor *new_debug_monitor (int port)
struct debug_monitor *new_debug_monitor (struct q_globals *gv, int port)
{
struct debug_monitor *dm;
if (config.monitor_port < 0)
if (gv->config.monitor_port < 0)
return NULL;
if (ddsi_tcp_init () < 0)
if (ddsi_tcp_init (gv) < 0)
return NULL;
dm = ddsrt_malloc (sizeof (*dm));
dm->gv = gv;
dm->plugins = NULL;
if ((dm->tran_factory = ddsi_factory_find ("tcp")) == NULL)
dm->tran_factory = ddsi_factory_find ("tcp6");
if ((dm->tran_factory = ddsi_factory_find (gv, "tcp")) == NULL)
dm->tran_factory = ddsi_factory_find (gv, "tcp6");
dm->servsock = ddsi_factory_create_listener (dm->tran_factory, port, NULL);
if (dm->servsock == NULL)
{
@ -370,7 +372,7 @@ struct debug_monitor *new_debug_monitor (int port)
nn_locator_t loc;
char buf[DDSI_LOCSTRLEN];
(void) ddsi_listener_locator(dm->servsock, &loc);
DDS_LOG(DDS_LC_CONFIG, "debmon at %s\n", ddsi_locator_to_string (buf, sizeof(buf), &loc));
DDS_LOG(DDS_LC_CONFIG, "debmon at %s\n", ddsi_locator_to_string (gv, buf, sizeof(buf), &loc));
}
ddsrt_mutex_init (&dm->lock);
@ -378,7 +380,7 @@ struct debug_monitor *new_debug_monitor (int port)
if (ddsi_listener_listen (dm->servsock) < 0)
goto err_listen;
dm->stop = 0;
create_thread(&dm->servts, "debmon", debmon_main, dm);
create_thread (&dm->servts, gv, "debmon", debmon_main, dm);
return dm;
err_listen:

File diff suppressed because it is too large Load diff

View file

@ -69,18 +69,19 @@ static void gc_buckets_cb (struct gcreq *gcreq)
ddsrt_free (bs);
}
static void gc_buckets (void *bs)
static void gc_buckets (void *bs, void *varg)
{
struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, gc_buckets_cb);
struct q_globals *gv = varg;
struct gcreq *gcreq = gcreq_new (gv->gcreq_queue, gc_buckets_cb);
gcreq->arg = bs;
gcreq_enqueue (gcreq);
}
struct ephash *ephash_new (void)
struct ephash *ephash_new (struct q_globals *gv)
{
struct ephash *ephash;
ephash = ddsrt_malloc (sizeof (*ephash));
ephash->hash = ddsrt_chh_new (32, hash_entity_guid_wrapper, entity_guid_eq_wrapper, gc_buckets);
ephash->hash = ddsrt_chh_new (32, hash_entity_guid_wrapper, entity_guid_eq_wrapper, gc_buckets, gv);
if (ephash->hash == NULL) {
ddsrt_free (ephash);
return NULL;
@ -96,195 +97,190 @@ void ephash_free (struct ephash *ephash)
ddsrt_free (ephash);
}
static void ephash_guid_insert (struct entity_common *e)
static void ephash_guid_insert (struct ephash *gh, struct entity_common *e)
{
int x;
assert(gv.guid_hash);
assert(gv.guid_hash->hash);
x = ddsrt_chh_add (gv.guid_hash->hash, e);
x = ddsrt_chh_add (gh->hash, e);
(void)x;
assert (x);
}
static void ephash_guid_remove (struct entity_common *e)
static void ephash_guid_remove (struct ephash *gh, struct entity_common *e)
{
int x;
assert(gv.guid_hash);
assert(gv.guid_hash->hash);
x = ddsrt_chh_remove (gv.guid_hash->hash, e);
x = ddsrt_chh_remove (gh->hash, e);
(void)x;
assert (x);
}
void *ephash_lookup_guid_untyped (const struct nn_guid *guid)
void *ephash_lookup_guid_untyped (const struct ephash *gh, const struct nn_guid *guid)
{
/* FIXME: could (now) require guid to be first in entity_common; entity_common already is first in entity */
struct entity_common e;
e.guid = *guid;
assert (thread_is_awake ());
return ddsrt_chh_lookup (gv.guid_hash->hash, &e);
return ddsrt_chh_lookup (gh->hash, &e);
}
static void *ephash_lookup_guid_int (const struct ephash *ephash, const struct nn_guid *guid, enum entity_kind kind)
static void *ephash_lookup_guid_int (const struct ephash *gh, const struct nn_guid *guid, enum entity_kind kind)
{
struct entity_common *res;
(void)ephash;
if ((res = ephash_lookup_guid_untyped (guid)) != NULL && res->kind == kind)
if ((res = ephash_lookup_guid_untyped (gh, guid)) != NULL && res->kind == kind)
return res;
else
return NULL;
}
void *ephash_lookup_guid (const struct nn_guid *guid, enum entity_kind kind)
void *ephash_lookup_guid (const struct ephash *gh, const struct nn_guid *guid, enum entity_kind kind)
{
return ephash_lookup_guid_int (NULL, guid, kind);
return ephash_lookup_guid_int (gh, guid, kind);
}
void ephash_insert_participant_guid (struct participant *pp)
void ephash_insert_participant_guid (struct ephash *gh, struct participant *pp)
{
ephash_guid_insert (&pp->e);
ephash_guid_insert (gh, &pp->e);
}
void ephash_insert_proxy_participant_guid (struct proxy_participant *proxypp)
void ephash_insert_proxy_participant_guid (struct ephash *gh, struct proxy_participant *proxypp)
{
ephash_guid_insert (&proxypp->e);
ephash_guid_insert (gh, &proxypp->e);
}
void ephash_insert_writer_guid (struct writer *wr)
void ephash_insert_writer_guid (struct ephash *gh, struct writer *wr)
{
ephash_guid_insert (&wr->e);
ephash_guid_insert (gh, &wr->e);
}
void ephash_insert_reader_guid (struct reader *rd)
void ephash_insert_reader_guid (struct ephash *gh, struct reader *rd)
{
ephash_guid_insert (&rd->e);
ephash_guid_insert (gh, &rd->e);
}
void ephash_insert_proxy_writer_guid (struct proxy_writer *pwr)
void ephash_insert_proxy_writer_guid (struct ephash *gh, struct proxy_writer *pwr)
{
ephash_guid_insert (&pwr->e);
ephash_guid_insert (gh, &pwr->e);
}
void ephash_insert_proxy_reader_guid (struct proxy_reader *prd)
void ephash_insert_proxy_reader_guid (struct ephash *gh, struct proxy_reader *prd)
{
ephash_guid_insert (&prd->e);
ephash_guid_insert (gh, &prd->e);
}
void ephash_remove_participant_guid (struct participant *pp)
void ephash_remove_participant_guid (struct ephash *gh, struct participant *pp)
{
ephash_guid_remove (&pp->e);
ephash_guid_remove (gh, &pp->e);
}
void ephash_remove_proxy_participant_guid (struct proxy_participant *proxypp)
void ephash_remove_proxy_participant_guid (struct ephash *gh, struct proxy_participant *proxypp)
{
ephash_guid_remove (&proxypp->e);
ephash_guid_remove (gh, &proxypp->e);
}
void ephash_remove_writer_guid (struct writer *wr)
void ephash_remove_writer_guid (struct ephash *gh, struct writer *wr)
{
ephash_guid_remove (&wr->e);
ephash_guid_remove (gh, &wr->e);
}
void ephash_remove_reader_guid (struct reader *rd)
void ephash_remove_reader_guid (struct ephash *gh, struct reader *rd)
{
ephash_guid_remove (&rd->e);
ephash_guid_remove (gh, &rd->e);
}
void ephash_remove_proxy_writer_guid (struct proxy_writer *pwr)
void ephash_remove_proxy_writer_guid (struct ephash *gh, struct proxy_writer *pwr)
{
ephash_guid_remove (&pwr->e);
ephash_guid_remove (gh, &pwr->e);
}
void ephash_remove_proxy_reader_guid (struct proxy_reader *prd)
void ephash_remove_proxy_reader_guid (struct ephash *gh, struct proxy_reader *prd)
{
ephash_guid_remove (&prd->e);
ephash_guid_remove (gh, &prd->e);
}
struct participant *ephash_lookup_participant_guid (const struct nn_guid *guid)
struct participant *ephash_lookup_participant_guid (const struct ephash *gh, const struct nn_guid *guid)
{
assert (guid->entityid.u == NN_ENTITYID_PARTICIPANT);
assert (offsetof (struct participant, e) == 0);
return ephash_lookup_guid_int (gv.guid_hash, guid, EK_PARTICIPANT);
return ephash_lookup_guid_int (gh, guid, EK_PARTICIPANT);
}
struct proxy_participant *ephash_lookup_proxy_participant_guid (const struct nn_guid *guid)
struct proxy_participant *ephash_lookup_proxy_participant_guid (const struct ephash *gh, const struct nn_guid *guid)
{
assert (guid->entityid.u == NN_ENTITYID_PARTICIPANT);
assert (offsetof (struct proxy_participant, e) == 0);
return ephash_lookup_guid_int (gv.guid_hash, guid, EK_PROXY_PARTICIPANT);
return ephash_lookup_guid_int (gh, guid, EK_PROXY_PARTICIPANT);
}
struct writer *ephash_lookup_writer_guid (const struct nn_guid *guid)
struct writer *ephash_lookup_writer_guid (const struct ephash *gh, const struct nn_guid *guid)
{
assert (is_writer_entityid (guid->entityid));
assert (offsetof (struct writer, e) == 0);
return ephash_lookup_guid_int (gv.guid_hash, guid, EK_WRITER);
return ephash_lookup_guid_int (gh, guid, EK_WRITER);
}
struct reader *ephash_lookup_reader_guid (const struct nn_guid *guid)
struct reader *ephash_lookup_reader_guid (const struct ephash *gh, const struct nn_guid *guid)
{
assert (is_reader_entityid (guid->entityid));
assert (offsetof (struct reader, e) == 0);
return ephash_lookup_guid_int (gv.guid_hash, guid, EK_READER);
return ephash_lookup_guid_int (gh, guid, EK_READER);
}
struct proxy_writer *ephash_lookup_proxy_writer_guid (const struct nn_guid *guid)
struct proxy_writer *ephash_lookup_proxy_writer_guid (const struct ephash *gh, const struct nn_guid *guid)
{
assert (is_writer_entityid (guid->entityid));
assert (offsetof (struct proxy_writer, e) == 0);
return ephash_lookup_guid_int (gv.guid_hash, guid, EK_PROXY_WRITER);
return ephash_lookup_guid_int (gh, guid, EK_PROXY_WRITER);
}
struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct nn_guid *guid)
struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct ephash *gh, const struct nn_guid *guid)
{
assert (is_reader_entityid (guid->entityid));
assert (offsetof (struct proxy_reader, e) == 0);
return ephash_lookup_guid_int (gv.guid_hash, guid, EK_PROXY_READER);
return ephash_lookup_guid_int (gh, guid, EK_PROXY_READER);
}
/* Enumeration */
static void ephash_enum_init_int (struct ephash_enum *st, struct ephash *ephash, enum entity_kind kind)
static void ephash_enum_init_int (struct ephash_enum *st, const struct ephash *gh, enum entity_kind kind)
{
st->kind = kind;
st->cur = ddsrt_chh_iter_first (ephash->hash, &st->it);
st->cur = ddsrt_chh_iter_first (gh->hash, &st->it);
while (st->cur && st->cur->kind != st->kind)
st->cur = ddsrt_chh_iter_next (&st->it);
}
void ephash_enum_init (struct ephash_enum *st, enum entity_kind kind)
void ephash_enum_init (struct ephash_enum *st, const struct ephash *gh, enum entity_kind kind)
{
ephash_enum_init_int(st, gv.guid_hash, kind);
ephash_enum_init_int(st, gh, kind);
}
void ephash_enum_writer_init (struct ephash_enum_writer *st)
void ephash_enum_writer_init (struct ephash_enum_writer *st, const struct ephash *gh)
{
ephash_enum_init (&st->st, EK_WRITER);
ephash_enum_init (&st->st, gh, EK_WRITER);
}
void ephash_enum_reader_init (struct ephash_enum_reader *st)
void ephash_enum_reader_init (struct ephash_enum_reader *st, const struct ephash *gh)
{
ephash_enum_init (&st->st, EK_READER);
ephash_enum_init (&st->st, gh, EK_READER);
}
void ephash_enum_proxy_writer_init (struct ephash_enum_proxy_writer *st)
void ephash_enum_proxy_writer_init (struct ephash_enum_proxy_writer *st, const struct ephash *gh)
{
ephash_enum_init (&st->st, EK_PROXY_WRITER);
ephash_enum_init (&st->st, gh, EK_PROXY_WRITER);
}
void ephash_enum_proxy_reader_init (struct ephash_enum_proxy_reader *st)
void ephash_enum_proxy_reader_init (struct ephash_enum_proxy_reader *st, const struct ephash *gh)
{
ephash_enum_init (&st->st, EK_PROXY_READER);
ephash_enum_init (&st->st, gh, EK_PROXY_READER);
}
void ephash_enum_participant_init (struct ephash_enum_participant *st)
void ephash_enum_participant_init (struct ephash_enum_participant *st, const struct ephash *gh)
{
ephash_enum_init (&st->st, EK_PARTICIPANT);
ephash_enum_init (&st->st, gh, EK_PARTICIPANT);
}
void ephash_enum_proxy_participant_init (struct ephash_enum_proxy_participant *st)
void ephash_enum_proxy_participant_init (struct ephash_enum_proxy_participant *st, const struct ephash *gh)
{
ephash_enum_init (&st->st, EK_PROXY_PARTICIPANT);
ephash_enum_init (&st->st, gh, EK_PROXY_PARTICIPANT);
}
void *ephash_enum_next (struct ephash_enum *st)

View file

@ -25,6 +25,7 @@
#include "dds/ddsi/q_unused.h"
#include "dds/ddsi/q_lease.h"
#include "dds/ddsi/q_globals.h" /* for mattr, cattr */
#include "dds/ddsi/q_receive.h" /* for trigger_receive_threads */
#include "dds/ddsi/q_rtps.h" /* for guid_hash */
@ -35,10 +36,11 @@ struct gcreq_queue {
ddsrt_cond_t cond;
int terminate;
int32_t count;
struct q_globals *gv;
struct thread_state1 *ts;
};
static void threads_vtime_gather_for_wait (unsigned *nivs, struct idx_vtime *ivs)
static void threads_vtime_gather_for_wait (const struct q_globals *gv, unsigned *nivs, struct idx_vtime *ivs)
{
/* copy vtimes of threads, skipping those that are sleeping */
uint32_t i, j;
@ -47,9 +49,18 @@ static void threads_vtime_gather_for_wait (unsigned *nivs, struct idx_vtime *ivs
vtime_t vtime = ddsrt_atomic_ld32 (&thread_states.ts[i].vtime);
if (vtime_awake_p (vtime))
{
ivs[j].idx = i;
ivs[j].vtime = vtime;
++j;
ddsrt_atomic_fence_ldld ();
/* ts[i].gv is set before ts[i].vtime indicates the thread is awake, so if the thread hasn't
gone through another sleep/wake cycle since loading ts[i].vtime, ts[i].gv is correct; if
instead it has gone through another cycle since loading ts[i].vtime, then the thread will
be dropped from the live threads on the next check. So it won't ever wait with unknown
duration for progres of threads stuck in another domain */
if (gv == ddsrt_atomic_ldvoidp (&thread_states.ts[i].gv))
{
ivs[j].idx = i;
ivs[j].vtime = vtime;
++j;
}
}
}
*nivs = j;
@ -81,7 +92,8 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
{
struct thread_state1 * const ts1 = lookup_thread_state ();
nn_mtime_t next_thread_cputime = { 0 };
dds_time_t shortsleep = 1 * T_MILLISECOND;
nn_mtime_t t_trigger_recv_threads = { 0 };
int64_t shortsleep = 1 * T_MILLISECOND;
int64_t delay = T_MILLISECOND; /* force evaluation after startup */
struct gcreq *gcreq = NULL;
int trace_shortsleep = 1;
@ -90,6 +102,19 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
{
LOG_THREAD_CPUTIME (next_thread_cputime);
/* While deaf, we need to make sure the receive thread wakes up
every now and then to try recreating sockets & rejoining multicast
groups. Do rate-limit it a bit. */
if (q->gv->deaf)
{
nn_mtime_t tnow_mt = now_mt ();
if (tnow_mt.v > t_trigger_recv_threads.v)
{
trigger_recv_threads (q->gv);
t_trigger_recv_threads.v = tnow_mt.v + DDS_MSECS (100);
}
}
/* If we are waiting for a gcreq to become ready, don't bother
looking at the queue; if we aren't, wait for a request to come
in. We can't really wait until something came in because we're
@ -100,14 +125,15 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
if (q->first == NULL)
{
/* FIXME: use absolute timeouts */
/* avoid overflows; ensure periodic wakeups of receive thread if deaf */
const int64_t maxdelay = q->gv->deaf ? DDS_MSECS (100) : DDS_SECS (1000);
dds_time_t to;
if (delay >= 1000 * T_SECOND) {
/* avoid overflow */
to = DDS_SECS(1000);
if (delay >= maxdelay) {
to = maxdelay;
} else {
to = delay;
}
ddsrt_cond_waitfor(&q->cond, &q->lock, to);
ddsrt_cond_waitfor (&q->cond, &q->lock, to);
}
if (q->first)
{
@ -124,8 +150,8 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
very little impact on its primary purpose and be less of a
burden on the system than having a separate thread or adding it
to the workload of the data handling threads. */
thread_state_awake (ts1);
delay = check_and_handle_lease_expiration (now_et ());
thread_state_awake_fixed_domain (ts1);
delay = check_and_handle_lease_expiration (q->gv, now_et ());
thread_state_asleep (ts1);
if (gcreq)
@ -151,7 +177,7 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
multi-phase delete) or freeing the delete request. Reset
the current gcreq as this one obviously is no more. */
DDS_TRACE("gc %p: deleting\n", (void*)gcreq);
thread_state_awake (ts1);
thread_state_awake_fixed_domain (ts1);
gcreq->cb (gcreq);
thread_state_asleep (ts1);
gcreq = NULL;
@ -165,16 +191,17 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
return 0;
}
struct gcreq_queue *gcreq_queue_new (void)
struct gcreq_queue *gcreq_queue_new (struct q_globals *gv)
{
struct gcreq_queue *q = ddsrt_malloc (sizeof (*q));
q->first = q->last = NULL;
q->terminate = 0;
q->count = 0;
q->gv = gv;
ddsrt_mutex_init (&q->lock);
ddsrt_cond_init (&q->cond);
if (create_thread (&q->ts, "gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK)
if (create_thread (&q->ts, gv, "gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK)
return q;
else
{
@ -229,7 +256,7 @@ struct gcreq *gcreq_new (struct gcreq_queue *q, gcreq_cb_t cb)
gcreq = ddsrt_malloc (offsetof (struct gcreq, vtimes) + thread_states.nthreads * sizeof (*gcreq->vtimes));
gcreq->cb = cb;
gcreq->queue = q;
threads_vtime_gather_for_wait (&gcreq->nvtimes, gcreq->vtimes);
threads_vtime_gather_for_wait (q->gv, &gcreq->nvtimes, gcreq->vtimes);
ddsrt_mutex_lock (&q->lock);
q->count++;
ddsrt_mutex_unlock (&q->lock);

File diff suppressed because it is too large Load diff

View file

@ -55,9 +55,9 @@ static int compare_lease_tsched (const void *va, const void *vb);
static const ddsrt_fibheap_def_t lease_fhdef = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct lease, heapnode), compare_lease_tsched);
static void force_lease_check (void)
static void force_lease_check (struct gcreq_queue *gcreq_queue)
{
gcreq_enqueue(gcreq_new(gv.gcreq_queue, gcreq_free));
gcreq_enqueue (gcreq_new (gcreq_queue, gcreq_free));
}
static int compare_lease_tsched (const void *va, const void *vb)
@ -67,16 +67,16 @@ static int compare_lease_tsched (const void *va, const void *vb)
return (a->tsched.v == b->tsched.v) ? 0 : (a->tsched.v < b->tsched.v) ? -1 : 1;
}
void lease_management_init (void)
void lease_management_init (struct q_globals *gv)
{
ddsrt_mutex_init (&gv.leaseheap_lock);
ddsrt_fibheap_init (&lease_fhdef, &gv.leaseheap);
ddsrt_mutex_init (&gv->leaseheap_lock);
ddsrt_fibheap_init (&lease_fhdef, &gv->leaseheap);
}
void lease_management_term (void)
void lease_management_term (struct q_globals *gv)
{
assert (ddsrt_fibheap_min (&lease_fhdef, &gv.leaseheap) == NULL);
ddsrt_mutex_destroy (&gv.leaseheap_lock);
assert (ddsrt_fibheap_min (&lease_fhdef, &gv->leaseheap) == NULL);
ddsrt_mutex_destroy (&gv->leaseheap_lock);
}
struct lease *lease_new (nn_etime_t texpire, dds_duration_t tdur, struct entity_common *e)
@ -92,34 +92,36 @@ struct lease *lease_new (nn_etime_t texpire, dds_duration_t tdur, struct entity_
return l;
}
void lease_register (struct lease *l)
void lease_register (struct lease *l) /* FIXME: make lease admin struct */
{
struct q_globals * const gv = l->entity->gv;
DDS_TRACE("lease_register(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
ddsrt_mutex_lock (&gv.leaseheap_lock);
ddsrt_mutex_lock (&gv->leaseheap_lock);
assert (l->tsched.v == TSCHED_NOT_ON_HEAP);
int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
if (tend != T_NEVER)
{
l->tsched.v = tend;
ddsrt_fibheap_insert (&lease_fhdef, &gv.leaseheap, l);
ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
}
ddsrt_mutex_unlock (&gv.leaseheap_lock);
ddsrt_mutex_unlock (&gv->leaseheap_lock);
/* check_and_handle_lease_expiration runs on GC thread and the only way to be sure that it wakes up in time is by forcing re-evaluation (strictly speaking only needed if this is the first lease to expire, but this operation is quite rare anyway) */
force_lease_check();
force_lease_check (gv->gcreq_queue);
}
void lease_free (struct lease *l)
{
struct q_globals * const gv = l->entity->gv;
DDS_TRACE("lease_free(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
ddsrt_mutex_lock (&gv.leaseheap_lock);
ddsrt_mutex_lock (&gv->leaseheap_lock);
if (l->tsched.v != TSCHED_NOT_ON_HEAP)
ddsrt_fibheap_delete (&lease_fhdef, &gv.leaseheap, l);
ddsrt_mutex_unlock (&gv.leaseheap_lock);
ddsrt_fibheap_delete (&lease_fhdef, &gv->leaseheap, l);
ddsrt_mutex_unlock (&gv->leaseheap_lock);
ddsrt_free (l);
/* see lease_register() */
force_lease_check();
force_lease_check (gv->gcreq_queue);
}
void lease_renew (struct lease *l, nn_etime_t tnowE)
@ -149,9 +151,10 @@ void lease_renew (struct lease *l, nn_etime_t tnowE)
void lease_set_expiry (struct lease *l, nn_etime_t when)
{
struct q_globals * const gv = l->entity->gv;
bool trigger = false;
assert (when.v >= 0);
ddsrt_mutex_lock (&gv.leaseheap_lock);
ddsrt_mutex_lock (&gv->leaseheap_lock);
/* only possible concurrent action is to move tend into the future (renew_lease),
all other operations occur with leaseheap_lock held */
ddsrt_atomic_st64 (&l->tend, (uint64_t) when.v);
@ -160,35 +163,35 @@ void lease_set_expiry (struct lease *l, nn_etime_t when)
/* moved forward and currently scheduled (by virtue of
TSCHED_NOT_ON_HEAP == INT64_MIN) */
l->tsched = when;
ddsrt_fibheap_decrease_key (&lease_fhdef, &gv.leaseheap, l);
ddsrt_fibheap_decrease_key (&lease_fhdef, &gv->leaseheap, l);
trigger = true;
}
else if (l->tsched.v == TSCHED_NOT_ON_HEAP && when.v < T_NEVER)
{
/* not currently scheduled, with a finite new expiry time */
l->tsched = when;
ddsrt_fibheap_insert (&lease_fhdef, &gv.leaseheap, l);
ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
trigger = true;
}
ddsrt_mutex_unlock (&gv.leaseheap_lock);
ddsrt_mutex_unlock (&gv->leaseheap_lock);
/* see lease_register() */
if (trigger)
force_lease_check();
force_lease_check (gv->gcreq_queue);
}
int64_t check_and_handle_lease_expiration (nn_etime_t tnowE)
int64_t check_and_handle_lease_expiration (struct q_globals *gv, nn_etime_t tnowE)
{
struct lease *l;
int64_t delay;
ddsrt_mutex_lock (&gv.leaseheap_lock);
while ((l = ddsrt_fibheap_min (&lease_fhdef, &gv.leaseheap)) != NULL && l->tsched.v <= tnowE.v)
ddsrt_mutex_lock (&gv->leaseheap_lock);
while ((l = ddsrt_fibheap_min (&lease_fhdef, &gv->leaseheap)) != NULL && l->tsched.v <= tnowE.v)
{
nn_guid_t g = l->entity->guid;
enum entity_kind k = l->entity->kind;
assert (l->tsched.v != TSCHED_NOT_ON_HEAP);
ddsrt_fibheap_extract_min (&lease_fhdef, &gv.leaseheap);
ddsrt_fibheap_extract_min (&lease_fhdef, &gv->leaseheap);
/* only possible concurrent action is to move tend into the future (renew_lease),
all other operations occur with leaseheap_lock held */
int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
@ -199,7 +202,7 @@ int64_t check_and_handle_lease_expiration (nn_etime_t tnowE)
l->tsched.v = TSCHED_NOT_ON_HEAP;
} else {
l->tsched.v = tend;
ddsrt_fibheap_insert (&lease_fhdef, &gv.leaseheap, l);
ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
}
continue;
}
@ -234,47 +237,47 @@ int64_t check_and_handle_lease_expiration (nn_etime_t tnowE)
if (k == EK_PROXY_PARTICIPANT)
{
struct proxy_participant *proxypp;
if ((proxypp = ephash_lookup_proxy_participant_guid (&g)) != NULL &&
ephash_lookup_proxy_participant_guid (&proxypp->privileged_pp_guid) != NULL)
if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &g)) != NULL &&
ephash_lookup_proxy_participant_guid (gv->guid_hash, &proxypp->privileged_pp_guid) != NULL)
{
DDS_LOG(DDS_LC_DISCOVERY, "but postponing because privileged pp "PGUIDFMT" is still live\n",
PGUID (proxypp->privileged_pp_guid));
l->tsched = add_duration_to_etime (tnowE, 200 * T_MILLISECOND);
ddsrt_fibheap_insert (&lease_fhdef, &gv.leaseheap, l);
ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
continue;
}
}
l->tsched.v = TSCHED_NOT_ON_HEAP;
ddsrt_mutex_unlock (&gv.leaseheap_lock);
ddsrt_mutex_unlock (&gv->leaseheap_lock);
switch (k)
{
case EK_PARTICIPANT:
delete_participant (&g);
delete_participant (gv, &g);
break;
case EK_PROXY_PARTICIPANT:
delete_proxy_participant_by_guid (&g, now(), 1);
delete_proxy_participant_by_guid (gv, &g, now(), 1);
break;
case EK_WRITER:
delete_writer_nolinger (&g);
delete_writer_nolinger (gv, &g);
break;
case EK_PROXY_WRITER:
delete_proxy_writer (&g, now(), 1);
delete_proxy_writer (gv, &g, now(), 1);
break;
case EK_READER:
(void)delete_reader (&g);
delete_reader (gv, &g);
break;
case EK_PROXY_READER:
delete_proxy_reader (&g, now(), 1);
delete_proxy_reader (gv, &g, now(), 1);
break;
}
ddsrt_mutex_lock (&gv.leaseheap_lock);
ddsrt_mutex_lock (&gv->leaseheap_lock);
}
delay = (l == NULL) ? T_NEVER : (l->tsched.v - tnowE.v);
ddsrt_mutex_unlock (&gv.leaseheap_lock);
ddsrt_mutex_unlock (&gv->leaseheap_lock);
return delay;
}
@ -295,7 +298,7 @@ static void debug_print_rawdata (const char *msg, const void *data, size_t len)
DDS_TRACE(">");
}
void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), nn_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len)
void handle_PMD (const struct receiver_state *rst, nn_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len)
{
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
const int bswap = (data->identifier == CDR_LE) ^ (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN);
@ -325,7 +328,7 @@ void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), nn_wctime_t time
debug_print_rawdata ("", pmd->value, length);
ppguid.prefix = p;
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
if ((pp = ephash_lookup_proxy_participant_guid (&ppguid)) == NULL)
if ((pp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &ppguid)) == NULL)
DDS_TRACE(" PPunknown");
else
{
@ -349,7 +352,7 @@ void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), nn_wctime_t time
{
ppguid.prefix = nn_ntoh_guid_prefix (*((nn_guid_prefix_t *) (data + 1)));
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
if (delete_proxy_participant_by_guid (&ppguid, timestamp, 0) < 0)
if (delete_proxy_participant_by_guid (rst->gv, &ppguid, timestamp, 0) < 0)
DDS_TRACE(" unknown");
else
DDS_TRACE(" delete");

View file

@ -91,16 +91,16 @@ static void set_socket_nodelay (ddsrt_socket_t sock)
}
#endif
static int set_rcvbuf (ddsrt_socket_t socket)
static int set_rcvbuf (ddsrt_socket_t socket, const struct config_maybe_uint32 *min_size)
{
uint32_t ReceiveBufferSize;
socklen_t optlen = (socklen_t) sizeof (ReceiveBufferSize);
uint32_t socket_min_rcvbuf_size;
dds_return_t rc;
if (config.socket_min_rcvbuf_size.isdefault)
if (min_size->isdefault)
socket_min_rcvbuf_size = 1048576;
else
socket_min_rcvbuf_size = config.socket_min_rcvbuf_size.value;
socket_min_rcvbuf_size = min_size->value;
rc = ddsrt_getsockopt(
socket, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, &optlen);
/* TCP/IP stack may not support SO_RCVBUF. */
@ -128,7 +128,7 @@ static int set_rcvbuf (ddsrt_socket_t socket)
if (ReceiveBufferSize < socket_min_rcvbuf_size)
{
/* NN_ERROR does more than just DDS_ERROR(), hence the duplication */
if (config.socket_min_rcvbuf_size.isdefault)
if (min_size->isdefault)
DDS_LOG(DDS_LC_CONFIG, "failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n", socket_min_rcvbuf_size, ReceiveBufferSize);
else
DDS_ERROR("failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n", socket_min_rcvbuf_size, ReceiveBufferSize);
@ -141,7 +141,7 @@ static int set_rcvbuf (ddsrt_socket_t socket)
return 0;
}
static int set_sndbuf (ddsrt_socket_t socket)
static int set_sndbuf (ddsrt_socket_t socket, uint32_t min_size)
{
unsigned SendBufferSize;
socklen_t optlen = (socklen_t) sizeof(SendBufferSize);
@ -155,10 +155,10 @@ static int set_sndbuf (ddsrt_socket_t socket)
print_sockerror ("get SO_SNDBUF");
return -2;
}
if (SendBufferSize < config.socket_min_sndbuf_size )
if (SendBufferSize < min_size )
{
/* make sure the send buffersize is at least the minimum required */
SendBufferSize = config.socket_min_sndbuf_size;
SendBufferSize = min_size;
if (ddsrt_setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (const char *)&SendBufferSize, sizeof (SendBufferSize)) != DDS_RETCODE_OK)
{
print_sockerror ("SO_SNDBUF");
@ -168,12 +168,12 @@ static int set_sndbuf (ddsrt_socket_t socket)
return 0;
}
static int maybe_set_dont_route (ddsrt_socket_t socket)
static int maybe_set_dont_route (ddsrt_socket_t socket, const struct config *config)
{
if (config.dontRoute)
if (config->dontRoute)
{
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_TCP6 || config.transport_selector == TRANS_UDP6)
if (config->transport_selector == TRANS_TCP6 || config->transport_selector == TRANS_UDP6)
{
unsigned ipv6Flag = 1;
if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ipv6Flag, sizeof (ipv6Flag)) != DDS_RETCODE_OK)
@ -184,7 +184,7 @@ static int maybe_set_dont_route (ddsrt_socket_t socket)
}
else
#endif
if (config.transport_selector == TRANS_TCP || config.transport_selector == TRANS_UDP)
if (config->transport_selector == TRANS_TCP || config->transport_selector == TRANS_UDP)
{
int one = 1;
if (ddsrt_setsockopt (socket, SOL_SOCKET, SO_DONTROUTE, (char *) &one, sizeof (one)) != DDS_RETCODE_OK)
@ -215,12 +215,12 @@ static int set_reuse_options (ddsrt_socket_t socket)
return 0;
}
static int bind_socket (ddsrt_socket_t socket, unsigned short port)
static int bind_socket (ddsrt_socket_t socket, unsigned short port, const struct q_globals *gv)
{
dds_return_t rc = DDS_RETCODE_ERROR;
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_TCP6 || config.transport_selector == TRANS_UDP6)
if (gv->config.transport_selector == TRANS_TCP6 || gv->config.transport_selector == TRANS_UDP6)
{
struct sockaddr_in6 socketname;
memset (&socketname, 0, sizeof (socketname));
@ -228,13 +228,13 @@ static int bind_socket (ddsrt_socket_t socket, unsigned short port)
socketname.sin6_port = htons (port);
socketname.sin6_addr = ddsrt_in6addr_any;
if (IN6_IS_ADDR_LINKLOCAL (&socketname.sin6_addr)) {
socketname.sin6_scope_id = gv.interfaceNo;
socketname.sin6_scope_id = gv->interfaceNo;
}
rc = ddsrt_bind (socket, (struct sockaddr *) &socketname, sizeof (socketname));
}
else
#endif
if (config.transport_selector == TRANS_TCP || config.transport_selector == TRANS_UDP)
if (gv->config.transport_selector == TRANS_TCP || gv->config.transport_selector == TRANS_UDP)
{
struct sockaddr_in socketname;
socketname.sin_family = AF_INET;
@ -250,10 +250,10 @@ static int bind_socket (ddsrt_socket_t socket, unsigned short port)
}
#if DDSRT_HAVE_IPV6
static int set_mc_options_transmit_ipv6 (ddsrt_socket_t socket)
static int set_mc_options_transmit_ipv6 (ddsrt_socket_t socket, const struct q_globals *gv)
{
unsigned interfaceNo = gv.interfaceNo;
unsigned ttl = (unsigned) config.multicast_ttl;
unsigned interfaceNo = gv->interfaceNo;
unsigned ttl = (unsigned) gv->config.multicast_ttl;
unsigned loop;
if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_IF, &interfaceNo, sizeof (interfaceNo)) != DDS_RETCODE_OK)
{
@ -265,7 +265,7 @@ static int set_mc_options_transmit_ipv6 (ddsrt_socket_t socket)
print_sockerror ("IPV6_MULTICAST_HOPS");
return -2;
}
loop = (unsigned) !!config.enableMulticastLoopback;
loop = (unsigned) !!gv->config.enableMulticastLoopback;
if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof (loop)) != DDS_RETCODE_OK)
{
print_sockerror ("IPV6_MULTICAST_LOOP");
@ -275,30 +275,30 @@ static int set_mc_options_transmit_ipv6 (ddsrt_socket_t socket)
}
#endif
static int set_mc_options_transmit_ipv4 (ddsrt_socket_t socket)
static int set_mc_options_transmit_ipv4 (ddsrt_socket_t socket, const struct q_globals *gv)
{
unsigned char ttl = (unsigned char) config.multicast_ttl;
unsigned char ttl = (unsigned char) gv->config.multicast_ttl;
unsigned char loop;
dds_return_t ret;
#if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET
if (config.use_multicast_if_mreqn)
if (gv->config.use_multicast_if_mreqn)
{
struct ip_mreqn mreqn;
memset (&mreqn, 0, sizeof (mreqn));
/* looks like imr_multiaddr is not relevant, not sure about imr_address */
mreqn.imr_multiaddr.s_addr = htonl (INADDR_ANY);
if (config.use_multicast_if_mreqn > 1)
memcpy (&mreqn.imr_address.s_addr, gv.ownloc.address + 12, 4);
if (gv->config.use_multicast_if_mreqn > 1)
memcpy (&mreqn.imr_address.s_addr, gv->ownloc.address + 12, 4);
else
mreqn.imr_address.s_addr = htonl (INADDR_ANY);
mreqn.imr_ifindex = (int) gv.interfaceNo;
mreqn.imr_ifindex = (int) gv->interfaceNo;
ret = ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof (mreqn));
}
else
#endif
{
ret = ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, gv.ownloc.address + 12, 4);
ret = ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, gv->ownloc.address + 12, 4);
}
if (ret != DDS_RETCODE_OK)
{
@ -310,7 +310,7 @@ static int set_mc_options_transmit_ipv4 (ddsrt_socket_t socket)
print_sockerror ("IP_MULICAST_TTL");
return -2;
}
loop = (unsigned char) config.enableMulticastLoopback;
loop = (unsigned char) gv->config.enableMulticastLoopback;
if (ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof (loop)) != DDS_RETCODE_OK)
{
@ -320,18 +320,18 @@ static int set_mc_options_transmit_ipv4 (ddsrt_socket_t socket)
return 0;
}
static int set_mc_options_transmit (ddsrt_socket_t socket)
static int set_mc_options_transmit (ddsrt_socket_t socket, const struct q_globals *gv)
{
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_TCP6 || config.transport_selector == TRANS_UDP6)
if (gv->config.transport_selector == TRANS_TCP6 || gv->config.transport_selector == TRANS_UDP6)
{
return set_mc_options_transmit_ipv6 (socket);
return set_mc_options_transmit_ipv6 (socket, gv);
}
else
#endif
if (config.transport_selector == TRANS_TCP || config.transport_selector == TRANS_UDP)
if (gv->config.transport_selector == TRANS_TCP || gv->config.transport_selector == TRANS_UDP)
{
return set_mc_options_transmit_ipv4 (socket);
return set_mc_options_transmit_ipv4 (socket, gv);
}
else
{
@ -339,25 +339,20 @@ static int set_mc_options_transmit (ddsrt_socket_t socket)
}
}
int make_socket
(
ddsrt_socket_t * sock,
uint16_t port,
bool stream,
bool reuse
)
int make_socket (ddsrt_socket_t *sock, uint16_t port, bool stream, bool reuse, const struct q_globals *gv)
{
/* FIXME: this stuff has to move to the transports */
int rc = -2;
dds_return_t ret;
#if DDSRT_HAVE_IPV6
if (config.transport_selector == TRANS_TCP6 || config.transport_selector == TRANS_UDP6)
if (gv->config.transport_selector == TRANS_TCP6 || gv->config.transport_selector == TRANS_UDP6)
{
ret = ddsrt_socket(sock, AF_INET6, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
}
else
#endif
if (config.transport_selector == TRANS_TCP || config.transport_selector == TRANS_UDP)
if (gv->config.transport_selector == TRANS_TCP || gv->config.transport_selector == TRANS_UDP)
{
ret = ddsrt_socket(sock, AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
}
@ -379,10 +374,10 @@ int make_socket
if
(
(rc = set_rcvbuf (*sock) < 0) ||
(rc = set_sndbuf (*sock) < 0) ||
((rc = maybe_set_dont_route (*sock)) < 0) ||
((rc = bind_socket (*sock, port)) < 0)
(rc = set_rcvbuf (*sock, &gv->config.socket_min_rcvbuf_size) < 0) ||
(rc = set_sndbuf (*sock, gv->config.socket_min_sndbuf_size) < 0) ||
((rc = maybe_set_dont_route (*sock, &gv->config)) < 0) ||
((rc = bind_socket (*sock, port, gv)) < 0)
)
{
goto fail;
@ -390,7 +385,7 @@ int make_socket
if (! stream)
{
if ((rc = set_mc_options_transmit (*sock)) < 0)
if ((rc = set_mc_options_transmit (*sock, gv)) < 0)
{
goto fail;
}
@ -402,7 +397,7 @@ int make_socket
set_socket_nosigpipe (*sock);
#endif
#ifdef TCP_NODELAY
if (config.tcp_nodelay)
if (gv->config.tcp_nodelay)
{
set_socket_nodelay (*sock);
}
@ -418,9 +413,9 @@ fail:
return rc;
}
static int multicast_override(const char *ifname)
static int multicast_override(const char *ifname, const struct config *config)
{
char *copy = ddsrt_strdup (config.assumeMulticastCapable), *cursor = copy, *tok;
char *copy = ddsrt_strdup (config->assumeMulticastCapable), *cursor = copy, *tok;
int match = 0;
if (copy != NULL)
{
@ -439,7 +434,7 @@ static int multicast_override(const char *ifname)
#include <linux/if_packet.h>
#endif
int find_own_ip (const char *requested_address)
int find_own_ip (struct q_globals *gv, const char *requested_address)
{
const char *sep = " ";
char last_if_name[80] = "";
@ -456,14 +451,14 @@ int find_own_ip (const char *requested_address)
{
int ret;
ret = ddsi_enumerate_interfaces(gv.m_factory, &ifa_root);
ret = ddsi_enumerate_interfaces(gv->m_factory, gv->config.transport_selector, &ifa_root);
if (ret < 0) {
DDS_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, ret);
DDS_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv->m_factory->m_typename, ret);
return 0;
}
}
gv.n_interfaces = 0;
gv->n_interfaces = 0;
last_if_name[0] = 0;
for (ifa = ifa_root; ifa != NULL; ifa = ifa->next)
{
@ -501,7 +496,7 @@ int find_own_ip (const char *requested_address)
if (ifa->addr->sa_family == AF_PACKET)
{
/* FIXME: weirdo warning warranted */
nn_locator_t *l = &gv.interfaces[gv.n_interfaces].loc;
nn_locator_t *l = &gv->interfaces[gv->n_interfaces].loc;
l->kind = NN_LOCATOR_KIND_RAWETH;
l->port = NN_LOCATOR_PORT_INVALID;
memset(l->address, 0, 10);
@ -510,12 +505,12 @@ int find_own_ip (const char *requested_address)
else
#endif
{
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, ifa->addr, gv.m_factory->m_kind);
ddsi_ipaddr_to_loc(&gv->interfaces[gv->n_interfaces].loc, ifa->addr, gv->m_factory->m_kind);
}
ddsi_locator_to_string_no_port(addrbuf, sizeof(addrbuf), &gv.interfaces[gv.n_interfaces].loc);
ddsi_locator_to_string_no_port(gv, addrbuf, sizeof(addrbuf), &gv->interfaces[gv->n_interfaces].loc);
DDS_LOG(DDS_LC_CONFIG, " %s(", addrbuf);
if (!(ifa->flags & IFF_MULTICAST) && multicast_override (if_name))
if (!(ifa->flags & IFF_MULTICAST) && multicast_override (if_name, &gv->config))
{
DDS_LOG(DDS_LC_CONFIG, "assume-mc:");
ifa->flags |= IFF_MULTICAST;
@ -562,11 +557,11 @@ int find_own_ip (const char *requested_address)
DDS_LOG(DDS_LC_CONFIG, "q%d)", q);
if (q == quality) {
maxq_list[maxq_count] = gv.n_interfaces;
maxq_list[maxq_count] = gv->n_interfaces;
maxq_strlen += 2 + strlen (if_name);
maxq_count++;
} else if (q > quality) {
maxq_list[0] = gv.n_interfaces;
maxq_list[0] = gv->n_interfaces;
maxq_strlen += 2 + strlen (if_name);
maxq_count = 1;
quality = q;
@ -574,20 +569,20 @@ int find_own_ip (const char *requested_address)
if (ifa->addr->sa_family == AF_INET && ifa->netmask)
{
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].netmask, ifa->netmask, gv.m_factory->m_kind);
ddsi_ipaddr_to_loc(&gv->interfaces[gv->n_interfaces].netmask, ifa->netmask, gv->m_factory->m_kind);
}
else
{
gv.interfaces[gv.n_interfaces].netmask.kind = gv.m_factory->m_kind;
gv.interfaces[gv.n_interfaces].netmask.port = NN_LOCATOR_PORT_INVALID;
memset(&gv.interfaces[gv.n_interfaces].netmask.address, 0, sizeof(gv.interfaces[gv.n_interfaces].netmask.address));
gv->interfaces[gv->n_interfaces].netmask.kind = gv->m_factory->m_kind;
gv->interfaces[gv->n_interfaces].netmask.port = NN_LOCATOR_PORT_INVALID;
memset(&gv->interfaces[gv->n_interfaces].netmask.address, 0, sizeof(gv->interfaces[gv->n_interfaces].netmask.address));
}
gv.interfaces[gv.n_interfaces].mc_capable = ((ifa->flags & IFF_MULTICAST) != 0);
gv.interfaces[gv.n_interfaces].mc_flaky = ((ifa->type == DDSRT_IFTYPE_WIFI) != 0);
gv.interfaces[gv.n_interfaces].point_to_point = ((ifa->flags & IFF_POINTOPOINT) != 0);
gv.interfaces[gv.n_interfaces].if_index = ifa->index;
gv.interfaces[gv.n_interfaces].name = ddsrt_strdup (if_name);
gv.n_interfaces++;
gv->interfaces[gv->n_interfaces].mc_capable = ((ifa->flags & IFF_MULTICAST) != 0);
gv->interfaces[gv->n_interfaces].mc_flaky = ((ifa->type == DDSRT_IFTYPE_WIFI) != 0);
gv->interfaces[gv->n_interfaces].point_to_point = ((ifa->flags & IFF_POINTOPOINT) != 0);
gv->interfaces[gv->n_interfaces].if_index = ifa->index;
gv->interfaces[gv->n_interfaces].name = ddsrt_strdup (if_name);
gv->n_interfaces++;
}
DDS_LOG(DDS_LC_CONFIG, "\n");
ddsrt_freeifaddrs (ifa_root);
@ -599,13 +594,13 @@ int find_own_ip (const char *requested_address)
const int idx = maxq_list[0];
char *names;
int p;
ddsi_locator_to_string_no_port (addrbuf, sizeof(addrbuf), &gv.interfaces[idx].loc);
ddsi_locator_to_string_no_port (gv, addrbuf, sizeof(addrbuf), &gv->interfaces[idx].loc);
names = ddsrt_malloc (maxq_strlen + 1);
p = 0;
for (i = 0; i < maxq_count && (size_t) p < maxq_strlen; i++)
p += snprintf (names + p, maxq_strlen - (size_t) p, ", %s", gv.interfaces[maxq_list[i]].name);
p += snprintf (names + p, maxq_strlen - (size_t) p, ", %s", gv->interfaces[maxq_list[i]].name);
DDS_WARNING("using network interface %s (%s) selected arbitrarily from: %s\n",
gv.interfaces[idx].name, addrbuf, names + 2);
gv->interfaces[idx].name, addrbuf, names + 2);
ddsrt_free (names);
}
@ -618,32 +613,32 @@ int find_own_ip (const char *requested_address)
{
nn_locator_t req;
/* Presumably an interface name */
for (i = 0; i < gv.n_interfaces; i++)
for (i = 0; i < gv->n_interfaces; i++)
{
if (strcmp (gv.interfaces[i].name, config.networkAddressString) == 0)
if (strcmp (gv->interfaces[i].name, gv->config.networkAddressString) == 0)
break;
}
if (i < gv.n_interfaces)
if (i < gv->n_interfaces)
; /* got a match */
else if (ddsi_locator_from_string(&req, config.networkAddressString) != AFSR_OK)
; /* not good, i = gv.n_interfaces, so error handling will kick in */
else if (ddsi_locator_from_string(gv, &req, gv->config.networkAddressString, gv->m_factory) != AFSR_OK)
; /* not good, i = gv->n_interfaces, so error handling will kick in */
else
{
/* Try an exact match on the address */
for (i = 0; i < gv.n_interfaces; i++)
if (compare_locators(&gv.interfaces[i].loc, &req) == 0)
for (i = 0; i < gv->n_interfaces; i++)
if (compare_locators(&gv->interfaces[i].loc, &req) == 0)
break;
if (i == gv.n_interfaces && req.kind == NN_LOCATOR_KIND_UDPv4)
if (i == gv->n_interfaces && req.kind == NN_LOCATOR_KIND_UDPv4)
{
/* Try matching on network portion only, where the network
portion is based on the netmask of the interface under
consideration */
for (i = 0; i < gv.n_interfaces; i++)
for (i = 0; i < gv->n_interfaces; i++)
{
uint32_t req1, ip1, nm1;
memcpy (&req1, req.address + 12, sizeof (req1));
memcpy (&ip1, gv.interfaces[i].loc.address + 12, sizeof (ip1));
memcpy (&nm1, gv.interfaces[i].netmask.address + 12, sizeof (nm1));
memcpy (&ip1, gv->interfaces[i].loc.address + 12, sizeof (ip1));
memcpy (&nm1, gv->interfaces[i].netmask.address + 12, sizeof (nm1));
/* If the host portion of the requested address is non-zero,
skip this interface */
@ -656,33 +651,33 @@ int find_own_ip (const char *requested_address)
}
}
if (i < gv.n_interfaces)
if (i < gv->n_interfaces)
selected_idx = i;
else
DDS_ERROR("%s: does not match an available interface\n", config.networkAddressString);
DDS_ERROR("%s: does not match an available interface\n", gv->config.networkAddressString);
}
if (selected_idx < 0)
return 0;
else
{
gv.ownloc = gv.interfaces[selected_idx].loc;
gv.selected_interface = selected_idx;
gv.interfaceNo = gv.interfaces[selected_idx].if_index;
gv->ownloc = gv->interfaces[selected_idx].loc;
gv->selected_interface = selected_idx;
gv->interfaceNo = gv->interfaces[selected_idx].if_index;
#if DDSRT_HAVE_IPV6
if (gv.extloc.kind == NN_LOCATOR_KIND_TCPv6 || gv.extloc.kind == NN_LOCATOR_KIND_UDPv6)
if (gv->extloc.kind == NN_LOCATOR_KIND_TCPv6 || gv->extloc.kind == NN_LOCATOR_KIND_UDPv6)
{
struct sockaddr_in6 addr;
memcpy(&addr.sin6_addr, gv.ownloc.address, sizeof(addr.sin6_addr));
gv.ipv6_link_local = IN6_IS_ADDR_LINKLOCAL (&addr.sin6_addr) != 0;
memcpy(&addr.sin6_addr, gv->ownloc.address, sizeof(addr.sin6_addr));
gv->ipv6_link_local = IN6_IS_ADDR_LINKLOCAL (&addr.sin6_addr) != 0;
}
else
{
gv.ipv6_link_local = 0;
gv->ipv6_link_local = 0;
}
#endif
DDS_LOG(DDS_LC_CONFIG, "selected interface: %s (index %u)\n",
gv.interfaces[selected_idx].name, gv.interfaceNo);
gv->interfaces[selected_idx].name, gv->interfaceNo);
return 1;
}

View file

@ -127,17 +127,9 @@ static uint16_t calc_ipv4_checksum (const uint16_t *x)
return (uint16_t) ~s;
}
void write_pcap_received
(
FILE * fp,
nn_wctime_t tstamp,
const struct sockaddr_storage * src,
const struct sockaddr_storage * dst,
unsigned char * buf,
size_t sz
)
void write_pcap_received (struct q_globals *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz)
{
if (config.transport_selector == TRANS_UDP)
if (gv->config.transport_selector == TRANS_UDP)
{
pcaprec_hdr_t pcap_hdr;
union {
@ -147,37 +139,30 @@ void write_pcap_received
udp_hdr_t udp_hdr;
size_t sz_ud = sz + UDP_HDR_SIZE;
size_t sz_iud = sz_ud + IPV4_HDR_SIZE;
ddsrt_mutex_lock (&gv.pcap_lock);
ddsrt_mutex_lock (&gv->pcap_lock);
wctime_to_sec_usec (&pcap_hdr.ts_sec, &pcap_hdr.ts_usec, tstamp);
pcap_hdr.incl_len = pcap_hdr.orig_len = (uint32_t) sz_iud;
fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, fp);
fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, gv->pcap_fp);
u.ipv4_hdr = ipv4_hdr_template;
u.ipv4_hdr.totallength = toBE2u ((unsigned short) sz_iud);
u.ipv4_hdr.ttl = 128;
u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr;
u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr.s_addr;
u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x);
fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, fp);
fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp);
udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port;
udp_hdr.dstport = ((struct sockaddr_in*) dst)->sin_port;
udp_hdr.length = toBE2u ((unsigned short) sz_ud);
udp_hdr.checksum = 0; /* don't have to compute a checksum for UDPv4 */
fwrite (&udp_hdr, sizeof (udp_hdr), 1, fp);
fwrite (buf, sz, 1, fp);
ddsrt_mutex_unlock (&gv.pcap_lock);
fwrite (&udp_hdr, sizeof (udp_hdr), 1, gv->pcap_fp);
fwrite (buf, sz, 1, gv->pcap_fp);
ddsrt_mutex_unlock (&gv->pcap_lock);
}
}
void write_pcap_sent
(
FILE * fp,
nn_wctime_t tstamp,
const struct sockaddr_storage * src,
const ddsrt_msghdr_t * hdr,
size_t sz
)
void write_pcap_sent (struct q_globals *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, const ddsrt_msghdr_t *hdr, size_t sz)
{
if (config.transport_selector == TRANS_UDP)
if (gv->config.transport_selector == TRANS_UDP)
{
pcaprec_hdr_t pcap_hdr;
union {
@ -187,23 +172,23 @@ void write_pcap_sent
udp_hdr_t udp_hdr;
size_t sz_ud = sz + UDP_HDR_SIZE;
size_t sz_iud = sz_ud + IPV4_HDR_SIZE;
ddsrt_mutex_lock (&gv.pcap_lock);
ddsrt_mutex_lock (&gv->pcap_lock);
wctime_to_sec_usec (&pcap_hdr.ts_sec, &pcap_hdr.ts_usec, tstamp);
pcap_hdr.incl_len = pcap_hdr.orig_len = (uint32_t) sz_iud;
fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, fp);
fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, gv->pcap_fp);
u.ipv4_hdr = ipv4_hdr_template;
u.ipv4_hdr.totallength = toBE2u ((unsigned short) sz_iud);
u.ipv4_hdr.ttl = 255;
u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr;
u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr.s_addr;
u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x);
fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, fp);
fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp);
udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port;
udp_hdr.dstport = ((struct sockaddr_in*) hdr->msg_name)->sin_port;
udp_hdr.length = toBE2u ((unsigned short) sz_ud);
udp_hdr.checksum = 0; /* don't have to compute a checksum for UDPv4 */
fwrite (&udp_hdr, sizeof (udp_hdr), 1, fp);
write_data (fp, hdr, sz);
ddsrt_mutex_unlock (&gv.pcap_lock);
fwrite (&udp_hdr, sizeof (udp_hdr), 1, gv->pcap_fp);
write_data (gv->pcap_fp, hdr, sz);
ddsrt_mutex_unlock (&gv->pcap_lock);
}
}

View file

@ -75,6 +75,7 @@ struct dd {
unsigned bswap: 1;
nn_protocol_version_t protocol_version;
nn_vendorid_t vendorid;
ddsi_tran_factory_t factory;
};
#define PDF_QOS 1 /* part of dds_qos_t */
@ -136,9 +137,10 @@ static dds_return_t validate_resource_limits_qospolicy (const dds_resource_limit
static dds_return_t validate_history_and_resource_limits (const dds_history_qospolicy_t *qh, const dds_resource_limits_qospolicy_t *qr);
static dds_return_t validate_external_duration (const ddsi_duration_t *d);
static dds_return_t validate_durability_service_qospolicy_acceptzero (const dds_durability_service_qospolicy_t *q, bool acceptzero);
static dds_return_t do_locator (nn_locators_t *ls, uint64_t *present, uint64_t wanted, uint64_t fl, const struct dd *dd);
static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_version_t protocol_version, nn_vendorid_t vendorid, bool *dursvc_accepted_allzero);
static dds_return_t do_locator (nn_locators_t *ls, uint64_t *present, uint64_t wanted, uint64_t fl, const struct dd *dd, const struct ddsi_tran_factory *factory);
static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_version_t protocol_version, nn_vendorid_t vendorid, bool *dursvc_accepted_allzero, bool strict);
static int partitions_equal (const dds_partition_qospolicy_t *a, const dds_partition_qospolicy_t *b);
static dds_return_t nn_xqos_valid_strictness (const dds_qos_t *xqos, bool strict);
static size_t align4size (size_t x)
{
@ -271,7 +273,7 @@ static dds_return_t deser_locator (void * __restrict dst, size_t * __restrict ds
struct dd tmpdd = *dd;
tmpdd.buf += *srcoff;
tmpdd.bufsz -= *srcoff;
if (do_locator (x, flagset->present, flagset->wanted, flag, &tmpdd) < 0)
if (do_locator (x, flagset->present, flagset->wanted, flag, &tmpdd, dd->factory) < 0)
return DDS_RETCODE_BAD_PARAMETER;
*srcoff += 24;
*dstoff += sizeof (*x);
@ -1457,7 +1459,7 @@ void nn_plist_unalias (nn_plist_t *plist)
plist_or_xqos_unalias (plist, 0);
}
dds_return_t nn_xqos_valid (const dds_qos_t *xqos)
static dds_return_t nn_xqos_valid_strictness (const dds_qos_t *xqos, bool strict)
{
dds_return_t ret;
if (piddesc_unalias[0] == NULL)
@ -1485,13 +1487,18 @@ dds_return_t nn_xqos_valid (const dds_qos_t *xqos)
}
}
}
if ((ret = final_validation_qos (xqos, (nn_protocol_version_t) { RTPS_MAJOR, RTPS_MINOR }, NN_VENDORID_ECLIPSE, NULL)) < 0)
if ((ret = final_validation_qos (xqos, (nn_protocol_version_t) { RTPS_MAJOR, RTPS_MINOR }, NN_VENDORID_ECLIPSE, NULL, strict)) < 0)
{
DDS_LOG (DDS_LC_PLIST, "nn_xqos_valid: final validation failed\n");
}
return ret;
}
dds_return_t nn_xqos_valid (const dds_qos_t *xqos)
{
return nn_xqos_valid_strictness (xqos, true);
}
uint64_t nn_xqos_delta (const dds_qos_t *x, const dds_qos_t *y, uint64_t mask)
{
if (piddesc_unalias[0] == NULL)
@ -1682,7 +1689,7 @@ static int locator_address_zero (const nn_locator_t *loc)
return (u[0] == 0 && u[1] == 0 && u[2] == 0 && u[3] == 0);
}
static dds_return_t do_locator (nn_locators_t *ls, uint64_t *present, uint64_t wanted, uint64_t fl, const struct dd *dd)
static dds_return_t do_locator (nn_locators_t *ls, uint64_t *present, uint64_t wanted, uint64_t fl, const struct dd *dd, const struct ddsi_tran_factory *factory)
{
nn_locator_t loc;
@ -1711,7 +1718,7 @@ static dds_return_t do_locator (nn_locators_t *ls, uint64_t *present, uint64_t w
break;
case NN_LOCATOR_KIND_UDPv4MCGEN: {
const nn_udpv4mcgen_address_t *x = (const nn_udpv4mcgen_address_t *) loc.address;
if (!ddsi_factory_supports (gv.m_factory, NN_LOCATOR_KIND_UDPv4))
if (!ddsi_factory_supports (factory, NN_LOCATOR_KIND_UDPv4))
return 0;
if (loc.port <= 0 || loc.port > 65536)
return DDS_RETCODE_BAD_PARAMETER;
@ -1730,20 +1737,20 @@ static dds_return_t do_locator (nn_locators_t *ls, uint64_t *present, uint64_t w
/* silently dropped "reserved" locators. */
return 0;
default:
return NN_PEDANTIC_P ? DDS_RETCODE_BAD_PARAMETER : 0;
return 0;
}
return add_locator (ls, present, wanted, fl, &loc);
}
static void locator_from_ipv4address_port (nn_locator_t *loc, const nn_ipv4address_t *a, const nn_port_t *p)
static void locator_from_ipv4address_port (nn_locator_t *loc, const nn_ipv4address_t *a, const nn_port_t *p, ddsi_tran_factory_t factory)
{
loc->kind = gv.m_factory->m_connless ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_TCPv4;
loc->kind = factory->m_connless ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_TCPv4;
loc->port = *p;
memset (loc->address, 0, 12);
memcpy (loc->address + 12, a, 4);
}
static dds_return_t do_ipv4address (nn_plist_t *dest, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t wanted, uint32_t fl_tmp, const struct dd *dd)
static dds_return_t do_ipv4address (nn_plist_t *dest, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t wanted, uint32_t fl_tmp, const struct dd *dd, ddsi_tran_factory_t factory)
{
nn_ipv4address_t *a;
nn_port_t *p;
@ -1800,7 +1807,7 @@ static dds_return_t do_ipv4address (nn_plist_t *dest, nn_ipaddress_params_tmp_t
allows adding another pair. */
nn_locator_t loc;
locator_from_ipv4address_port (&loc, a, p);
locator_from_ipv4address_port (&loc, a, p, factory);
dest_tmp->present &= ~(fl_tmp | fl1_tmp);
return add_locator (ls, &dest->present, wanted, fldest, &loc);
}
@ -1810,7 +1817,7 @@ static dds_return_t do_ipv4address (nn_plist_t *dest, nn_ipaddress_params_tmp_t
}
}
static dds_return_t do_port (nn_plist_t *dest, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t wanted, uint32_t fl_tmp, const struct dd *dd)
static dds_return_t do_port (nn_plist_t *dest, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t wanted, uint32_t fl_tmp, const struct dd *dd, ddsi_tran_factory_t factory)
{
nn_ipv4address_t *a;
nn_port_t *p;
@ -1857,7 +1864,7 @@ static dds_return_t do_port (nn_plist_t *dest, nn_ipaddress_params_tmp_t *dest_t
both address & port from the set of present plist: this
allows adding another pair. */
nn_locator_t loc;
locator_from_ipv4address_port (&loc, a, p);
locator_from_ipv4address_port (&loc, a, p, factory);
dest_tmp->present &= ~(fl_tmp | fl1_tmp);
return add_locator (ls, &dest->present, wanted, fldest, &loc);
}
@ -1878,14 +1885,14 @@ static dds_return_t return_unrecognized_pid (nn_plist_t *plist, nn_parameterid_t
}
}
static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t pwanted, uint64_t qwanted, uint16_t pid, const struct dd *dd)
static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t pwanted, uint64_t qwanted, uint16_t pid, const struct dd *dd, ddsi_tran_factory_t factory)
{
/* special-cased ipv4address and port, because they have state beyond that what gets
passed into the generic code */
switch (pid)
{
#define XA(NAME_) case PID_##NAME_##_IPADDRESS: return do_ipv4address (plist, dest_tmp, pwanted, PPTMP_##NAME_##_IPADDRESS, dd)
#define XP(NAME_) case PID_##NAME_##_PORT: return do_port (plist, dest_tmp, pwanted, PPTMP_##NAME_##_PORT, dd)
#define XA(NAME_) case PID_##NAME_##_IPADDRESS: return do_ipv4address (plist, dest_tmp, pwanted, PPTMP_##NAME_##_IPADDRESS, dd, factory)
#define XP(NAME_) case PID_##NAME_##_PORT: return do_port (plist, dest_tmp, pwanted, PPTMP_##NAME_##_PORT, dd, factory)
XA (MULTICAST);
XA (DEFAULT_UNICAST);
XP (DEFAULT_UNICAST);
@ -2014,7 +2021,7 @@ void nn_plist_init_empty (nn_plist_t *dest)
nn_xqos_init_empty (&dest->qos);
}
static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_version_t protocol_version, nn_vendorid_t vendorid, bool *dursvc_accepted_allzero)
static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_version_t protocol_version, nn_vendorid_t vendorid, bool *dursvc_accepted_allzero, bool strict)
{
/* input is const, but we need to validate the combination of
history & resource limits: so use a copy of those two policies */
@ -2066,7 +2073,7 @@ static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_ver
acceptzero = false;
else if (protocol_version_is_newer (protocol_version))
acceptzero = true;
else if (NN_STRICT_P)
else if (strict)
acceptzero = vendor_is_twinoaks (vendorid);
else
acceptzero = !vendor_is_eclipse (vendorid);
@ -2091,9 +2098,9 @@ static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_ver
return 0;
}
static dds_return_t final_validation (nn_plist_t *dest, nn_protocol_version_t protocol_version, nn_vendorid_t vendorid, bool *dursvc_accepted_allzero)
static dds_return_t final_validation (nn_plist_t *dest, nn_protocol_version_t protocol_version, nn_vendorid_t vendorid, bool *dursvc_accepted_allzero, bool strict)
{
return final_validation_qos (&dest->qos, protocol_version, vendorid, dursvc_accepted_allzero);
return final_validation_qos (&dest->qos, protocol_version, vendorid, dursvc_accepted_allzero, strict);
}
dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uint64_t pwanted, uint64_t qwanted, const nn_plist_src_t *src)
@ -2110,6 +2117,7 @@ dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uin
*nextafterplist = NULL;
dd.protocol_version = src->protocol_version;
dd.vendorid = src->vendorid;
dd.factory = src->factory;
switch (src->encoding)
{
case PL_CDR_LE:
@ -2153,7 +2161,7 @@ dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uin
/* Sentinel terminates list, the length is ignored, DDSI 9.4.2.11. */
bool dursvc_accepted_allzero;
DDS_LOG(DDS_LC_PLIST, "%4"PRIx32" PID %"PRIx16"\n", (uint32_t) (pl - src->buf), pid);
if ((res = final_validation (dest, src->protocol_version, src->vendorid, &dursvc_accepted_allzero)) < 0)
if ((res = final_validation (dest, src->protocol_version, src->vendorid, &dursvc_accepted_allzero, src->strict)) < 0)
{
nn_plist_fini (dest);
return res;
@ -2194,7 +2202,7 @@ dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uin
dd.buf = (const unsigned char *) (par + 1);
dd.bufsz = length;
if ((res = init_one_parameter (dest, &dest_tmp, pwanted, qwanted, pid, &dd)) < 0)
if ((res = init_one_parameter (dest, &dest_tmp, pwanted, qwanted, pid, &dd, src->factory)) < 0)
{
/* make sure we print a trace message on error */
DDS_TRACE("plist(vendor %u.%u): failed at pid=%"PRIx16"\n", src->vendorid.id[0], src->vendorid.id[1], pid);

View file

@ -1613,12 +1613,13 @@ struct nn_reorder {
enum nn_reorder_mode mode;
uint32_t max_samples;
uint32_t n_samples;
bool late_ack_mode;
};
static const ddsrt_avl_treedef_t reorder_sampleivtree_treedef =
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct nn_rsample, u.reorder.avlnode), offsetof (struct nn_rsample, u.reorder.min), compare_seqno, 0);
struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples)
struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples, bool late_ack_mode)
{
struct nn_reorder *r;
if ((r = ddsrt_malloc (sizeof (*r))) == NULL)
@ -1629,6 +1630,7 @@ struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_sampl
r->mode = mode;
r->max_samples = max_samples;
r->n_samples = 0;
r->late_ack_mode = late_ack_mode;
return r;
}
@ -1988,7 +1990,7 @@ nn_reorder_result_t nn_reorder_rsample (struct nn_rsample_chain *sc, struct nn_r
struct nn_rsample *predeq, *immsucc;
DDS_LOG(DDS_LC_RADMIN, " hard case ...\n");
if (config.late_ack_mode && delivery_queue_full_p)
if (reorder->late_ack_mode && delivery_queue_full_p)
{
DDS_LOG(DDS_LC_RADMIN, " discarding sample: delivery queue full\n");
return NN_REORDER_REJECT;
@ -2421,7 +2423,7 @@ static uint32_t dqueue_thread (struct nn_dqueue *q)
q->sc.first = q->sc.last = NULL;
ddsrt_mutex_unlock (&q->lock);
thread_state_awake (ts1);
thread_state_awake_fixed_domain (ts1);
while (sc.first)
{
struct nn_rsample_chain_elem *e = sc.first;
@ -2489,7 +2491,7 @@ static uint32_t dqueue_thread (struct nn_dqueue *q)
return 0;
}
struct nn_dqueue *nn_dqueue_new (const char *name, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg)
struct nn_dqueue *nn_dqueue_new (const char *name, const struct q_globals *gv, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg)
{
struct nn_dqueue *q;
char *thrname;
@ -2512,7 +2514,7 @@ struct nn_dqueue *nn_dqueue_new (const char *name, uint32_t max_samples, nn_dque
if ((thrname = ddsrt_malloc (thrnamesz)) == NULL)
goto fail_thrname;
snprintf (thrname, thrnamesz, "dq.%s", name);
if (create_thread (&q->ts, thrname, (uint32_t (*) (void *)) dqueue_thread, q) != DDS_RETCODE_OK)
if (create_thread (&q->ts, gv, thrname, (uint32_t (*) (void *)) dqueue_thread, q) != DDS_RETCODE_OK)
goto fail_thread;
ddsrt_free (thrname);
return q;

View file

@ -224,24 +224,9 @@ static int valid_Heartbeat (Heartbeat_t *msg, size_t size, int byteswap)
}
msg->readerId = nn_ntoh_entityid (msg->readerId);
msg->writerId = nn_ntoh_entityid (msg->writerId);
/* Validation following 8.3.7.5.3 */
if (fromSN (msg->firstSN) <= 0 ||
/* fromSN (msg->lastSN) <= 0 || -- implicit in last < first */
fromSN (msg->lastSN) < fromSN (msg->firstSN))
{
if (NN_STRICT_P)
return 0;
else
{
/* Note that we don't actually know the set of all possible
malformed messages that we have to process, so we stick to
the ones we've seen */
if (fromSN (msg->firstSN) == fromSN (msg->lastSN) + 1)
; /* ok */
else
return 0;
}
}
/* Validation following 8.3.7.5.3; lastSN + 1 == firstSN: no data */
if (fromSN (msg->firstSN) <= 0 || fromSN (msg->lastSN) + 1 < fromSN (msg->firstSN))
return 0;
return 1;
}
@ -293,9 +278,9 @@ static int valid_NackFrag (NackFrag_t *msg, size_t size, int byteswap)
return 1;
}
static void set_sampleinfo_proxy_writer (struct nn_rsample_info *sampleinfo, nn_guid_t * pwr_guid)
static void set_sampleinfo_proxy_writer (struct nn_rsample_info *sampleinfo, nn_guid_t *pwr_guid)
{
struct proxy_writer * pwr = ephash_lookup_proxy_writer_guid (pwr_guid);
struct proxy_writer * pwr = ephash_lookup_proxy_writer_guid (sampleinfo->rst->gv->guid_hash, pwr_guid);
sampleinfo->pwr = pwr;
}
@ -432,7 +417,7 @@ static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rms
pwr_guid.prefix = rst->src_guid_prefix;
pwr_guid.entityid = msg->x.writerId;
if (NN_STRICT_P && msg->fragmentSize <= 1024 && msg->fragmentSize < config.fragment_size)
if (NN_STRICT_P (rst->gv->config) && msg->fragmentSize <= 1024 && msg->fragmentSize < rst->gv->config.fragment_size)
{
/* Spec says fragments must > 1kB; not allowing 1024 bytes is IMHO
totally ridiculous; and I really don't care how small the
@ -443,7 +428,7 @@ static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rms
}
if (msg->fragmentSize == 0 || msg->fragmentStartingNum == 0 || msg->fragmentsInSubmessage == 0)
return 0;
if (NN_STRICT_P && msg->fragmentSize >= msg->sampleSize)
if (NN_STRICT_P (rst->gv->config) && msg->fragmentSize >= msg->sampleSize)
/* may not fragment if not needed -- but I don't care */
return 0;
if ((msg->fragmentStartingNum + msg->fragmentsInSubmessage - 2) * msg->fragmentSize >= msg->sampleSize)
@ -554,7 +539,7 @@ static void force_heartbeat_to_peer (struct writer *wr, const struct whc_state *
ASSERT_MUTEX_HELD (&wr->e.lock);
assert (wr->reliable);
m = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
m = nn_xmsg_new (wr->e.gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
if (nn_xmsg_setdstPRD (m, prd) < 0)
{
/* If we don't have an address, give up immediately */
@ -668,7 +653,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
return 1;
}
if ((wr = ephash_lookup_writer_guid (&dst)) == NULL)
if ((wr = ephash_lookup_writer_guid (rst->gv->guid_hash, &dst)) == NULL)
{
DDS_TRACE(" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst));
return 1;
@ -677,7 +662,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
the normal pure ack steady state. If (a big "if"!) this shows up
as a significant portion of the time, we can always rewrite it to
only retrieve it when needed. */
if ((prd = ephash_lookup_proxy_reader_guid (&src)) == NULL)
if ((prd = ephash_lookup_proxy_reader_guid (rst->gv->guid_hash, &src)) == NULL)
{
DDS_TRACE(" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
return 1;
@ -724,7 +709,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
work so well if the timestamp can be a left over from some other
submessage -- but then, it is no more than a quick hack at the
moment. */
if (config.meas_hb_to_ack_latency && timestamp.v)
if (rst->gv->config.meas_hb_to_ack_latency && timestamp.v)
{
nn_wctime_t tstamp_now = now ();
nn_lat_estim_update (&rn->hb_to_ack_latency, tstamp_now.v - timestamp.v);
@ -814,7 +799,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
DDS_TRACE(" rebase ");
force_heartbeat_to_peer (wr, &whcst, prd, 0);
hb_sent_in_response = 1;
numbits = config.accelerate_rexmit_block_size;
numbits = rst->gv->config.accelerate_rexmit_block_size;
seqbase = whcst.min_seq;
}
}
@ -830,12 +815,12 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
DDS_TRACE(" happy-now");
rn->assumed_in_sync = 1;
}
else if (msg->readerSNState.numbits < config.accelerate_rexmit_block_size)
else if (msg->readerSNState.numbits < rst->gv->config.accelerate_rexmit_block_size)
{
DDS_TRACE(" accelerating");
accelerate_rexmit = 1;
if (accelerate_rexmit && numbits < config.accelerate_rexmit_block_size)
numbits = config.accelerate_rexmit_block_size;
if (accelerate_rexmit && numbits < rst->gv->config.accelerate_rexmit_block_size)
numbits = rst->gv->config.accelerate_rexmit_block_size;
}
else
{
@ -871,11 +856,11 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
if (!wr->retransmitting && sample.unacked)
writer_set_retransmitting (wr);
if (config.retransmit_merging != REXMIT_MERGE_NEVER && rn->assumed_in_sync)
if (rst->gv->config.retransmit_merging != REXMIT_MERGE_NEVER && rn->assumed_in_sync)
{
/* send retransmit to all receivers, but skip if recently done */
nn_mtime_t tstamp = now_mt ();
if (tstamp.v > sample.last_rexmit_ts.v + config.retransmit_merging_period)
if (tstamp.v > sample.last_rexmit_ts.v + rst->gv->config.retransmit_merging_period)
{
DDS_TRACE(" RX%"PRId64, seqbase + i);
enqueued = (enqueue_sample_wrlock_held (wr, seq, sample.plist, sample.serdata, NULL, 0) >= 0);
@ -951,7 +936,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
DDS_TRACE(" XGAP%"PRId64"..%"PRId64"/%u:", gapstart, gapend, gapnumbits);
for (uint32_t i = 0; i < gapnumbits; i++)
DDS_TRACE("%c", nn_bitset_isset (gapnumbits, gapbits, i) ? '1' : '0');
m = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
m = nn_xmsg_new (rst->gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
nn_xmsg_setencoderid (m, wr->partition_id);
#endif
@ -1054,6 +1039,7 @@ struct handle_Heartbeat_helper_arg {
static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct handle_Heartbeat_helper_arg * const arg)
{
struct receiver_state * const rst = arg->rst;
Heartbeat_t const * const msg = arg->msg;
struct proxy_writer * const pwr = arg->pwr;
seqno_t refseq;
@ -1090,11 +1076,11 @@ static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct hand
if (pwr->last_seq > refseq)
{
DDS_TRACE("/NAK");
if (arg->tnow_mt.v >= wn->t_last_nack.v + config.nack_delay || refseq >= wn->seq_last_nack)
if (arg->tnow_mt.v >= wn->t_last_nack.v + rst->gv->config.nack_delay || refseq >= wn->seq_last_nack)
tsched = arg->tnow_mt;
else
{
tsched.v = arg->tnow_mt.v + config.nack_delay;
tsched.v = arg->tnow_mt.v + rst->gv->config.nack_delay;
DDS_TRACE("d");
}
}
@ -1104,7 +1090,7 @@ static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct hand
}
if (resched_xevent_if_earlier (wn->acknack_xevent, tsched))
{
if (config.meas_hb_to_ack_latency && arg->timestamp.v)
if (rst->gv->config.meas_hb_to_ack_latency && arg->timestamp.v)
wn->hb_timestamp = arg->timestamp;
}
}
@ -1142,7 +1128,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct
return 1;
}
if ((pwr = ephash_lookup_proxy_writer_guid (&src)) == NULL)
if ((pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &src)) == NULL)
{
DDS_TRACE(PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
return 1;
@ -1279,7 +1265,7 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
return 1;
}
if ((pwr = ephash_lookup_proxy_writer_guid (&src)) == NULL)
if ((pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &src)) == NULL)
{
DDS_TRACE(" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
return 1;
@ -1360,7 +1346,7 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
{
/* Yes we are (note that this potentially also happens for
samples we no longer care about) */
int64_t delay = config.nack_delay;
int64_t delay = rst->gv->config.nack_delay;
DDS_TRACE("/nackfrag");
resched_xevent_if_earlier (m->acknack_xevent, add_duration_to_mtime (now_mt(), delay));
}
@ -1397,7 +1383,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
return 1;
}
if ((wr = ephash_lookup_writer_guid (&dst)) == NULL)
if ((wr = ephash_lookup_writer_guid (rst->gv->guid_hash, &dst)) == NULL)
{
DDS_TRACE(" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst));
return 1;
@ -1406,7 +1392,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
the normal pure ack steady state. If (a big "if"!) this shows up
as a significant portion of the time, we can always rewrite it to
only retrieve it when needed. */
if ((prd = ephash_lookup_proxy_reader_guid (&src)) == NULL)
if ((prd = ephash_lookup_proxy_reader_guid (rst->gv->guid_hash, &src)) == NULL)
{
DDS_TRACE(" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
return 1;
@ -1462,7 +1448,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
static uint32_t zero = 0;
struct nn_xmsg *m;
DDS_TRACE(" msg not available: scheduling Gap\n");
m = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
m = nn_xmsg_new (rst->gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
nn_xmsg_setencoderid (m, wr->partition_id);
#endif
@ -1508,8 +1494,8 @@ static int handle_InfoDST (struct receiver_state *rst, const InfoDST_t *msg, con
nn_guid_t dst;
dst.prefix = rst->dst_guid_prefix;
dst.entityid = to_entityid(NN_ENTITYID_PARTICIPANT);
rst->forme = (ephash_lookup_participant_guid (&dst) != NULL ||
is_deleted_participant_guid (gv.deleted_participants, &dst, DPG_LOCAL));
rst->forme = (ephash_lookup_participant_guid (rst->gv->guid_hash, &dst) != NULL ||
is_deleted_participant_guid (rst->gv->deleted_participants, &dst, DPG_LOCAL));
}
return 1;
}
@ -1653,7 +1639,7 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
return 1;
}
if ((pwr = ephash_lookup_proxy_writer_guid (&src)) == NULL)
if ((pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &src)) == NULL)
{
DDS_TRACE(""PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
return 1;
@ -1788,7 +1774,7 @@ static struct ddsi_serdata *extract_sample_from_data
{
/* RTI always tries to make us survive on the keyhash. RTI must
mend its ways. */
if (NN_STRICT_P)
if (NN_STRICT_P (sampleinfo->rst->gv->config))
failmsg = "no content";
else if (!(qos->present & PP_KEYHASH))
failmsg = "qos present but without keyhash";
@ -1911,6 +1897,8 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE;
src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset);
src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset;
src.strict = NN_STRICT_P (rst->gv->config);
src.factory = rst->gv->m_factory;
if ((plist_ret = nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH | PP_COHERENT_SET, 0, &src)) < 0)
{
if (plist_ret != DDS_RETCODE_UNSUPPORTED)
@ -1940,11 +1928,11 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
/* Generate the DDS_SampleInfo (which is faked to some extent
because we don't actually have a data reader) */
struct ddsi_tkmap_instance * tk;
if ((tk = ddsi_tkmap_lookup_instance_ref(payload)) != NULL)
struct ddsi_tkmap_instance *tk;
if ((tk = ddsi_tkmap_lookup_instance_ref (pwr->e.gv->m_tkmap, payload)) != NULL)
{
struct proxy_writer_info pwr_info;
make_proxy_writer_info(&pwr_info, &pwr->e, pwr->c.xqos);
make_proxy_writer_info (&pwr_info, &pwr->e, pwr->c.xqos);
if (rdguid == NULL)
{
@ -1996,7 +1984,7 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
for (m = ddsrt_avl_iter_first (&pwr_readers_treedef, &pwr->readers, &it); m != NULL; m = ddsrt_avl_iter_next (&it))
{
struct reader *rd;
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL && m->in_sync == PRMSS_SYNC)
if ((rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, &m->rd_guid)) != NULL && m->in_sync == PRMSS_SYNC)
{
DDS_TRACE("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
(void) rhc_store (rd->rhc, &pwr_info, payload, tk);
@ -2009,16 +1997,16 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
}
else
{
struct reader *rd = ephash_lookup_reader_guid (rdguid);;
struct reader *rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, rdguid);
DDS_TRACE(" %"PRId64"=>"PGUIDFMT"%s\n", sampleinfo->seq, PGUID (*rdguid), rd ? "" : "?");
while (rd && ! rhc_store (rd->rhc, &pwr_info, payload, tk) && ephash_lookup_proxy_writer_guid (&pwr->e.guid))
while (rd && ! rhc_store (rd->rhc, &pwr_info, payload, tk) && ephash_lookup_proxy_writer_guid (pwr->e.gv->guid_hash, &pwr->e.guid))
{
if (pwr_locked) ddsrt_mutex_unlock (&pwr->e.lock);
dds_sleepfor (DDS_MSECS (1));
if (pwr_locked) ddsrt_mutex_lock (&pwr->e.lock);
}
}
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (pwr->e.gv->m_tkmap, tk);
}
ddsi_serdata_unref (payload);
no_payload:
@ -2255,18 +2243,19 @@ static void handle_regular (struct receiver_state *rst, nn_etime_t tnow, struct
static int handle_SPDP (const struct nn_rsample_info *sampleinfo, struct nn_rdata *rdata)
{
struct q_globals * const gv = sampleinfo->rst->gv;
struct nn_rsample *rsample;
struct nn_rsample_chain sc;
struct nn_rdata *fragchain;
nn_reorder_result_t rres;
int refc_adjust = 0;
ddsrt_mutex_lock (&gv.spdp_lock);
rsample = nn_defrag_rsample (gv.spdp_defrag, rdata, sampleinfo);
ddsrt_mutex_lock (&gv->spdp_lock);
rsample = nn_defrag_rsample (gv->spdp_defrag, rdata, sampleinfo);
fragchain = nn_rsample_fragchain (rsample);
if ((rres = nn_reorder_rsample (&sc, gv.spdp_reorder, rsample, &refc_adjust, nn_dqueue_is_full (gv.builtins_dqueue))) > 0)
nn_dqueue_enqueue (gv.builtins_dqueue, &sc, rres);
if ((rres = nn_reorder_rsample (&sc, gv->spdp_reorder, rsample, &refc_adjust, nn_dqueue_is_full (gv->builtins_dqueue))) > 0)
nn_dqueue_enqueue (gv->builtins_dqueue, &sc, rres);
nn_fragchain_adjust_refcount (fragchain, refc_adjust);
ddsrt_mutex_unlock (&gv.spdp_lock);
ddsrt_mutex_unlock (&gv->spdp_lock);
return 0;
}
@ -2281,7 +2270,7 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con
if (msg->writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)
{
DDS_WARNING ("dropping oversize (%"PRIu32" > %"PRIu32") SPDP sample %"PRId64" from remote writer "PGUIDFMT"\n",
sampleinfo->size, config.max_sample_size, sampleinfo->seq,
sampleinfo->size, rst->gv->config.max_sample_size, sampleinfo->seq,
PGUIDPREFIX (rst->src_guid_prefix), msg->writerId.u);
}
}
@ -2311,7 +2300,7 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con
const char *tname = pwr->c.topic ? pwr->c.topic->name : "(null)";
const char *ttname = pwr->c.topic ? pwr->c.topic->type_name : "(null)";
DDS_WARNING ("dropping oversize (%"PRIu32" > %"PRIu32") sample %"PRId64" from remote writer "PGUIDFMT" %s/%s\n",
sampleinfo->size, config.max_sample_size, sampleinfo->seq,
sampleinfo->size, rst->gv->config.max_sample_size, sampleinfo->seq,
PGUIDPREFIX (rst->src_guid_prefix), msg->writerId.u,
tname, ttname);
}
@ -2330,7 +2319,7 @@ static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_r
return 1;
}
if (sampleinfo->size > config.max_sample_size)
if (sampleinfo->size > rst->gv->config.max_sample_size)
drop_oversize (rst, rmsg, &msg->x, sampleinfo);
else
{
@ -2375,7 +2364,7 @@ static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct
return 1;
}
if (sampleinfo->size > config.max_sample_size)
if (sampleinfo->size > rst->gv->config.max_sample_size)
drop_oversize (rst, rmsg, &msg->x, sampleinfo);
else
{
@ -2595,6 +2584,7 @@ static struct receiver_state *rst_cow_if_needed (int *rst_live, struct nn_rmsg *
static int handle_submsg_sequence
(
struct thread_state1 * const ts1,
struct q_globals *gv,
ddsi_tran_conn_t conn,
const nn_locator_t *srcloc,
nn_wctime_t tnowWC,
@ -2640,12 +2630,13 @@ static int handle_submsg_sequence
rst->vendor = hdr->vendorid;
rst->protocol_version = hdr->version;
rst->srcloc = *srcloc;
rst->gv = gv;
rst_live = 0;
ts_for_latmeas = 0;
timestamp = NN_WCTIME_INVALID;
assert (thread_is_asleep ());
thread_state_awake (ts1);
thread_state_awake_fixed_domain (ts1);
while (submsg <= (end - sizeof (SubmessageHeader_t)))
{
Submessage_t *sm = (Submessage_t *) submsg;
@ -2911,6 +2902,7 @@ malformed_asleep:
static bool do_packet
(
struct thread_state1 * const ts1,
struct q_globals *gv,
ddsi_tran_conn_t conn,
const nn_guid_prefix_t * guidprefix,
struct nn_rbufpool *rbpool
@ -2918,7 +2910,7 @@ static bool do_packet
{
/* UDP max packet size is 64kB */
const size_t maxsz = config.rmsg_chunk_size < 65536 ? config.rmsg_chunk_size : 65536;
const size_t maxsz = gv->config.rmsg_chunk_size < 65536 ? gv->config.rmsg_chunk_size : 65536;
const size_t ddsi_msg_len_size = 8;
const size_t stream_hdr_size = RTPS_MESSAGE_HEADER_SIZE + ddsi_msg_len_size;
ssize_t sz;
@ -2995,7 +2987,7 @@ static bool do_packet
sz = ddsi_conn_read (conn, buff, buff_len, true, &srcloc);
}
if (sz > 0 && !gv.deaf)
if (sz > 0 && !gv->deaf)
{
nn_rmsg_setsize (rmsg, (uint32_t) sz);
assert (thread_is_asleep ());
@ -3009,7 +3001,7 @@ static bool do_packet
if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM))
DDS_TRACE("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n",
PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, hdr->version.major, hdr->version.minor);
if (NN_PEDANTIC_P)
if (NN_PEDANTIC_P (gv->config))
malformed_packet_received_nosubmsg (buff, sz, "header", hdr->vendorid);
}
else
@ -3019,12 +3011,12 @@ static bool do_packet
if (dds_get_log_mask() & DDS_LC_TRACE)
{
char addrstr[DDSI_LOCSTRLEN];
ddsi_locator_to_string(addrstr, sizeof(addrstr), &srcloc);
ddsi_locator_to_string(gv, addrstr, sizeof(addrstr), &srcloc);
DDS_TRACE("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu from %s\n",
PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, addrstr);
}
handle_submsg_sequence (ts1, conn, &srcloc, now (), now_et (), &hdr->guid_prefix, guidprefix, buff, (size_t) sz, buff + RTPS_MESSAGE_HEADER_SIZE, rmsg);
handle_submsg_sequence (ts1, gv, conn, &srcloc, now (), now_et (), &hdr->guid_prefix, guidprefix, buff, (size_t) sz, buff + RTPS_MESSAGE_HEADER_SIZE, rmsg);
}
}
nn_rmsg_commit (rmsg);
@ -3077,11 +3069,11 @@ struct local_participant_set {
uint32_t gen;
};
static void local_participant_set_init (struct local_participant_set *lps)
static void local_participant_set_init (struct local_participant_set *lps, ddsrt_atomic_uint32_t *ppset_generation)
{
lps->ps = NULL;
lps->nps = 0;
lps->gen = ddsrt_atomic_ld32 (&gv.participant_set_generation) - 1;
lps->gen = ddsrt_atomic_ld32 (ppset_generation) - 1;
}
static void local_participant_set_fini (struct local_participant_set *lps)
@ -3089,23 +3081,23 @@ static void local_participant_set_fini (struct local_participant_set *lps)
ddsrt_free (lps->ps);
}
static void rebuild_local_participant_set (struct thread_state1 * const ts1, struct local_participant_set *lps)
static void rebuild_local_participant_set (struct thread_state1 * const ts1, struct q_globals *gv, struct local_participant_set *lps)
{
struct ephash_enum_participant est;
struct participant *pp;
unsigned nps_alloc;
DDS_TRACE("pp set gen changed: local %"PRIu32" global %"PRIu32"\n", lps->gen, ddsrt_atomic_ld32(&gv.participant_set_generation));
thread_state_awake (ts1);
DDS_TRACE("pp set gen changed: local %"PRIu32" global %"PRIu32"\n", lps->gen, ddsrt_atomic_ld32 (&gv->participant_set_generation));
thread_state_awake_fixed_domain (ts1);
restart:
lps->gen = ddsrt_atomic_ld32 (&gv.participant_set_generation);
lps->gen = ddsrt_atomic_ld32 (&gv->participant_set_generation);
/* Actual local set of participants may never be older than the
local generation count => membar to guarantee the ordering */
ddsrt_atomic_fence_acq ();
nps_alloc = gv.nparticipants;
nps_alloc = gv->nparticipants;
ddsrt_free (lps->ps);
lps->nps = 0;
lps->ps = (nps_alloc == 0) ? NULL : ddsrt_malloc (nps_alloc * sizeof (*lps->ps));
ephash_enum_participant_init (&est);
ephash_enum_participant_init (&est, gv->guid_hash);
while ((pp = ephash_enum_participant_next (&est)) != NULL)
{
if (lps->nps == nps_alloc)
@ -3135,7 +3127,7 @@ static void rebuild_local_participant_set (struct thread_state1 * const ts1, str
explicit destination. Membar because we must have completed
the loop before testing the generation again. */
ddsrt_atomic_fence_acq ();
if (lps->gen != ddsrt_atomic_ld32 (&gv.participant_set_generation))
if (lps->gen != ddsrt_atomic_ld32 (&gv->participant_set_generation))
{
DDS_TRACE(" set changed - restarting\n");
goto restart;
@ -3155,19 +3147,20 @@ static void rebuild_local_participant_set (struct thread_state1 * const ts1, str
DDS_TRACE(" nparticipants %u\n", lps->nps);
}
uint32_t listen_thread (struct ddsi_tran_listener * listener)
uint32_t listen_thread (struct ddsi_tran_listener *listener)
{
struct q_globals *gv = listener->m_base.gv;
ddsi_tran_conn_t conn;
while (ddsrt_atomic_ld32 (&gv.rtps_keepgoing))
while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing))
{
/* Accept connection from listener */
conn = ddsi_listener_accept (listener);
if (conn)
{
os_sockWaitsetAdd (gv.recv_threads[0].arg.u.many.ws, conn);
os_sockWaitsetTrigger (gv.recv_threads[0].arg.u.many.ws);
os_sockWaitsetAdd (gv->recv_threads[0].arg.u.many.ws, conn);
os_sockWaitsetTrigger (gv->recv_threads[0].arg.u.many.ws);
}
}
return 0;
@ -3177,10 +3170,14 @@ static int recv_thread_waitset_add_conn (os_sockWaitset ws, ddsi_tran_conn_t con
{
if (conn == NULL)
return 0;
for (uint32_t i = 0; i < gv.n_recv_threads; i++)
if (gv.recv_threads[i].arg.mode == RTM_SINGLE && gv.recv_threads[i].arg.u.single.conn == conn)
return 0;
return os_sockWaitsetAdd (ws, conn);
else
{
struct q_globals *gv = conn->m_base.gv;
for (uint32_t i = 0; i < gv->n_recv_threads; i++)
if (gv->recv_threads[i].arg.mode == RTM_SINGLE && gv->recv_threads[i].arg.u.single.conn == conn)
return 0;
return os_sockWaitsetAdd (ws, conn);
}
}
enum local_deaf_state_recover {
@ -3194,7 +3191,7 @@ struct local_deaf_state {
nn_mtime_t tnext;
};
static int check_and_handle_deafness_recover(struct local_deaf_state *st, unsigned num_fixed_uc)
static int check_and_handle_deafness_recover (struct q_globals *gv, struct local_deaf_state *st, unsigned num_fixed_uc)
{
int rebuildws = 0;
if (now_mt().v < st->tnext.v)
@ -3208,19 +3205,19 @@ static int check_and_handle_deafness_recover(struct local_deaf_state *st, unsign
assert(0);
break;
case LDSR_DEAF: {
ddsi_tran_conn_t disc = gv.disc_conn_mc, data = gv.data_conn_mc;
DDS_TRACE("check_and_handle_deafness_recover: state %d create new sockets\n", (int)st->state);
if (!create_multicast_sockets())
ddsi_tran_conn_t disc = gv->disc_conn_mc, data = gv->data_conn_mc;
DDS_TRACE("check_and_handle_deafness_recover: state %d create new sockets\n", (int) st->state);
if (!create_multicast_sockets (gv))
goto error;
DDS_TRACE("check_and_handle_deafness_recover: state %d transfer group membership admin\n", (int)st->state);
ddsi_transfer_group_membership(disc, gv.disc_conn_mc);
ddsi_transfer_group_membership(data, gv.data_conn_mc);
DDS_TRACE("check_and_handle_deafness_recover: state %d drop from waitset and add new\n", (int)st->state);
DDS_TRACE("check_and_handle_deafness_recover: state %d transfer group membership admin\n", (int) st->state);
ddsi_transfer_group_membership (gv->mship, disc, gv->disc_conn_mc);
ddsi_transfer_group_membership (gv->mship, data, gv->data_conn_mc);
DDS_TRACE("check_and_handle_deafness_recover: state %d drop from waitset and add new\n", (int) st->state);
/* see waitset construction code in recv_thread */
os_sockWaitsetPurge (gv.recv_threads[0].arg.u.many.ws, num_fixed_uc);
if (recv_thread_waitset_add_conn (gv.recv_threads[0].arg.u.many.ws, gv.disc_conn_mc) < 0)
os_sockWaitsetPurge (gv->recv_threads[0].arg.u.many.ws, num_fixed_uc);
if (recv_thread_waitset_add_conn (gv->recv_threads[0].arg.u.many.ws, gv->disc_conn_mc) < 0)
DDS_FATAL("check_and_handle_deafness_recover: failed to add disc_conn_mc to waitset\n");
if (recv_thread_waitset_add_conn (gv.recv_threads[0].arg.u.many.ws, gv.data_conn_mc) < 0)
if (recv_thread_waitset_add_conn (gv->recv_threads[0].arg.u.many.ws, gv->data_conn_mc) < 0)
DDS_FATAL("check_and_handle_deafness_recover: failed to add data_conn_mc to waitset\n");
DDS_TRACE("check_and_handle_deafness_recover: state %d close sockets\n", (int)st->state);
ddsi_conn_free(disc);
@ -3231,10 +3228,10 @@ static int check_and_handle_deafness_recover(struct local_deaf_state *st, unsign
/* FALLS THROUGH */
case LDSR_REJOIN:
DDS_TRACE("check_and_handle_deafness_recover: state %d rejoin on disc socket\n", (int)st->state);
if (ddsi_rejoin_transferred_mcgroups(gv.disc_conn_mc) < 0)
if (ddsi_rejoin_transferred_mcgroups (gv, gv->mship, gv->disc_conn_mc) < 0)
goto error;
DDS_TRACE("check_and_handle_deafness_recover: state %d rejoin on data socket\n", (int)st->state);
if (ddsi_rejoin_transferred_mcgroups(gv.data_conn_mc) < 0)
if (ddsi_rejoin_transferred_mcgroups (gv, gv->mship, gv->data_conn_mc) < 0)
goto error;
DDS_TRACE("check_and_handle_deafness_recover: state %d done\n", (int)st->state);
st->state = LDSR_NORMAL;
@ -3249,9 +3246,9 @@ DDS_TRACE("check_and_handle_deafness_recover: state %d failed, returning %d\n",
return rebuildws;
}
static int check_and_handle_deafness(struct local_deaf_state *st, unsigned num_fixed_uc)
static int check_and_handle_deafness (struct q_globals *gv, struct local_deaf_state *st, unsigned num_fixed_uc)
{
const int gv_deaf = gv.deaf;
const int gv_deaf = gv->deaf;
assert (gv_deaf == 0 || gv_deaf == 1);
if (gv_deaf == (int)st->state)
return 0;
@ -3262,7 +3259,7 @@ static int check_and_handle_deafness(struct local_deaf_state *st, unsigned num_f
st->tnext = now_mt();
return 0;
}
else if (!config.allowMulticast)
else if (!gv->config.allowMulticast)
{
DDS_TRACE("check_and_handle_deafness: no longer deaf (multicast disabled)\n");
st->state = LDSR_NORMAL;
@ -3270,32 +3267,32 @@ static int check_and_handle_deafness(struct local_deaf_state *st, unsigned num_f
}
else
{
return check_and_handle_deafness_recover(st, num_fixed_uc);
return check_and_handle_deafness_recover (gv, st, num_fixed_uc);
}
}
void trigger_recv_threads (void)
void trigger_recv_threads (const struct q_globals *gv)
{
for (uint32_t i = 0; i < gv.n_recv_threads; i++)
for (uint32_t i = 0; i < gv->n_recv_threads; i++)
{
if (gv.recv_threads[i].ts == NULL)
if (gv->recv_threads[i].ts == NULL)
continue;
switch (gv.recv_threads[i].arg.mode)
switch (gv->recv_threads[i].arg.mode)
{
case RTM_SINGLE: {
char buf[DDSI_LOCSTRLEN];
char dummy = 0;
const nn_locator_t *dst = gv.recv_threads[i].arg.u.single.loc;
const nn_locator_t *dst = gv->recv_threads[i].arg.u.single.loc;
ddsrt_iovec_t iov;
iov.iov_base = &dummy;
iov.iov_len = 1;
DDS_TRACE("trigger_recv_threads: %d single %s\n", i, ddsi_locator_to_string (buf, sizeof (buf), dst));
ddsi_conn_write (gv.data_conn_uc, dst, 1, &iov, 0);
DDS_TRACE("trigger_recv_threads: %d single %s\n", i, ddsi_locator_to_string (gv, buf, sizeof (buf), dst));
ddsi_conn_write (gv->data_conn_uc, dst, 1, &iov, 0);
break;
}
case RTM_MANY: {
DDS_TRACE("trigger_recv_threads: %d many %p\n", i, (void *) gv.recv_threads[i].arg.u.many.ws);
os_sockWaitsetTrigger (gv.recv_threads[i].arg.u.many.ws);
DDS_TRACE("trigger_recv_threads: %d many %p\n", i, (void *) gv->recv_threads[i].arg.u.many.ws);
os_sockWaitsetTrigger (gv->recv_threads[i].arg.u.many.ws);
break;
}
}
@ -3306,6 +3303,7 @@ uint32_t recv_thread (void *vrecv_thread_arg)
{
struct thread_state1 * const ts1 = lookup_thread_state ();
struct recv_thread_arg *recv_thread_arg = vrecv_thread_arg;
struct q_globals * const gv = recv_thread_arg->gv;
struct nn_rbufpool *rbpool = recv_thread_arg->rbpool;
os_sockWaitset waitset = recv_thread_arg->mode == RTM_MANY ? recv_thread_arg->u.many.ws : NULL;
nn_mtime_t next_thread_cputime = { 0 };
@ -3313,10 +3311,11 @@ uint32_t recv_thread (void *vrecv_thread_arg)
nn_rbufpool_setowner (rbpool, ddsrt_thread_self ());
if (waitset == NULL)
{
while (ddsrt_atomic_ld32 (&gv.rtps_keepgoing))
struct ddsi_tran_conn *conn = recv_thread_arg->u.single.conn;
while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing))
{
LOG_THREAD_CPUTIME (next_thread_cputime);
(void) do_packet (ts1, recv_thread_arg->u.single.conn, NULL, rbpool);
(void) do_packet (ts1, gv, conn, NULL, rbpool);
}
}
else
@ -3325,46 +3324,46 @@ uint32_t recv_thread (void *vrecv_thread_arg)
unsigned num_fixed = 0, num_fixed_uc = 0;
os_sockWaitsetCtx ctx;
struct local_deaf_state lds;
lds.state = gv.deaf ? LDSR_DEAF : LDSR_NORMAL;
lds.state = gv->deaf ? LDSR_DEAF : LDSR_NORMAL;
lds.tnext = now_mt();
local_participant_set_init (&lps);
if (gv.m_factory->m_connless)
local_participant_set_init (&lps, &gv->participant_set_generation);
if (gv->m_factory->m_connless)
{
int rc;
if ((rc = recv_thread_waitset_add_conn (waitset, gv.disc_conn_uc)) < 0)
if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_uc)) < 0)
DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n");
num_fixed_uc += (unsigned)rc;
if ((rc = recv_thread_waitset_add_conn (waitset, gv.data_conn_uc)) < 0)
if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_uc)) < 0)
DDS_FATAL("recv_thread: failed to add data_conn_uc to waitset\n");
num_fixed_uc += (unsigned)rc;
num_fixed += num_fixed_uc;
if ((rc = recv_thread_waitset_add_conn (waitset, gv.disc_conn_mc)) < 0)
if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_mc)) < 0)
DDS_FATAL("recv_thread: failed to add disc_conn_mc to waitset\n");
num_fixed += (unsigned)rc;
if ((rc = recv_thread_waitset_add_conn (waitset, gv.data_conn_mc)) < 0)
if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_mc)) < 0)
DDS_FATAL("recv_thread: failed to add data_conn_mc to waitset\n");
num_fixed += (unsigned)rc;
}
while (ddsrt_atomic_ld32 (&gv.rtps_keepgoing))
while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing))
{
int rebuildws;
LOG_THREAD_CPUTIME (next_thread_cputime);
rebuildws = check_and_handle_deafness(&lds, num_fixed_uc);
if (config.many_sockets_mode != MSM_MANY_UNICAST)
rebuildws = check_and_handle_deafness (gv, &lds, num_fixed_uc);
if (gv->config.many_sockets_mode != MSM_MANY_UNICAST)
{
/* no other sockets to check */
}
else if (ddsrt_atomic_ld32 (&gv.participant_set_generation) != lps.gen)
else if (ddsrt_atomic_ld32 (&gv->participant_set_generation) != lps.gen)
{
rebuildws = 1;
}
if (rebuildws && waitset && config.many_sockets_mode == MSM_MANY_UNICAST)
if (rebuildws && waitset && gv->config.many_sockets_mode == MSM_MANY_UNICAST)
{
/* first rebuild local participant set - unless someone's toggling "deafness", this
only happens when the participant set has changed, so might as well rebuild it */
rebuild_local_participant_set (ts1, &lps);
rebuild_local_participant_set (ts1, gv, &lps);
os_sockWaitsetPurge (waitset, num_fixed);
for (uint32_t i = 0; i < lps.nps; i++)
{
@ -3380,12 +3379,12 @@ uint32_t recv_thread (void *vrecv_thread_arg)
while ((idx = os_sockWaitsetNextEvent (ctx, &conn)) >= 0)
{
const nn_guid_prefix_t *guid_prefix;
if (((unsigned)idx < num_fixed) || config.many_sockets_mode != MSM_MANY_UNICAST)
if (((unsigned)idx < num_fixed) || gv->config.many_sockets_mode != MSM_MANY_UNICAST)
guid_prefix = NULL;
else
guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix;
/* Process message and clean out connection if failed or closed */
if (!do_packet (ts1, conn, guid_prefix, rbpool) && !conn->m_connless)
if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) && !conn->m_connless)
ddsi_conn_free (conn);
}
}

View file

@ -41,10 +41,12 @@ extern inline struct thread_state1 *lookup_thread_state (void);
extern inline bool thread_is_asleep (void);
extern inline bool thread_is_awake (void);
extern inline void thread_state_asleep (struct thread_state1 *ts1);
extern inline void thread_state_awake (struct thread_state1 *ts1);
extern inline void thread_state_awake (struct thread_state1 *ts1, const struct q_globals *gv);
extern inline void thread_state_awake_domain_ok (struct thread_state1 *ts1);
extern inline void thread_state_awake_fixed_domain (struct thread_state1 *ts1);
extern inline void thread_state_awake_to_awake_no_nest (struct thread_state1 *ts1);
static struct thread_state1 *init_thread_state (const char *tname, enum thread_state state);
static struct thread_state1 *init_thread_state (const char *tname, const struct q_globals *gv, enum thread_state state);
static void *ddsrt_malloc_aligned_cacheline (size_t size)
{
@ -148,7 +150,7 @@ static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self)
char name[128];
ddsrt_thread_getname (name, sizeof (name));
ddsrt_mutex_lock (&thread_states.lock);
if ((ts1 = init_thread_state (name, THREAD_STATE_LAZILY_CREATED)) != NULL) {
if ((ts1 = init_thread_state (name, NULL, THREAD_STATE_LAZILY_CREATED)) != NULL) {
ddsrt_init ();
ts1->extTid = self;
ts1->tid = self;
@ -211,22 +213,24 @@ void upgrade_main_thread (void)
assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime)));
ts1->state = THREAD_STATE_LAZILY_CREATED;
ts1->tid = ddsrt_thread_self ();
DDSRT_WARNING_MSVC_OFF(4996);
strncpy (ts1->name, main_thread_name, sizeof (ts1->name));
DDSRT_WARNING_MSVC_ON(4996);
ts1->name[sizeof (ts1->name) - 1] = 0;
ddsrt_mutex_unlock (&thread_states.lock);
tsd_thread_state = ts1;
}
const struct config_thread_properties_listelem *lookup_thread_properties (const char *name)
const struct config_thread_properties_listelem *lookup_thread_properties (const struct config *config, const char *name)
{
const struct config_thread_properties_listelem *e;
for (e = config.thread_properties; e != NULL; e = e->next)
for (e = config->thread_properties; e != NULL; e = e->next)
if (strcmp (e->name, name) == 0)
break;
return e;
}
static struct thread_state1 *init_thread_state (const char *tname, enum thread_state state)
static struct thread_state1 *init_thread_state (const char *tname, const struct q_globals *gv, enum thread_state state)
{
int cand;
struct thread_state1 *ts;
@ -235,24 +239,26 @@ static struct thread_state1 *init_thread_state (const char *tname, enum thread_s
return NULL;
ts = &thread_states.ts[cand];
ddsrt_atomic_stvoidp (&ts->gv, (struct q_globals *) gv);
assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts->vtime)));
DDSRT_WARNING_MSVC_OFF(4996);
strncpy (ts->name, tname, sizeof (ts->name));
DDSRT_WARNING_MSVC_ON(4996);
ts->name[sizeof (ts->name) - 1] = 0;
ts->state = state;
return ts;
}
dds_return_t create_thread (struct thread_state1 **ts1, const char *name, uint32_t (*f) (void *arg), void *arg)
static dds_return_t create_thread_int (struct thread_state1 **ts1, const struct q_globals *gv, struct config_thread_properties_listelem const * const tprops, const char *name, uint32_t (*f) (void *arg), void *arg)
{
struct config_thread_properties_listelem const * const tprops = lookup_thread_properties (name);
ddsrt_threadattr_t tattr;
ddsrt_thread_t tid;
struct thread_context *ctxt;
ctxt = ddsrt_malloc (sizeof (*ctxt));
ddsrt_mutex_lock (&thread_states.lock);
*ts1 = init_thread_state (name, THREAD_STATE_ALIVE);
*ts1 = init_thread_state (name, gv, THREAD_STATE_ALIVE);
if (*ts1 == NULL)
goto fatal;
@ -279,7 +285,7 @@ dds_return_t create_thread (struct thread_state1 **ts1, const char *name, uint32
(*ts1)->extTid = tid; /* overwrite the temporary value with the correct external one */
ddsrt_mutex_unlock (&thread_states.lock);
return DDS_RETCODE_OK;
fatal:
fatal:
ddsrt_mutex_unlock (&thread_states.lock);
ddsrt_free (ctxt);
*ts1 = NULL;
@ -287,6 +293,17 @@ dds_return_t create_thread (struct thread_state1 **ts1, const char *name, uint32
return DDS_RETCODE_ERROR;
}
dds_return_t create_thread_with_properties (struct thread_state1 **ts1, struct config_thread_properties_listelem const * const tprops, const char *name, uint32_t (*f) (void *arg), void *arg)
{
return create_thread_int (ts1, NULL, tprops, name, f, arg);
}
dds_return_t create_thread (struct thread_state1 **ts1, const struct q_globals *gv, const char *name, uint32_t (*f) (void *arg), void *arg)
{
struct config_thread_properties_listelem const * const tprops = lookup_thread_properties (&gv->config, name);
return create_thread_int (ts1, gv, tprops, name, f, arg);
}
static void reap_thread_state (struct thread_state1 *ts1)
{
ddsrt_mutex_lock (&thread_states.lock);

View file

@ -77,14 +77,15 @@ static void writer_hbcontrol_note_hb (struct writer *wr, nn_mtime_t tnow, int an
int64_t writer_hbcontrol_intv (const struct writer *wr, const struct whc_state *whcst, UNUSED_ARG (nn_mtime_t tnow))
{
struct q_globals const * const gv = wr->e.gv;
struct hbcontrol const * const hbc = &wr->hbcontrol;
int64_t ret = config.const_hb_intv_sched;
int64_t ret = gv->config.const_hb_intv_sched;
size_t n_unacked;
if (hbc->hbs_since_last_write > 2)
{
unsigned cnt = hbc->hbs_since_last_write;
while (cnt-- > 2 && 2 * ret < config.const_hb_intv_sched_max)
while (cnt-- > 2 && 2 * ret < gv->config.const_hb_intv_sched_max)
ret *= 2;
}
@ -95,13 +96,14 @@ int64_t writer_hbcontrol_intv (const struct writer *wr, const struct whc_state *
ret /= 2;
if (wr->throttling)
ret /= 2;
if (ret < config.const_hb_intv_sched_min)
ret = config.const_hb_intv_sched_min;
if (ret < gv->config.const_hb_intv_sched_min)
ret = gv->config.const_hb_intv_sched_min;
return ret;
}
void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow)
{
struct q_globals const * const gv = wr->e.gv;
struct hbcontrol * const hbc = &wr->hbcontrol;
nn_mtime_t tnext;
@ -111,7 +113,7 @@ void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow)
/* We know this is new data, so we want a heartbeat event after one
base interval */
tnext.v = tnow.v + config.const_hb_intv_sched;
tnext.v = tnow.v + gv->config.const_hb_intv_sched;
if (tnext.v < hbc->tsched.v)
{
/* Insertion of a message with WHC locked => must now have at
@ -130,6 +132,7 @@ int writer_hbcontrol_must_send (const struct writer *wr, const struct whc_state
struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow, int hbansreq, int issync)
{
struct q_globals const * const gv = wr->e.gv;
struct nn_xmsg *msg;
const nn_guid_t *prd_guid;
@ -137,7 +140,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
assert (wr->reliable);
assert (hbansreq >= 0);
if ((msg = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
/* out of memory at worst slows down traffic */
return NULL;
@ -196,7 +199,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
else
{
struct proxy_reader *prd;
if ((prd = ephash_lookup_proxy_reader_guid (prd_guid)) == NULL)
if ((prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, prd_guid)) == NULL)
{
DDS_TRACE("writer_hbcontrol: wr "PGUIDFMT" unknown prd "PGUIDFMT"\n", PGUID (wr->e.guid), PGUID (*prd_guid));
nn_xmsg_free (msg);
@ -221,8 +224,9 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
static int writer_hbcontrol_ack_required_generic (const struct writer *wr, const struct whc_state *whcst, nn_mtime_t tlast, nn_mtime_t tnow, int piggyback)
{
struct q_globals const * const gv = wr->e.gv;
struct hbcontrol const * const hbc = &wr->hbcontrol;
const int64_t hb_intv_ack = config.const_hb_intv_sched;
const int64_t hb_intv_ack = gv->config.const_hb_intv_sched;
assert(wr->heartbeat_xevent != NULL && whcst != NULL);
if (piggyback)
@ -245,9 +249,9 @@ static int writer_hbcontrol_ack_required_generic (const struct writer *wr, const
if (whcst->unacked_bytes >= wr->whc_low + (wr->whc_high - wr->whc_low) / 2)
{
if (tnow.v >= hbc->t_of_last_ackhb.v + config.const_hb_intv_sched_min)
if (tnow.v >= hbc->t_of_last_ackhb.v + gv->config.const_hb_intv_sched_min)
return 2;
else if (tnow.v >= hbc->t_of_last_ackhb.v + config.const_hb_intv_min)
else if (tnow.v >= hbc->t_of_last_ackhb.v + gv->config.const_hb_intv_min)
return 1;
}
@ -311,6 +315,7 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_
void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_state *whcst, int hbansreq, nn_entityid_t dst, int issync)
{
struct q_globals const * const gv = wr->e.gv;
struct nn_xmsg_marker sm_marker;
Heartbeat_t * hb;
seqno_t max = 0, min = 1;
@ -320,7 +325,7 @@ void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_sta
assert (wr->reliable);
assert (hbansreq >= 0);
if (config.meas_hb_to_ack_latency)
if (gv->config.meas_hb_to_ack_latency)
{
/* If configured to measure heartbeat-to-ack latency, we must add
a timestamp. No big deal if it fails. */
@ -382,6 +387,7 @@ static dds_return_t create_fragment_message_simple (struct writer *wr, seqno_t s
/* actual expected_inline_qos_size is typically 0, but always claiming 32 bytes won't make
a difference, so no point in being precise */
const size_t expected_inline_qos_size = /* statusinfo */ 8 + /* keyhash */ 20 + /* sentinel */ 4;
struct q_globals const * const gv = wr->e.gv;
struct nn_xmsg_marker sm_marker;
unsigned char contentflag = 0;
Data_t *data;
@ -405,7 +411,7 @@ static dds_return_t create_fragment_message_simple (struct writer *wr, seqno_t s
ASSERT_MUTEX_HELD (&wr->e.lock);
/* INFO_TS: 12 bytes, Data_t: 24 bytes, expected inline QoS: 32 => should be single chunk */
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)
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)
return DDS_RETCODE_OUT_OF_RESOURCES;
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
@ -466,6 +472,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
actual expected_inline_qos_size is typically 0, but always claiming 32 bytes won't make
a difference, so no point in being precise */
const size_t expected_inline_qos_size = /* statusinfo */ 8 + /* keyhash */ 20 + /* sentinel */ 4;
struct q_globals const * const gv = wr->e.gv;
struct nn_xmsg_marker sm_marker;
void *sm;
Data_DataFrag_common_t *ddcmn;
@ -478,7 +485,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
ASSERT_MUTEX_HELD (&wr->e.lock);
if (fragnum * config.fragment_size >= size && size > 0)
if (fragnum * gv->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
@ -487,10 +494,10 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
return DDS_RETCODE_BAD_PARAMETER;
}
fragging = (config.fragment_size < size);
fragging = (gv->config.fragment_size < size);
/* INFO_TS: 12 bytes, DataFrag_t: 36 bytes, expected inline QoS: 32 => should be single chunk */
if ((*pmsg = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, sizeof (InfoTimestamp_t) + sizeof (DataFrag_t) + expected_inline_qos_size, xmsg_kind)) == NULL)
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 DDS_RETCODE_OUT_OF_RESOURCES;
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
@ -554,18 +561,18 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
frag->fragmentStartingNum = fragnum + 1;
frag->fragmentsInSubmessage = 1;
frag->fragmentSize = (unsigned short) config.fragment_size;
frag->fragmentSize = (unsigned short) gv->config.fragment_size;
frag->sampleSize = (uint32_t)size;
fragstart = fragnum * config.fragment_size;
fragstart = fragnum * gv->config.fragment_size;
#if MULTIPLE_FRAGS_IN_SUBMSG /* ugly hack for testing only */
if (fragstart + config.fragment_size < ddsi_serdata_size (serdata) &&
fragstart + 2 * config.fragment_size >= ddsi_serdata_size (serdata))
if (fragstart + gv->config.fragment_size < ddsi_serdata_size (serdata) &&
fragstart + 2 * gv->config.fragment_size >= ddsi_serdata_size (serdata))
frag->fragmentsInSubmessage++;
ret = frag->fragmentsInSubmessage;
#endif
fraglen = config.fragment_size * frag->fragmentsInSubmessage;
fraglen = gv->config.fragment_size * frag->fragmentsInSubmessage;
if (fragstart + fraglen > size)
fraglen = (uint32_t)(size - fragstart);
ddcmn->octetsToInlineQos = (unsigned short) ((char*) (frag+1) - ((char*) &ddcmn->octetsToInlineQos + 2));
@ -624,10 +631,11 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
static void create_HeartbeatFrag (struct writer *wr, seqno_t seq, unsigned fragnum, struct proxy_reader *prd, struct nn_xmsg **pmsg)
{
struct q_globals const * const gv = wr->e.gv;
struct nn_xmsg_marker sm_marker;
HeartbeatFrag_t *hbf;
ASSERT_MUTEX_HELD (&wr->e.lock);
if ((*pmsg = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, sizeof (HeartbeatFrag_t), NN_XMSG_KIND_CONTROL)) == NULL)
if ((*pmsg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, sizeof (HeartbeatFrag_t), NN_XMSG_KIND_CONTROL)) == NULL)
return; /* ignore out-of-memory: HeartbeatFrag is only advisory anyway */
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
nn_xmsg_setencoderid (*pmsg, wr->partition_id);
@ -741,17 +749,18 @@ 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, struct ddsi_serdata *serdata, struct proxy_reader *prd, int isnew)
{
/* on entry: &wr->e.lock held; on exit: lock no longer held */
struct q_globals const * const gv = wr->e.gv;
struct nn_xmsg *fmsg;
uint32_t sz;
assert(xp);
assert((wr->heartbeat_xevent != NULL) == (whcst != NULL));
sz = ddsi_serdata_size (serdata);
if (sz > config.fragment_size || !isnew || plist != NULL || prd != NULL)
if (sz > gv->config.fragment_size || !isnew || plist != NULL || prd != NULL)
{
uint32_t nfrags;
ddsrt_mutex_unlock (&wr->e.lock);
nfrags = (sz + config.fragment_size - 1) / config.fragment_size;
nfrags = (sz + gv->config.fragment_size - 1) / gv->config.fragment_size;
transmit_sample_lgmsg_unlocked (xp, wr, whcst, seq, plist, serdata, prd, isnew, nfrags);
return;
}
@ -782,13 +791,14 @@ 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, struct ddsi_serdata *serdata, struct proxy_reader *prd, int isnew)
{
struct q_globals const * const gv = wr->e.gv;
uint32_t i, sz, nfrags;
int enqueued = 1;
ASSERT_MUTEX_HELD (&wr->e.lock);
sz = ddsi_serdata_size (serdata);
nfrags = (sz + config.fragment_size - 1) / config.fragment_size;
nfrags = (sz + gv->config.fragment_size - 1) / gv->config.fragment_size;
if (nfrags == 0)
{
/* end-of-transaction messages are empty, but still need to be sent */
@ -924,7 +934,7 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
resent to them, until a ACKNACK is received from that
reader. This implicitly clears the whc and unblocks the
writer. */
struct q_globals const * const gv = wr->e.gv;
dds_return_t result = DDS_RETCODE_OK;
nn_mtime_t tnow = now_mt ();
const nn_mtime_t abstimeout = add_duration_to_mtime (tnow, wr->xqos->reliability.max_blocking_time);
@ -958,7 +968,7 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
whc_get_state (wr->whc, &whcst);
}
while (ddsrt_atomic_ld32 (&gv.rtps_keepgoing) && !writer_may_continue (wr, &whcst))
while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing) && !writer_may_continue (wr, &whcst))
{
int64_t reltimeout;
tnow = now_mt ();
@ -969,7 +979,7 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
thread_state_asleep (ts1);
if (ddsrt_cond_waitfor (&wr->throttle_cond, &wr->e.lock, reltimeout))
result = DDS_RETCODE_OK;
thread_state_awake (ts1);
thread_state_awake_domain_ok (ts1);
whc_get_state(wr->whc, &whcst);
}
if (result == DDS_RETCODE_TIMEOUT)
@ -991,14 +1001,15 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
static int maybe_grow_whc (struct writer *wr)
{
if (!wr->retransmitting && config.whc_adaptive && wr->whc_high < config.whc_highwater_mark)
struct q_globals const * const gv = wr->e.gv;
if (!wr->retransmitting && gv->config.whc_adaptive && wr->whc_high < gv->config.whc_highwater_mark)
{
nn_etime_t tnow = now_et();
nn_etime_t tgrow = add_duration_to_etime (wr->t_whc_high_upd, 10 * T_MILLISECOND);
if (tnow.v >= tgrow.v)
{
uint32_t m = (config.whc_highwater_mark - wr->whc_high) / 32;
wr->whc_high = (m == 0) ? config.whc_highwater_mark : wr->whc_high + m;
uint32_t m = (gv->config.whc_highwater_mark - wr->whc_high) / 32;
wr->whc_high = (m == 0) ? gv->config.whc_highwater_mark : wr->whc_high + m;
wr->t_whc_high_upd = tnow;
return 1;
}
@ -1008,6 +1019,7 @@ static int maybe_grow_whc (struct writer *wr)
static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk, int end_of_txn, int gc_allowed)
{
struct q_globals const * const gv = wr->e.gv;
int r;
seqno_t seq;
nn_mtime_t tnow;
@ -1016,7 +1028,7 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
assert(gc_allowed || (wr->xqos->history.kind == DDS_HISTORY_KEEP_LAST && wr->whc_low == INT32_MAX));
(void)gc_allowed;
if (ddsi_serdata_size (serdata) > config.max_sample_size)
if (ddsi_serdata_size (serdata) > gv->config.max_sample_size)
{
char ppbuf[1024];
int tmp;
@ -1025,7 +1037,7 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
ppbuf[0] = '\0';
tmp = sizeof (ppbuf) - 1;
DDS_WARNING ("dropping oversize (%"PRIu32" > %"PRIu32") sample from local writer "PGUIDFMT" %s/%s:%s%s\n",
ddsi_serdata_size (serdata), config.max_sample_size,
ddsi_serdata_size (serdata), gv->config.max_sample_size,
PGUID (wr->e.guid), tname, ttname, ppbuf,
tmp < (int) sizeof (ppbuf) ? "" : " (trunc)");
r = DDS_RETCODE_BAD_PARAMETER;
@ -1047,7 +1059,7 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
{
dds_return_t ores;
assert(gc_allowed); /* also see beginning of the function */
if (config.prioritize_retransmit && wr->retransmitting)
if (gv->config.prioritize_retransmit && wr->retransmitting)
ores = throttle_writer (ts1, xp, wr);
else
{
@ -1177,9 +1189,9 @@ int write_sample_gc_notk (struct thread_state1 * const ts1, struct nn_xpack *xp,
struct ddsi_tkmap_instance *tk;
int res;
assert (thread_is_awake ());
tk = ddsi_tkmap_lookup_instance_ref (serdata);
tk = ddsi_tkmap_lookup_instance_ref (wr->e.gv->m_tkmap, serdata);
res = write_sample_eot (ts1, xp, wr, NULL, serdata, tk, 0, 1);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (wr->e.gv->m_tkmap, tk);
return res;
}
@ -1188,8 +1200,8 @@ int write_sample_nogc_notk (struct thread_state1 * const ts1, struct nn_xpack *x
struct ddsi_tkmap_instance *tk;
int res;
assert (thread_is_awake ());
tk = ddsi_tkmap_lookup_instance_ref (serdata);
tk = ddsi_tkmap_lookup_instance_ref (wr->e.gv->m_tkmap, serdata);
res = write_sample_eot (ts1, xp, wr, NULL, serdata, tk, 0, 0);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (wr->e.gv->m_tkmap, tk);
return res;
}

View file

@ -139,6 +139,7 @@ struct xeventq {
size_t max_queued_rexmit_msgs;
int terminate;
struct thread_state1 *ts;
struct q_globals *gv;
ddsrt_mutex_t lock;
ddsrt_cond_t cond;
ddsi_tran_conn_t tev_conn;
@ -375,9 +376,9 @@ static struct xevent * qxev_common (struct xeventq *evq, nn_mtime_t tsched, enum
ASSERT_MUTEX_HELD (&evq->lock);
/* round up the scheduled time if required */
if (tsched.v != T_NEVER && config.schedule_time_rounding != 0)
if (tsched.v != T_NEVER && evq->gv->config.schedule_time_rounding != 0)
{
nn_mtime_t tsched_rounded = mtime_round_up (tsched, config.schedule_time_rounding);
nn_mtime_t tsched_rounded = mtime_round_up (tsched, evq->gv->config.schedule_time_rounding);
DDS_TRACE("rounded event scheduled for %"PRId64" to %"PRId64"\n", tsched.v, tsched_rounded.v);
tsched = tsched_rounded;
}
@ -463,6 +464,7 @@ struct xeventq * xeventq_new
evq->queued_rexmit_bytes = 0;
evq->queued_rexmit_msgs = 0;
evq->tev_conn = conn;
evq->gv = conn->m_base.gv;
ddsrt_mutex_init (&evq->lock);
ddsrt_cond_init (&evq->cond);
return evq;
@ -482,7 +484,7 @@ dds_return_t xeventq_start (struct xeventq *evq, const char *name)
}
evq->terminate = 0;
rc = create_thread (&evq->ts, evqname, (uint32_t (*) (void *)) xevent_thread, evq);
rc = create_thread (&evq->ts, evq->gv, evqname, (uint32_t (*) (void *)) xevent_thread, evq);
if (name)
{
@ -526,7 +528,7 @@ void xeventq_free (struct xeventq *evq)
{
struct nn_xpack *xp = nn_xpack_new (evq->tev_conn, evq->auxiliary_bandwidth_limit, false);
thread_state_awake (lookup_thread_state ());
thread_state_awake (lookup_thread_state (), evq->gv);
ddsrt_mutex_lock (&evq->lock);
while (!non_timed_xmit_list_is_empty (evq))
{
@ -576,13 +578,14 @@ static void handle_xevk_entityid (struct nn_xpack *xp, struct xevent_nt *ev)
static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mtime_t tnow /* monotonic */)
{
struct q_globals const * const gv = ev->evq->gv;
struct nn_xmsg *msg;
struct writer *wr;
nn_mtime_t t_next;
int hbansreq = 0;
struct whc_state whcst;
if ((wr = ephash_lookup_writer_guid (&ev->u.heartbeat.wr_guid)) == NULL)
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &ev->u.heartbeat.wr_guid)) == NULL)
{
DDS_TRACE("heartbeat(wr "PGUIDFMT") writer gone\n",
PGUID (ev->u.heartbeat.wr_guid));
@ -714,7 +717,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
if (rwn->in_sync != PRMSS_OUT_OF_SYNC)
{
reorder = pwr->reorder;
if (!config.late_ack_mode)
if (!pwr->e.gv->config.late_ack_mode)
bitmap_base = nn_reorder_next_seq (reorder);
else
{
@ -847,12 +850,13 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent
A little snag is that the defragmenter can throw out partial samples in
favour of others, so MUST ensure that the defragmenter won't start
threshing and fail to make progress! */
struct q_globals *gv = ev->evq->gv;
struct proxy_writer *pwr;
struct nn_xmsg *msg;
struct pwr_rd_match *rwn;
nn_locator_t loc;
if ((pwr = ephash_lookup_proxy_writer_guid (&ev->u.acknack.pwr_guid)) == NULL)
if ((pwr = ephash_lookup_proxy_writer_guid (gv->guid_hash, &ev->u.acknack.pwr_guid)) == NULL)
{
return;
}
@ -867,10 +871,10 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent
if (addrset_any_uc (pwr->c.as, &loc) || addrset_any_mc (pwr->c.as, &loc))
{
seqno_t nack_seq;
if ((msg = nn_xmsg_new (gv.xmsgpool, &ev->u.acknack.rd_guid.prefix, ACKNACK_SIZE_MAX, NN_XMSG_KIND_CONTROL)) == NULL)
if ((msg = nn_xmsg_new (gv->xmsgpool, &ev->u.acknack.rd_guid.prefix, ACKNACK_SIZE_MAX, NN_XMSG_KIND_CONTROL)) == NULL)
goto outofmem;
nn_xmsg_setdst1 (msg, &ev->u.acknack.pwr_guid.prefix, &loc);
if (config.meas_hb_to_ack_latency && rwn->hb_timestamp.v)
if (gv->config.meas_hb_to_ack_latency && rwn->hb_timestamp.v)
{
/* If HB->ACK latency measurement is enabled, and we have a
timestamp available, add it and clear the time stamp. There
@ -890,7 +894,7 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent
HEARTBEAT, I've seen too many cases of not sending an NACK
because the writing side got confused ... Better to recover
eventually. */
resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, config.auto_resched_nack_delay));
resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, gv->config.auto_resched_nack_delay));
}
DDS_TRACE("send acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT")\n",
PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid));
@ -937,18 +941,19 @@ static bool resend_spdp_sample_by_guid_key (struct writer *wr, const nn_guid_t *
/* 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 */
struct q_globals *gv = wr->e.gv;
bool sample_found;
nn_plist_t ps;
nn_plist_init_empty (&ps);
ps.present |= PP_PARTICIPANT_GUID;
ps.participant_guid = *guid;
struct nn_xmsg *mpayload = nn_xmsg_new (gv.xmsgpool, &guid->prefix, 0, NN_XMSG_KIND_DATA);
struct nn_xmsg *mpayload = nn_xmsg_new (gv->xmsgpool, &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);
struct ddsi_serdata *sd = ddsi_serdata_from_sample (gv->plist_topic, SDK_KEY, &plist_sample);
struct whc_borrowed_sample sample;
nn_xmsg_free (mpayload);
@ -972,12 +977,13 @@ static bool resend_spdp_sample_by_guid_key (struct writer *wr, const nn_guid_t *
static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, nn_mtime_t tnow)
{
/* Like the writer pointer in the heartbeat event, the participant pointer in the spdp event is assumed valid. */
struct q_globals *gv = ev->evq->gv;
struct participant *pp;
struct proxy_reader *prd;
struct writer *spdp_wr;
bool do_write;
if ((pp = ephash_lookup_participant_guid (&ev->u.spdp.pp_guid)) == NULL)
if ((pp = ephash_lookup_participant_guid (gv->guid_hash, &ev->u.spdp.pp_guid)) == NULL)
{
DDS_TRACE("handle_xevk_spdp "PGUIDFMT" - unknown guid\n",
PGUID (ev->u.spdp.pp_guid));
@ -1007,7 +1013,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
nn_guid_t guid;
guid.prefix = ev->u.spdp.dest_proxypp_guid_prefix;
guid.entityid.u = NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER;
prd = ephash_lookup_proxy_reader_guid (&guid);
prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, &guid);
do_write = (prd != NULL);
if (!do_write)
DDS_TRACE("xmit spdp: no proxy reader "PGUIDFMT"\n", PGUID (guid));
@ -1045,7 +1051,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
{
/* Directed events are used to send SPDP packets to newly
discovered peers, and used just once. */
if (--ev->u.spdp.directed == 0 || config.spdp_interval < T_SECOND || pp->lease_duration < T_SECOND)
if (--ev->u.spdp.directed == 0 || gv->config.spdp_interval < T_SECOND || pp->lease_duration < T_SECOND)
delete_xevent (ev);
else
{
@ -1073,8 +1079,8 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
intv = 4 * ldur / 5;
else
intv = ldur - 2 * T_SECOND;
if (intv > config.spdp_interval)
intv = config.spdp_interval;
if (intv > gv->config.spdp_interval)
intv = gv->config.spdp_interval;
tnext = add_duration_to_mtime (tnow, intv);
DDS_TRACE("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
@ -1088,6 +1094,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
static void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, struct participant *pp, unsigned pmd_kind)
{
#define PMD_DATA_LENGTH 1
struct q_globals * const gv = pp->e.gv;
struct writer *wr;
union {
ParticipantMessageData_t pmd;
@ -1113,22 +1120,23 @@ static void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack
.key = &u.pmd,
.keysize = 16
};
serdata = ddsi_serdata_from_sample (gv.rawcdr_topic, SDK_DATA, &raw);
serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw);
serdata->timestamp = now ();
tk = ddsi_tkmap_lookup_instance_ref(serdata);
tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata);
write_sample_nogc (ts1, xp, wr, serdata, tk);
ddsi_tkmap_instance_unref(tk);
ddsi_tkmap_instance_unref (gv->m_tkmap, tk);
#undef PMD_DATA_LENGTH
}
static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_xpack *xp, struct xevent *ev, nn_mtime_t tnow)
{
struct q_globals * const gv = ev->evq->gv;
struct participant *pp;
dds_duration_t intv;
nn_mtime_t tnext;
if ((pp = ephash_lookup_participant_guid (&ev->u.pmd_update.pp_guid)) == NULL)
if ((pp = ephash_lookup_participant_guid (gv->guid_hash, &ev->u.pmd_update.pp_guid)) == NULL)
{
return;
}
@ -1168,8 +1176,9 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_
static void handle_xevk_delete_writer (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, UNUSED_ARG (nn_mtime_t tnow))
{
/* don't worry if the writer is already gone by the time we get here. */
struct q_globals * const gv = ev->evq->gv;
DDS_TRACE("handle_xevk_delete_writer: "PGUIDFMT"\n", PGUID (ev->u.delete_writer.guid));
delete_writer_nolinger (&ev->u.delete_writer.guid);
delete_writer_nolinger (gv, &ev->u.delete_writer.guid);
delete_xevent (ev);
}
@ -1317,7 +1326,7 @@ static uint32_t xevent_thread (struct xeventq * xevq)
struct nn_xpack *xp;
nn_mtime_t next_thread_cputime = { 0 };
xp = nn_xpack_new (xevq->tev_conn, xevq->auxiliary_bandwidth_limit, config.xpack_send_async);
xp = nn_xpack_new (xevq->tev_conn, xevq->auxiliary_bandwidth_limit, xevq->gv->config.xpack_send_async);
ddsrt_mutex_lock (&xevq->lock);
while (!xevq->terminate)
@ -1326,7 +1335,7 @@ static uint32_t xevent_thread (struct xeventq * xevq)
LOG_THREAD_CPUTIME (next_thread_cputime);
thread_state_awake (ts1);
thread_state_awake_fixed_domain (ts1);
handle_xevents (ts1, xevq, xp, tnow);
/* Send to the network unlocked, as it may sleep due to bandwidth limitation */
ddsrt_mutex_unlock (&xevq->lock);
@ -1379,25 +1388,26 @@ void qxev_msg (struct xeventq *evq, struct nn_xmsg *msg)
ddsrt_mutex_unlock (&evq->lock);
}
void qxev_prd_entityid (struct proxy_reader * prd, nn_guid_prefix_t * id)
void qxev_prd_entityid (struct proxy_reader *prd, nn_guid_prefix_t *id)
{
struct q_globals * const gv = prd->e.gv;
struct nn_xmsg *msg;
struct xevent_nt *ev;
/* For connected transports, may need to establish and identify connection */
if (! gv.xevents->tev_conn->m_connless)
if (! gv->xevents->tev_conn->m_connless)
{
msg = nn_xmsg_new (gv.xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
msg = nn_xmsg_new (gv->xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
if (nn_xmsg_setdstPRD (msg, prd) == 0)
{
DDS_TRACE(" qxev_prd_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
nn_xmsg_add_entityid (msg);
ddsrt_mutex_lock (&gv.xevents->lock);
ev = qxev_common_nt (gv.xevents, XEVK_ENTITYID);
ddsrt_mutex_lock (&gv->xevents->lock);
ev = qxev_common_nt (gv->xevents, XEVK_ENTITYID);
ev->u.entityid.msg = msg;
qxev_insert_nt (ev);
ddsrt_mutex_unlock (&gv.xevents->lock);
ddsrt_mutex_unlock (&gv->xevents->lock);
}
else
{
@ -1406,8 +1416,9 @@ void qxev_prd_entityid (struct proxy_reader * prd, nn_guid_prefix_t * id)
}
}
void qxev_pwr_entityid (struct proxy_writer * pwr, nn_guid_prefix_t * id)
void qxev_pwr_entityid (struct proxy_writer *pwr, nn_guid_prefix_t *id)
{
struct q_globals * const gv = pwr->e.gv;
struct nn_xmsg *msg;
struct xevent_nt *ev;
@ -1415,7 +1426,7 @@ void qxev_pwr_entityid (struct proxy_writer * pwr, nn_guid_prefix_t * id)
if (! pwr->evq->tev_conn->m_connless)
{
msg = nn_xmsg_new (gv.xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
msg = nn_xmsg_new (gv->xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
if (nn_xmsg_setdstPWR (msg, pwr) == 0)
{
DDS_TRACE(" qxev_pwr_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
@ -1435,13 +1446,14 @@ void qxev_pwr_entityid (struct proxy_writer * pwr, nn_guid_prefix_t * id)
int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg *msg, int force)
{
struct q_globals * const gv = evq->gv;
size_t msg_size = nn_xmsg_size (msg);
struct xevent_nt *ev;
assert (evq);
assert (nn_xmsg_kind (msg) == NN_XMSG_KIND_DATA_REXMIT);
ddsrt_mutex_lock (&evq->lock);
if ((ev = lookup_msg (evq, msg)) != NULL && nn_xmsg_merge_rexmit_destinations_wrlock_held (ev->u.msg_rexmit.msg, msg))
if ((ev = lookup_msg (evq, msg)) != NULL && nn_xmsg_merge_rexmit_destinations_wrlock_held (gv, ev->u.msg_rexmit.msg, msg))
{
/* MSG got merged with a pending retransmit, so it has effectively been queued */
ddsrt_mutex_unlock (&evq->lock);
@ -1505,11 +1517,11 @@ struct xevent *qxev_acknack (struct xeventq *evq, nn_mtime_t tsched, const nn_gu
return ev;
}
struct xevent *qxev_spdp (nn_mtime_t tsched, const nn_guid_t *pp_guid, const nn_guid_t *dest_proxypp_guid)
struct xevent *qxev_spdp (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *pp_guid, const nn_guid_t *dest_proxypp_guid)
{
struct xevent *ev;
ddsrt_mutex_lock (&gv.xevents->lock);
ev = qxev_common (gv.xevents, tsched, XEVK_SPDP);
ddsrt_mutex_lock (&evq->lock);
ev = qxev_common (evq, tsched, XEVK_SPDP);
ev->u.spdp.pp_guid = *pp_guid;
if (dest_proxypp_guid == NULL)
ev->u.spdp.directed = 0;
@ -1519,40 +1531,40 @@ struct xevent *qxev_spdp (nn_mtime_t tsched, const nn_guid_t *pp_guid, const nn_
ev->u.spdp.directed = 4;
}
qxev_insert (ev);
ddsrt_mutex_unlock (&gv.xevents->lock);
ddsrt_mutex_unlock (&evq->lock);
return ev;
}
struct xevent *qxev_pmd_update (nn_mtime_t tsched, const nn_guid_t *pp_guid)
struct xevent *qxev_pmd_update (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *pp_guid)
{
struct xevent *ev;
ddsrt_mutex_lock (&gv.xevents->lock);
ev = qxev_common (gv.xevents, tsched, XEVK_PMD_UPDATE);
ddsrt_mutex_lock (&evq->lock);
ev = qxev_common (evq, tsched, XEVK_PMD_UPDATE);
ev->u.pmd_update.pp_guid = *pp_guid;
qxev_insert (ev);
ddsrt_mutex_unlock (&gv.xevents->lock);
ddsrt_mutex_unlock (&evq->lock);
return ev;
}
struct xevent *qxev_delete_writer (nn_mtime_t tsched, const nn_guid_t *guid)
struct xevent *qxev_delete_writer (struct xeventq *evq, nn_mtime_t tsched, const nn_guid_t *guid)
{
struct xevent *ev;
ddsrt_mutex_lock (&gv.xevents->lock);
ev = qxev_common (gv.xevents, tsched, XEVK_DELETE_WRITER);
ddsrt_mutex_lock (&evq->lock);
ev = qxev_common (evq, tsched, XEVK_DELETE_WRITER);
ev->u.delete_writer.guid = *guid;
qxev_insert (ev);
ddsrt_mutex_unlock (&gv.xevents->lock);
ddsrt_mutex_unlock (&evq->lock);
return ev;
}
struct xevent *qxev_callback (nn_mtime_t tsched, void (*cb) (struct xevent *ev, void *arg, nn_mtime_t tnow), void *arg)
struct xevent *qxev_callback (struct xeventq *evq, nn_mtime_t tsched, void (*cb) (struct xevent *ev, void *arg, nn_mtime_t tnow), void *arg)
{
struct xevent *ev;
ddsrt_mutex_lock (&gv.xevents->lock);
ev = qxev_common (gv.xevents, tsched, XEVK_CALLBACK);
ddsrt_mutex_lock (&evq->lock);
ev = qxev_common (evq, tsched, XEVK_CALLBACK);
ev->u.callback.cb = cb;
ev->u.callback.arg = arg;
qxev_insert (ev);
ddsrt_mutex_unlock (&gv.xevents->lock);
ddsrt_mutex_unlock (&evq->lock);
return ev;
}

View file

@ -134,7 +134,7 @@ struct nn_xmsg_chain {
#define NN_BW_UNLIMITED (0)
struct nn_bw_limiter {
uint32_t bandwidth; /*Config in bytes/s (0 = UNLIMITED)*/
uint32_t bandwidth; /*gv.config in bytes/s (0 = UNLIMITED)*/
int64_t balance;
nn_mtime_t last_update;
};
@ -202,6 +202,7 @@ struct nn_xpack
size_t niov;
ddsrt_iovec_t *iov;
enum nn_xmsg_dstmode dstmode;
struct q_globals *gv;
union
{
@ -651,7 +652,7 @@ static int readerId_compatible (const struct nn_xmsg *m, const struct nn_xmsg *m
return e.u == NN_ENTITYID_UNKNOWN || e.u == eadd.u;
}
int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct nn_xmsg *m, const struct nn_xmsg *madd)
int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct nn_xmsg *m, const struct nn_xmsg *madd)
{
assert (m->kindspecific.data.wrseq >= 1);
assert (m->kindspecific.data.wrguid.prefix.u[0] != 0);
@ -702,7 +703,7 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct nn_xmsg *m, const stru
an addrset in rebuild_writer_addrset: then we don't
need the lock anymore, and the '_wrlock_held' suffix
can go and everyone's life will become easier! */
if ((wr = ephash_lookup_writer_guid (&m->kindspecific.data.wrguid)) == NULL)
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &m->kindspecific.data.wrguid)) == NULL)
{
DDS_TRACE("writer-dead)");
return 0;
@ -837,7 +838,7 @@ int nn_xmsg_addpar_sentinel_ifparam (struct nn_xmsg * m)
pointer we compute the address of the xmsg from the address of the
chain element, &c. */
static void nn_xmsg_chain_release (struct nn_xmsg_chain *chain)
static void nn_xmsg_chain_release (struct q_globals *gv, struct nn_xmsg_chain *chain)
{
nn_guid_t wrguid;
memset (&wrguid, 0, sizeof (wrguid));
@ -868,7 +869,7 @@ static void nn_xmsg_chain_release (struct nn_xmsg_chain *chain)
struct writer *wr;
assert (m->kindspecific.data.wrseq != 0);
wrguid = m->kindspecific.data.wrguid;
if ((wr = ephash_lookup_writer_guid (&m->kindspecific.data.wrguid)) != NULL)
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &m->kindspecific.data.wrguid)) != NULL)
UPDATE_SEQ_XMIT_UNLOCKED(wr, m->kindspecific.data.wrseq);
}
}
@ -973,12 +974,13 @@ struct nn_xpack * nn_xpack_new (ddsi_tran_conn_t conn, uint32_t bw_limit, bool a
/* Disallow setting async_mode if not configured to enable async mode: this way we
can avoid starting the async send thread altogether */
assert (!async_mode || config.xpack_send_async);
assert (!async_mode || conn->m_base.gv->config.xpack_send_async);
xp = ddsrt_malloc (sizeof (*xp));
memset (xp, 0, sizeof (*xp));
xp->async_mode = async_mode;
xp->iov = NULL;
xp->gv = conn->m_base.gv;
/* Fixed header fields, initialized just once */
xp->hdr.protocol.id[0] = 'R';
@ -998,7 +1000,7 @@ struct nn_xpack * nn_xpack_new (ddsi_tran_conn_t conn, uint32_t bw_limit, bool a
xp->conn = conn;
nn_xpack_reinit (xp);
if (gv.thread_pool)
if (xp->gv->thread_pool)
ddsi_sem_init (&xp->sem, 0);
#ifdef DDSI_INCLUDE_ENCRYPTION
@ -1029,7 +1031,7 @@ void nn_xpack_free (struct nn_xpack *xp)
(q_security_plugin.free_encoder) (xp->codec);
}
#endif
if (gv.thread_pool)
if (xp->gv->thread_pool)
ddsi_sem_destroy (&xp->sem);
ddsrt_free (xp->iov);
ddsrt_free (xp);
@ -1043,14 +1045,14 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
if (dds_get_log_mask() & DDS_LC_TRACE)
{
char buf[DDSI_LOCSTRLEN];
DDS_TRACE(" %s", ddsi_locator_to_string (buf, sizeof(buf), loc));
DDS_TRACE(" %s", ddsi_locator_to_string (xp->gv, buf, sizeof(buf), loc));
}
if (config.xmit_lossiness > 0)
if (xp->gv->config.xmit_lossiness > 0)
{
/* We drop APPROXIMATELY a fraction of xmit_lossiness * 10**(-3)
of all packets to be sent */
if ((ddsrt_random () % 1000) < (uint32_t) config.xmit_lossiness)
if ((ddsrt_random () % 1000) < (uint32_t) xp->gv->config.xmit_lossiness)
{
DDS_TRACE("(dropped)");
xp->call_flags = 0;
@ -1068,7 +1070,7 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
else
#endif
{
if (!gv.mute)
if (!xp->gv->mute)
{
nbytes = ddsi_conn_write (xp->conn, loc, xp->niov, xp->iov, xp->call_flags);
#ifndef NDEBUG
@ -1129,7 +1131,7 @@ static void nn_xpack_send1_threaded (const nn_locator_t *loc, void * varg)
arg->xp = (struct nn_xpack *) varg;
arg->loc = loc;
ddsrt_atomic_inc32 (&arg->xp->calls);
ddsrt_thread_pool_submit (gv.thread_pool, nn_xpack_send1_thread, arg);
ddsrt_thread_pool_submit (arg->xp->gv->thread_pool, nn_xpack_send1_thread, arg);
}
static void nn_xpack_send_real (struct nn_xpack * xp)
@ -1169,7 +1171,7 @@ static void nn_xpack_send_real (struct nn_xpack * xp)
calls = 0;
if (xp->dstaddr.all.as)
{
if (gv.thread_pool == NULL)
if (xp->gv->thread_pool == NULL)
{
calls = addrset_forall_count (xp->dstaddr.all.as, nn_xpack_send1v, xp);
}
@ -1203,7 +1205,7 @@ static void nn_xpack_send_real (struct nn_xpack * xp)
{
DDS_LOG(DDS_LC_TRAFFIC, "traffic-xmit (%lu) %"PRIu32"\n", (unsigned long) calls, xp->msg_len.length);
}
nn_xmsg_chain_release (&xp->included_msgs);
nn_xmsg_chain_release (xp->gv, &xp->included_msgs);
nn_xpack_reinit (xp);
}
@ -1211,60 +1213,61 @@ static void nn_xpack_send_real (struct nn_xpack * xp)
#define SENDQ_HW 10
#define SENDQ_LW 0
static uint32_t nn_xpack_sendq_thread (UNUSED_ARG (void *arg))
static uint32_t nn_xpack_sendq_thread (void *vgv)
{
ddsrt_mutex_lock (&gv.sendq_lock);
while (!(gv.sendq_stop && gv.sendq_head == NULL))
struct q_globals *gv = vgv;
ddsrt_mutex_lock (&gv->sendq_lock);
while (!(gv->sendq_stop && gv->sendq_head == NULL))
{
struct nn_xpack *xp;
if ((xp = gv.sendq_head) == NULL)
if ((xp = gv->sendq_head) == NULL)
{
ddsrt_cond_waitfor (&gv.sendq_cond, &gv.sendq_lock, 1000000);
ddsrt_cond_waitfor (&gv->sendq_cond, &gv->sendq_lock, 1000000);
}
else
{
gv.sendq_head = xp->sendq_next;
if (--gv.sendq_length == SENDQ_LW)
ddsrt_cond_broadcast (&gv.sendq_cond);
ddsrt_mutex_unlock (&gv.sendq_lock);
gv->sendq_head = xp->sendq_next;
if (--gv->sendq_length == SENDQ_LW)
ddsrt_cond_broadcast (&gv->sendq_cond);
ddsrt_mutex_unlock (&gv->sendq_lock);
nn_xpack_send_real (xp);
nn_xpack_free (xp);
ddsrt_mutex_lock (&gv.sendq_lock);
ddsrt_mutex_lock (&gv->sendq_lock);
}
}
ddsrt_mutex_unlock (&gv.sendq_lock);
ddsrt_mutex_unlock (&gv->sendq_lock);
return 0;
}
void nn_xpack_sendq_init (void)
void nn_xpack_sendq_init (struct q_globals *gv)
{
gv.sendq_stop = 0;
gv.sendq_head = NULL;
gv.sendq_tail = NULL;
gv.sendq_length = 0;
ddsrt_mutex_init (&gv.sendq_lock);
ddsrt_cond_init (&gv.sendq_cond);
gv->sendq_stop = 0;
gv->sendq_head = NULL;
gv->sendq_tail = NULL;
gv->sendq_length = 0;
ddsrt_mutex_init (&gv->sendq_lock);
ddsrt_cond_init (&gv->sendq_cond);
}
void nn_xpack_sendq_start (void)
void nn_xpack_sendq_start (struct q_globals *gv)
{
create_thread (&gv.sendq_ts, "sendq", nn_xpack_sendq_thread, NULL);
create_thread (&gv->sendq_ts, gv, "sendq", nn_xpack_sendq_thread, NULL);
}
void nn_xpack_sendq_stop (void)
void nn_xpack_sendq_stop (struct q_globals *gv)
{
ddsrt_mutex_lock (&gv.sendq_lock);
gv.sendq_stop = 1;
ddsrt_cond_broadcast (&gv.sendq_cond);
ddsrt_mutex_unlock (&gv.sendq_lock);
ddsrt_mutex_lock (&gv->sendq_lock);
gv->sendq_stop = 1;
ddsrt_cond_broadcast (&gv->sendq_cond);
ddsrt_mutex_unlock (&gv->sendq_lock);
}
void nn_xpack_sendq_fini (void)
void nn_xpack_sendq_fini (struct q_globals *gv)
{
assert (gv.sendq_head == NULL);
join_thread(gv.sendq_ts);
ddsrt_cond_destroy(&gv.sendq_cond);
ddsrt_mutex_destroy(&gv.sendq_lock);
assert (gv->sendq_head == NULL);
join_thread (gv->sendq_ts);
ddsrt_cond_destroy (&gv->sendq_cond);
ddsrt_mutex_destroy (&gv->sendq_lock);
}
void nn_xpack_send (struct nn_xpack *xp, bool immediately)
@ -1275,27 +1278,28 @@ void nn_xpack_send (struct nn_xpack *xp, bool immediately)
}
else
{
struct q_globals * const gv = xp->gv;
struct nn_xpack *xp1 = ddsrt_malloc (sizeof (*xp));
memcpy (xp1, xp, sizeof (*xp1));
nn_xpack_reinit (xp);
xp1->sendq_next = NULL;
ddsrt_mutex_lock (&gv.sendq_lock);
if (immediately || gv.sendq_length == SENDQ_HW)
ddsrt_cond_broadcast (&gv.sendq_cond);
if (gv.sendq_length >= SENDQ_MAX)
ddsrt_mutex_lock (&gv->sendq_lock);
if (immediately || gv->sendq_length == SENDQ_HW)
ddsrt_cond_broadcast (&gv->sendq_cond);
if (gv->sendq_length >= SENDQ_MAX)
{
while (gv.sendq_length > SENDQ_LW)
ddsrt_cond_wait (&gv.sendq_cond, &gv.sendq_lock);
while (gv->sendq_length > SENDQ_LW)
ddsrt_cond_wait (&gv->sendq_cond, &gv->sendq_lock);
}
if (gv.sendq_head)
gv.sendq_tail->sendq_next = xp1;
if (gv->sendq_head)
gv->sendq_tail->sendq_next = xp1;
else
{
gv.sendq_head = xp1;
gv->sendq_head = xp1;
}
gv.sendq_tail = xp1;
gv.sendq_length++;
ddsrt_mutex_unlock (&gv.sendq_lock);
gv->sendq_tail = xp1;
gv->sendq_length++;
ddsrt_mutex_unlock (&gv->sendq_lock);
}
}
@ -1337,7 +1341,7 @@ static int addressing_info_eq_onesidederr (const struct nn_xpack *xp, const stru
static int nn_xpack_mayaddmsg (const struct nn_xpack *xp, const struct nn_xmsg *m, const uint32_t flags)
{
unsigned max_msg_size = config.max_msg_size;
unsigned max_msg_size = xp->gv->config.max_msg_size;
unsigned payload_size;
if (xp->niov == 0)
@ -1574,9 +1578,9 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
xp->msg_len.length = (uint32_t) sz;
xp->niov = niov;
if (xpo_niov > 0 && sz > config.max_msg_size)
if (xpo_niov > 0 && sz > xp->gv->config.max_msg_size)
{
DDS_TRACE(" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", (int) niov, sz, config.max_msg_size, (int) xpo_niov, xpo_sz);
DDS_TRACE(" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", (int) niov, sz, xp->gv->config.max_msg_size, (int) xpo_niov, xpo_sz);
xp->msg_len.length = xpo_sz;
xp->niov = xpo_niov;
nn_xpack_send (xp, false);

View file

@ -16,7 +16,6 @@
#include "dds/ddsrt/misc.h"
#include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/sysdeps.h"
#if DDSRT_WITH_FREERTOS || !(defined __APPLE__ || defined __linux) || (__GNUC__ > 0 && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40100)
@ -47,40 +46,33 @@ static void log_stacktrace_sigh (int sig __attribute__ ((unused)))
void log_stacktrace (const char *name, ddsrt_thread_t tid)
{
if (dds_get_log_mask() == 0)
; /* no op if nothing logged */
else if (!config.noprogress_log_stacktraces)
DDS_LOG(~DDS_LC_FATAL, "-- stack trace of %s requested, but traces disabled --\n", name);
const dds_time_t d = 1000000;
struct sigaction act, oact;
char **strs;
int i;
DDS_LOG(~DDS_LC_FATAL, "-- stack trace of %s requested --\n", name);
act.sa_handler = log_stacktrace_sigh;
act.sa_flags = 0;
sigfillset (&act.sa_mask);
while (!ddsrt_atomic_cas32 (&log_stacktrace_flag, 0, 1))
dds_sleepfor (d);
sigaction (SIGXCPU, &act, &oact);
pthread_kill (tid.v, SIGXCPU);
while (!ddsrt_atomic_cas32 (&log_stacktrace_flag, 2, 3) && pthread_kill (tid.v, 0) == 0)
dds_sleepfor (d);
sigaction (SIGXCPU, &oact, NULL);
if (pthread_kill (tid.v, 0) != 0)
DDS_LOG(~DDS_LC_FATAL, "-- thread exited --\n");
else
{
const dds_time_t d = 1000000;
struct sigaction act, oact;
char **strs;
int i;
DDS_LOG(~DDS_LC_FATAL, "-- stack trace of %s requested --\n", name);
act.sa_handler = log_stacktrace_sigh;
act.sa_flags = 0;
sigfillset (&act.sa_mask);
while (!ddsrt_atomic_cas32 (&log_stacktrace_flag, 0, 1))
dds_sleepfor (d);
sigaction (SIGXCPU, &act, &oact);
pthread_kill (tid.v, SIGXCPU);
while (!ddsrt_atomic_cas32 (&log_stacktrace_flag, 2, 3) && pthread_kill (tid.v, 0) == 0)
dds_sleepfor (d);
sigaction (SIGXCPU, &oact, NULL);
if (pthread_kill (tid.v, 0) != 0)
DDS_LOG(~DDS_LC_FATAL, "-- thread exited --\n");
else
{
DDS_LOG(~DDS_LC_FATAL, "-- stack trace follows --\n");
strs = backtrace_symbols (log_stacktrace_stk.stk, log_stacktrace_stk.depth);
for (i = 0; i < log_stacktrace_stk.depth; i++)
DDS_LOG(~DDS_LC_FATAL, "%s\n", strs[i]);
free (strs);
DDS_LOG(~DDS_LC_FATAL, "-- end of stack trace --\n");
}
ddsrt_atomic_st32 (&log_stacktrace_flag, 0);
DDS_LOG(~DDS_LC_FATAL, "-- stack trace follows --\n");
strs = backtrace_symbols (log_stacktrace_stk.stk, log_stacktrace_stk.depth);
for (i = 0; i < log_stacktrace_stk.depth; i++)
DDS_LOG(~DDS_LC_FATAL, "%s\n", strs[i]);
free (strs);
DDS_LOG(~DDS_LC_FATAL, "-- end of stack trace --\n");
}
ddsrt_atomic_st32 (&log_stacktrace_flag, 0);
}
#endif

View file

@ -104,13 +104,14 @@ static struct ddsi_serdata *mkkeysample (int32_t keyval, unsigned statusinfo)
return sd;
}
static uint64_t store (struct dds_rhc *rhc, struct proxy_writer *wr, struct ddsi_serdata *sd, bool print)
static uint64_t store (struct ddsi_tkmap *tkmap, struct dds_rhc *rhc, struct proxy_writer *wr, struct ddsi_serdata *sd, bool print)
{
/* beware: unrefs sd */
struct ddsi_tkmap_instance *tk;
struct proxy_writer_info pwr_info;
thread_state_awake (lookup_thread_state ());
tk = ddsi_tkmap_lookup_instance_ref(sd);
/* single-domain application ... so domain won't change */
thread_state_awake_domain_ok (lookup_thread_state ());
tk = ddsi_tkmap_lookup_instance_ref (tkmap, sd);
uint64_t iid = tk->m_iid;
if (print)
{
@ -132,13 +133,13 @@ static uint64_t store (struct dds_rhc *rhc, struct proxy_writer *wr, struct ddsi
pwr_info.iid = wr->e.iid;
pwr_info.ownership_strength = wr->c.xqos->ownership_strength.value;
dds_rhc_store (rhc, &pwr_info, sd, tk);
ddsi_tkmap_instance_unref (tk);
ddsi_tkmap_instance_unref (tkmap, tk);
thread_state_asleep (lookup_thread_state ());
ddsi_serdata_unref (sd);
return iid;
}
static struct proxy_writer *mkwr (bool auto_dispose)
static struct proxy_writer *mkwr (const struct q_globals *gv, bool auto_dispose)
{
struct proxy_writer *pwr;
struct dds_qos *xqos;
@ -148,7 +149,7 @@ static struct proxy_writer *mkwr (bool auto_dispose)
wr_iid = ddsi_iid_gen ();
memset (pwr, 0, sizeof (*pwr));
nn_xqos_init_empty (xqos);
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr, ~(uint64_t)0);
nn_xqos_mergein_missing (xqos, &gv->default_xqos_wr, ~(uint64_t)0);
xqos->ownership_strength.value = 0;
xqos->writer_data_lifecycle.autodispose_unregistered_instances = auto_dispose;
pwr->e.iid = wr_iid;
@ -162,7 +163,7 @@ static void fwr (struct proxy_writer *wr)
free (wr);
}
static struct dds_rhc *mkrhc (dds_reader *rd, dds_history_kind_t hk, int32_t hdepth, dds_destination_order_kind_t dok)
static struct dds_rhc *mkrhc (const struct q_globals *gv, dds_reader *rd, dds_history_kind_t hk, int32_t hdepth, dds_destination_order_kind_t dok)
{
struct dds_rhc *rhc;
dds_qos_t rqos;
@ -171,9 +172,9 @@ static struct dds_rhc *mkrhc (dds_reader *rd, dds_history_kind_t hk, int32_t hde
rqos.history.kind = hk;
rqos.history.depth = hdepth;
rqos.destination_order.kind = dok;
nn_xqos_mergein_missing (&rqos, &gv.default_xqos_rd, ~(uint64_t)0);
thread_state_awake (lookup_thread_state ());
rhc = dds_rhc_default_new (rd, mdtopic);
nn_xqos_mergein_missing (&rqos, &gv->default_xqos_rd, ~(uint64_t)0);
thread_state_awake_domain_ok (lookup_thread_state ());
rhc = dds_rhc_default_new_xchecks (rd, gv->m_tkmap, mdtopic, true);
dds_rhc_set_qos(rhc, &rqos);
thread_state_asleep (lookup_thread_state ());
return rhc;
@ -181,7 +182,7 @@ static struct dds_rhc *mkrhc (dds_reader *rd, dds_history_kind_t hk, int32_t hde
static void frhc (struct dds_rhc *rhc)
{
thread_state_awake (lookup_thread_state ());
thread_state_awake_domain_ok (lookup_thread_state ());
dds_rhc_free (rhc);
thread_state_asleep (lookup_thread_state ());
}
@ -289,7 +290,7 @@ static void rdtkcond (struct dds_rhc *rhc, dds_readcond *cond, const struct chec
if (print)
printf ("%s:\n", opname);
thread_state_awake (lookup_thread_state ());
thread_state_awake_domain_ok (lookup_thread_state ());
cnt = op (rhc, true, rres_ptrs, rres_iseq, (max <= 0) ? (uint32_t) (sizeof (rres_iseq) / sizeof (rres_iseq[0])) : (uint32_t) max, cond ? NO_STATE_MASK_SET : (DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE), 0, cond);
thread_state_asleep (lookup_thread_state ());
if (max > 0 && cnt > max) {
@ -468,10 +469,10 @@ static void wait_gc_cycle_impl (struct gcreq *gcreq)
gcreq_free (gcreq);
}
static void wait_gc_cycle (void)
static void wait_gc_cycle (struct gcreq_queue *gcreq_queue)
{
/* only single-threaded for now */
struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, wait_gc_cycle_impl);
struct gcreq *gcreq = gcreq_new (gcreq_queue, wait_gc_cycle_impl);
#ifndef NDEBUG
ddsrt_mutex_lock (&wait_gc_cycle_lock);
assert (wait_gc_cycle_trig == 0);
@ -531,6 +532,17 @@ static dds_entity_t readcond_wrapper (dds_entity_t reader, uint32_t mask, dds_qu
return dds_create_readcondition (reader, mask);
}
static struct q_globals *get_gv (dds_entity_t e)
{
struct q_globals *gv;
dds_entity *x;
if (dds_entity_pin (e, &x) < 0)
abort ();
gv = &x->m_domain->gv;
dds_entity_unpin (x);
return gv;
}
static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count, dds_entity_t (*create_cond) (dds_entity_t reader, uint32_t mask, dds_querycondition_filter_fn filter), dds_querycondition_filter_fn filter0, dds_querycondition_filter_fn filter1, bool print)
{
dds_qos_t *qos = dds_create_qos ();
@ -550,7 +562,10 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
rhc[i] = rdp->m_rhc;
dds_entity_unlock (x);
}
struct proxy_writer *wr[] = { mkwr (0), mkwr (1), mkwr (1) };
const struct q_globals *gv = get_gv (pp);
struct ddsi_tkmap *tkmap = gv->m_tkmap;
struct proxy_writer *wr[] = { mkwr (gv, 0), mkwr (gv, 1), mkwr (gv, 1) };
static const uint32_t stab[] = {
DDS_READ_SAMPLE_STATE, DDS_NOT_READ_SAMPLE_STATE,
@ -700,42 +715,42 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
case 0: { /* wr */
struct ddsi_serdata *s = mksample (keyval, 0);
for (size_t k = 0; k < nrd; k++)
store (rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
ddsi_serdata_unref (s);
break;
}
case 1: { /* wr disp */
struct ddsi_serdata *s = mksample (keyval, NN_STATUSINFO_DISPOSE);
for (size_t k = 0; k < nrd; k++)
store (rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
ddsi_serdata_unref (s);
break;
}
case 2: { /* disp */
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_DISPOSE);
for (size_t k = 0; k < nrd; k++)
store (rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
ddsi_serdata_unref (s);
break;
}
case 3: { /* unreg */
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_UNREGISTER);
for (size_t k = 0; k < nrd; k++)
store (rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
ddsi_serdata_unref (s);
break;
}
case 4: { /* disp unreg */
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER);
for (size_t k = 0; k < nrd; k++)
store (rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
ddsi_serdata_unref (s);
break;
}
case 5: { /* wr disp unreg */
struct ddsi_serdata *s = mksample (keyval, NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER);
for (size_t k = 0; k < nrd; k++)
store (rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
ddsi_serdata_unref (s);
break;
}
@ -766,7 +781,7 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
break;
}
case 11: {
thread_state_awake (lookup_thread_state ());
thread_state_awake_domain_ok (lookup_thread_state ());
struct proxy_writer_info wr_info;
wr_info.auto_dispose = wr[which]->c.xqos->writer_data_lifecycle.autodispose_unregistered_instances;
wr_info.guid = wr[which]->e.guid;
@ -780,7 +795,7 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
}
if ((i % 200) == 0)
wait_gc_cycle ();
wait_gc_cycle (gv->gcreq_queue);
}
for (size_t oper = 0; oper < sizeof (opcount) / sizeof (opcount[0]); oper++)
@ -838,6 +853,7 @@ int main (int argc, char **argv)
tref_dds = dds_time();
mainthread = lookup_thread_state ();
assert (ddsrt_atomic_ldvoidp (&mainthread->gv) != NULL);
{
struct dds_entity *x;
if (dds_entity_lock(tp, DDS_KIND_TOPIC, &x) < 0) abort();
@ -847,20 +863,22 @@ int main (int argc, char **argv)
if (0 >= first)
{
struct q_globals *gv = get_gv (pp);
struct ddsi_tkmap *tkmap = gv->m_tkmap;
if (print)
printf ("************* 0 *************\n");
struct dds_rhc *rhc = mkrhc (NULL, DDS_HISTORY_KEEP_LAST, 1, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
struct proxy_writer *wr0 = mkwr (1);
struct dds_rhc *rhc = mkrhc (gv, NULL, DDS_HISTORY_KEEP_LAST, 1, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
struct proxy_writer *wr0 = mkwr (gv, 1);
uint64_t iid0, iid1, iid_t;
iid0 = store (rhc, wr0, mksample (0, 0), print);
iid1 = store (rhc, wr0, mksample (1, NN_STATUSINFO_DISPOSE), print);
iid0 = store (tkmap, rhc, wr0, mksample (0, 0), print);
iid1 = store (tkmap, rhc, wr0, mksample (1, NN_STATUSINFO_DISPOSE), print);
const struct check c0[] = {
{ "NNA", iid0, wr0->e.iid, 0,0, 1, 0,1 },
{ "NND", iid1, wr0->e.iid, 0,0, 1, 1,2 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
rdall (rhc, c0, print, states_seen);
iid_t = store (rhc, wr0, mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
iid_t = store (tkmap, rhc, wr0, mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
assert (iid_t == iid0);
(void)iid0;
(void)iid_t;
@ -871,7 +889,7 @@ int main (int argc, char **argv)
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
rdall (rhc, c1, print, states_seen);
thread_state_awake (lookup_thread_state ());
thread_state_awake_domain_ok (lookup_thread_state ());
struct proxy_writer_info wr0_info;
wr0_info.auto_dispose = wr0->c.xqos->writer_data_lifecycle.autodispose_unregistered_instances;
wr0_info.guid = wr0->e.guid;
@ -893,15 +911,17 @@ int main (int argc, char **argv)
if (1 >= first)
{
struct q_globals *gv = get_gv (pp);
struct ddsi_tkmap *tkmap = gv->m_tkmap;
if (print)
printf ("************* 1 *************\n");
struct dds_rhc *rhc = mkrhc (NULL, DDS_HISTORY_KEEP_LAST, 4, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
struct proxy_writer *wr[] = { mkwr (0), mkwr (0), mkwr (0) };
struct dds_rhc *rhc = mkrhc (gv, NULL, DDS_HISTORY_KEEP_LAST, 4, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
struct proxy_writer *wr[] = { mkwr (gv, 0), mkwr (gv, 0), mkwr (gv, 0) };
uint64_t iid0, iid_t;
int nregs = 3, isreg[] = { 1, 1, 1 };
iid0 = store (rhc, wr[0], mksample (0, 0), print);
iid_t = store (rhc, wr[1], mksample (0, 0), print); assert (iid0 == iid_t);
iid_t = store (rhc, wr[2], mksample (0, 0), print); assert (iid0 == iid_t);
iid0 = store (tkmap, rhc, wr[0], mksample (0, 0), print);
iid_t = store (tkmap, rhc, wr[1], mksample (0, 0), print); assert (iid0 == iid_t);
iid_t = store (tkmap, rhc, wr[2], mksample (0, 0), print); assert (iid0 == iid_t);
(void)iid0;
tkall (rhc, NULL, print, states_seen);
for (int i = 0; i < 3*3 * 3*3 * 3*3 * 3*3; i++)
@ -913,17 +933,17 @@ int main (int argc, char **argv)
switch (oper)
{
case 0:
iid_t = store (rhc, wr[which], mksample (0, 0), print);
iid_t = store (tkmap, rhc, wr[which], mksample (0, 0), print);
if (!isreg[which]) { nregs++; isreg[which] = 1; }
break;
case 1:
iid_t = store (rhc, wr[which], mkkeysample (0, NN_STATUSINFO_DISPOSE), print);
iid_t = store (tkmap, rhc, wr[which], mkkeysample (0, NN_STATUSINFO_DISPOSE), print);
if (!isreg[which]) { nregs++; isreg[which] = 1; }
break;
case 2:
if (nregs > 1 || !isreg[which])
{
iid_t = store (rhc, wr[which], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
iid_t = store (tkmap, rhc, wr[which], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
if (isreg[which]) { isreg[which] = 0; nregs--; }
}
break;
@ -932,13 +952,13 @@ int main (int argc, char **argv)
}
}
tkall (rhc, 0, print, states_seen);
wait_gc_cycle ();
wait_gc_cycle (gv->gcreq_queue);
assert (nregs > 0);
for (int i = 0; i < 3; i++)
{
if (isreg[i])
{
iid_t = store (rhc, wr[i], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
iid_t = store (tkmap, rhc, wr[i], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
assert (iid_t == iid0);
isreg[i] = 0;
nregs--;
@ -946,11 +966,11 @@ int main (int argc, char **argv)
}
assert (nregs == 0);
tkall (rhc, 0, print, states_seen);
wait_gc_cycle ();
iid_t = store (rhc, wr[0], mksample (0, 0), print);
wait_gc_cycle (gv->gcreq_queue);
iid_t = store (tkmap, rhc, wr[0], mksample (0, 0), print);
assert (iid_t != iid0);
iid0 = iid_t;
iid_t = store (rhc, wr[0], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
iid_t = store (tkmap, rhc, wr[0], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
assert (iid_t == iid0);
frhc (rhc);

View file

@ -215,6 +215,12 @@ inline void ddsrt_atomic_orptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v)
inline void ddsrt_atomic_fence (void) {
__asm volatile ("dmb" : : : "memory");
}
inline void ddsrt_atomic_fence_ldld (void) {
ddsrt_atomic_fence ();
}
inline void ddsrt_atomic_fence_stst (void) {
ddsrt_atomic_fence ();
}
inline void ddsrt_atomic_fence_acq (void) {
ddsrt_atomic_fence ();
}

View file

@ -326,6 +326,11 @@ inline void ddsrt_atomic_fence_ldld (void) {
__sync_synchronize ();
#endif
}
inline void ddsrt_atomic_fence_stst (void) {
#if !(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64)
__sync_synchronize ();
#endif
}
inline void ddsrt_atomic_fence_acq (void) {
#if !(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();

View file

@ -302,6 +302,11 @@ inline void ddsrt_atomic_fence_ldld (void) {
ddsrt_atomic_fence ();
#endif
}
inline void ddsrt_atomic_fence_stst (void) {
#if !(defined _M_IX86 || defined _M_X64)
ddsrt_atomic_fence ();
#endif
}
inline void ddsrt_atomic_fence_acq (void) {
ddsrt_atomic_fence ();
}

View file

@ -245,7 +245,10 @@ inline void ddsrt_atomic_fence (void) {
membar_enter ();
}
inline void ddsrt_atomic_fence_ldld (void) {
membar_enter ();
membar_consumer ();
}
inline void ddsrt_atomic_fence_stst (void) {
membar_producer ();
}
inline void ddsrt_atomic_fence_acq (void) {
membar_enter ();

View file

@ -30,20 +30,20 @@ extern "C" {
* When proper distributed hash values are generated, then hopscotch
* works nice and quickly.
*/
typedef uint32_t (*ddsrt_hh_hash_fn) (const void *);
typedef uint32_t (*ddsrt_hh_hash_fn) (const void *a);
/*
* Hopscotch needs to be able to compare two elements.
* Returns 0 when not equal.
*/
typedef int (*ddsrt_hh_equals_fn) (const void *, const void *);
typedef int (*ddsrt_hh_equals_fn) (const void *a, const void *b);
/*
* Hopscotch is will resize its internal buckets list when needed. It will
* call this garbage collection function with the old buckets list. The
* caller has to delete the list when it deems it safe to do so.
*/
typedef void (*ddsrt_hh_buckets_gc_fn) (void *);
typedef void (*ddsrt_hh_buckets_gc_fn) (void *bs, void *arg);
/* Sequential version */
struct ddsrt_hh;
@ -79,7 +79,7 @@ struct ddsrt_chh_iter {
};
#endif
DDS_EXPORT struct ddsrt_chh *ddsrt_chh_new (uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals, ddsrt_hh_buckets_gc_fn gc_buckets);
DDS_EXPORT struct ddsrt_chh *ddsrt_chh_new (uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals, ddsrt_hh_buckets_gc_fn gc_buckets, void *gc_buckets_arg);
DDS_EXPORT void ddsrt_chh_free (struct ddsrt_chh * __restrict hh);
DDS_EXPORT void *ddsrt_chh_lookup (struct ddsrt_chh * __restrict rt, const void * __restrict template);
DDS_EXPORT int ddsrt_chh_add (struct ddsrt_chh * __restrict rt, const void * __restrict data);

View file

@ -125,6 +125,7 @@ extern inline int ddsrt_atomic_casvoidp2 (volatile ddsrt_atomic_uintptr2_t *x, u
/* FENCES */
extern inline void ddsrt_atomic_fence (void);
extern inline void ddsrt_atomic_fence_ldld (void);
extern inline void ddsrt_atomic_fence_stst (void);
extern inline void ddsrt_atomic_fence_acq (void);
extern inline void ddsrt_atomic_fence_rel (void);

View file

@ -299,6 +299,7 @@ struct ddsrt_chh {
ddsrt_hh_equals_fn equals;
ddsrt_rwlock_t resize_locks[N_RESIZE_LOCKS];
ddsrt_hh_buckets_gc_fn gc_buckets;
void *gc_buckets_arg;
};
#define CHH_MAX_TRIES 4
@ -309,7 +310,7 @@ static int ddsrt_chh_data_valid_p (void *data)
return data != NULL && data != CHH_BUSY;
}
static int ddsrt_chh_init (struct ddsrt_chh *rt, uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals, ddsrt_hh_buckets_gc_fn gc_buckets)
static int ddsrt_chh_init (struct ddsrt_chh *rt, uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals, ddsrt_hh_buckets_gc_fn gc_buckets, void *gc_buckets_arg)
{
uint32_t size;
uint32_t i;
@ -322,6 +323,7 @@ static int ddsrt_chh_init (struct ddsrt_chh *rt, uint32_t init_size, ddsrt_hh_ha
rt->hash = hash;
rt->equals = equals;
rt->gc_buckets = gc_buckets;
rt->gc_buckets_arg = gc_buckets_arg;
buckets = ddsrt_malloc (offsetof (struct ddsrt_chh_bucket_array, bs) + size * sizeof (*buckets->bs));
ddsrt_atomic_stvoidp (&rt->buckets, buckets);
@ -359,10 +361,10 @@ static void ddsrt_chh_fini (struct ddsrt_chh *rt)
}
}
struct ddsrt_chh *ddsrt_chh_new (uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals, ddsrt_hh_buckets_gc_fn gc_buckets)
struct ddsrt_chh *ddsrt_chh_new (uint32_t init_size, ddsrt_hh_hash_fn hash, ddsrt_hh_equals_fn equals, ddsrt_hh_buckets_gc_fn gc_buckets, void *gc_buckets_arg)
{
struct ddsrt_chh *hh = ddsrt_malloc (sizeof (*hh));
if (ddsrt_chh_init (hh, init_size, hash, equals, gc_buckets) < 0) {
if (ddsrt_chh_init (hh, init_size, hash, equals, gc_buckets, gc_buckets_arg) < 0) {
ddsrt_free (hh);
return NULL;
} else {
@ -572,7 +574,7 @@ static void ddsrt_chh_resize (struct ddsrt_chh *rt)
ddsrt_atomic_fence ();
ddsrt_atomic_stvoidp (&rt->buckets, bsary1);
rt->gc_buckets (bsary0);
rt->gc_buckets (bsary0, rt->gc_buckets_arg);
}
int ddsrt_chh_add (struct ddsrt_chh * __restrict rt, const void * __restrict data)