Refactor handling of an SPDP-republish event
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
0064def595
commit
ca99fd10aa
1 changed files with 43 additions and 51 deletions
|
@ -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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -966,10 +1002,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
|
|||
struct participant *pp;
|
||||
struct proxy_reader *prd;
|
||||
struct writer *spdp_wr;
|
||||
struct whc_borrowed_sample sample;
|
||||
#ifndef NDEBUG
|
||||
bool sample_found;
|
||||
#endif
|
||||
bool do_write;
|
||||
|
||||
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 (&ev->u.spdp.dest_proxypp_guid_prefix, 0, sizeof (ev->u.spdp.dest_proxypp_guid_prefix));
|
||||
prd = NULL;
|
||||
do_write = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nn_guid_t guid;
|
||||
guid.prefix = ev->u.spdp.dest_proxypp_guid_prefix;
|
||||
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));
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look up data in (transient-local) WHC by key value -- FIXME: clearly
|
||||
a slightly more efficient and elegant way of looking up the key value
|
||||
is to be preferred */
|
||||
nn_plist_t ps;
|
||||
nn_plist_init_empty (&ps);
|
||||
ps.present |= PP_PARTICIPANT_GUID;
|
||||
ps.participant_guid = ev->u.spdp.pp_guid;
|
||||
struct nn_xmsg *mpayload = nn_xmsg_new (gv.xmsgpool, &ev->u.spdp.pp_guid.prefix, 0, NN_XMSG_KIND_DATA);
|
||||
nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
|
||||
nn_xmsg_addpar_sentinel (mpayload);
|
||||
nn_plist_fini (&ps);
|
||||
struct ddsi_plist_sample plist_sample;
|
||||
nn_xmsg_payload_to_plistsample (&plist_sample, PID_PARTICIPANT_GUID, mpayload);
|
||||
struct ddsi_serdata *sd = ddsi_serdata_from_sample (gv.plist_topic, SDK_KEY, &plist_sample);
|
||||
nn_xmsg_free (mpayload);
|
||||
|
||||
os_mutexLock (&spdp_wr->e.lock);
|
||||
if (whc_borrow_sample_key (spdp_wr->whc, sd, &sample))
|
||||
if (do_write && !resend_spdp_sample_by_guid_key (spdp_wr, &ev->u.spdp.pp_guid, prd))
|
||||
{
|
||||
/* 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
|
||||
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
|
||||
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",
|
||||
PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_PARTICIPANT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
skip:
|
||||
if (ev->u.spdp.directed)
|
||||
{
|
||||
/* Directed events are used to send SPDP packets to newly
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue