make proxy reader/writer references to sertopics properly counted, strong references

without this, deleting the last reader/writer that references the topic results in a dangling pointer ... but there is another intriguing solution: erase the topic from the proxy reader/writer when the last matching local one disappears, so that the topic completely disappears. I rather like this second solution, but I am not yet sure of the consequences and the first (implemented one) is such a simple change that fixes a real problem that it is a no-brainer

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-01-03 17:30:25 +01:00
parent 0d0a2bd2df
commit c61c880fd2
2 changed files with 4 additions and 3 deletions

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

@ -1795,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;
@ -1910,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",
@ -4055,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);