Commit graph

740 commits

Author SHA1 Message Date
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
33a389fdaa Include port numbers in "config" trace category
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
81be40ec0e Fix dropping of first digit of time stamp in log
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
572d2528f3 Update config source id for implied CycloneDDS tag
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
c0aad847fb Reduce risk of problems cleaning thread state
Leak a small amount of memory when there are still application threads
around, that's slightly less problematic than the old code.  It really
needs an overhaul.

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
dennis-adlink
0c23eea7cb Fix compilation errors for RMW build on Windows (#248)
* Fix compilation errors for RMW build on Windows

This commit fixes the compilation errors that occur when building
the ROS2 rmw_cyclonedds_cpp module on Windows with the msvc C++
compiler. The error are fixed by adding explicit casts when calling
operations on atomics and a different syntax is used for compound
literals (the c99 syntax is not supported in msvc in C++ mode).

In additionally some warnings related to emtpy array usage
in structs are suppressed for msvc.

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

* Restructured macros for vendor id cast and casts for atomic operations

To improve readability I've restructured the macros that are used
for vendor id casts on msvc in c++ mode and macros for type-casting
arguments in operations on atomics (as suggested in the review of
my previous commit)

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

* Moved atomic function suffix to macro

Moved the suffix for (msvc) 64 bit atomic functions to the
DDSRT_ATOMIC_OP64 macro

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
2019-09-09 14:18:13 +02:00
Erik Boasson
9b9a07a8e5 Test delivery under discovery stress
This commit adds a test that checks all data published by (reliable)
volatile writers is delivered to readers that existed at the time of the
writer creation, while continuously creating and deleting these writers
and relying on the writer lingering long enough for the data to be
actually delivered.  It also verifies that the match counts end up at 0.

By also semi-continuously creating and deleting an additional reader in
the subscribing process, all three delivery paths (steady state, proxy
writer deletion or matching in progress, and delivery of data to
out-of-sync readers) are hit, as verified by a coverage test.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +02:00
Erik Boasson
53ebc6a529 Deliver initial samples to all readers
While commit a652ecb78e addressed most of
the issues with a new reader possibly not accepting all samples a proxy
writer published after it matched that reader, it failed to do so
properly for 2nd and later readers.  The cause was, once again,
prematurely considering the reader to be "in sync" with the proxy
writer and not requesting any old samples.

The desire to consider them "in sync" from the very beginning is that it
avoids a lot of network traffic.  With this commit, all new readers are
treated equally, despite the additional traffic that generates.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +02:00
Erik Boasson
8ae5f706d0 Do not update match counts on redundant unmatch
Dropping a match from a data reader generated unregisters and signalled
a SUBSCRIPTION_MATCHED event even when another thread raced it and did
so before.  The consequence is possible undercounting of the number of
matched writers.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +02:00
Erik Boasson
87398bdc98 Generate (hopefully) decent DDSI2.2-compliant GUID
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +02:00
Erik Boasson
a632f80000 Add a global counter in ddsrt_random_init fallback
It currently uses process id and timestamp, but on a low-resolution
clock that might result in two subsequent initialisations in the same
process yielding the same seed, and that wasn't the intent.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +02:00
Erik Boasson
68b85d0a2d Do not cache topic in proxy endpoint (#207)
The only place it was used for more than printing the name (which is
available via the QoS object) was in deserializing the sample, but there
is never a need to deserialize a sample if there is no local reader.  So
instead of caching the topic object in the proxy endpoint, take it from
a reader to which it is to be delivered and avoid having to keep things
in sync.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +02:00
Erik Boasson
bf095a32d4 Parenthesize macro arguments in MPT_ASSERT
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-09-03 12:23:50 +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
Scott K Logan
1c8c2944ff Add a colcon.pkg file to override the CMake package name (#242)
* Add a colcon.pkg file to override the CMake package name

Without this file, colcon will take the project name from the
CMakeLists.txt file, which is `CycloneDDS`. This name does not conform
to the standard practices for a ROS package name, and should be
lowercase (i.e. `cyclonedds`).

This `colcon.pkg` will make colcon detect the package dependencies using
this name.

Signed-off-by: Scott K Logan <logans@cottsay.net>

* Drop unneeded package type

This isn't needed as colcon can detect the package type as `cmake`
without it.

Signed-off-by: Scott K Logan <logans@cottsay.net>
2019-08-30 11:26:33 +02:00
Jeroen Koekkoek
b421e1039f Fix submission to Coverity Scan
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-08-28 07:20:33 +02:00
Erik Boasson
13eb5f1d87 Disabling idlc means no IdlcGenerate
Setting BUILD_IDLC=OFF makes it possible to build Cyclone without
its (Java-based) IDL preprocessor.  In that case there is no
IdlcGenerate.cmake, and therefore the generated CycloneDDSConfig.cmake
must not try to include it either.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-26 14:07:46 +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
Erik Boasson
8964c0b1bc Handle malformed pre-emptive ACKNACK from FastRTPS
The pre-emptive ACKNACK messages from FastRTPS have a base sequence
number of 0, which is malformed and must be rejected according to DDSI
8.3.7.1 / 8.3.5.5.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-26 11:50:26 +02:00
Jeroen Koekkoek
93addbbda0 Fix shadow warnings in CUnit tests
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-08-23 12:37:15 +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
Jeroen Koekkoek
1200bfd109 Set project name via string literal
Some tools (e.g. colcon) require the project name to be a string literal in
order to extract it. Fix proposed by Dirk Thomas.

Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-08-23 12:37:15 +02:00
Erik Boasson
6f33dc0e6d CI tests: log DDSI configuration to stderr
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
f06d3bf9ad FreeRTOS: replace DDS_TRACE+abort by DDS_FATAL
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +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
da05024fe3 Fixup for repository reorg: Solaris 2.6 makefile
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
70a342991f Build no-SSL version on CI as well
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-21 14:16:51 +02:00
Erik Boasson
711026114b Add multi-domain version of topic_data test
This is the same test for verifying set_qos on topic_data is reflected
in the DCPSPublication and DCPSSubscription topics as the one that
already exists, but it uses two threads in two domains.  A barrier is
used to ensure the threads in the two processes indeed execute
concurrently, and different topic data sequences are used to increase
the likelihood of detecting leakage from one domain into the other.

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
103210bf8e Check sequence number of SEDP messages
Historical data can processed after new data, effectively going backward
in time, so only process data that is newer than the current state.

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
7190bb3d3e Pacification of native compiler on OpenIndiana
* constness in ternary expressions
* removal of OS_MAX_INTEGER
* inclusion of dds/ddsrt/attributes.h everywhere DDS_EXPORT inline
  occurs
* _POSIX_PTHREAD_SEMANTICS in ddsperf

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