Allow domain/cyclonedds as waitset/guardcond owner
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
0b12ff5cfc
commit
6da50bdbae
5 changed files with 287 additions and 17 deletions
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds__init.h"
|
||||
#include "dds__reader.h"
|
||||
#include "dds__guardcond.h"
|
||||
#include "dds__participant.h"
|
||||
|
@ -28,22 +29,45 @@ const struct dds_entity_deriver dds_entity_deriver_guardcondition = {
|
|||
.validate_status = dds_entity_deriver_dummy_validate_status
|
||||
};
|
||||
|
||||
dds_entity_t dds_create_guardcondition (dds_entity_t participant)
|
||||
dds_entity_t dds_create_guardcondition (dds_entity_t owner)
|
||||
{
|
||||
dds_participant *pp;
|
||||
dds_entity *e;
|
||||
dds_return_t rc;
|
||||
|
||||
if ((rc = dds_participant_lock (participant, &pp)) != DDS_RETCODE_OK)
|
||||
/* If the owner is any ordinary (allowed) entity, the library is already initialised and calling
|
||||
init here is cheap. If it is DDS_CYCLONEDDS_HANDLE, we may have to initialise the library, so
|
||||
have to call it. If it is some bogus value and the library is not initialised yet ... so be
|
||||
it. Naturally, this requires us to call delete on DDS_CYCLONEDDS_HANDLE afterward. */
|
||||
if ((rc = dds_init ()) < 0)
|
||||
return rc;
|
||||
else
|
||||
|
||||
if ((rc = dds_entity_lock (owner, DDS_KIND_DONTCARE, &e)) != DDS_RETCODE_OK)
|
||||
goto err_entity_lock;
|
||||
|
||||
switch (dds_entity_kind (e))
|
||||
{
|
||||
dds_guardcond *gcond = dds_alloc (sizeof (*gcond));
|
||||
dds_entity_t hdl = dds_entity_init (&gcond->m_entity, &pp->m_entity, DDS_KIND_COND_GUARD, NULL, NULL, 0);
|
||||
gcond->m_entity.m_iid = ddsi_iid_gen ();
|
||||
dds_entity_register_child (&pp->m_entity, &gcond->m_entity);
|
||||
dds_participant_unlock (pp);
|
||||
return hdl;
|
||||
case DDS_KIND_CYCLONEDDS:
|
||||
case DDS_KIND_DOMAIN:
|
||||
case DDS_KIND_PARTICIPANT:
|
||||
break;
|
||||
default:
|
||||
rc = DDS_RETCODE_ILLEGAL_OPERATION;
|
||||
goto err_entity_kind;
|
||||
}
|
||||
|
||||
dds_guardcond *gcond = dds_alloc (sizeof (*gcond));
|
||||
dds_entity_t hdl = dds_entity_init (&gcond->m_entity, e, DDS_KIND_COND_GUARD, NULL, NULL, 0);
|
||||
gcond->m_entity.m_iid = ddsi_iid_gen ();
|
||||
dds_entity_register_child (e, &gcond->m_entity);
|
||||
dds_entity_unlock (e);
|
||||
dds_delete (DDS_CYCLONEDDS_HANDLE);
|
||||
return hdl;
|
||||
|
||||
err_entity_kind:
|
||||
dds_entity_unlock (e);
|
||||
err_entity_lock:
|
||||
dds_delete (DDS_CYCLONEDDS_HANDLE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dds_return_t dds_set_guardcondition (dds_entity_t condition, bool triggered)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "dds__participant.h"
|
||||
#include "dds__querycond.h"
|
||||
#include "dds__readcond.h"
|
||||
#include "dds__init.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds/ddsi/ddsi_iid.h"
|
||||
|
||||
|
@ -112,24 +113,48 @@ const struct dds_entity_deriver dds_entity_deriver_waitset = {
|
|||
.validate_status = dds_entity_deriver_dummy_validate_status
|
||||
};
|
||||
|
||||
dds_entity_t dds_create_waitset (dds_entity_t participant)
|
||||
dds_entity_t dds_create_waitset (dds_entity_t owner)
|
||||
{
|
||||
dds_entity_t hdl;
|
||||
dds_participant *par;
|
||||
dds_entity *e;
|
||||
dds_return_t rc;
|
||||
|
||||
if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||
/* If the owner is any ordinary (allowed) entity, the library is already initialised and calling
|
||||
init here is cheap. If it is DDS_CYCLONEDDS_HANDLE, we may have to initialise the library, so
|
||||
have to call it. If it is some bogus value and the library is not initialised yet ... so be
|
||||
it. Naturally, this requires us to call delete on DDS_CYCLONEDDS_HANDLE afterward. */
|
||||
if ((rc = dds_init ()) < 0)
|
||||
return rc;
|
||||
|
||||
if ((rc = dds_entity_lock (owner, DDS_KIND_DONTCARE, &e)) != DDS_RETCODE_OK)
|
||||
goto err_entity_lock;
|
||||
|
||||
switch (dds_entity_kind (e))
|
||||
{
|
||||
case DDS_KIND_CYCLONEDDS:
|
||||
case DDS_KIND_DOMAIN:
|
||||
case DDS_KIND_PARTICIPANT:
|
||||
break;
|
||||
default:
|
||||
rc = DDS_RETCODE_ILLEGAL_OPERATION;
|
||||
goto err_entity_kind;
|
||||
}
|
||||
|
||||
dds_waitset *waitset = dds_alloc (sizeof (*waitset));
|
||||
hdl = dds_entity_init (&waitset->m_entity, &par->m_entity, DDS_KIND_WAITSET, NULL, NULL, 0);
|
||||
dds_entity_t hdl = dds_entity_init (&waitset->m_entity, e, DDS_KIND_WAITSET, NULL, NULL, 0);
|
||||
waitset->m_entity.m_iid = ddsi_iid_gen ();
|
||||
dds_entity_register_child (&par->m_entity, &waitset->m_entity);
|
||||
dds_entity_register_child (e, &waitset->m_entity);
|
||||
waitset->nentities = 0;
|
||||
waitset->ntriggered = 0;
|
||||
waitset->entities = NULL;
|
||||
dds_participant_unlock (par);
|
||||
dds_entity_unlock (e);
|
||||
dds_delete (DDS_CYCLONEDDS_HANDLE);
|
||||
return hdl;
|
||||
|
||||
err_entity_kind:
|
||||
dds_entity_unlock (e);
|
||||
err_entity_lock:
|
||||
dds_delete (DDS_CYCLONEDDS_HANDLE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dds_return_t dds_waitset_get_entities (dds_entity_t waitset, dds_entity_t *entities, size_t size)
|
||||
|
|
|
@ -31,6 +31,7 @@ set(ddsc_test_sources
|
|||
"publisher.c"
|
||||
"qos.c"
|
||||
"querycondition.c"
|
||||
"guardcondition.c"
|
||||
"readcondition.c"
|
||||
"reader.c"
|
||||
"reader_iterator.c"
|
||||
|
|
187
src/core/ddsc/tests/guardcondition.c
Normal file
187
src/core/ddsc/tests/guardcondition.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "dds/dds.h"
|
||||
#include "CUnit/Theory.h"
|
||||
#include "RoundTrip.h"
|
||||
|
||||
#include "dds/ddsrt/cdtors.h"
|
||||
#include "dds/ddsrt/misc.h"
|
||||
#include "dds/ddsrt/process.h"
|
||||
#include "dds/ddsrt/threads.h"
|
||||
#include "dds/ddsrt/atomics.h"
|
||||
#include "dds/ddsrt/time.h"
|
||||
|
||||
CU_Test (ddsc_guardcond_create, cyclonedds)
|
||||
{
|
||||
dds_entity_t gc;
|
||||
dds_return_t rc;
|
||||
/* Expect an uninitialised library */
|
||||
rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET);
|
||||
gc = dds_create_guardcondition (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (gc > 0);
|
||||
rc = dds_delete (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
/* And the same afterward */
|
||||
rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET);
|
||||
}
|
||||
|
||||
CU_Test (ddsc_guardcond_create, domain)
|
||||
{
|
||||
dds_entity_t par, dom, gc;
|
||||
dds_return_t rc;
|
||||
par = dds_create_participant (0, NULL, NULL);
|
||||
CU_ASSERT_FATAL (par > 0);
|
||||
dom = dds_get_parent (par);
|
||||
CU_ASSERT_FATAL (dom > 0);
|
||||
gc = dds_create_guardcondition (dom);
|
||||
CU_ASSERT_FATAL (gc > 0);
|
||||
rc = dds_delete (dom);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
}
|
||||
|
||||
CU_Test (ddsc_guardcond_create, participant)
|
||||
{
|
||||
dds_entity_t par, gc;
|
||||
dds_return_t rc;
|
||||
par = dds_create_participant (0, NULL, NULL);
|
||||
CU_ASSERT_FATAL (par > 0);
|
||||
gc = dds_create_guardcondition (par);
|
||||
CU_ASSERT_FATAL (gc > 0);
|
||||
rc = dds_delete (par);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
}
|
||||
|
||||
CU_Test (ddsc_guardcond, set_trigger)
|
||||
{
|
||||
dds_entity_t par, gc;
|
||||
dds_return_t rc;
|
||||
bool trig;
|
||||
par = dds_create_participant (0, NULL, NULL);
|
||||
CU_ASSERT_FATAL (par > 0);
|
||||
gc = dds_create_guardcondition (par);
|
||||
CU_ASSERT_FATAL (gc > 0);
|
||||
rc = dds_read_guardcondition (gc, &trig);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
CU_ASSERT (!trig);
|
||||
rc = dds_set_guardcondition (gc, true);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
rc = dds_read_guardcondition (gc, &trig);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
CU_ASSERT (trig);
|
||||
rc = dds_delete (par);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
}
|
||||
|
||||
CU_Test (ddsc_guardcond, take_trigger)
|
||||
{
|
||||
dds_entity_t par, gc;
|
||||
dds_return_t rc;
|
||||
bool trig;
|
||||
par = dds_create_participant (0, NULL, NULL);
|
||||
CU_ASSERT_FATAL (par > 0);
|
||||
gc = dds_create_guardcondition (par);
|
||||
CU_ASSERT_FATAL (gc > 0);
|
||||
rc = dds_read_guardcondition (gc, &trig);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
CU_ASSERT (!trig);
|
||||
rc = dds_set_guardcondition (gc, true);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
rc = dds_take_guardcondition (gc, &trig);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
CU_ASSERT (trig);
|
||||
rc = dds_read_guardcondition (gc, &trig);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
CU_ASSERT (!trig);
|
||||
rc = dds_delete (par);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
}
|
||||
|
||||
CU_Test (ddsc_guardcond, waitset)
|
||||
{
|
||||
dds_entity_t par, gc, ws;
|
||||
dds_attach_t xs[1];
|
||||
dds_return_t rc;
|
||||
par = dds_create_participant (0, NULL, NULL);
|
||||
CU_ASSERT_FATAL (par > 0);
|
||||
gc = dds_create_guardcondition (par);
|
||||
CU_ASSERT_FATAL (gc > 0);
|
||||
ws = dds_create_waitset (par);
|
||||
CU_ASSERT_FATAL (ws > 0);
|
||||
rc = dds_waitset_attach (ws, gc, gc);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
/* guard cond not triggered: waitset should return 0 */
|
||||
rc = dds_waitset_wait (ws, xs, 1, 0);
|
||||
CU_ASSERT (rc == 0);
|
||||
rc = dds_set_guardcondition (gc, true);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
/* guard triggered: waitset should return it */
|
||||
rc = dds_waitset_wait (ws, xs, 1, 0);
|
||||
CU_ASSERT (rc == 1);
|
||||
CU_ASSERT (xs[0] == gc);
|
||||
rc = dds_delete (par);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
}
|
||||
|
||||
struct guardcond_thread_arg {
|
||||
dds_entity_t gc;
|
||||
dds_return_t ret;
|
||||
};
|
||||
|
||||
static uint32_t guardcond_thread (void *varg)
|
||||
{
|
||||
struct guardcond_thread_arg *arg = varg;
|
||||
/* 200ms sleep is hopefully always long enough for the main thread to
|
||||
enter wait() and block; a further 800ms (see wait call) similarly
|
||||
for the guard condition to actually trigger it. */
|
||||
dds_sleepfor (DDS_MSECS (200));
|
||||
arg->ret = dds_set_guardcondition (arg->gc, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CU_Test (ddsc_guardcond, waitset_thread)
|
||||
{
|
||||
dds_entity_t par, gc, ws;
|
||||
dds_attach_t xs[1];
|
||||
dds_return_t rc;
|
||||
ddsrt_thread_t tid;
|
||||
ddsrt_threadattr_t tattr;
|
||||
|
||||
par = dds_create_participant (0, NULL, NULL);
|
||||
CU_ASSERT_FATAL (par > 0);
|
||||
gc = dds_create_guardcondition (par);
|
||||
CU_ASSERT_FATAL (gc > 0);
|
||||
ws = dds_create_waitset (par);
|
||||
CU_ASSERT_FATAL (ws > 0);
|
||||
rc = dds_waitset_attach (ws, gc, gc);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
|
||||
struct guardcond_thread_arg arg = { .gc = gc };
|
||||
ddsrt_threadattr_init (&tattr);
|
||||
rc = ddsrt_thread_create (&tid, "guardcond_thread", &tattr, guardcond_thread, &arg);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
|
||||
rc = dds_waitset_wait (ws, xs, 1, DDS_SECS (1));
|
||||
CU_ASSERT (rc == 1);
|
||||
CU_ASSERT (xs[0] == gc);
|
||||
|
||||
rc = ddsrt_thread_join (tid, NULL);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
CU_ASSERT_FATAL (arg.ret == 0);
|
||||
|
||||
rc = dds_delete (par);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
}
|
|
@ -256,6 +256,39 @@ CU_Theory((dds_entity_t *par), ddsc_waitset_create, non_participants, .init=ddsc
|
|||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
CU_Test (ddsc_waitset_create, domain)
|
||||
{
|
||||
dds_entity_t par, dom, ws;
|
||||
dds_return_t rc;
|
||||
par = dds_create_participant (0, NULL, NULL);
|
||||
CU_ASSERT_FATAL (par > 0);
|
||||
dom = dds_get_parent (par);
|
||||
CU_ASSERT_FATAL (dom > 0);
|
||||
ws = dds_create_waitset (dom);
|
||||
CU_ASSERT_FATAL (ws > 0);
|
||||
rc = dds_delete (dom);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
CU_Test (ddsc_waitset_create, cyclonedds)
|
||||
{
|
||||
dds_entity_t ws;
|
||||
dds_return_t rc;
|
||||
/* Expect an uninitialised library */
|
||||
rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET);
|
||||
ws = dds_create_waitset (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (ws > 0);
|
||||
rc = dds_delete (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (rc == 0);
|
||||
/* And the same afterward */
|
||||
rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE);
|
||||
CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue