Use NO_KEY GUIDs for topics without key fields

Submit to the tyranny of the majority:

The DCPS specification makes no distinction between topics with and
topics without key fields: in the latter case, there is simply a single
instance but that instance obeys all the normal rules.  In particular,
this implies dispose/unregister work regardless of whether a topic has
key fields.

The DDSI specification makes a distinction between WITH_KEY endpoints
and NO_KEY endpoints and does not support dispose/unregister operations
on NO_KEY endpoints.  This implies that a DCPS implementation must limit
itself to the use of WITH_KEY endpoints.

Most implementations nonetheless map topics without key fields to the
NO_KEY type, and as the DDSI specification also states that a WITH_KEY
reader/writer does not match a NO_KEY writer/reader, Cyclone's correctly
mapping everything to WITH_KEY means there are interoperability problems
for topics without key fields.

This commit changes Cyclone to use NO_KEY like the others, but without
changing any other part of its behaviour: it continues to support
dispose/unregister operations regardless of whether a topic has key
fields or not.  That is the lesser of the two evils.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-08-21 11:57:37 +02:00 committed by eboasson
parent 8964c0b1bc
commit e42092af92
8 changed files with 97 additions and 55 deletions

View file

@ -29,16 +29,7 @@
struct ddsi_sertopic *new_sertopic_builtintopic (enum ddsi_sertopic_builtintopic_type type, const char *name, const char *typename, struct q_globals *gv)
{
struct ddsi_sertopic_builtintopic *tp = ddsrt_malloc (sizeof (*tp));
tp->c.iid = ddsi_iid_gen();
tp->c.name = dds_string_dup (name);
tp->c.type_name = dds_string_dup (typename);
const size_t name_typename_size = strlen (tp->c.name) + 1 + strlen (tp->c.type_name) + 1;
tp->c.name_type_name = dds_alloc (name_typename_size);
snprintf (tp->c.name_type_name, name_typename_size, "%s/%s", tp->c.name, tp->c.type_name);
tp->c.ops = &ddsi_sertopic_ops_builtintopic;
tp->c.serdata_ops = &ddsi_serdata_ops_builtintopic;
tp->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (tp->c.serdata_ops);
ddsrt_atomic_st32 (&tp->c.refc, 1);
ddsi_sertopic_init (&tp->c, name, typename, &ddsi_sertopic_ops_builtintopic, &ddsi_serdata_ops_builtintopic, false);
tp->type = type;
tp->gv = gv;
return &tp->c;
@ -46,9 +37,7 @@ struct ddsi_sertopic *new_sertopic_builtintopic (enum ddsi_sertopic_builtintopic
static void sertopic_builtin_free (struct ddsi_sertopic *tp)
{
ddsrt_free (tp->name_type_name);
ddsrt_free (tp->name);
ddsrt_free (tp->type_name);
ddsi_sertopic_fini (tp);
ddsrt_free (tp);
}

View file

@ -454,12 +454,9 @@ err_invalid_qos:
dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descriptor_t *desc, const char *name, const dds_qos_t *qos, const dds_listener_t *listener)
{
char *key = NULL;
struct ddsi_sertopic_default *st;
const char *typename;
nn_plist_t plist;
dds_entity_t hdl;
size_t keysz;
struct dds_entity *ppent;
dds_return_t ret;
@ -469,21 +466,9 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
if ((ret = dds_entity_pin (participant, &ppent)) < 0)
return ret;
typename = desc->m_typename;
keysz = strlen (name) + strlen (typename) + 2;
key = dds_alloc (keysz);
(void) snprintf (key, keysz, "%s/%s", name, typename);
st = dds_alloc (sizeof (*st));
ddsrt_atomic_st32 (&st->c.refc, 1);
st->c.iid = ddsi_iid_gen ();
st->c.name_type_name = key;
st->c.name = ddsrt_strdup (name);
st->c.type_name = ddsrt_strdup (typename);
st->c.ops = &ddsi_sertopic_ops_default;
st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey;
st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops);
ddsi_sertopic_init (&st->c, name, desc->m_typename, &ddsi_sertopic_ops_default, desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey, (desc->m_nkeys == 0));
st->native_encoding_identifier = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? CDR_LE : CDR_BE);
st->serpool = ppent->m_domain->gv.serpool;
st->type = (void*) desc;