Merge pull request #84 from eboasson/odds-and-ends

Odds and ends
This commit is contained in:
eboasson 2019-01-07 16:39:52 +01:00 committed by GitHub
commit 1990007614
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 347 additions and 305 deletions

View file

@ -370,7 +370,8 @@ dds__builtin_write(
_In_ nn_wctime_t timestamp, _In_ nn_wctime_t timestamp,
_In_ bool alive) _In_ bool alive)
{ {
dds_entity_t topic; /* initialize to avoid compiler warning ultimately caused by C's horrible type system */
dds_entity_t topic = 0;
switch (type) switch (type)
{ {
case DSBT_PARTICIPANT: case DSBT_PARTICIPANT:
@ -383,6 +384,7 @@ dds__builtin_write(
topic = DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION; topic = DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION;
break; break;
} }
assert(topic != 0);
(void)dds__builtin_write_int(topic, guid, timestamp.v, alive); (void)dds__builtin_write_int(topic, guid, timestamp.v, alive);
} }

View file

@ -560,7 +560,7 @@ dds_get_qos(
{ {
dds_entity *e; dds_entity *e;
dds__retcode_t rc; dds__retcode_t rc;
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret;
if (qos == NULL) { if (qos == NULL) {
DDS_ERROR("Argument qos is NULL\n"); DDS_ERROR("Argument qos is NULL\n");
@ -574,11 +574,10 @@ dds_get_qos(
goto fail; goto fail;
} }
if (e->m_deriver.set_qos) { if (e->m_deriver.set_qos) {
rc = dds_copy_qos(qos, e->m_qos); ret = dds_copy_qos(qos, e->m_qos);
} else { } else {
rc = DDS_RETCODE_ILLEGAL_OPERATION;
DDS_ERROR("QoS cannot be set on this entity\n"); DDS_ERROR("QoS cannot be set on this entity\n");
ret = DDS_ERRNO(rc); ret = DDS_ERRNO(DDS_RETCODE_ILLEGAL_OPERATION);
} }
dds_entity_unlock(e); dds_entity_unlock(e);
fail: fail:
@ -1121,6 +1120,16 @@ dds_triggered(
} }
static bool in_observer_list_p (const struct dds_entity *observed, const dds_entity_t observer)
{
dds_entity_observer *cur;
for (cur = observed->m_observers; cur != NULL; cur = cur->m_next) {
if (cur->m_observer == observer) {
return true;
}
}
return false;
}
_Check_return_ dds__retcode_t _Check_return_ dds__retcode_t
dds_entity_observer_register_nl( dds_entity_observer_register_nl(
@ -1128,30 +1137,19 @@ dds_entity_observer_register_nl(
_In_ dds_entity_t observer, _In_ dds_entity_t observer,
_In_ dds_entity_callback cb) _In_ dds_entity_callback cb)
{ {
dds__retcode_t rc = DDS_RETCODE_OK; dds__retcode_t rc;
dds_entity_observer *o = os_malloc(sizeof(dds_entity_observer)); dds_entity_observer *o = os_malloc(sizeof(dds_entity_observer));
assert(observed); assert(observed);
o->m_cb = cb; o->m_cb = cb;
o->m_observer = observer; o->m_observer = observer;
o->m_next = NULL;
os_mutexLock(&observed->m_observers_lock); os_mutexLock(&observed->m_observers_lock);
if (observed->m_observers == NULL) { if (in_observer_list_p (observed, observer)) {
observed->m_observers = o; rc = DDS_RETCODE_PRECONDITION_NOT_MET;
os_free (o);
} else { } else {
dds_entity_observer *last; rc = DDS_RETCODE_OK;
dds_entity_observer *idx = observed->m_observers; o->m_next = observed->m_observers;
while ((idx != NULL) && (o != NULL)) { observed->m_observers = o;
if (idx->m_observer == observer) {
os_free(o);
o = NULL;
rc = DDS_RETCODE_PRECONDITION_NOT_MET;
}
last = idx;
idx = idx->m_next;
}
if (o != NULL) {
last->m_next = o;
}
} }
os_mutexUnlock(&observed->m_observers_lock); os_mutexUnlock(&observed->m_observers_lock);
return rc; return rc;

View file

@ -325,14 +325,12 @@ dds_reader_status_cb(
/* There's a deletion or closing going on. */ /* There's a deletion or closing going on. */
} }
} else if (rc == DDS_RETCODE_NO_DATA) { } else if (rc == DDS_RETCODE_NO_DATA) {
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status. */ /* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status, consider successful. */
dds_entity_status_set(entity, data->status); dds_entity_status_set(entity, data->status);
/* Notify possible interested observers. */ /* Notify possible interested observers. */
dds_entity_status_signal(entity); dds_entity_status_signal(entity);
rc = DDS_RETCODE_OK;
} else if (rc == DDS_RETCODE_ALREADY_DELETED) { } else if (rc == DDS_RETCODE_ALREADY_DELETED) {
/* An entity up the hierarchy is being deleted. */ /* An entity up the hierarchy is being deleted, consider successful. */
rc = DDS_RETCODE_OK;
} else { } else {
/* Something went wrong up the hierarchy. */ /* Something went wrong up the hierarchy. */
} }

View file

@ -367,6 +367,7 @@ static void remove_inst_from_nonempty_list (struct rhc *rhc, struct rhc_instance
#ifndef NDEBUG #ifndef NDEBUG
{ {
const struct rhc_instance *x = rhc->nonempty_instances; const struct rhc_instance *x = rhc->nonempty_instances;
assert (x);
do { if (x == inst) break; x = x->next; } while (x != rhc->nonempty_instances); do { if (x == inst) break; x = x->next; } while (x != rhc->nonempty_instances);
assert (x == inst); assert (x == inst);
} }
@ -391,7 +392,8 @@ static void remove_inst_from_nonempty_list (struct rhc *rhc, struct rhc_instance
struct rhc * dds_rhc_new (dds_reader * reader, const struct ddsi_sertopic * topic) struct rhc * dds_rhc_new (dds_reader * reader, const struct ddsi_sertopic * topic)
{ {
struct rhc * rhc = dds_alloc (sizeof (*rhc)); struct rhc * rhc = os_malloc (sizeof (*rhc));
memset (rhc, 0, sizeof (*rhc));
lwregs_init (&rhc->registrations); lwregs_init (&rhc->registrations);
os_mutexInit (&rhc->lock); os_mutexInit (&rhc->lock);
@ -431,7 +433,7 @@ static struct rhc_sample * alloc_sample (struct rhc_instance *inst)
{ {
/* This instead of sizeof(rhc_sample) gets us type checking */ /* This instead of sizeof(rhc_sample) gets us type checking */
struct rhc_sample *s; struct rhc_sample *s;
s = dds_alloc (sizeof (*s)); s = os_malloc (sizeof (*s));
return s; return s;
} }
} }
@ -449,7 +451,7 @@ static void free_sample (struct rhc_instance *inst, struct rhc_sample *s)
} }
else else
{ {
dds_free (s); os_free (s);
} }
} }
@ -505,7 +507,7 @@ static void free_instance (void *vnode, void *varg)
remove_inst_from_nonempty_list (rhc, inst); remove_inst_from_nonempty_list (rhc, inst);
} }
ddsi_tkmap_instance_unref (inst->tk); ddsi_tkmap_instance_unref (inst->tk);
dds_free (inst); os_free (inst);
} }
uint32_t dds_rhc_lock_samples (struct rhc *rhc) uint32_t dds_rhc_lock_samples (struct rhc *rhc)
@ -529,7 +531,7 @@ void dds_rhc_free (struct rhc *rhc)
lwregs_fini (&rhc->registrations); lwregs_fini (&rhc->registrations);
os_mutexDestroy (&rhc->lock); os_mutexDestroy (&rhc->lock);
os_mutexDestroy (&rhc->conds_lock); os_mutexDestroy (&rhc->conds_lock);
dds_free (rhc); os_free (rhc);
} }
void dds_rhc_fini (struct rhc * rhc) void dds_rhc_fini (struct rhc * rhc)
@ -1028,14 +1030,13 @@ static struct rhc_instance * alloc_new_instance
struct rhc_instance *inst; struct rhc_instance *inst;
ddsi_tkmap_instance_ref (tk); ddsi_tkmap_instance_ref (tk);
inst = dds_alloc (sizeof (*inst)); inst = os_malloc (sizeof (*inst));
memset (inst, 0, sizeof (*inst));
inst->iid = tk->m_iid; inst->iid = tk->m_iid;
inst->tk = tk; inst->tk = tk;
inst->wrcount = (serdata->statusinfo & NN_STATUSINFO_UNREGISTER) ? 0 : 1; inst->wrcount = (serdata->statusinfo & NN_STATUSINFO_UNREGISTER) ? 0 : 1;
inst->isdisposed = (serdata->statusinfo & NN_STATUSINFO_DISPOSE); inst->isdisposed = (serdata->statusinfo & NN_STATUSINFO_DISPOSE) != 0;
inst->isnew = 1; inst->isnew = 1;
inst->inv_exists = 0;
inst->inv_isread = 0; /* don't care */
inst->a_sample_free = 1; inst->a_sample_free = 1;
inst->wr_iid = pwr_info->iid; inst->wr_iid = pwr_info->iid;
inst->wr_iid_islive = (inst->wrcount != 0); inst->wr_iid_islive = (inst->wrcount != 0);
@ -2132,7 +2133,7 @@ void dds_rhc_add_readcondition (dds_readcond * cond)
DDS_TRACE("add_readcondition(%p, %x, %x, %x) => %p qminv %x ; rhc %u conds\n", DDS_TRACE("add_readcondition(%p, %x, %x, %x) => %p qminv %x ; rhc %u conds\n",
(void *) rhc, cond->m_sample_states, cond->m_view_states, (void *) rhc, cond->m_sample_states, cond->m_view_states,
cond->m_instance_states, cond, cond->m_qminv, rhc->nconds); cond->m_instance_states, (void *) cond, cond->m_qminv, rhc->nconds);
os_mutexUnlock (&rhc->conds_lock); os_mutexUnlock (&rhc->conds_lock);
os_mutexUnlock (&rhc->lock); os_mutexUnlock (&rhc->lock);

View file

@ -130,14 +130,12 @@ dds_topic_status_cb(
dds_topic_unlock(topic); dds_topic_unlock(topic);
} }
} else if (rc == DDS_RETCODE_NO_DATA) { } else if (rc == DDS_RETCODE_NO_DATA) {
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status. */ /* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status; consider it successful. */
dds_entity_status_set((dds_entity*)topic, DDS_INCONSISTENT_TOPIC_STATUS); dds_entity_status_set((dds_entity*)topic, DDS_INCONSISTENT_TOPIC_STATUS);
/* Notify possible interested observers. */ /* Notify possible interested observers. */
dds_entity_status_signal((dds_entity*)topic); dds_entity_status_signal((dds_entity*)topic);
rc = DDS_RETCODE_OK;
} else if (rc == DDS_RETCODE_ALREADY_DELETED) { } else if (rc == DDS_RETCODE_ALREADY_DELETED) {
/* An entity up the hierarchy is being deleted. */ /* An entity up the hierarchy is being deleted; consider it successful. */
rc = DDS_RETCODE_OK;
} else { } else {
/* Something went wrong up the hierarchy. */ /* Something went wrong up the hierarchy. */
} }
@ -318,7 +316,7 @@ static bool dupdef_qos_ok(const dds_qos_t *qos, const struct ddsi_sertopic *st)
static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct ddsi_sertopic *b) static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct ddsi_sertopic *b)
{ {
printf ("sertopic_equivalent %p %p (%s %s; %u %u; %p %p; %p %p)\n", a, b, a->name_typename, b->name_typename, a->serdata_basehash, b->serdata_basehash, a->ops, b->ops, a->serdata_ops, b->serdata_ops); printf ("sertopic_equivalent %p %p (%s %s; %u %u; %p %p; %p %p)\n", (void*)a, (void*)b, a->name_typename, b->name_typename, a->serdata_basehash, b->serdata_basehash, (void *)a->ops, (void *)b->ops, (void *)a->serdata_ops, (void *)b->serdata_ops);
if (strcmp (a->name_typename, b->name_typename) != 0) if (strcmp (a->name_typename, b->name_typename) != 0)
return false; return false;

View file

@ -170,14 +170,12 @@ dds_writer_status_cb(
/* There's a deletion or closing going on. */ /* There's a deletion or closing going on. */
} }
} else if (rc == DDS_RETCODE_NO_DATA) { } else if (rc == DDS_RETCODE_NO_DATA) {
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status. */ /* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status; consider it successful. */
dds_entity_status_set(entity, data->status); dds_entity_status_set(entity, data->status);
/* Notify possible interested observers. */ /* Notify possible interested observers. */
dds_entity_status_signal(entity); dds_entity_status_signal(entity);
rc = DDS_RETCODE_OK;
} else if (rc == DDS_RETCODE_ALREADY_DELETED) { } else if (rc == DDS_RETCODE_ALREADY_DELETED) {
/* An entity up the hierarchy is being deleted. */ /* An entity up the hierarchy is being deleted; consider it successful. */
rc = DDS_RETCODE_OK;
} else { } else {
/* Something went wrong up the hierarchy. */ /* Something went wrong up the hierarchy. */
} }
@ -395,12 +393,6 @@ static struct whc *make_whc(const dds_qos_t *qos)
} else { } else {
tldepth = 0; tldepth = 0;
} }
if (hdepth == 0 && tldepth == 0)
{
/* no index at all - so no need to bother with startup mode */
startup_mode = 0;
}
return whc_new (handle_as_transient_local, hdepth, tldepth); return whc_new (handle_as_transient_local, hdepth, tldepth);
} }

View file

@ -26,7 +26,6 @@ struct dds_topic;
struct ddsi_tkmap_instance struct ddsi_tkmap_instance
{ {
struct ddsi_serdata * m_sample; struct ddsi_serdata * m_sample;
struct ddsi_tkmap * m_map;
uint64_t m_iid; uint64_t m_iid;
os_atomic_uint32_t m_refc; os_atomic_uint32_t m_refc;
}; };

View file

@ -328,7 +328,7 @@ struct proxy_endpoint_common
struct proxy_endpoint_common *next_ep; /* next \ endpoint belonging to this proxy participant */ struct proxy_endpoint_common *next_ep; /* next \ endpoint belonging to this proxy participant */
struct proxy_endpoint_common *prev_ep; /* prev / -- this is in arbitrary ordering */ struct proxy_endpoint_common *prev_ep; /* prev / -- this is in arbitrary ordering */
struct nn_xqos *xqos; /* proxy endpoint QoS lives here; FIXME: local ones should have it moved to common as well */ struct nn_xqos *xqos; /* proxy endpoint QoS lives here; FIXME: local ones should have it moved to common as well */
const struct ddsi_sertopic * topic; /* topic may be NULL: for built-ins, but also for never-yet matched proxies (so we don't have to know the topic; when we match, we certainly do know) */ struct ddsi_sertopic * topic; /* topic may be NULL: for built-ins, but also for never-yet matched proxies (so we don't have to know the topic; when we match, we certainly do know) */
struct addrset *as; /* address set to use for communicating with this endpoint */ struct addrset *as; /* address set to use for communicating with this endpoint */
nn_guid_t group_guid; /* 0:0:0:0 if not available */ nn_guid_t group_guid; /* 0:0:0:0 if not available */
nn_vendorid_t vendor; /* cached from proxypp->vendor */ nn_vendorid_t vendor; /* cached from proxypp->vendor */

View file

@ -22,5 +22,6 @@
#define ERR_BUSY -8 #define ERR_BUSY -8
#define ERR_NO_ADDRESS -9 #define ERR_NO_ADDRESS -9
#define ERR_TIMEOUT -10 #define ERR_TIMEOUT -10
#define ERR_INCOMPATIBLE -11
#endif /* NN_ERROR_H */ #endif /* NN_ERROR_H */

View file

@ -156,6 +156,11 @@ typedef struct Header {
nn_guid_prefix_t guid_prefix; nn_guid_prefix_t guid_prefix;
} Header_t; } Header_t;
#define NN_PROTOCOLID_INITIALIZER {{ 'R','T','P','S' }} #define NN_PROTOCOLID_INITIALIZER {{ 'R','T','P','S' }}
#if PLATFORM_IS_LITTLE_ENDIAN
#define NN_PROTOCOLID_AS_UINT32 (((uint32_t)'R' << 0) | ((uint32_t)'T' << 8) | ((uint32_t)'P' << 16) | ((uint32_t)'S' << 24))
#else
#define NN_PROTOCOLID_AS_UINT32 (((uint32_t)'R' << 24) | ((uint32_t)'T' << 16) | ((uint32_t)'P' << 8) | ((uint32_t)'S' << 0))
#endif
#define NN_PROTOCOL_VERSION_INITIALIZER { RTPS_MAJOR, RTPS_MINOR } #define NN_PROTOCOL_VERSION_INITIALIZER { RTPS_MAJOR, RTPS_MINOR }
#define NN_VENDORID_INITIALIER MY_VENDOR_ID #define NN_VENDORID_INITIALIER MY_VENDOR_ID
#define NN_HEADER_INITIALIZER { NN_PROTOCOLID_INITIALIZER, NN_PROTOCOL_VERSION_INITIALIZER, NN_VENDORID_INITIALIER, NN_GUID_PREFIX_UNKNOWN_INITIALIZER } #define NN_HEADER_INITIALIZER { NN_PROTOCOLID_INITIALIZER, NN_PROTOCOL_VERSION_INITIALIZER, NN_VENDORID_INITIALIER, NN_GUID_PREFIX_UNKNOWN_INITIALIZER }

View file

@ -38,7 +38,7 @@ int ddsi_ipaddr_compare (const os_sockaddr *const sa1, const os_sockaddr *const
sin1 = (os_sockaddr_in *)sa1; sin1 = (os_sockaddr_in *)sa1;
sin2 = (os_sockaddr_in *)sa2; sin2 = (os_sockaddr_in *)sa2;
sz = sizeof(sin1->sin_addr); sz = sizeof(sin1->sin_addr);
eq = memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(sz)); eq = memcmp(&sin1->sin_addr, &sin2->sin_addr, sz);
break; break;
} }
default: { default: {

View file

@ -133,7 +133,7 @@ struct ddsi_serdata *ddsi_serdata_builtin_from_keyhash (const struct ddsi_sertop
const struct entity_common *entity = ephash_lookup_guid_untyped ((const nn_guid_t *) keyhash->value); const struct entity_common *entity = ephash_lookup_guid_untyped ((const nn_guid_t *) keyhash->value);
struct ddsi_serdata_builtin *d = serdata_builtin_new(tp, entity ? SDK_DATA : SDK_KEY); struct ddsi_serdata_builtin *d = serdata_builtin_new(tp, entity ? SDK_DATA : SDK_KEY);
memcpy (&d->key, keyhash->value, sizeof (d->key)); memcpy (&d->key, keyhash->value, sizeof (d->key));
if (d->c.kind == SDK_DATA) if (entity)
{ {
switch (entity->kind) switch (entity->kind)
{ {

View file

@ -60,7 +60,7 @@ static void serdata_free_wrap (void *elem)
void ddsi_serdatapool_free (struct serdatapool * pool) void ddsi_serdatapool_free (struct serdatapool * pool)
{ {
DDS_TRACE("ddsi_serdatapool_free(%p)\n", pool); DDS_TRACE("ddsi_serdatapool_free(%p)\n", (void *) pool);
nn_freelist_fini (&pool->freelist, serdata_free_wrap); nn_freelist_fini (&pool->freelist, serdata_free_wrap);
os_free (pool); os_free (pool);
} }
@ -167,6 +167,12 @@ static struct ddsi_serdata *fix_serdata_default(struct ddsi_serdata_default *d,
return &d->c; return &d->c;
} }
static struct ddsi_serdata *fix_serdata_default_nokey(struct ddsi_serdata_default *d, uint32_t basehash)
{
d->c.hash = basehash;
return &d->c;
}
static uint32_t serdata_default_get_size(const struct ddsi_serdata *dcmn) static uint32_t serdata_default_get_size(const struct ddsi_serdata *dcmn)
{ {
const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *) dcmn; const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *) dcmn;
@ -240,7 +246,7 @@ static struct ddsi_serdata_default *serdata_default_new(const struct ddsi_sertop
} }
/* Construct a serdata from a fragchain received over the network */ /* Construct a serdata from a fragchain received over the network */
static struct ddsi_serdata *serdata_default_from_ser (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size) static struct ddsi_serdata_default *serdata_default_from_ser_common (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size)
{ {
const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn;
struct ddsi_serdata_default *d = serdata_default_new(tp, kind); struct ddsi_serdata_default *d = serdata_default_new(tp, kind);
@ -270,7 +276,17 @@ static struct ddsi_serdata *serdata_default_from_ser (const struct ddsi_sertopic
dds_stream_t is; dds_stream_t is;
dds_stream_from_serdata_default (&is, d); dds_stream_from_serdata_default (&is, d);
dds_stream_read_keyhash (&is, &d->keyhash, (const dds_topic_descriptor_t *)tp->type, kind == SDK_KEY); dds_stream_read_keyhash (&is, &d->keyhash, (const dds_topic_descriptor_t *)tp->type, kind == SDK_KEY);
return fix_serdata_default (d, tp->c.serdata_basehash); return d;
}
static struct ddsi_serdata *serdata_default_from_ser (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size)
{
return fix_serdata_default (serdata_default_from_ser_common (tpcmn, kind, fragchain, size), tpcmn->serdata_basehash);
}
static struct ddsi_serdata *serdata_default_from_ser_nokey (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size)
{
return fix_serdata_default_nokey (serdata_default_from_ser_common (tpcmn, kind, fragchain, size), tpcmn->serdata_basehash);
} }
struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash) struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash)
@ -301,11 +317,10 @@ struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr_nokey (const struct ddsi_sert
(void)keyhash; (void)keyhash;
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1; d->keyhash.m_iskey = 1;
d->c.hash = tp->c.serdata_basehash; return fix_serdata_default_nokey(d, tp->c.serdata_basehash);
return (struct ddsi_serdata *)d;
} }
static struct ddsi_serdata *serdata_default_from_sample_cdr (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample) static struct ddsi_serdata_default *serdata_default_from_sample_cdr_common (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample)
{ {
const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn; const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn;
struct ddsi_serdata_default *d = serdata_default_new(tp, kind); struct ddsi_serdata_default *d = serdata_default_new(tp, kind);
@ -324,7 +339,17 @@ static struct ddsi_serdata *serdata_default_from_sample_cdr (const struct ddsi_s
break; break;
} }
dds_stream_add_to_serdata_default (&os, &d); dds_stream_add_to_serdata_default (&os, &d);
return fix_serdata_default (d, tp->c.serdata_basehash); return d;
}
static struct ddsi_serdata *serdata_default_from_sample_cdr (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample)
{
return fix_serdata_default (serdata_default_from_sample_cdr_common (tpcmn, kind, sample), tpcmn->serdata_basehash);
}
static struct ddsi_serdata *serdata_default_from_sample_cdr_nokey (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample)
{
return fix_serdata_default_nokey (serdata_default_from_sample_cdr_common (tpcmn, kind, sample), tpcmn->serdata_basehash);
} }
static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample) static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample)
@ -345,7 +370,7 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi
case PID_GROUP_GUID: case PID_GROUP_GUID:
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1; d->keyhash.m_iskey = 1;
memcpy (&d->keyhash.m_hash, rawkey, 16); memcpy (d->keyhash.m_hash, rawkey, 16);
#ifndef NDEBUG #ifndef NDEBUG
keysize = 16; keysize = 16;
#endif #endif
@ -358,13 +383,14 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi
md5_state_t md5st; md5_state_t md5st;
md5_byte_t digest[16]; md5_byte_t digest[16];
topic_name_sz = (uint32_t) strlen (topic_name) + 1; topic_name_sz = (uint32_t) strlen (topic_name) + 1;
topic_name_sz_BE = toBE4u (topic_name_sz);
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 0; d->keyhash.m_iskey = 0;
md5_init (&md5st); md5_init (&md5st);
md5_append (&md5st, (const md5_byte_t *) &topic_name_sz_BE, sizeof (topic_name_sz_BE)); md5_append (&md5st, (const md5_byte_t *) &topic_name_sz_BE, sizeof (topic_name_sz_BE));
md5_append (&md5st, (const md5_byte_t *) topic_name, topic_name_sz); md5_append (&md5st, (const md5_byte_t *) topic_name, topic_name_sz);
md5_finish (&md5st, digest); md5_finish (&md5st, digest);
memcpy (&d->keyhash.m_hash, digest, 16); memcpy (d->keyhash.m_hash, digest, 16);
#ifndef NDEBUG #ifndef NDEBUG
keysize = sizeof (uint32_t) + topic_name_sz; keysize = sizeof (uint32_t) + topic_name_sz;
#endif #endif
@ -391,9 +417,13 @@ static struct ddsi_serdata *serdata_default_from_sample_rawcdr (const struct dds
serdata_default_append_blob (&d, 1, sample->size, sample->blob); serdata_default_append_blob (&d, 1, sample->size, sample->blob);
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1; d->keyhash.m_iskey = 1;
if (sample->keysize > 0) if (sample->keysize == 0)
return fix_serdata_default_nokey (d, tp->c.serdata_basehash);
else
{
memcpy (&d->keyhash.m_hash, sample->key, sample->keysize); memcpy (&d->keyhash.m_hash, sample->key, sample->keysize);
return fix_serdata_default (d, tp->c.serdata_basehash); return fix_serdata_default (d, tp->c.serdata_basehash);
}
} }
static struct ddsi_serdata *serdata_default_to_topicless (const struct ddsi_serdata *serdata_common) static struct ddsi_serdata *serdata_default_to_topicless (const struct ddsi_serdata *serdata_common)
@ -518,9 +548,9 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey = {
.get_size = serdata_default_get_size, .get_size = serdata_default_get_size,
.eqkey = serdata_default_eqkey_nokey, .eqkey = serdata_default_eqkey_nokey,
.free = serdata_default_free, .free = serdata_default_free,
.from_ser = serdata_default_from_ser, .from_ser = serdata_default_from_ser_nokey,
.from_keyhash = ddsi_serdata_from_keyhash_cdr_nokey, .from_keyhash = ddsi_serdata_from_keyhash_cdr_nokey,
.from_sample = serdata_default_from_sample_cdr, .from_sample = serdata_default_from_sample_cdr_nokey,
.to_ser = serdata_default_to_ser, .to_ser = serdata_default_to_ser,
.to_sample = serdata_default_to_sample_cdr, .to_sample = serdata_default_to_sample_cdr,
.to_ser_ref = serdata_default_to_ser_ref, .to_ser_ref = serdata_default_to_ser_ref,

View file

@ -114,7 +114,7 @@ static void sertopic_builtin_free_samples (const struct ddsi_sertopic *sertopic_
#endif #endif
if (op & DDS_FREE_CONTENTS_BIT) if (op & DDS_FREE_CONTENTS_BIT)
{ {
void (*f) (void *); void (*f) (void *) = 0;
char *ptr = ptrs[0]; char *ptr = ptrs[0];
switch (tp->type) switch (tp->type)
{ {
@ -126,6 +126,7 @@ static void sertopic_builtin_free_samples (const struct ddsi_sertopic *sertopic_
f = free_endpoint; f = free_endpoint;
break; break;
} }
assert (f != 0);
for (size_t i = 0; i < count; i++) for (size_t i = 0; i < count; i++)
{ {
f (ptr); f (ptr);

View file

@ -73,7 +73,7 @@ typedef struct ddsi_tcp_listener
} }
* ddsi_tcp_listener_t; * ddsi_tcp_listener_t;
static int ddsi_tcp_cmp_conn (const ddsi_tcp_conn_t c1, const ddsi_tcp_conn_t c2) static int ddsi_tcp_cmp_conn (const struct ddsi_tcp_conn *c1, const struct ddsi_tcp_conn *c2)
{ {
const os_sockaddr *a1s = (os_sockaddr *)&c1->m_peer_addr; const os_sockaddr *a1s = (os_sockaddr *)&c1->m_peer_addr;
const os_sockaddr *a2s = (os_sockaddr *)&c2->m_peer_addr; const os_sockaddr *a2s = (os_sockaddr *)&c2->m_peer_addr;
@ -84,6 +84,11 @@ static int ddsi_tcp_cmp_conn (const ddsi_tcp_conn_t c1, const ddsi_tcp_conn_t c2
return ddsi_ipaddr_compare (a1s, a2s); return ddsi_ipaddr_compare (a1s, a2s);
} }
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
{ {
ut_avlNode_t m_avlnode; ut_avlNode_t m_avlnode;
@ -95,7 +100,7 @@ static const ut_avlTreedef_t ddsi_tcp_treedef = UT_AVL_TREEDEF_INITIALIZER_INDKE
( (
offsetof (struct ddsi_tcp_node, m_avlnode), offsetof (struct ddsi_tcp_node, m_avlnode),
offsetof (struct ddsi_tcp_node, m_conn), offsetof (struct ddsi_tcp_node, m_conn),
ddsi_tcp_cmp_conn, ddsi_tcp_cmp_conn_wrap,
0 0
); );

View file

@ -189,7 +189,6 @@ retry:
return NULL; return NULL;
tk->m_sample = ddsi_serdata_to_topicless (sd); tk->m_sample = ddsi_serdata_to_topicless (sd);
tk->m_map = map;
os_atomic_st32 (&tk->m_refc, 1); os_atomic_st32 (&tk->m_refc, 1);
tk->m_iid = ddsi_iid_gen (); tk->m_iid = ddsi_iid_gen ();
if (!ut_chhAdd (map->m_hh, tk)) if (!ut_chhAdd (map->m_hh, tk))
@ -203,7 +202,7 @@ retry:
if (tk && rd) if (tk && rd)
{ {
DDS_TRACE("tk=%p iid=%"PRIx64" ", &tk, tk->m_iid); DDS_TRACE("tk=%p iid=%"PRIx64" ", (void *) &tk, tk->m_iid);
} }
return tk; return tk;
} }
@ -235,7 +234,7 @@ void ddsi_tkmap_instance_unref (_In_ struct ddsi_tkmap_instance * tk)
} while (!os_atomic_cas32(&tk->m_refc, old, new)); } while (!os_atomic_cas32(&tk->m_refc, old, new));
if (new == REFC_DELETE) if (new == REFC_DELETE)
{ {
struct ddsi_tkmap *map = tk->m_map; struct ddsi_tkmap *map = gv.m_tkmap;
/* Remove from hash table */ /* Remove from hash table */
int removed = ut_chhRemove(map->m_hh, tk); int removed = ut_chhRemove(map->m_hh, tk);

View file

@ -520,9 +520,6 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time
nn_duration_t lease_duration; nn_duration_t lease_duration;
unsigned custom_flags = 0; unsigned custom_flags = 0;
if (!(dds_get_log_mask() & DDS_LC_DISCOVERY))
DDS_LOG(DDS_LC_DISCOVERY, "SPDP ST0");
if (!(datap->present & PP_PARTICIPANT_GUID) || !(datap->present & PP_BUILTIN_ENDPOINT_SET)) if (!(datap->present & PP_PARTICIPANT_GUID) || !(datap->present & PP_BUILTIN_ENDPOINT_SET))
{ {
DDS_WARNING("data (SPDP, vendor %u.%u): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]); DDS_WARNING("data (SPDP, vendor %u.%u): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]);
@ -565,8 +562,6 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time
prismtech_builtin_endpoint_set |= NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_WRITER | NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_WRITER; prismtech_builtin_endpoint_set |= NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_WRITER | NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_WRITER;
} }
DDS_LOG(DDS_LC_DISCOVERY, " %x:%x:%x:%x", PGUID (datap->participant_guid));
/* Local SPDP packets may be looped back, and that may include ones /* Local SPDP packets may be looped back, and that may include ones
currently being deleted. The first thing that happens when currently being deleted. The first thing that happens when
deleting a participant is removing it from the hash table, and deleting a participant is removing it from the hash table, and
@ -575,7 +570,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time
if (is_deleted_participant_guid (&datap->participant_guid, DPG_REMOTE)) if (is_deleted_participant_guid (&datap->participant_guid, DPG_REMOTE))
{ {
DDS_LOG(DDS_LC_DISCOVERY, " (recently deleted)"); DDS_LOG(DDS_LC_TRACE, "SPDP ST0 %x:%x:%x:%x (recently deleted)", PGUID (datap->participant_guid));
return 1; return 1;
} }
@ -585,7 +580,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time
islocal = 1; islocal = 1;
if (islocal) if (islocal)
{ {
DDS_LOG(DDS_LC_DISCOVERY, " (local %d)", islocal); DDS_LOG(DDS_LC_TRACE, "SPDP ST0 %x:%x:%x:%x (local %d)", islocal, PGUID (datap->participant_guid));
return 0; return 0;
} }
} }
@ -596,7 +591,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time
are even skipping the automatic lease renewal. Therefore do it are even skipping the automatic lease renewal. Therefore do it
regardless of regardless of
config.arrival_of_data_asserts_pp_and_ep_liveliness. */ config.arrival_of_data_asserts_pp_and_ep_liveliness. */
DDS_LOG(DDS_LC_DISCOVERY, " (known)"); DDS_LOG(DDS_LC_TRACE, "SPDP ST0 %x:%x:%x:%x (known)", PGUID (datap->participant_guid));
lease_renew (os_atomic_ldvoidp (&proxypp->lease), now_et ()); lease_renew (os_atomic_ldvoidp (&proxypp->lease), now_et ());
os_mutexLock (&proxypp->e.lock); os_mutexLock (&proxypp->e.lock);
if (proxypp->implicitly_created) if (proxypp->implicitly_created)
@ -609,7 +604,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time
return 0; return 0;
} }
DDS_LOG(DDS_LC_DISCOVERY, " bes %x ptbes %x NEW", builtin_endpoint_set, prismtech_builtin_endpoint_set); DDS_LOG(DDS_LC_DISCOVERY, "SPDP ST0 %x:%x:%x:%x bes %x ptbes %x NEW", PGUID (datap->participant_guid), builtin_endpoint_set, prismtech_builtin_endpoint_set);
if (datap->present & PP_PARTICIPANT_LEASE_DURATION) if (datap->present & PP_PARTICIPANT_LEASE_DURATION)
{ {
@ -799,14 +794,16 @@ static void handle_SPDP (const struct receiver_state *rst, nn_wctime_t timestamp
nn_plist_t decoded_data; nn_plist_t decoded_data;
nn_plist_src_t src; nn_plist_src_t src;
int interesting = 0; int interesting = 0;
int plist_ret;
src.protocol_version = rst->protocol_version; src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor; src.vendorid = rst->vendor;
src.encoding = data->identifier; src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4; src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4; src.bufsz = len - 4;
if (nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src) < 0) if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{ {
DDS_WARNING("SPDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]); if (plist_ret != ERR_INCOMPATIBLE)
DDS_WARNING("SPDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
return; return;
} }
@ -1340,14 +1337,16 @@ static void handle_SEDP (const struct receiver_state *rst, nn_wctime_t timestamp
{ {
nn_plist_t decoded_data; nn_plist_t decoded_data;
nn_plist_src_t src; nn_plist_src_t src;
int plist_ret;
src.protocol_version = rst->protocol_version; src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor; src.vendorid = rst->vendor;
src.encoding = data->identifier; src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4; src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4; src.bufsz = len - 4;
if (nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src) < 0) if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{ {
DDS_WARNING("SEDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]); if (plist_ret != ERR_INCOMPATIBLE)
DDS_WARNING("SEDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
return; return;
} }
@ -1466,14 +1465,16 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e
{ {
nn_plist_t decoded_data; nn_plist_t decoded_data;
nn_plist_src_t src; nn_plist_src_t src;
int plist_ret;
src.protocol_version = rst->protocol_version; src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor; src.vendorid = rst->vendor;
src.encoding = data->identifier; src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4; src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4; src.bufsz = len - 4;
if (nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src) < 0) if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{ {
DDS_WARNING("SEDP_CM (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]); if (plist_ret != ERR_INCOMPATIBLE)
DDS_WARNING("SEDP_CM (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
return; return;
} }
@ -1626,14 +1627,16 @@ static void handle_SEDP_GROUP (const struct receiver_state *rst, nn_wctime_t tim
{ {
nn_plist_t decoded_data; nn_plist_t decoded_data;
nn_plist_src_t src; nn_plist_src_t src;
int plist_ret;
src.protocol_version = rst->protocol_version; src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor; src.vendorid = rst->vendor;
src.encoding = data->identifier; src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4; src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4; src.bufsz = len - 4;
if (nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src) < 0) if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{ {
DDS_WARNING("SEDP_GROUP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]); if (plist_ret != ERR_INCOMPATIBLE)
DDS_WARNING("SEDP_GROUP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
return; return;
} }
@ -1747,15 +1750,17 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
{ {
nn_plist_src_t src; nn_plist_src_t src;
size_t qos_offset = NN_RDATA_SUBMSG_OFF (fragchain) + offsetof (Data_DataFrag_common_t, octetsToInlineQos) + sizeof (msg->octetsToInlineQos) + msg->octetsToInlineQos; size_t qos_offset = NN_RDATA_SUBMSG_OFF (fragchain) + offsetof (Data_DataFrag_common_t, octetsToInlineQos) + sizeof (msg->octetsToInlineQos) + msg->octetsToInlineQos;
int plist_ret;
src.protocol_version = sampleinfo->rst->protocol_version; src.protocol_version = sampleinfo->rst->protocol_version;
src.vendorid = sampleinfo->rst->vendor; src.vendorid = sampleinfo->rst->vendor;
src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE; src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE;
src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset); src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset);
src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset; src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset;
if (nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH, 0, &src) < 0) if ((plist_ret = nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH, 0, &src)) < 0)
{ {
DDS_WARNING("data(builtin, vendor %u.%u): %x:%x:%x:%x #%"PRId64": invalid inline qos\n", if (plist_ret != ERR_INCOMPATIBLE)
src.vendorid.id[0], src.vendorid.id[1], PGUID (srcguid), sampleinfo->seq); DDS_WARNING("data(builtin, vendor %u.%u): %x:%x:%x:%x #%"PRId64": invalid inline qos\n",
src.vendorid.id[0], src.vendorid.id[1], PGUID (srcguid), sampleinfo->seq);
goto done_upd_deliv; goto done_upd_deliv;
} }
/* Complex qos bit also gets set when statusinfo bits other than /* Complex qos bit also gets set when statusinfo bits other than

View file

@ -240,24 +240,28 @@ void local_reader_ary_setinvalid (struct local_reader_ary *x)
static void write_builtin_topic_any (const struct entity_common *e, nn_wctime_t timestamp, bool alive, nn_vendorid_t vendorid, struct ddsi_tkmap_instance *tk) static void write_builtin_topic_any (const struct entity_common *e, nn_wctime_t timestamp, bool alive, nn_vendorid_t vendorid, struct ddsi_tkmap_instance *tk)
{ {
enum ddsi_sertopic_builtin_type type;
switch (e->kind)
{
case EK_PARTICIPANT:
case EK_PROXY_PARTICIPANT:
type = DSBT_PARTICIPANT;
break;
case EK_READER:
case EK_PROXY_READER:
type = DSBT_READER;
break;
case EK_WRITER:
case EK_PROXY_WRITER:
type = DSBT_WRITER;
break;
}
if (!(e->onlylocal || is_builtin_endpoint(e->guid.entityid, vendorid))) if (!(e->onlylocal || is_builtin_endpoint(e->guid.entityid, vendorid)))
{
/* initialize to avoid gcc warning ultimately caused by C's horrible type system */
enum ddsi_sertopic_builtin_type type = DSBT_PARTICIPANT;
switch (e->kind)
{
case EK_PARTICIPANT:
case EK_PROXY_PARTICIPANT:
type = DSBT_PARTICIPANT;
break;
case EK_READER:
case EK_PROXY_READER:
type = DSBT_READER;
break;
case EK_WRITER:
case EK_PROXY_WRITER:
type = DSBT_WRITER;
break;
}
assert(type != DSBT_PARTICIPANT || (e->kind == EK_PARTICIPANT || e->kind == EK_PROXY_PARTICIPANT));
ddsi_plugin.builtin_write (type, &e->guid, timestamp, alive); ddsi_plugin.builtin_write (type, &e->guid, timestamp, alive);
}
/* tkmap instance only needs to be kept around until the first write of a built-in topic (if none ever happens, it needn't be kept at all): afterward, the WHC of the local built-in topic writer will keep the entry alive. FIXME: the SPDP/SEPD ones currently use default sertopics instead of builtin sertopics, and so use different mappings and different instnace ids. No-one ever sees those ids, so it doesn't matter, but it would nicer if it could actually be the same one. FIXME: it would also be nicer if the local built-in topics and the SPDP/SEDP writers were the same, but I want the locally created endpoints visible in the built-in topics as well, and those don't exist in the discovery writers ... */ /* tkmap instance only needs to be kept around until the first write of a built-in topic (if none ever happens, it needn't be kept at all): afterward, the WHC of the local built-in topic writer will keep the entry alive. FIXME: the SPDP/SEPD ones currently use default sertopics instead of builtin sertopics, and so use different mappings and different instnace ids. No-one ever sees those ids, so it doesn't matter, but it would nicer if it could actually be the same one. FIXME: it would also be nicer if the local built-in topics and the SPDP/SEDP writers were the same, but I want the locally created endpoints visible in the built-in topics as well, and those don't exist in the discovery writers ... */
if (tk) if (tk)
ddsi_tkmap_instance_unref (tk); ddsi_tkmap_instance_unref (tk);
@ -1039,7 +1043,7 @@ static void rebuild_make_covered(int8_t **covered, const struct writer *wr, int
struct wr_prd_match *m; struct wr_prd_match *m;
ut_avlIter_t it; ut_avlIter_t it;
int rdidx, i, j; int rdidx, i, j;
int8_t *cov = os_malloc((size_t) *nreaders * (size_t) nlocs * sizeof (*covered)); int8_t *cov = os_malloc((size_t) *nreaders * (size_t) nlocs * sizeof (*cov));
for (i = 0; i < *nreaders * nlocs; i++) for (i = 0; i < *nreaders * nlocs; i++)
cov[i] = -1; cov[i] = -1;
rdidx = 0; rdidx = 0;
@ -1280,6 +1284,7 @@ void rebuild_or_clear_writer_addrsets(int rebuild)
} }
os_rwlockUnlock (&gv.qoslock); os_rwlockUnlock (&gv.qoslock);
ephash_enum_writer_fini (&est); ephash_enum_writer_fini (&est);
unref_addrset(empty);
DDS_LOG(DDS_LC_DISCOVERY, "rebuild_or_delete_writer_addrsets(%d) done\n", rebuild); DDS_LOG(DDS_LC_DISCOVERY, "rebuild_or_delete_writer_addrsets(%d) done\n", rebuild);
} }
@ -1350,16 +1355,16 @@ static void writer_drop_connection (const struct nn_guid * wr_guid, const struct
rebuild_writer_addrset (wr); rebuild_writer_addrset (wr);
remove_acked_messages (wr, &whcst, &deferred_free_list); remove_acked_messages (wr, &whcst, &deferred_free_list);
wr->num_reliable_readers -= m->is_reliable; wr->num_reliable_readers -= m->is_reliable;
if (wr->status_cb)
{
status_cb_data_t data;
data.status = DDS_PUBLICATION_MATCHED_STATUS;
data.add = false;
data.handle = prd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data);
}
} }
os_mutexUnlock (&wr->e.lock); os_mutexUnlock (&wr->e.lock);
if (m != NULL && wr->status_cb)
{
status_cb_data_t data;
data.status = DDS_PUBLICATION_MATCHED_STATUS;
data.add = false;
data.handle = prd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data);
}
whc_free_deferred_free_list (wr->whc, deferred_free_list); whc_free_deferred_free_list (wr->whc, deferred_free_list);
free_wr_prd_match (m); free_wr_prd_match (m);
} }
@ -1379,7 +1384,8 @@ static void writer_drop_local_connection (const struct nn_guid *wr_guid, struct
ut_avlDelete (&wr_local_readers_treedef, &wr->local_readers, m); ut_avlDelete (&wr_local_readers_treedef, &wr->local_readers, m);
} }
local_reader_ary_remove (&wr->rdary, rd); local_reader_ary_remove (&wr->rdary, rd);
if (wr->status_cb) os_mutexUnlock (&wr->e.lock);
if (m != NULL && wr->status_cb)
{ {
status_cb_data_t data; status_cb_data_t data;
data.status = DDS_PUBLICATION_MATCHED_STATUS; data.status = DDS_PUBLICATION_MATCHED_STATUS;
@ -1387,7 +1393,6 @@ static void writer_drop_local_connection (const struct nn_guid *wr_guid, struct
data.handle = rd->e.iid; data.handle = rd->e.iid;
(wr->status_cb) (wr->status_cb_entity, &data); (wr->status_cb) (wr->status_cb_entity, &data);
} }
os_mutexUnlock (&wr->e.lock);
free_wr_rd_match (m); free_wr_rd_match (m);
} }
} }
@ -1790,7 +1795,7 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader
goto already_matched; goto already_matched;
if (pwr->c.topic == NULL && rd->topic) if (pwr->c.topic == NULL && rd->topic)
pwr->c.topic = rd->topic; pwr->c.topic = ddsi_sertopic_ref (rd->topic);
if (pwr->ddsi2direct_cb == 0 && rd->ddsi2direct_cb != 0) if (pwr->ddsi2direct_cb == 0 && rd->ddsi2direct_cb != 0)
{ {
pwr->ddsi2direct_cb = rd->ddsi2direct_cb; pwr->ddsi2direct_cb = rd->ddsi2direct_cb;
@ -1905,7 +1910,7 @@ static void proxy_reader_add_connection (struct proxy_reader *prd, struct writer
m->wr_guid = wr->e.guid; m->wr_guid = wr->e.guid;
os_mutexLock (&prd->e.lock); os_mutexLock (&prd->e.lock);
if (prd->c.topic == NULL) if (prd->c.topic == NULL)
prd->c.topic = wr->topic; prd->c.topic = ddsi_sertopic_ref (wr->topic);
if (ut_avlLookupIPath (&prd_writers_treedef, &prd->writers, &wr->e.guid, &path)) if (ut_avlLookupIPath (&prd_writers_treedef, &prd->writers, &wr->e.guid, &path))
{ {
DDS_LOG(DDS_LC_DISCOVERY, " proxy_reader_add_connection(wr %x:%x:%x:%x prd %x:%x:%x:%x) - already connected\n", DDS_LOG(DDS_LC_DISCOVERY, " proxy_reader_add_connection(wr %x:%x:%x:%x prd %x:%x:%x:%x) - already connected\n",
@ -4050,6 +4055,7 @@ static void proxy_endpoint_common_fini (struct entity_common *e, struct proxy_en
{ {
unref_proxy_participant (c->proxypp, c); unref_proxy_participant (c->proxypp, c);
ddsi_sertopic_unref (c->topic);
nn_xqos_fini (c->xqos); nn_xqos_fini (c->xqos);
os_free (c->xqos); os_free (c->xqos);
unref_addrset (c->as); unref_addrset (c->as);

View file

@ -1343,7 +1343,7 @@ err_mc_conn:
if (gv.pcap_fp) if (gv.pcap_fp)
os_mutexDestroy (&gv.pcap_lock); os_mutexDestroy (&gv.pcap_lock);
if (gv.disc_conn_uc != gv.disc_conn_mc) if (gv.disc_conn_uc != gv.disc_conn_mc)
ddsi_conn_free (gv.data_conn_uc); ddsi_conn_free (gv.disc_conn_uc);
if (gv.data_conn_uc != gv.disc_conn_uc) if (gv.data_conn_uc != gv.disc_conn_uc)
ddsi_conn_free (gv.data_conn_uc); ddsi_conn_free (gv.data_conn_uc);
free_group_membership(gv.mship); free_group_membership(gv.mship);
@ -1381,6 +1381,8 @@ err_unicast_sockets:
(ddsi_plugin.fini_fn) (); (ddsi_plugin.fini_fn) ();
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS #ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
err_network_partition_addrset: err_network_partition_addrset:
for (struct config_networkpartition_listelem *np = config.networkPartitions; np; np = np->next)
unref_addrset (np->as);
#endif #endif
err_set_ext_address: err_set_ext_address:
while (gv.recvips) while (gv.recvips)
@ -1614,6 +1616,10 @@ void rtps_term (void)
fclose (gv.pcap_fp); fclose (gv.pcap_fp);
} }
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
for (struct config_networkpartition_listelem *np = config.networkPartitions; np; np = np->next)
unref_addrset (np->as);
#endif
unref_addrset (gv.as_disc); unref_addrset (gv.as_disc);
unref_addrset (gv.as_disc_group); unref_addrset (gv.as_disc_group);

View file

@ -2779,18 +2779,18 @@ static int init_one_parameter
one implemented, and fail it if it isn't. I know all RFPs say one implemented, and fail it if it isn't. I know all RFPs say
to be tolerant in what is accepted, but that is where the to be tolerant in what is accepted, but that is where the
bugs & the buffer overflows originate! */ bugs & the buffer overflows originate! */
if (pid & PID_UNRECOGNIZED_INCOMPATIBLE_FLAG) if (pid & PID_UNRECOGNIZED_INCOMPATIBLE_FLAG) {
dest->present |= PP_INCOMPATIBLE; dest->present |= PP_INCOMPATIBLE;
else if (pid & PID_VENDORSPECIFIC_FLAG) return ERR_INCOMPATIBLE;
} else if (pid & PID_VENDORSPECIFIC_FLAG) {
return 0; return 0;
else if (!protocol_version_is_newer (dd->protocol_version) && NN_STRICT_P) } else if (!protocol_version_is_newer (dd->protocol_version) && NN_STRICT_P) {
{
DDS_TRACE("plist/init_one_parameter[pid=%u,mode=STRICT,proto=%u.%u]: undefined paramter id\n", DDS_TRACE("plist/init_one_parameter[pid=%u,mode=STRICT,proto=%u.%u]: undefined paramter id\n",
pid, dd->protocol_version.major, dd->protocol_version.minor); pid, dd->protocol_version.major, dd->protocol_version.minor);
return ERR_INVALID; return ERR_INVALID;
} } else {
else
return 0; return 0;
}
} }
assert (0); assert (0);
@ -3477,7 +3477,7 @@ void nn_xqos_fini (nn_xqos_t *xqos)
else else
{ {
/* until proper message buffers arrive */ /* until proper message buffers arrive */
DDS_LOG(DDS_LC_PLIST, "NN_XQOS_FINI free %p\n", xqos->partition.strs); DDS_LOG(DDS_LC_PLIST, "NN_XQOS_FINI free %p\n", (void *) xqos->partition.strs);
os_free (xqos->partition.strs); os_free (xqos->partition.strs);
} }
} }
@ -3488,7 +3488,7 @@ void nn_xqos_fini (nn_xqos_t *xqos)
else else
{ {
/* until proper message buffers arrive */ /* until proper message buffers arrive */
DDS_LOG(DDS_LC_PLIST, "NN_XQOS_FINI free %p\n", xqos->subscription_keys.key_list.strs); DDS_LOG(DDS_LC_PLIST, "NN_XQOS_FINI free %p\n", (void *) xqos->subscription_keys.key_list.strs);
os_free (xqos->subscription_keys.key_list.strs); os_free (xqos->subscription_keys.key_list.strs);
} }
} }

View file

@ -425,7 +425,7 @@ static struct nn_rbuf *nn_rbuf_alloc_new (struct nn_rbufpool *rbufpool)
rb->size = rbufpool->rbuf_size; rb->size = rbufpool->rbuf_size;
rb->max_rmsg_size = rbufpool->max_rmsg_size; rb->max_rmsg_size = rbufpool->max_rmsg_size;
rb->freeptr = rb->u.raw; rb->freeptr = rb->u.raw;
DDS_LOG(DDS_LC_RADMIN, "rbuf_alloc_new(%p) = %p\n", rbufpool, rb); DDS_LOG(DDS_LC_RADMIN, "rbuf_alloc_new(%p) = %p\n", (void *) rbufpool, (void *) rb);
return rb; return rb;
} }
@ -447,10 +447,10 @@ static struct nn_rbuf *nn_rbuf_new (struct nn_rbufpool *rbufpool)
static void nn_rbuf_release (struct nn_rbuf *rbuf) static void nn_rbuf_release (struct nn_rbuf *rbuf)
{ {
struct nn_rbufpool *rbp = rbuf->rbufpool; struct nn_rbufpool *rbp = rbuf->rbufpool;
DDS_LOG(DDS_LC_RADMIN, "rbuf_release(%p) pool %p current %p\n", rbuf, rbp, rbp->current); DDS_LOG(DDS_LC_RADMIN, "rbuf_release(%p) pool %p current %p\n", (void *) rbuf, (void *) rbp, (void *) rbp->current);
if (os_atomic_dec32_ov (&rbuf->n_live_rmsg_chunks) == 1) if (os_atomic_dec32_ov (&rbuf->n_live_rmsg_chunks) == 1)
{ {
DDS_LOG(DDS_LC_RADMIN, "rbuf_release(%p) free\n", rbuf); DDS_LOG(DDS_LC_RADMIN, "rbuf_release(%p) free\n", (void *) rbuf);
os_free (rbuf); os_free (rbuf);
} }
} }
@ -513,7 +513,7 @@ struct nn_rmsg *nn_rmsg_new (struct nn_rbufpool *rbufpool)
{ {
/* Note: only one thread calls nn_rmsg_new on a pool */ /* Note: only one thread calls nn_rmsg_new on a pool */
struct nn_rmsg *rmsg; struct nn_rmsg *rmsg;
DDS_LOG(DDS_LC_RADMIN, "rmsg_new(%p)\n", rbufpool); DDS_LOG(DDS_LC_RADMIN, "rmsg_new(%p)\n", (void *) rbufpool);
rmsg = nn_rbuf_alloc (rbufpool); rmsg = nn_rbuf_alloc (rbufpool);
if (rmsg == NULL) if (rmsg == NULL)
@ -526,14 +526,14 @@ struct nn_rmsg *nn_rmsg_new (struct nn_rbufpool *rbufpool)
rmsg->lastchunk = &rmsg->chunk; rmsg->lastchunk = &rmsg->chunk;
/* Incrementing freeptr happens in commit(), so that discarding the /* Incrementing freeptr happens in commit(), so that discarding the
message is really simple. */ message is really simple. */
DDS_LOG(DDS_LC_RADMIN, "rmsg_new(%p) = %p\n", rbufpool, rmsg); DDS_LOG(DDS_LC_RADMIN, "rmsg_new(%p) = %p\n", (void *) rbufpool, (void *) rmsg);
return rmsg; return rmsg;
} }
void nn_rmsg_setsize (struct nn_rmsg *rmsg, uint32_t size) void nn_rmsg_setsize (struct nn_rmsg *rmsg, uint32_t size)
{ {
uint32_t size8 = align8uint32 (size); uint32_t size8 = align8uint32 (size);
DDS_LOG(DDS_LC_RADMIN, "rmsg_setsize(%p, %u => %u)\n", rmsg, size, size8); DDS_LOG(DDS_LC_RADMIN, "rmsg_setsize(%p, %u => %u)\n", (void *) rmsg, size, size8);
ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg); ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (os_atomic_ld32 (&rmsg->refcount) == RMSG_REFCOUNT_UNCOMMITTED_BIAS); assert (os_atomic_ld32 (&rmsg->refcount) == RMSG_REFCOUNT_UNCOMMITTED_BIAS);
@ -556,7 +556,7 @@ void nn_rmsg_free (struct nn_rmsg *rmsg)
free() which we don't do currently. And ideally, you'd use free() which we don't do currently. And ideally, you'd use
compare-and-swap for this. */ compare-and-swap for this. */
struct nn_rmsg_chunk *c; struct nn_rmsg_chunk *c;
DDS_LOG(DDS_LC_RADMIN, "rmsg_free(%p)\n", rmsg); DDS_LOG(DDS_LC_RADMIN, "rmsg_free(%p)\n", (void *) rmsg);
assert (os_atomic_ld32 (&rmsg->refcount) == 0); assert (os_atomic_ld32 (&rmsg->refcount) == 0);
c = &rmsg->chunk; c = &rmsg->chunk;
while (c) while (c)
@ -579,7 +579,7 @@ void nn_rmsg_free (struct nn_rmsg *rmsg)
static void commit_rmsg_chunk (struct nn_rmsg_chunk *chunk) static void commit_rmsg_chunk (struct nn_rmsg_chunk *chunk)
{ {
struct nn_rbuf *rbuf = chunk->rbuf; struct nn_rbuf *rbuf = chunk->rbuf;
DDS_LOG(DDS_LC_RADMIN, "commit_rmsg_chunk(%p)\n", chunk); DDS_LOG(DDS_LC_RADMIN, "commit_rmsg_chunk(%p)\n", (void *) chunk);
rbuf->freeptr = chunk->u.payload + chunk->size; rbuf->freeptr = chunk->u.payload + chunk->size;
} }
@ -595,7 +595,7 @@ void nn_rmsg_commit (struct nn_rmsg *rmsg)
completed before we got to commit. */ completed before we got to commit. */
struct nn_rmsg_chunk *chunk = rmsg->lastchunk; struct nn_rmsg_chunk *chunk = rmsg->lastchunk;
DDS_LOG(DDS_LC_RADMIN, "rmsg_commit(%p) refcount 0x%x last-chunk-size %u\n", DDS_LOG(DDS_LC_RADMIN, "rmsg_commit(%p) refcount 0x%x last-chunk-size %u\n",
rmsg, rmsg->refcount.v, chunk->size); (void *) rmsg, rmsg->refcount.v, chunk->size);
ASSERT_RBUFPOOL_OWNER (chunk->rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (chunk->rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg); ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (chunk->size <= chunk->rbuf->max_rmsg_size); assert (chunk->size <= chunk->rbuf->max_rmsg_size);
@ -610,7 +610,7 @@ void nn_rmsg_commit (struct nn_rmsg *rmsg)
{ {
/* Other references exist, so either stored in defrag, reorder /* Other references exist, so either stored in defrag, reorder
and/or delivery queue */ and/or delivery queue */
DDS_LOG(DDS_LC_RADMIN, "rmsg_commit(%p) => keep\n", rmsg); DDS_LOG(DDS_LC_RADMIN, "rmsg_commit(%p) => keep\n", (void *) rmsg);
commit_rmsg_chunk (chunk); commit_rmsg_chunk (chunk);
} }
} }
@ -623,7 +623,7 @@ static void nn_rmsg_addbias (struct nn_rmsg *rmsg)
However, other threads (e.g., delivery threads) may have been However, other threads (e.g., delivery threads) may have been
triggered already, so the increment must be done atomically. */ triggered already, so the increment must be done atomically. */
DDS_LOG(DDS_LC_RADMIN, "rmsg_addbias(%p)\n", rmsg); DDS_LOG(DDS_LC_RADMIN, "rmsg_addbias(%p)\n", (void *) rmsg);
ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg); ASSERT_RMSG_UNCOMMITTED (rmsg);
os_atomic_add32 (&rmsg->refcount, RMSG_REFCOUNT_RDATA_BIAS); os_atomic_add32 (&rmsg->refcount, RMSG_REFCOUNT_RDATA_BIAS);
@ -635,7 +635,7 @@ static void nn_rmsg_rmbias_and_adjust (struct nn_rmsg *rmsg, int adjust)
progressing through the pipeline, but only by the receive progressing through the pipeline, but only by the receive
thread. Can't require it to be uncommitted. */ thread. Can't require it to be uncommitted. */
uint32_t sub; uint32_t sub;
DDS_LOG(DDS_LC_RADMIN, "rmsg_rmbias_and_adjust(%p, %d)\n", rmsg, adjust); DDS_LOG(DDS_LC_RADMIN, "rmsg_rmbias_and_adjust(%p, %d)\n", (void *) rmsg, adjust);
ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool);
assert (adjust >= 0); assert (adjust >= 0);
assert ((uint32_t) adjust < RMSG_REFCOUNT_RDATA_BIAS); assert ((uint32_t) adjust < RMSG_REFCOUNT_RDATA_BIAS);
@ -649,14 +649,14 @@ static void nn_rmsg_rmbias_anythread (struct nn_rmsg *rmsg)
{ {
/* For removing garbage when freeing a nn_defrag. */ /* For removing garbage when freeing a nn_defrag. */
uint32_t sub = RMSG_REFCOUNT_RDATA_BIAS; uint32_t sub = RMSG_REFCOUNT_RDATA_BIAS;
DDS_LOG(DDS_LC_RADMIN, "rmsg_rmbias_anythread(%p)\n", rmsg); DDS_LOG(DDS_LC_RADMIN, "rmsg_rmbias_anythread(%p)\n", (void *) rmsg);
assert (os_atomic_ld32 (&rmsg->refcount) >= sub); assert (os_atomic_ld32 (&rmsg->refcount) >= sub);
if (os_atomic_sub32_nv (&rmsg->refcount, sub) == 0) if (os_atomic_sub32_nv (&rmsg->refcount, sub) == 0)
nn_rmsg_free (rmsg); nn_rmsg_free (rmsg);
} }
static void nn_rmsg_unref (struct nn_rmsg *rmsg) static void nn_rmsg_unref (struct nn_rmsg *rmsg)
{ {
DDS_LOG(DDS_LC_RADMIN, "rmsg_unref(%p)\n", rmsg); DDS_LOG(DDS_LC_RADMIN, "rmsg_unref(%p)\n", (void *) rmsg);
assert (os_atomic_ld32 (&rmsg->refcount) > 0); assert (os_atomic_ld32 (&rmsg->refcount) > 0);
if (os_atomic_dec32_ov (&rmsg->refcount) == 1) if (os_atomic_dec32_ov (&rmsg->refcount) == 1)
nn_rmsg_free (rmsg); nn_rmsg_free (rmsg);
@ -668,7 +668,7 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
struct nn_rbuf *rbuf = chunk->rbuf; struct nn_rbuf *rbuf = chunk->rbuf;
uint32_t size8 = align8uint32 (size); uint32_t size8 = align8uint32 (size);
void *ptr; void *ptr;
DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %u => %u)\n", rmsg, size, size8); DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %u => %u)\n", (void *) rmsg, size, size8);
ASSERT_RBUFPOOL_OWNER (rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg); ASSERT_RMSG_UNCOMMITTED (rmsg);
assert ((chunk->size % 8) == 0); assert ((chunk->size % 8) == 0);
@ -678,7 +678,7 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
{ {
struct nn_rbufpool *rbufpool = rbuf->rbufpool; struct nn_rbufpool *rbufpool = rbuf->rbufpool;
struct nn_rmsg_chunk *newchunk; struct nn_rmsg_chunk *newchunk;
DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %u) limit hit - new chunk\n", rmsg, size); DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %u) limit hit - new chunk\n", (void *) rmsg, size);
commit_rmsg_chunk (chunk); commit_rmsg_chunk (chunk);
newchunk = nn_rbuf_alloc (rbufpool); newchunk = nn_rbuf_alloc (rbufpool);
if (newchunk == NULL) if (newchunk == NULL)
@ -693,7 +693,7 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
ptr = chunk->u.payload + chunk->size; ptr = chunk->u.payload + chunk->size;
chunk->size += size8; chunk->size += size8;
DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %u) = %p\n", rmsg, size, ptr); DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %u) = %p\n", (void *) rmsg, size, ptr);
#if USE_VALGRIND #if USE_VALGRIND
if (chunk == &rmsg->chunk) { if (chunk == &rmsg->chunk) {
VALGRIND_MEMPOOL_CHANGE (rbuf->rbufpool, rmsg, rmsg, offsetof (struct nn_rmsg, chunk.u.payload) + chunk->size); VALGRIND_MEMPOOL_CHANGE (rbuf->rbufpool, rmsg, rmsg, offsetof (struct nn_rmsg, chunk.u.payload) + chunk->size);
@ -720,13 +720,13 @@ struct nn_rdata *nn_rdata_new (struct nn_rmsg *rmsg, uint32_t start, uint32_t en
#ifndef NDEBUG #ifndef NDEBUG
os_atomic_st32 (&d->refcount_bias_added, 0); os_atomic_st32 (&d->refcount_bias_added, 0);
#endif #endif
DDS_LOG(DDS_LC_RADMIN, "rdata_new(%p, bytes [%u,%u), submsg @ %u, payload @ %u) = %p\n", rmsg, start, endp1, NN_RDATA_SUBMSG_OFF (d), NN_RDATA_PAYLOAD_OFF (d), d); DDS_LOG(DDS_LC_RADMIN, "rdata_new(%p, bytes [%u,%u), submsg @ %u, payload @ %u) = %p\n", (void *) rmsg, start, endp1, NN_RDATA_SUBMSG_OFF (d), NN_RDATA_PAYLOAD_OFF (d), (void *) d);
return d; return d;
} }
static void nn_rdata_addbias (struct nn_rdata *rdata) static void nn_rdata_addbias (struct nn_rdata *rdata)
{ {
DDS_LOG(DDS_LC_RADMIN, "rdata_addbias(%p)\n", rdata); DDS_LOG(DDS_LC_RADMIN, "rdata_addbias(%p)\n", (void *) rdata);
#ifndef NDEBUG #ifndef NDEBUG
ASSERT_RBUFPOOL_OWNER (rdata->rmsg->chunk.rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (rdata->rmsg->chunk.rbuf->rbufpool);
if (os_atomic_inc32_nv (&rdata->refcount_bias_added) != 1) if (os_atomic_inc32_nv (&rdata->refcount_bias_added) != 1)
@ -737,7 +737,7 @@ static void nn_rdata_addbias (struct nn_rdata *rdata)
static void nn_rdata_rmbias_and_adjust (struct nn_rdata *rdata, int adjust) static void nn_rdata_rmbias_and_adjust (struct nn_rdata *rdata, int adjust)
{ {
DDS_LOG(DDS_LC_RADMIN, "rdata_rmbias_and_adjust(%p, %d)\n", rdata, adjust); DDS_LOG(DDS_LC_RADMIN, "rdata_rmbias_and_adjust(%p, %d)\n", (void *) rdata, adjust);
#ifndef NDEBUG #ifndef NDEBUG
if (os_atomic_dec32_ov (&rdata->refcount_bias_added) != 1) if (os_atomic_dec32_ov (&rdata->refcount_bias_added) != 1)
abort (); abort ();
@ -747,7 +747,7 @@ static void nn_rdata_rmbias_and_adjust (struct nn_rdata *rdata, int adjust)
static void nn_rdata_rmbias_anythread (struct nn_rdata *rdata) static void nn_rdata_rmbias_anythread (struct nn_rdata *rdata)
{ {
DDS_LOG(DDS_LC_RADMIN, "rdata_rmbias_anythread(%p)\n", rdata); DDS_LOG(DDS_LC_RADMIN, "rdata_rmbias_anythread(%p)\n", (void *) rdata);
#ifndef NDEBUG #ifndef NDEBUG
if (os_atomic_dec32_ov (&rdata->refcount_bias_added) != 1) if (os_atomic_dec32_ov (&rdata->refcount_bias_added) != 1)
abort (); abort ();
@ -757,7 +757,7 @@ static void nn_rdata_rmbias_anythread (struct nn_rdata *rdata)
static void nn_rdata_unref (struct nn_rdata *rdata) static void nn_rdata_unref (struct nn_rdata *rdata)
{ {
DDS_LOG(DDS_LC_RADMIN, "rdata_rdata_unref(%p)\n", rdata); DDS_LOG(DDS_LC_RADMIN, "rdata_rdata_unref(%p)\n", (void *) rdata);
nn_rmsg_unref (rdata->rmsg); nn_rmsg_unref (rdata->rmsg);
} }
@ -894,7 +894,7 @@ struct nn_defrag *nn_defrag_new (enum nn_defrag_drop_mode drop_mode, uint32_t ma
void nn_fragchain_adjust_refcount (struct nn_rdata *frag, int adjust) void nn_fragchain_adjust_refcount (struct nn_rdata *frag, int adjust)
{ {
struct nn_rdata *frag1; struct nn_rdata *frag1;
DDS_LOG(DDS_LC_RADMIN, "fragchain_adjust_refcount(%p, %d)\n", frag, adjust); DDS_LOG(DDS_LC_RADMIN, "fragchain_adjust_refcount(%p, %d)\n", (void *) frag, adjust);
while (frag) while (frag)
{ {
frag1 = frag->nextfrag; frag1 = frag->nextfrag;
@ -906,7 +906,7 @@ void nn_fragchain_adjust_refcount (struct nn_rdata *frag, int adjust)
static void nn_fragchain_rmbias_anythread (struct nn_rdata *frag, UNUSED_ARG (int adjust)) static void nn_fragchain_rmbias_anythread (struct nn_rdata *frag, UNUSED_ARG (int adjust))
{ {
struct nn_rdata *frag1; struct nn_rdata *frag1;
DDS_LOG(DDS_LC_RADMIN, "fragchain_rmbias_anythread(%p)\n", frag); DDS_LOG(DDS_LC_RADMIN, "fragchain_rmbias_anythread(%p)\n", (void *) frag);
while (frag) while (frag)
{ {
frag1 = frag->nextfrag; frag1 = frag->nextfrag;
@ -940,7 +940,7 @@ void nn_defrag_free (struct nn_defrag *defrag)
s = ut_avlFindMin (&defrag_sampletree_treedef, &defrag->sampletree); s = ut_avlFindMin (&defrag_sampletree_treedef, &defrag->sampletree);
while (s) while (s)
{ {
DDS_LOG(DDS_LC_RADMIN, "defrag_free(%p, sample %p seq %"PRId64")\n", defrag, s, s->u.defrag.seq); DDS_LOG(DDS_LC_RADMIN, "defrag_free(%p, sample %p seq %"PRId64")\n", (void *) defrag, (void *) s, s->u.defrag.seq);
defrag_rsample_drop (defrag, s, nn_fragchain_rmbias_anythread); defrag_rsample_drop (defrag, s, nn_fragchain_rmbias_anythread);
s = ut_avlFindMin (&defrag_sampletree_treedef, &defrag->sampletree); s = ut_avlFindMin (&defrag_sampletree_treedef, &defrag->sampletree);
} }
@ -1161,6 +1161,7 @@ static struct nn_rsample *defrag_add_fragment (struct nn_rsample *sample, struct
concerns the message pointer to by sample */ concerns the message pointer to by sample */
assert (min < maxp1); assert (min < maxp1);
/* and it must concern this message */ /* and it must concern this message */
assert (dfsample);
assert (dfsample->seq == sampleinfo->seq); assert (dfsample->seq == sampleinfo->seq);
/* there must be a last fragment */ /* there must be a last fragment */
assert (dfsample->lastfrag); assert (dfsample->lastfrag);
@ -1357,7 +1358,7 @@ struct nn_rsample *nn_defrag_rsample (struct nn_defrag *defrag, struct nn_rdata
assert (defrag->max_sample == ut_avlFindMax (&defrag_sampletree_treedef, &defrag->sampletree)); assert (defrag->max_sample == ut_avlFindMax (&defrag_sampletree_treedef, &defrag->sampletree));
max_seq = defrag->max_sample ? defrag->max_sample->u.defrag.seq : 0; max_seq = defrag->max_sample ? defrag->max_sample->u.defrag.seq : 0;
DDS_LOG(DDS_LC_RADMIN, "defrag_rsample(%p, %p [%u..%u) msg %p, %p seq %"PRId64" size %u) max_seq %p %"PRId64":\n", DDS_LOG(DDS_LC_RADMIN, "defrag_rsample(%p, %p [%u..%u) msg %p, %p seq %"PRId64" size %u) max_seq %p %"PRId64":\n",
(void *) defrag, (void *) rdata, rdata->min, rdata->maxp1, rdata->rmsg, (void *) defrag, (void *) rdata, rdata->min, rdata->maxp1, (void *) rdata->rmsg,
(void *) sampleinfo, sampleinfo->seq, sampleinfo->size, (void *) sampleinfo, sampleinfo->seq, sampleinfo->size,
(void *) defrag->max_sample, max_seq); (void *) defrag->max_sample, max_seq);
/* fast path: rdata is part of message with the highest sequence /* fast path: rdata is part of message with the highest sequence

View file

@ -1959,15 +1959,17 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
{ {
nn_plist_src_t src; nn_plist_src_t src;
size_t qos_offset = NN_RDATA_SUBMSG_OFF (fragchain) + offsetof (Data_DataFrag_common_t, octetsToInlineQos) + sizeof (msg->octetsToInlineQos) + msg->octetsToInlineQos; size_t qos_offset = NN_RDATA_SUBMSG_OFF (fragchain) + offsetof (Data_DataFrag_common_t, octetsToInlineQos) + sizeof (msg->octetsToInlineQos) + msg->octetsToInlineQos;
int plist_ret;
src.protocol_version = rst->protocol_version; src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor; src.vendorid = rst->vendor;
src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE; src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE;
src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset); src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset);
src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset; src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset;
if (nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH | PP_COHERENT_SET | PP_PRISMTECH_EOTINFO, 0, &src) < 0) if ((plist_ret = nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH | PP_COHERENT_SET | PP_PRISMTECH_EOTINFO, 0, &src)) < 0)
{ {
DDS_WARNING ("data(application, vendor %u.%u): %x:%x:%x:%x #%"PRId64": invalid inline qos\n", if (plist_ret != ERR_INCOMPATIBLE)
src.vendorid.id[0], src.vendorid.id[1], PGUID (pwr->e.guid), sampleinfo->seq); DDS_WARNING ("data(application, vendor %u.%u): %x:%x:%x:%x #%"PRId64": invalid inline qos\n",
src.vendorid.id[0], src.vendorid.id[1], PGUID (pwr->e.guid), sampleinfo->seq);
return 0; return 0;
} }
statusinfo = (qos.present & PP_STATUSINFO) ? qos.statusinfo : 0; statusinfo = (qos.present & PP_STATUSINFO) ? qos.statusinfo : 0;
@ -2113,14 +2115,17 @@ static void deliver_user_data_synchronously (struct nn_rsample_chain *sc)
static void clean_defrag (struct proxy_writer *pwr) static void clean_defrag (struct proxy_writer *pwr)
{ {
seqno_t seq = nn_reorder_next_seq (pwr->reorder); seqno_t seq = nn_reorder_next_seq (pwr->reorder);
struct pwr_rd_match *wn; if (pwr->n_readers_out_of_sync > 0)
for (wn = ut_avlFindMin (&pwr_readers_treedef, &pwr->readers); wn != NULL; wn = ut_avlFindSucc (&pwr_readers_treedef, &pwr->readers, wn))
{ {
if (wn->in_sync == PRMSS_OUT_OF_SYNC) struct pwr_rd_match *wn;
for (wn = ut_avlFindMin (&pwr_readers_treedef, &pwr->readers); wn != NULL; wn = ut_avlFindSucc (&pwr_readers_treedef, &pwr->readers, wn))
{ {
seqno_t seq1 = nn_reorder_next_seq (wn->u.not_in_sync.reorder); if (wn->in_sync == PRMSS_OUT_OF_SYNC)
if (seq1 < seq) {
seq = seq1; seqno_t seq1 = nn_reorder_next_seq (wn->u.not_in_sync.reorder);
if (seq1 < seq)
seq = seq1;
}
} }
} }
nn_defrag_notegap (pwr->defrag, 1, seq); nn_defrag_notegap (pwr->defrag, 1, seq);
@ -2701,7 +2706,7 @@ static int handle_submsg_sequence
if (submsg + submsg_size > end) if (submsg + submsg_size > end)
{ {
DDS_TRACE(" BREAK (%u %"PRIuSIZE": %p %u)\n", (unsigned) (submsg - msg), submsg_size, msg, (unsigned) len); DDS_TRACE(" BREAK (%u %"PRIuSIZE": %p %u)\n", (unsigned) (submsg - msg), submsg_size, (void *) msg, (unsigned) len);
break; break;
} }
@ -2907,7 +2912,7 @@ static int handle_submsg_sequence
{ {
state = "parse:shortmsg"; state = "parse:shortmsg";
state_smkind = SMID_PAD; state_smkind = SMID_PAD;
DDS_TRACE("short (size %"PRIuSIZE" exp %p act %p)", submsg_size, submsg, end); DDS_TRACE("short (size %"PRIuSIZE" exp %p act %p)", submsg_size, (void *) submsg, (void *) end);
goto malformed; goto malformed;
} }
return 0; return 0;
@ -3004,16 +3009,15 @@ static bool do_packet
nn_rmsg_setsize (rmsg, (uint32_t) sz); nn_rmsg_setsize (rmsg, (uint32_t) sz);
assert (vtime_asleep_p (self->vtime)); assert (vtime_asleep_p (self->vtime));
if if ((size_t)sz < RTPS_MESSAGE_HEADER_SIZE || *(uint32_t *)buff != NN_PROTOCOLID_AS_UINT32)
(
(size_t) sz < RTPS_MESSAGE_HEADER_SIZE ||
buff[0] != 'R' || buff[1] != 'T' || buff[2] != 'P' || buff[3] != 'S' ||
hdr->version.major != RTPS_MAJOR || (hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)
)
{ {
if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) /* discard packets that are really too small or don't have magic cookie */
DDS_TRACE("HDR(%x:%x:%x 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); else if (hdr->version.major != RTPS_MAJOR || (hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM))
{
if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM))
DDS_TRACE("HDR(%x:%x:%x 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)
malformed_packet_received_nosubmsg (buff, sz, "header", hdr->vendorid); malformed_packet_received_nosubmsg (buff, sz, "header", hdr->vendorid);
} }
@ -3029,22 +3033,7 @@ static bool do_packet
PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, addrstr); PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, addrstr);
} }
{ handle_submsg_sequence (conn, &srcloc, self, now (), now_et (), &hdr->guid_prefix, guidprefix, buff, (size_t) sz, buff + RTPS_MESSAGE_HEADER_SIZE, rmsg);
handle_submsg_sequence
(
conn,
&srcloc,
self,
now (),
now_et (),
&hdr->guid_prefix,
guidprefix,
buff,
(size_t) sz,
buff + RTPS_MESSAGE_HEADER_SIZE,
rmsg
);
}
} }
thread_state_asleep (self); thread_state_asleep (self);
} }
@ -3317,7 +3306,7 @@ void trigger_recv_threads (void)
break; break;
} }
case RTM_MANY: { case RTM_MANY: {
DDS_TRACE("trigger_recv_threads: %d many %p\n", i, 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); os_sockWaitsetTrigger (gv.recv_threads[i].arg.u.many.ws);
break; break;
} }

View file

@ -233,6 +233,7 @@ static int writer_hbcontrol_ack_required_generic (const struct writer *wr, const
{ {
struct hbcontrol const * const hbc = &wr->hbcontrol; struct hbcontrol const * const hbc = &wr->hbcontrol;
const int64_t hb_intv_ack = config.const_hb_intv_sched; const int64_t hb_intv_ack = config.const_hb_intv_sched;
assert(wr->heartbeat_xevent != NULL && whcst != NULL);
if (piggyback) if (piggyback)
{ {
@ -707,6 +708,7 @@ static void transmit_sample_lgmsg_unlocked (struct nn_xpack *xp, struct writer *
const char *frags_to_skip = getenv ("SKIPFRAGS"); const char *frags_to_skip = getenv ("SKIPFRAGS");
#endif #endif
assert(xp); assert(xp);
assert((wr->heartbeat_xevent != NULL) == (whcst != NULL));
for (i = 0; i < nfrags; i++) for (i = 0; i < nfrags; i++)
{ {
@ -744,6 +746,7 @@ static void transmit_sample_lgmsg_unlocked (struct nn_xpack *xp, struct writer *
{ {
struct nn_xmsg *msg = NULL; struct nn_xmsg *msg = NULL;
int hbansreq; int hbansreq;
assert (whcst != NULL);
os_mutexLock (&wr->e.lock); os_mutexLock (&wr->e.lock);
msg = writer_hbcontrol_piggyback (wr, whcst, serdata->twrite, nn_xpack_packetid (xp), &hbansreq); msg = writer_hbcontrol_piggyback (wr, whcst, serdata->twrite, nn_xpack_packetid (xp), &hbansreq);
os_mutexUnlock (&wr->e.lock); os_mutexUnlock (&wr->e.lock);
@ -762,6 +765,7 @@ static void transmit_sample_unlocks_wr (struct nn_xpack *xp, struct writer *wr,
struct nn_xmsg *fmsg; struct nn_xmsg *fmsg;
uint32_t sz; uint32_t sz;
assert(xp); assert(xp);
assert((wr->heartbeat_xevent != NULL) == (whcst != NULL));
sz = ddsi_serdata_size (serdata); sz = ddsi_serdata_size (serdata);
if (sz > config.fragment_size || !isnew || plist != NULL || prd != NULL) if (sz > config.fragment_size || !isnew || plist != NULL || prd != NULL)
@ -1116,10 +1120,6 @@ static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_p
} }
else else
{ {
struct whc_state whcst;
if (wr->heartbeat_xevent)
whc_get_state(wr->whc, &whcst);
/* Note the subtlety of enqueueing with the lock held but /* Note the subtlety of enqueueing with the lock held but
transmitting without holding the lock. Still working on transmitting without holding the lock. Still working on
cleaning that up. */ cleaning that up. */
@ -1130,6 +1130,7 @@ static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_p
* plist's are only used for coherent sets, which is assumed to be rare, * plist's are only used for coherent sets, which is assumed to be rare,
* which in turn means that an extra copy doesn't hurt too badly ... */ * which in turn means that an extra copy doesn't hurt too badly ... */
nn_plist_t plist_stk, *plist_copy; nn_plist_t plist_stk, *plist_copy;
struct whc_state whcst, *whcstptr;
if (plist == NULL) if (plist == NULL)
plist_copy = NULL; plist_copy = NULL;
else else
@ -1137,7 +1138,14 @@ static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_p
plist_copy = &plist_stk; plist_copy = &plist_stk;
nn_plist_copy (plist_copy, plist); nn_plist_copy (plist_copy, plist);
} }
transmit_sample_unlocks_wr (xp, wr, &whcst, seq, plist_copy, serdata, NULL, 1); if (wr->heartbeat_xevent == NULL)
whcstptr = NULL;
else
{
whc_get_state(wr->whc, &whcst);
whcstptr = &whcst;
}
transmit_sample_unlocks_wr (xp, wr, whcstptr, seq, plist_copy, serdata, NULL, 1);
if (plist_copy) if (plist_copy)
nn_plist_fini (plist_copy); nn_plist_fini (plist_copy);
} }

View file

@ -959,6 +959,42 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent
resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, 100 * T_MILLISECOND)); resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, 100 * T_MILLISECOND));
} }
static bool resend_spdp_sample_by_guid_key (struct writer *wr, const nn_guid_t *guid, struct proxy_reader *prd)
{
/* 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 */
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);
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 whc_borrowed_sample sample;
nn_xmsg_free (mpayload);
os_mutexLock (&wr->e.lock);
sample_found = whc_borrow_sample_key (wr->whc, sd, &sample);
if (sample_found)
{
/* Claiming it is new rather than a retransmit so that the rexmit
limiting won't kick in. It is best-effort and therefore the
updating of the last transmitted sequence number won't take
place anyway. Nor is it necessary to fiddle with heartbeat
control stuff. */
enqueue_sample_wrlock_held (wr, sample.seq, sample.plist, sample.serdata, prd, 1);
whc_return_sample(wr->whc, &sample, false);
}
os_mutexUnlock (&wr->e.lock);
ddsi_serdata_unref (sd);
return sample_found;
}
static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, nn_mtime_t tnow) static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, nn_mtime_t tnow)
{ {
@ -966,10 +1002,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
struct participant *pp; struct participant *pp;
struct proxy_reader *prd; struct proxy_reader *prd;
struct writer *spdp_wr; struct writer *spdp_wr;
struct whc_borrowed_sample sample; bool do_write;
#ifndef NDEBUG
bool sample_found;
#endif
if ((pp = ephash_lookup_participant_guid (&ev->u.spdp.pp_guid)) == NULL) if ((pp = ephash_lookup_participant_guid (&ev->u.spdp.pp_guid)) == NULL)
{ {
@ -994,62 +1027,22 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
/* memset is for tracing output */ /* memset is for tracing output */
memset (&ev->u.spdp.dest_proxypp_guid_prefix, 0, sizeof (ev->u.spdp.dest_proxypp_guid_prefix)); memset (&ev->u.spdp.dest_proxypp_guid_prefix, 0, sizeof (ev->u.spdp.dest_proxypp_guid_prefix));
prd = NULL; prd = NULL;
do_write = true;
} }
else else
{ {
nn_guid_t guid; nn_guid_t guid;
guid.prefix = ev->u.spdp.dest_proxypp_guid_prefix; guid.prefix = ev->u.spdp.dest_proxypp_guid_prefix;
guid.entityid.u = NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER; guid.entityid.u = NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER;
if ((prd = ephash_lookup_proxy_reader_guid (&guid)) == NULL) prd = ephash_lookup_proxy_reader_guid (&guid);
{ do_write = (prd != NULL);
if (!do_write)
DDS_TRACE("xmit spdp: no proxy reader %x:%x:%x:%x\n", PGUID (guid)); DDS_TRACE("xmit spdp: no proxy reader %x:%x:%x:%x\n", PGUID (guid));
goto skip;
}
} }
/* Look up data in (transient-local) WHC by key value -- FIXME: clearly if (do_write && !resend_spdp_sample_by_guid_key (spdp_wr, &ev->u.spdp.pp_guid, prd))
a slightly more efficient and elegant way of looking up the key value
is to be preferred */
nn_plist_t ps;
nn_plist_init_empty (&ps);
ps.present |= PP_PARTICIPANT_GUID;
ps.participant_guid = ev->u.spdp.pp_guid;
struct nn_xmsg *mpayload = nn_xmsg_new (gv.xmsgpool, &ev->u.spdp.pp_guid.prefix, 0, NN_XMSG_KIND_DATA);
nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
nn_xmsg_addpar_sentinel (mpayload);
nn_plist_fini (&ps);
struct ddsi_plist_sample plist_sample;
nn_xmsg_payload_to_plistsample (&plist_sample, PID_PARTICIPANT_GUID, mpayload);
struct ddsi_serdata *sd = ddsi_serdata_from_sample (gv.plist_topic, SDK_KEY, &plist_sample);
nn_xmsg_free (mpayload);
os_mutexLock (&spdp_wr->e.lock);
if (whc_borrow_sample_key (spdp_wr->whc, sd, &sample))
{ {
/* Claiming it is new rather than a retransmit so that the rexmit
limiting won't kick in. It is best-effort and therefore the
updating of the last transmitted sequence number won't take
place anyway. Nor is it necessary to fiddle with heartbeat
control stuff. */
enqueue_sample_wrlock_held (spdp_wr, sample.seq, sample.plist, sample.serdata, prd, 1);
whc_return_sample(spdp_wr->whc, &sample, false);
#ifndef NDEBUG #ifndef NDEBUG
sample_found = true;
#endif
}
#ifndef NDEBUG
else
{
sample_found = false;
}
#endif
os_mutexUnlock (&spdp_wr->e.lock);
ddsi_serdata_unref (sd);
#ifndef NDEBUG
if (!sample_found)
{
/* If undirected, it is pp->spdp_xevent, and that one must never /* If undirected, it is pp->spdp_xevent, and that one must never
run into an empty WHC unless it is already marked for deletion. run into an empty WHC unless it is already marked for deletion.
@ -1072,10 +1065,9 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
DDS_TRACE("xmit spdp: suppressing early spdp response from %x:%x:%x:%x to %x:%x:%x:%x\n", DDS_TRACE("xmit spdp: suppressing early spdp response from %x:%x:%x:%x to %x:%x:%x:%x\n",
PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_PARTICIPANT); PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_PARTICIPANT);
} }
}
#endif #endif
}
skip:
if (ev->u.spdp.directed) if (ev->u.spdp.directed)
{ {
/* Directed events are used to send SPDP packets to newly /* Directed events are used to send SPDP packets to newly

View file

@ -256,7 +256,7 @@ static void nn_xmsg_realfree_wrap (void *elem)
void nn_xmsgpool_free (struct nn_xmsgpool *pool) void nn_xmsgpool_free (struct nn_xmsgpool *pool)
{ {
nn_freelist_fini (&pool->freelist, nn_xmsg_realfree_wrap); nn_freelist_fini (&pool->freelist, nn_xmsg_realfree_wrap);
DDS_TRACE("xmsgpool_free(%p)\n", pool); DDS_TRACE("xmsgpool_free(%p)\n", (void *)pool);
os_free (pool); os_free (pool);
} }

View file

@ -37,11 +37,11 @@ static dds_entity_t reader;
static dds_entity_t writer; static dds_entity_t writer;
static dds_entity_t readCond; static dds_entity_t readCond;
static void data_available(dds_entity_t reader, void *arg) static void data_available(dds_entity_t rd, void *arg)
{ {
int status, samplecount; int status, samplecount;
(void)arg; (void)arg;
samplecount = dds_take (reader, samples, info, MAX_SAMPLES, MAX_SAMPLES); samplecount = dds_take (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES);
DDS_ERR_CHECK (samplecount, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (samplecount, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
for (int j = 0; !dds_triggered (waitSet) && j < samplecount; j++) for (int j = 0; !dds_triggered (waitSet) && j < samplecount; j++)
{ {
@ -136,18 +136,18 @@ int main (int argc, char *argv[])
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static void finalize_dds(dds_entity_t participant, RoundTripModule_DataType data[MAX_SAMPLES]) static void finalize_dds(dds_entity_t pp, RoundTripModule_DataType xs[MAX_SAMPLES])
{ {
dds_return_t status; dds_return_t status;
status = dds_delete (participant); status = dds_delete (pp);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
for (unsigned int i = 0; i < MAX_SAMPLES; i++) for (unsigned int i = 0; i < MAX_SAMPLES; i++)
{ {
RoundTripModule_DataType_free (&data[i], DDS_FREE_CONTENTS); RoundTripModule_DataType_free (&xs[i], DDS_FREE_CONTENTS);
} }
} }
static dds_entity_t prepare_dds(dds_entity_t *writer, dds_entity_t *reader, dds_entity_t *readCond, dds_listener_t *listener) static dds_entity_t prepare_dds(dds_entity_t *wr, dds_entity_t *rd, dds_entity_t *rdcond, dds_listener_t *rdlist)
{ {
const char *pubPartitions[] = { "pong" }; const char *pubPartitions[] = { "pong" };
const char *subPartitions[] = { "ping" }; const char *subPartitions[] = { "ping" };
@ -176,8 +176,8 @@ static dds_entity_t prepare_dds(dds_entity_t *writer, dds_entity_t *reader, dds_
qos = dds_create_qos (); qos = dds_create_qos ();
dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(10)); dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(10));
dds_qset_writer_data_lifecycle (qos, false); dds_qset_writer_data_lifecycle (qos, false);
*writer = dds_create_writer (publisher, topic, qos, NULL); *wr = dds_create_writer (publisher, topic, qos, NULL);
DDS_ERR_CHECK (*writer, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (*wr, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
dds_delete_qos (qos); dds_delete_qos (qos);
/* A DDS Subscriber is created on the domain participant. */ /* A DDS Subscriber is created on the domain participant. */
@ -193,17 +193,17 @@ static dds_entity_t prepare_dds(dds_entity_t *writer, dds_entity_t *reader, dds_
qos = dds_create_qos (); qos = dds_create_qos ();
dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(10)); dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(10));
*reader = dds_create_reader (subscriber, topic, qos, listener); *rd = dds_create_reader (subscriber, topic, qos, rdlist);
DDS_ERR_CHECK (*reader, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (*rd, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
dds_delete_qos (qos); dds_delete_qos (qos);
waitSet = dds_create_waitset (participant); waitSet = dds_create_waitset (participant);
if (listener == NULL) { if (rdlist == NULL) {
*readCond = dds_create_readcondition (*reader, DDS_ANY_STATE); *rdcond = dds_create_readcondition (*rd, DDS_ANY_STATE);
status = dds_waitset_attach (waitSet, *readCond, *reader); status = dds_waitset_attach (waitSet, *rdcond, *rd);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
} else { } else {
*readCond = 0; *rdcond = 0;
} }
status = dds_waitset_attach (waitSet, waitSet, waitSet); status = dds_waitset_attach (waitSet, waitSet, waitSet);
DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (status, DDS_CHECK_REPORT | DDS_CHECK_EXIT);

View file

@ -207,7 +207,7 @@ static dds_return_t wait_for_reader(dds_entity_t writer, dds_entity_t participan
DDS_ERR_CHECK (waitset, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (waitset, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
ret = dds_waitset_attach(waitset, writer, (dds_attach_t)NULL); ret = dds_waitset_attach(waitset, writer, (dds_attach_t)NULL);
DDS_ERR_CHECK (waitset, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (ret, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
ret = dds_waitset_wait(waitset, NULL, 0, DDS_SECS(30)); ret = dds_waitset_wait(waitset, NULL, 0, DDS_SECS(30));
DDS_ERR_CHECK (ret, DDS_CHECK_REPORT | DDS_CHECK_EXIT); DDS_ERR_CHECK (ret, DDS_CHECK_REPORT | DDS_CHECK_EXIT);

View file

@ -331,6 +331,11 @@ VDDS_INLINE int os_atomic_casvoidp (volatile os_atomic_voidp_t *x, void *exp, vo
VDDS_INLINE void os_atomic_fence (void) { VDDS_INLINE void os_atomic_fence (void) {
__sync_synchronize (); __sync_synchronize ();
} }
VDDS_INLINE void os_atomic_fence_ldld (void) {
#if !(defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64)
__sync_synchronize ();
#endif
}
VDDS_INLINE void os_atomic_fence_acq (void) { VDDS_INLINE void os_atomic_fence_acq (void) {
os_atomic_fence (); os_atomic_fence ();
} }

View file

@ -231,6 +231,9 @@ VDDS_INLINE void os_atomic_fence (void) {
membar_exit (); membar_exit ();
membar_enter (); membar_enter ();
} }
VDDS_INLINE void os_atomic_fence_ldld (void) {
membar_enter ();
}
VDDS_INLINE void os_atomic_fence_acq (void) { VDDS_INLINE void os_atomic_fence_acq (void) {
membar_enter (); membar_enter ();
} }

View file

@ -416,6 +416,11 @@ OS_ATOMIC_API_INLINE void os_atomic_fence (void) {
InterlockedExchange (&tmp, 0); InterlockedExchange (&tmp, 0);
#pragma warning (pop) #pragma warning (pop)
} }
OS_ATOMIC_API_INLINE void os_atomic_fence_ldld (void) {
#if !(defined _M_IX86 || defined _M_X64)
os_atomic_fence ();
#endif
}
OS_ATOMIC_API_INLINE void os_atomic_fence_acq (void) { OS_ATOMIC_API_INLINE void os_atomic_fence_acq (void) {
os_atomic_fence (); os_atomic_fence ();
} }

View file

@ -188,7 +188,7 @@ dds_set_log_mask(_In_ uint32_t cats)
static void print_header(char *str) static void print_header(char *str)
{ {
int cnt; int cnt;
char *tid, buf[MAX_TID_LEN] = { 0 }; char *tid, buf[MAX_TID_LEN+1] = { 0 };
static const char fmt[] = "%10u.%06d/%*.*s:"; static const char fmt[] = "%10u.%06d/%*.*s:";
os_time tv; os_time tv;
unsigned sec; unsigned sec;

View file

@ -142,7 +142,7 @@ static int os_sockaddr_compare(
sin1 = (os_sockaddr_in *)sa1; sin1 = (os_sockaddr_in *)sa1;
sin2 = (os_sockaddr_in *)sa2; sin2 = (os_sockaddr_in *)sa2;
sz = sizeof(sin1->sin_addr); sz = sizeof(sin1->sin_addr);
eq = memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(sz)); eq = memcmp(&sin1->sin_addr, &sin2->sin_addr, sz);
} }
break; break;
} }

View file

@ -155,8 +155,6 @@ os_startRoutineWrapper (
os_threadContext *context = threadContext; os_threadContext *context = threadContext;
uintptr_t resultValue; uintptr_t resultValue;
resultValue = 0;
#if !defined(__VXWORKS__) && !defined(__APPLE__) && !defined(__sun) #if !defined(__VXWORKS__) && !defined(__APPLE__) && !defined(__sun)
prctl(PR_SET_NAME, context->threadName); prctl(PR_SET_NAME, context->threadName);
#endif #endif

View file

@ -805,7 +805,6 @@ static void print_sampleinfo(dds_time_t *tstart, dds_time_t tnow, const dds_samp
relt = tnow - *tstart; relt = tnow - *tstart;
// instancehandle_to_id(&ihSystemId, &ihLocalId, si->instance_handle); // instancehandle_to_id(&ihSystemId, &ihLocalId, si->instance_handle);
// instancehandle_to_id(&phSystemId, &phLocalId, si->publication_handle); // instancehandle_to_id(&phSystemId, &phLocalId, si->publication_handle);
sep = "";
if (print_metadata & PM_PID) { if (print_metadata & PM_PID) {
n += printf ("%d", pid); n += printf ("%d", pid);
} }
@ -826,7 +825,6 @@ static void print_sampleinfo(dds_time_t *tstart, dds_time_t tnow, const dds_samp
sep = " : "; sep = " : ";
if (print_metadata & PM_STIME) { if (print_metadata & PM_STIME) {
n += printf ("%s%lld.%09lld", n > 0 ? sep : "", (si->source_timestamp/DDS_NSECS_IN_SEC), (si->source_timestamp%DDS_NSECS_IN_SEC)); n += printf ("%s%lld.%09lld", n > 0 ? sep : "", (si->source_timestamp/DDS_NSECS_IN_SEC), (si->source_timestamp%DDS_NSECS_IN_SEC));
sep = " ";
} }
sep = " : "; sep = " : ";
if (print_metadata & PM_DGEN) { if (print_metadata & PM_DGEN) {
@ -843,7 +841,6 @@ static void print_sampleinfo(dds_time_t *tstart, dds_time_t tnow, const dds_samp
sep = " : "; sep = " : ";
if (print_metadata & PM_STATE) { if (print_metadata & PM_STATE) {
n += printf ("%s%c%c%c", n > 0 ? sep : "", isc, ssc, vsc); n += printf ("%s%c%c%c", n > 0 ? sep : "", isc, ssc, vsc);
sep = " ";
} }
if (n > 0) { if (n > 0) {
printf(" : "); printf(" : ");
@ -1895,9 +1892,9 @@ static uint32_t subthread(void *vspec) {
case MODE_ZEROLOAD: case MODE_ZEROLOAD:
break; break;
case MODE_PRINT: case MODE_PRINT:
rc = dds_waitset_detach(ws, rdcondA); dds_waitset_detach(ws, rdcondA);
dds_delete(rdcondA); dds_delete(rdcondA);
rc = dds_waitset_detach(ws, rdcondD); dds_waitset_detach(ws, rdcondD);
dds_delete(rdcondD); dds_delete(rdcondD);
break; break;
case MODE_CHECK: case MODE_CHECK:
@ -1952,9 +1949,8 @@ static uint32_t autotermthread(void *varg __attribute__((unused))) {
tnow = dds_time(); tnow = dds_time();
} }
rc = dds_waitset_detach(ws, termcond); dds_waitset_detach(ws, termcond);
rc = dds_delete(ws); dds_delete(ws);
return 0; return 0;
} }

View file

@ -21,6 +21,10 @@ target_link_libraries(util PUBLIC OSAPI)
target_include_directories(util PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/exports/>" target_include_directories(util PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/exports/>"
"$<INSTALL_INTERFACE:${INSTALL_PREFIX}/include/>" "$<INSTALL_INTERFACE:${INSTALL_PREFIX}/exports/>") "$<INSTALL_INTERFACE:${INSTALL_PREFIX}/include/>" "$<INSTALL_INTERFACE:${INSTALL_PREFIX}/exports/>")
if(${CMAKE_C_COMPILER_ID} STREQUAL "SunPro")
add_definitions(-KPIC)
endif()
# TODO: improve test inclusion. # TODO: improve test inclusion.
if((BUILD_TESTING) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800"))) if((BUILD_TESTING) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800")))
add_subdirectory(tests) add_subdirectory(tests)

View file

@ -190,7 +190,6 @@ typedef struct ut_avlTreedef {
size_t avlnodeoffset; size_t avlnodeoffset;
size_t keyoffset; size_t keyoffset;
union { union {
int (*cmp) ();
ut_avlCompare_t comparekk; ut_avlCompare_t comparekk;
ut_avlCompare_r_t comparekk_r; ut_avlCompare_r_t comparekk_r;
} u; } u;
@ -239,14 +238,14 @@ typedef struct ut_avlCIter {
} ut_avlCIter_t; } ut_avlCIter_t;
/* avlnodeoffset and keyoffset must both be in [0,2**31-1] */ /* avlnodeoffset and keyoffset must both be in [0,2**31-1] */
#define UT_AVL_TREEDEF_INITIALIZER(avlnodeoffset, keyoffset, comparekk, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), 0, 0 } #define UT_AVL_TREEDEF_INITIALIZER(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), 0, 0 }
#define UT_AVL_TREEDEF_INITIALIZER_INDKEY(avlnodeoffset, keyoffset, comparekk, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY, 0 } #define UT_AVL_TREEDEF_INITIALIZER_INDKEY(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY, 0 }
#define UT_AVL_TREEDEF_INITIALIZER_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), UT_AVL_TREEDEF_FLAG_ALLOWDUPS, 0 } #define UT_AVL_TREEDEF_INITIALIZER_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), UT_AVL_TREEDEF_FLAG_ALLOWDUPS, 0 }
#define UT_AVL_TREEDEF_INITIALIZER_INDKEY_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY|UT_AVL_TREEDEF_FLAG_ALLOWDUPS, 0 } #define UT_AVL_TREEDEF_INITIALIZER_INDKEY_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, augment) { (avlnodeoffset), (keyoffset), { .comparekk = (comparekk_) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY|UT_AVL_TREEDEF_FLAG_ALLOWDUPS, 0 }
#define UT_AVL_TREEDEF_INITIALIZER_R(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), UT_AVL_TREEDEF_FLAG_R, (cmparg) } #define UT_AVL_TREEDEF_INITIALIZER_R(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), UT_AVL_TREEDEF_FLAG_R, (cmparg) }
#define UT_AVL_TREEDEF_INITIALIZER_INDKEY_R(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY|UT_AVL_TREEDEF_FLAG_R, (cmparg) } #define UT_AVL_TREEDEF_INITIALIZER_INDKEY_R(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY|UT_AVL_TREEDEF_FLAG_R, (cmparg) }
#define UT_AVL_TREEDEF_INITIALIZER_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), UT_AVL_TREEDEF_FLAG_R|UT_AVL_TREEDEF_FLAG_ALLOWDUPS, (cmparg) } #define UT_AVL_TREEDEF_INITIALIZER_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), UT_AVL_TREEDEF_FLAG_R|UT_AVL_TREEDEF_FLAG_ALLOWDUPS, (cmparg) }
#define UT_AVL_TREEDEF_INITIALIZER_INDKEY_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk, cmparg, augment) { (avlnodeoffset), (keyoffset), { (int (*) ()) (comparekk) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY|UT_AVL_TREEDEF_FLAG_R|UT_AVL_TREEDEF_FLAG_ALLOWDUPS, (cmparg) } #define UT_AVL_TREEDEF_INITIALIZER_INDKEY_R_ALLOWDUPS(avlnodeoffset, keyoffset, comparekk_, cmparg, augment) { (avlnodeoffset), (keyoffset), { .comparekk_r = (comparekk_) }, (augment), UT_AVL_TREEDEF_FLAG_INDKEY|UT_AVL_TREEDEF_FLAG_R|UT_AVL_TREEDEF_FLAG_ALLOWDUPS, (cmparg) }
/* Not maintaining # nodes */ /* Not maintaining # nodes */

View file

@ -91,26 +91,27 @@ static const char *conode_from_node (const ut_avlTreedef_t *td, const ut_avlNode
} }
} }
static void treedef_init_common (ut_avlTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, int (*cmp) (), ut_avlAugment_t augment, uint32_t flags) static void treedef_init_common (ut_avlTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, ut_avlAugment_t augment, uint32_t flags)
{ {
assert (avlnodeoffset <= 0x7fffffff); assert (avlnodeoffset <= 0x7fffffff);
assert (keyoffset <= 0x7fffffff); assert (keyoffset <= 0x7fffffff);
td->avlnodeoffset = avlnodeoffset; td->avlnodeoffset = avlnodeoffset;
td->keyoffset = keyoffset; td->keyoffset = keyoffset;
td->u.cmp = cmp;
td->augment = augment; td->augment = augment;
td->flags = flags; td->flags = flags;
} }
void ut_avlTreedefInit (_Out_ ut_avlTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_t comparekk, _In_opt_ ut_avlAugment_t augment, uint32_t flags) void ut_avlTreedefInit (_Out_ ut_avlTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_t comparekk, _In_opt_ ut_avlAugment_t augment, uint32_t flags)
{ {
treedef_init_common (td, avlnodeoffset, keyoffset, (int (*) ()) comparekk, augment, flags); treedef_init_common (td, avlnodeoffset, keyoffset, augment, flags);
td->u.comparekk = comparekk;
} }
void ut_avlTreedefInit_r (_Out_ ut_avlTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_r_t comparekk_r, _Inout_opt_ void *cmp_arg, ut_avlAugment_t augment, uint32_t flags) void ut_avlTreedefInit_r (_Out_ ut_avlTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_r_t comparekk_r, _Inout_opt_ void *cmp_arg, ut_avlAugment_t augment, uint32_t flags)
{ {
treedef_init_common (td, avlnodeoffset, keyoffset, augment, flags | UT_AVL_TREEDEF_FLAG_R);
td->cmp_arg = cmp_arg; td->cmp_arg = cmp_arg;
treedef_init_common (td, avlnodeoffset, keyoffset, (int (*) ()) comparekk_r, augment, flags | UT_AVL_TREEDEF_FLAG_R); td->u.comparekk_r = comparekk_r;
} }
void ut_avlInit (_In_ const ut_avlTreedef_t *td, _Out_ ut_avlTree_t *tree) void ut_avlInit (_In_ const ut_avlTreedef_t *td, _Out_ ut_avlTree_t *tree)
@ -256,11 +257,11 @@ static ut_avlNode_t *rotate (const ut_avlTreedef_t *td, ut_avlNode_t **pnode, ut
rotation, _ND_D means the grandchild that is the right child of rotation, _ND_D means the grandchild that is the right child of
the left child. */ the left child. */
ut_avlNode_t * const node_ND = node->cs[1-dir]; ut_avlNode_t * const node_ND = node->cs[1-dir];
assert (node_ND != NULL);
ut_avlNode_t * const node_ND_ND = node_ND->cs[1-dir]; ut_avlNode_t * const node_ND_ND = node_ND->cs[1-dir];
ut_avlNode_t * const node_ND_D = node_ND->cs[dir]; ut_avlNode_t * const node_ND_D = node_ND->cs[dir];
int height_ND_ND, height_ND_D; int height_ND_ND, height_ND_D;
assert (dir == !!dir); assert (dir == !!dir);
assert (node_ND != NULL);
height_ND_ND = node_ND_ND ? node_ND_ND->height : 0; height_ND_ND = node_ND_ND ? node_ND_ND->height : 0;
height_ND_D = node_ND_D ? node_ND_D->height : 0; height_ND_D = node_ND_D ? node_ND_D->height : 0;
if (height_ND_ND < height_ND_D) { if (height_ND_ND < height_ND_D) {
@ -948,13 +949,15 @@ _Ret_notnull_ void *ut_avlRootNonEmpty (_In_ const ut_avlTreedef_t *td, _In_ con
void ut_avlCTreedefInit (_Out_ ut_avlCTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_t comparekk, _In_opt_ ut_avlAugment_t augment, uint32_t flags) void ut_avlCTreedefInit (_Out_ ut_avlCTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_t comparekk, _In_opt_ ut_avlAugment_t augment, uint32_t flags)
{ {
treedef_init_common (&td->t, avlnodeoffset, keyoffset, (int (*) ()) comparekk, augment, flags); treedef_init_common (&td->t, avlnodeoffset, keyoffset, augment, flags);
td->t.u.comparekk = comparekk;
} }
void ut_avlCTreedefInit_r (_Out_ ut_avlCTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_r_t comparekk_r, _Inout_opt_ void *cmp_arg, _In_opt_ ut_avlAugment_t augment, uint32_t flags) void ut_avlCTreedefInit_r (_Out_ ut_avlCTreedef_t *td, size_t avlnodeoffset, size_t keyoffset, _In_ ut_avlCompare_r_t comparekk_r, _Inout_opt_ void *cmp_arg, _In_opt_ ut_avlAugment_t augment, uint32_t flags)
{ {
treedef_init_common (&td->t, avlnodeoffset, keyoffset, augment, flags | UT_AVL_TREEDEF_FLAG_R);
td->t.cmp_arg = cmp_arg; td->t.cmp_arg = cmp_arg;
treedef_init_common (&td->t, avlnodeoffset, keyoffset, (int (*) ()) comparekk_r, augment, flags | UT_AVL_TREEDEF_FLAG_R); td->t.u.comparekk_r = comparekk_r;
} }
void ut_avlCInit (_In_ const ut_avlCTreedef_t *td, _Out_ ut_avlCTree_t *tree) void ut_avlCInit (_In_ const ut_avlCTreedef_t *td, _Out_ ut_avlCTree_t *tree)

View file

@ -34,11 +34,7 @@ struct ut_chhBucket {
struct _Struct_size_bytes_(size) ut_chhBucketArray { struct _Struct_size_bytes_(size) ut_chhBucketArray {
uint32_t size; /* power of 2 */ uint32_t size; /* power of 2 */
#if __STDC_VERSION__ >= 199901L
struct ut_chhBucket bs[]; struct ut_chhBucket bs[];
#else
struct ut_chhBucket bs[1];
#endif
}; };
struct ut_chhBackingLock { struct ut_chhBackingLock {
@ -91,9 +87,6 @@ static int ut_chhInit (struct ut_chh *rt, uint32_t init_size, ut_hhHash_fn hash,
for (i = 0; i < N_BACKING_LOCKS; i++) { for (i = 0; i < N_BACKING_LOCKS; i++) {
struct ut_chhBackingLock *s = &rt->backingLocks[i]; struct ut_chhBackingLock *s = &rt->backingLocks[i];
os_mutexInit (&s->lock); os_mutexInit (&s->lock);
}
for (i = 0; i < N_BACKING_LOCKS; i++) {
struct ut_chhBackingLock *s = &rt->backingLocks[i];
os_condInit (&s->cv, &s->lock); os_condInit (&s->cv, &s->lock);
} }
for (i = 0; i < N_RESIZE_LOCKS; i++) { for (i = 0; i < N_RESIZE_LOCKS; i++) {
@ -205,7 +198,7 @@ static void *ut_chhLookupInternal (struct ut_chhBucketArray const * const bsary,
do { do {
uint32_t hopinfo; uint32_t hopinfo;
timestamp = os_atomic_ld32 (&bs[bucket].timestamp); timestamp = os_atomic_ld32 (&bs[bucket].timestamp);
os_atomic_fence (); os_atomic_fence_ldld ();
hopinfo = os_atomic_ld32 (&bs[bucket].hopinfo); hopinfo = os_atomic_ld32 (&bs[bucket].hopinfo);
for (idx = 0; hopinfo != 0; hopinfo >>= 1, idx++) { for (idx = 0; hopinfo != 0; hopinfo >>= 1, idx++) {
const uint32_t bidx = (bucket + idx) & idxmask; const uint32_t bidx = (bucket + idx) & idxmask;
@ -214,7 +207,7 @@ static void *ut_chhLookupInternal (struct ut_chhBucketArray const * const bsary,
return data; return data;
} }
} }
os_atomic_fence (); os_atomic_fence_ldld ();
} while (timestamp != os_atomic_ld32 (&bs[bucket].timestamp) && ++try_counter < CHH_MAX_TRIES); } while (timestamp != os_atomic_ld32 (&bs[bucket].timestamp) && ++try_counter < CHH_MAX_TRIES);
if (try_counter == CHH_MAX_TRIES) { if (try_counter == CHH_MAX_TRIES) {
/* Note: try_counter would not have been incremented to /* Note: try_counter would not have been incremented to