Commit graph

206 commits

Author SHA1 Message Date
Erik Boasson
fd103a8d6a Remove dead store triggering Clang static analyzer
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-11-25 18:37:24 +01:00
Dennis Potman
476507fd5d Liveliness QoS implementation for kind manual_by_topic
This commit adds the implementation for the liveliness kind manual-by-topic.
With these changes, the api function dds_assert_liveliness now accepts a
writer as entity. Asserting liveliness on a writer triggers sending a
heartbeat message with the liveliness flag set.

The code for handling reception of a heartbeat message checks for this flag and
if set the lease for the proxy writer is renewed (and the shortest manual-by-participant
lease on the proxy participant as well, because the message also indicates that the
remote participant is alive). Receiving data (handle_regular) also renews the
lease on the proxy writer in case it has the manual-by-topic liveliness kind.

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>

Refactored locking for pwr->alive so that locking order is consistent (locking
pwr->c.proxypp->e.lock while holding pwr->e.lock is the expected order). And
processed other review comments: removed lock for ephash_lookup, added
additional comments, set pwr->lease to null if not initialised.

Because of intermittent timing issues with liveliness expiry test in Travis, I've
increase the time-out and retry limit for this test.

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>

Check that proxy writer is still alive (could be not-alive due to deleting) in code path for proxy writer's lease expiry

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>

Some additional refactoring in locking for pwr->alive for liveliness qos, moved lease free to gc_delete_pwr, refactored the set pwr alive/not alive functions and some minor changes in liveliness tests

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>

Fixed building liveliness tests on Windows and some cleaning up in liveliness test code

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
2019-11-25 18:37:12 +01:00
Dennis Potman
32c5a59c8f Additional tests for liveliness QoS and minor refactoring
Added unit tests for (1) testing the scenario that a proxy writer writes data
after its lease is expired, to check that the status for the pwr is set to alive
again and (2) stress-testing the creation and deletetion of writers with
decreasing lease duration. In addition I've optimized the locking in
unref_proxy_participant a bit and fixed the liveliness changed callback
when a writer with expired lease (not-alive) gets alive again.

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
2019-11-25 18:37:12 +01:00
Dennis Potman
3822f42eff Liveliness QoS implementation for auto and manual-by-participant
This commit adds support for the liveliness QoS for the liveliness
kinds automatic and manual-by-participant. It also implements the
lease_duration from this QoS, which was ignored until now. In the
api the function dds_assert_liveliness is added to assert liveliness
on a participant, which can be used when using liveliness kind
manual-by-participant.

Liveliness kind manual-by-topic is not yet supported, this will be
added in a later commit.

* Proxy participants now have 2 fibheaps to keep leases: one for leases
of pwrs with automatic liveliness and one for leases of the pwrs with
manual-by-participant liveliness (both protected by the proxypp lock).
The minl_auto and minl_man members represent the shortest lease from
these fibheaps and these leases are renewed when receiving data.
Replacing the minl_ leases is now done by replacing the lease object
(atomic ptr) with delayed deletion of the old lease using the gc.

* Proxy writers are set not-alive when the lease expired, and reset to
alive then data is received. When data is received by a pwr, the other
pwrs in the proxypp might also be set alive. I think the specification
is not clear at this point, and for now I have not implemented this

* I refactored out the counter for man-by-pp proxy writers and improved
locking when updating the min-leases on the proxy participant, so I
think this fixes the race conditions.

Some additional tests are required, e.g. to test the not-alive->alive
transition for pwrs. I will add these in short term, as well as the
implementation of the manual-by-topic liveliness kind.

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
2019-11-25 18:36:30 +01:00
Erik Boasson
482e1cd006 Fix rtps_start error handling on thread creation
Signed-off-by: Erik Boasson <eb@ilities.com>

Use static assert instead of run-time assert

Signed-off-by: Erik Boasson <eb@ilities.com>

Use static assertion to verify nn_rmsg offset calc

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-11-25 18:26:15 +01:00
Bart Poot
9a3a377327 Fixed coverity issues
Signed-off-by: Bart Poot <bart.poot@adlinktech.com>

Processed review comments

Signed-off-by: Bart Poot <bart.poot@adlinktech.com>
2019-11-25 18:26:15 +01:00
Erik Boasson
3a3fb64a35 Fix casing of domain "Id" attribute in test config (#283)
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-11-18 15:11:02 +01:00
Martin Bremmer
b6b0c25355 Add domain creation torture test.
Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>

Disabled domain_torture_imlicit test.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
2019-11-14 14:17:37 +01:00
Martin Bremmer
fc8b8fef3a Small entity deletion wip refactoring.
Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
2019-11-14 14:17:37 +01:00
Martin Bremmer
40973d8e29 Update function headers and added dds_create_domain() tests.
Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
2019-11-14 14:17:37 +01:00
Erik Boasson
33ba911192 Fix dds_create_domain return and error handling
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-11-14 14:17:37 +01:00
Dan Rose
c5b22bf629 Fix most of the validation problems
Signed-off-by: Dan Rose <dan@digilabs.io>
2019-11-06 20:39:20 +01:00
Dan Rose
ae1a8130c7 Namespace the schema and add references in xml files
Signed-off-by: Dan Rose <dan@digilabs.io>
2019-11-06 20:39:20 +01:00
dennis-adlink
c8aa6fee5a Moved bswap functions to ddsrt (#297)
* Moved bswap functions to ddsrt

Moved the byte swapping functions from ddsi to ddsrt so that
these can be re-used in e.g. the security plugins and tests.

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>

* Moved  decarations for bswap functions to ddsrt

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
2019-10-28 15:03:46 +01:00
Scott K Logan
94e4c0915d Skip some tests when BUILD_IDLC=OFF
These tests use `idlc_generate`, which is not available when
`BUILD_IDLC` is not `ON`.

Signed-off-by: Scott K Logan <logans@cottsay.net>
2019-10-22 15:20:30 +02:00
Dan Rose
98ce7d1971 Stylistic CMake changes
No functional impact intended
Signed-off-by: Dan Rose <dan@digilabs.io>
2019-10-22 15:18:26 +02:00
Dan Rose
960d4f7358 Use PROJECT_NAME instead of CMAKE_PROJECT_NAME
CMAKE_PROJECT_NAME refers to the top-level project name, not the most recent project. So any CMake project that pulls this in as a dependency was in for a nasty surprise.
https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_NAME.html

Signed-off-by: Dan Rose <dan@digilabs.io>
2019-10-20 03:28:15 -07:00
Erik Boasson
8ec68e1d7d No printing of null pointers in config errors
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-10-16 03:08:31 +02:00
Erik Boasson
94483e3371 Address Coverity, Clang static analyzer warnings
* Fix type of num reliable readers (int to int32_t)

* Conversion codes in debug monitor printf formats

* Dead code elimination

* Skipping a test case where SIZE_MAX is assumed > INT32_MAX if
  assumption is false on target platform

* Error handling in os_sockWaitsetNew

* Stick to unsigned in fragment size calculations

  This check is actually guarded by valid_DataFrag and was safe for
  datagrams up to 2GB, but the unintended and implicit conversion to is
  still best eliminated.

* A "server" connection never has an invalid socket in TCP wrapper

* Handle error return from gethostname in SPDP write (CID 248183)

* Handle extended retcodes in dds_strretcode

  CID 248131, introduced by 19aec98b8a

* Remove dead code in ddsrt logging test (CID 248195)

* Validate command-line argument in process test (CID 248117)

* Allow for extremely delayed store in test

  Test is constructed to have the events trigger only at the appropriate
  times, but it does assume that the store to cb_called becomes visible
  prior to the listener callback.  I'm pretty sure that will always be
  the case in practice, but I'm also pretty sure there is no formal
  guarantee without a memory barrier, which mutex_unlock provides.

  CID 248088, 248136, 248177, 253590, 253591, 253593

* Check unsetenv return value in test (CID 248099)

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-25 10:46:40 +02:00
Erik Boasson
d1ad60fdd1 Fix locking in DATA_ON_READERS when masked
In the case of when a DATA_ON_READERS listener is set, but with the
corresponding status mask is set to suppress the event, the reader lock
would not be in locked, resulting in a unlocked access of status flags
and a double unlock.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-25 10:46:40 +02:00
Frans Faase
f48bbd3d1c Initializing domain with configuration as a string
For targets that do not support ddsrt_setenv and ddsrt_getenv, an alternative
method is needed to supply an application specific configuration. One way to
implement this, is to add a function for creating a domain with a string
arguments, which needs to be called before any call to dds_create_participant
for given domain identifier.

The function dds_create_domain has been added, which has as arguments a domain
identifier and a configuration string. The string is treated in the same way
as the string that is retrieved from the environment variable, in that it may
containt a comma separated list of file names and/or XML fragments for the
configuration.

Two tests have been added. One limits the number of participants to two and
verifies that creating a third participant fails. The other tests checks
incorrect calls to dds_create_domain.

An assert in dds_handle_delete has been weakened.

Signed-off-by: Frans Faase <frans.faase@adlinktech.com>
2019-09-19 16:30:27 +02:00
Martin Bremmer
801c4b1456 Added participant mismatch tests.
Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
2019-09-12 15:15:48 +02:00
Erik Boasson
3ff26103cb Lengthen timeout in ddsc_guardcond_waitset_thread
Rare intermittent failure appears to be timing.  Increasing the timeout
doesn't affect the duration of a successful run and will still signal an
missing trigger.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
68e3e55c2f ddsi_sertopic_free_samples expects an array
So dds_read/dds_take should pass it the address of the first pointer,
rather than the first pointer itself, or the freeing of memory allocated
for samples because of an outstanding loan will crash.  Add a test that
reliable detects this case when no other participants are around.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
133014cdfa Address race conditions in deleting entities
Deleting entities concurrently with operating on them or creating child
entities should work properly, even if it is essentially abuse.  This
commit fixes (most?) of them, with exception of some nastiness when
deleting the last entity, and thus deinitialising the library, in
parallel to attempting to operate on a (by definition invalid) handle.

* Interrupting a blocked operation at the beginning of "delete" is now a
  separate operation.  E.g., a wait call on a waitset must be interrupted,
  but the data structures can't be touched yet because other threads may
  be doing an attach/detach in parallel.

* DDSI writer can now be switched to an intermediate state,
  "INTERRUPTED", to indicate that it should unblock any waiting threads
  and refuse to transmit any further data, but without actually
  embarking on the path of deleting data structures.

* The extra "pinning" of readers and writers is now gone, they remain
  fully functional until the no other threads can still access the
  entity.

* Future listener invocations are prevented as part of deleting the
  entity, but now it also guarantees the application can no longer
  re-enable them.  It furthermore waits until there are no further
  current or pending listener invocations, rather than simply no current
  ones.

* The internal state of the waitset now has its own lock, otherwise
  attaching the parent entity of the waitset can require locking the
  waitset after having locking the parent, which violates locking order.

* Handles are created in a pending state, where they are not included in
  a dds_get_children operation and refuse to be pinned.  This makes it
  possible (in a future commit) to undo deletion of complex entities.

* There is a test (ddsc_waitset_torture) that exercises some of these
  corner cases.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
ed59c388f5 Respect locking order in waitset attach/detach
This fixes a possible deadlock when detaching an entity at the same time
it is triggering: a triggering entity holds its m_observers_lock while
trying to acquire waiset::m_mutex, and so attach and detach must not do
the opposite.  The deadlock had excellent reproducibility in a seemingly
unrelated ROS2 application; this changes fixes it.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
fbc05777f3 Make it possible to create reader with custom RHC
The default RHC implementation is not always ideal and rather than
trying to squeeze everything in a fixed interface it makes more sense to
allow the caller to provide an arbitrary implementation of the
interface.

This is not yet a stable interface.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
57d20e07a4 Rearrange things to make RHC interface public
This makes it possible to write one's own RHC implementation.  This is
not a stable interface.  It shuffles a few things around and renames
some types used throughout the code to stick to having a "dds" prefix
for all the external things.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
801ae26872 Optionally include sample content in trace
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
78c255d432 Explicitly check CLOSED flag when creating entity
All functions creating an entity pin the parent, which guarantees that
the CLOSED is not set yet, but as setting it occurs within the mutex, it
may be set by the time the parent has been locked.  One should not try
to add a child entity at that point, so check it again.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
705b03cf09 Limit entities in waitset to those in same "scope"
Require that all entities attached to waitset are in the same
participant (if the waitset's parent is a participant) or in the same
domain (if the waitset's parent is a domain).  There used to be no check
on this, but it always seemed unhygenic and now that domains and the
entire library instantiation can be used as parents, it seems much
better to enforce this scoping rule.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
6da50bdbae Allow domain/cyclonedds as waitset/guardcond owner
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
0b12ff5cfc Promote domains and Cyclone library to entities
This commit adds two entity types: a "domain", which is the parent of
participants and which is instantiated for each domain that has at least
one participant in it; and "cyclonedds", which is a representation of
the (initialized) Cyclone DDS library in the process and that is the
parent of all domain entities.  The handle of the latter is a
compile-constant, DDS_CYCLONEDDS_HANDLE.

This changes the return value from dds_get_parent when executed on a
participant: it now returns the handle of the entity representing the
domain the participant is attached to.  Two participants in the same
domain self-evidently return the same domain entity.

This allows deleting all participants in a domain by calling dds_delete
on the domain entity, or tearing down everything and deinitializing the
library by calling dds_delete on the top-level entity.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
c6befb48a7 Delete implicit entities when deleting last child
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
f3d0438781 Check that topic is from the same participant
Things go really badly wrong when topics from one participant are used
to create a reader/writer in another participant.  This returns an error
if they are not.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
7feab2e982 Fix assertion in WHC transient-local handling
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-11 10:06:24 +02:00
Erik Boasson
3cb6f053ec Remove dds_domain_default() also from header file
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +02:00
Erik Boasson
e42092af92 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>
2019-08-26 11:50:26 +02:00
Jeroen Koekkoek
4e741e9137 Synchronize warning flags between Xcode and Clang
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-08-23 12:37:15 +02:00
Erik Boasson
5b2cc4e6f3 Work around FreeRTOS header trouble
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
1129939865 Cleanup assertions in serializer
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
891fc2b12f Support multiple domains in configuration
Change the structure of the configuration file (in a backwards
compatible manner) to allow specifying configurations for multiple
domains in a file.  (Listing multiple files in CYCLONEDDS_URI was
already supported.)  A configuration specifies an id, with a default of
any, configurations for an incompatible id are ignored.

If the application specifies an id other than DDS_DOMAIN_DEFAULT in the
call to create_participant, then only configuration specifications for
Domain elements with that id or with id "any" will be used.  If the
application does specify DDS_DOMAIN_DEFAULT, then the id will be taken
from the first Domain element that specifies an id.  If none do, the
domain id defaults to 0.  Each applicable domain specification is taken
as a separate source and may override settings made previously.

All settings moved from the top-level CycloneDDS element to the
CycloneDDS/Domain element.  The CycloneDDS/Domain/Id element moved to
become the "id" attribute of CycloneDDS/Domain.  The old locations still
work, with appropriate deprecation warnings.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
5e31a3df90 Use separate plist for local process settings
The default participant QoS/plist that is used for defaulting received
QoS and for determining which QoS/plist entries to send in discovery
data was mixed up with the one that contains local process information
such as hostname and process id.

It moreover was modified after starting up the protocol stack, and hence
after discovery of remote participants.  While unlikely, this could lead
to an assertion in plist_or_xqos_mergein_missing.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
09e08f7778 Lock entity QoS while accessing it
A QoS change can happen at the same time that a new reader for a
built-in topic is provisioned with historical data, and so cause reading
in inconsistent QoS, use-after-free or other fun things.

During QoS matching it is also necessary to guarantee the QoS doesn't
change (QoS changes affecting matching will be supported at some point,
and manipulating complex data structures where bitmasks determine which
parts are defined while reading the same data concurrently is a recipe
for disaster.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
966ec0dda7 Make logging config per-domain
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
c9f04ee5bd Allow coexisting domains and do a minimal test
The big issue is the there is still only a single log output that gets
opened on creating a domain and closed on deleting one, but otherwise at
least this minimal test works.

The other issue is that the GC waits until threads in all domains have
made sufficient progress, rather than just the threads in its own
domain.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
c1f3ad8a22 Eliminate domain-specific global variables
This commit moves all but a handful of the global variables into the
domain object, in particular including the DDSI configuration, globals
and all transport internal state.

The goal of this commit is not to produce the nicest code possible, but
to get a working version that can support multiple simultaneous domains.
Various choices are driven by this desire and it is expected that some
of the changes will have to be undone.  (E.g., passing the DDSI globals
into address set operations and locator printing because there is no
other way to figure out what transport to use for a given locator;
storing the transport pointer inside the locator would solve that.)

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
8a591fdc9b Liveliness monitoring to dds_global
Thread liveliness monitoring moves to dds_global and there is one
monitor running if there is at least one domain that requests it.  The
synchronization over freeing the thread name when reaping the thread
state is gone by no longer dynamically allocating the thread name.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
f05dd6ac07 Remove use of globals from config processing
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
782f032df8 DDSI stack init/fini in domain_create/free
This moves DDSI stack initialisation and finalisation to the creating
and deleting of a domain, and modifies the related code to trigger all
that from creating/deleting participants.

Built-in topic generation is partially domain-dependent, so that moves
as well.  The underlying ddsi_sertopics can be created are domain
independent and created without initialising DDSI, which necessitates
moving the IID generation (and thus init/fini) out of the DDSI stack and
to what will remain global data.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00