Use dummy guardcond to block on empty waitset
Cyclone DDS always returns immediately from ``dds_waitset_wait`` when there are no entities in the waitset, but the rcl timer test implies that the expectation is that blocks. By adding a guard condition that is never triggered this expectation is met. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
d06953bd91
commit
e4fa799090
1 changed files with 20 additions and 0 deletions
|
@ -161,6 +161,11 @@ struct Cdds
|
||||||
dds_entity_t ppant;
|
dds_entity_t ppant;
|
||||||
dds_entity_t builtin_readers[sizeof(builtin_topics) / sizeof(builtin_topics[0])];
|
dds_entity_t builtin_readers[sizeof(builtin_topics) / sizeof(builtin_topics[0])];
|
||||||
|
|
||||||
|
/* special guard condition that gets attached to every waitset but that is never triggered:
|
||||||
|
this way, we can avoid Cyclone's behaviour of always returning immediately when no
|
||||||
|
entities are attached to a waitset */
|
||||||
|
dds_entity_t gc_for_empty_waitset;
|
||||||
|
|
||||||
/* set of waitsets protected by lock, used to invalidate all waitsets caches when an entity is
|
/* set of waitsets protected by lock, used to invalidate all waitsets caches when an entity is
|
||||||
deleted */
|
deleted */
|
||||||
std::unordered_set<CddsWaitset *> waitsets;
|
std::unordered_set<CddsWaitset *> waitsets;
|
||||||
|
@ -326,6 +331,13 @@ static dds_entity_t ref_ppant()
|
||||||
return gcdds.ppant;
|
return gcdds.ppant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((gcdds.gc_for_empty_waitset = dds_create_guardcondition(gcdds.ppant)) < 0) {
|
||||||
|
RMW_SET_ERROR_MSG("failed to create guardcondition for handling empty waitsets");
|
||||||
|
dds_delete(gcdds.ppant);
|
||||||
|
gcdds.ppant = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static_assert(sizeof(gcdds.builtin_readers) / sizeof(gcdds.builtin_readers[0]) ==
|
static_assert(sizeof(gcdds.builtin_readers) / sizeof(gcdds.builtin_readers[0]) ==
|
||||||
sizeof(builtin_topics) / sizeof(builtin_topics[0]),
|
sizeof(builtin_topics) / sizeof(builtin_topics[0]),
|
||||||
"mismatch between array of built-in topics and array of built-in readers");
|
"mismatch between array of built-in topics and array of built-in readers");
|
||||||
|
@ -1392,12 +1404,20 @@ extern "C" rmw_wait_set_t * rmw_create_wait_set(rmw_context_t * context, size_t
|
||||||
RMW_SET_ERROR_MSG("failed to create waitset");
|
RMW_SET_ERROR_MSG("failed to create waitset");
|
||||||
goto fail_waitset;
|
goto fail_waitset;
|
||||||
}
|
}
|
||||||
|
// Attach never-triggered guard condition. As it will never be triggered, it will never be
|
||||||
|
// included in the result of dds_waitset_wait
|
||||||
|
if (dds_waitset_attach(ws->waitseth, gcdds.gc_for_empty_waitset, INTPTR_MAX) < 0) {
|
||||||
|
RMW_SET_ERROR_MSG("failed to attach dummy guard condition for blocking on empty waitset");
|
||||||
|
goto fail_attach_dummy;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(gcdds.lock);
|
std::lock_guard<std::mutex> lock(gcdds.lock);
|
||||||
gcdds.waitsets.insert(ws);
|
gcdds.waitsets.insert(ws);
|
||||||
}
|
}
|
||||||
return wait_set;
|
return wait_set;
|
||||||
|
|
||||||
|
fail_attach_dummy:
|
||||||
|
dds_delete(ws->waitseth);
|
||||||
fail_waitset:
|
fail_waitset:
|
||||||
unref_ppant();
|
unref_ppant();
|
||||||
fail_ws:
|
fail_ws:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue