Commit graph

29 commits

Author SHA1 Message Date
Erik Boasson
0006e09566 Add a dds_readcdr analogous to dds_takecdr
Signed-off-by: Erik Boasson <eb@ilities.com>
2020-05-16 11:38:05 +02:00
Erik Boasson
2da100a3c7 Merge remote-tracking branch 'upstream/master' into security 2020-05-11 15:05:46 +02:00
Erik Boasson
45c0f432a9 Add dds_get_guid to get the GUID of a local entity
This is merely a more convenient way of obtaining it: otherwise one has
subscribe to the correct built-in topic, read the sample corresponding
to the entity's instance handle and get the "key" field.  That's a bit
of a detour to get the network-wide unique identifier.

Signed-off-by: Erik Boasson <eb@ilities.com>
2020-04-09 17:02:11 +02:00
Erik Boasson
b2cf6921da Define dds_guid_t as dds_builtintopic_guid_t
The former name should be less confusing.  Backwards compatibility is
preserved by only adding the sensible name as a typedef.

Signed-off-by: Erik Boasson <eb@ilities.com>
2020-04-09 17:02:11 +02:00
Erik Boasson
d82b7fdd73 Return PRECONDITION_NOT_MET if security not supported
As opposed to NOT_ALLOWED_BY_SECURITY.  There is a meaningful
difference between something being disallowed and something being
impossible.

Co-Authored-By: Kyle Fazzari <github@status.e4ward.com>
Signed-off-by: Erik Boasson <eb@ilities.com>
2020-03-26 08:46:26 +01:00
Erik Boasson
ecbd585f12 Generate header with compile-time features
Currently:

* DDS_HAS_SECURITY for DDS Security support
* DDS_HAS_LIFESPAN for lifespan QoS support
* DDS_HAS_DEADLINE_MISSED for "deadline missed" event support

These are defined to 1 if support for the feature is included in the
build and left undefined if it isn't.

Signed-off-by: Erik Boasson <eb@ilities.com>
2020-03-26 08:46:26 +01:00
Erik Boasson
0845337f47 Test interface dropping incoming/outgoing packets
Signed-off-by: Erik Boasson <eb@ilities.com>
2020-03-05 16:10:46 +01:00
eboasson
e412f6fab2
Fix issue in dds_create_topic_arbitrary (#422)
* Fix issue in dds_create_topic_arbitrary

Changed the behaviour of dds_create_topic_arbitrary with respect to the
sertopic parameter: the existing function dds_create_topic_arbitrary is
marked deprecated and replaced by dds_create_topic_generic, which returns
the sertopic that is actually used in as an out parameter. This can be eiter
the provided sertopic (if this sertopic was not yet known in the domain) or an
existing sertopic if the sertopic was registered earlier.

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

* Fix memory leaks in case topic creation fails.

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
2020-03-05 15:21:02 +01:00
Erik Boasson
ad19f571ae Rename nn_plist, xqos to ddsi_plist, xqos
This already was leaking out in the interface, so this name change was
needed too.  The relationship between plist and xqos being so intimate,
doing the one but not the other made no sense.

Signed-off-by: Erik Boasson <eb@ilities.com>
2020-02-11 23:26:01 +01:00
Erik Boasson
27d7c72626 Relax constraints on topic entities
This commit changes the implementation of topics so that multiple topic
entities can exist in a single participant for the same topic.
Different entities may refer to different topic implementations
(sertopics, akin to a type support in the DDS specification).  All
entities (for the same participant) always have the same QoS, via the
new "ktopic" table in the participant.

Readers and writers are bound to a topic entity and inherit its
properties.  If a topic comes in two definitions, say one for C and one
for C++, one can have a single participant with a reader delivering the
data in C representation and another reader delivering it in C++
representation.

This changes the behaviour of create_topic and find_topic: these now (on
successful return) always return a new entity (and thus with a unique
handle), where previously these would simply return a existing one when
possible.

This also requires some small additions to the sertopic/serdata
interface.

Signed-off-by: Erik Boasson <eb@ilities.com>
2020-02-11 23:26:01 +01:00
Michel
2d252ad1f6 Description corrections.
Signed-off-by: Michel <michel.vandenhoek@adlinktech.com>
2020-02-10 14:41:31 +01:00
TheFixer
fc8d844519 Add missing documentation for dds_takecdr() (#357)
* Add missing documentation for dds_takecdr()

Signed-off-by: TheFixer <thefixer@iteazz.com>

* Updated documentation for dds_takecdr() and added documentation for dds_writecdr()

Signed-off-by: TheFixer <thefixer@iteazz.com>
2019-12-12 15:11:05 +02: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
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
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
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
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
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
TheFixer
1f5083aa44 #213 - Allow readconditions and queryconditions as valid entities for… (#214)
Allow readconditions and queryconditions as valid entities for dds_instance_get_key

Signed-off-by: TheFixer <thefixer@iteazz.com>
2019-07-16 13:09:06 +02:00
Erik Boasson
647f7466d6 Address locking order for entity locks
There were inconsistencies in the order in which entity locks were taken
when multiple entities needed to be locked at the same time.  In most
cases, the order was first locking entity X, then locking the parent
entity of X.  However, in some cases the order was reversed, a likely
cause of deadlocks.

This commit sorts these problems, and in particular propagating
operations into children.  The entity refcount is now part of the handle
administration so that it is no longer necessary to lock an entity to
determine whether it is still allowed to be used (previously it had to
check the CLOSED flag afterward).  This allows recursing into the
children while holding handles and the underlying objects alive, but
without violating lock order.

Attendant changes that would warrant there own commits but are too hard
to split off:

* Children are now no longer in a singly linked list, but in an AVL
  tree; this was necessary at some intermediate stage to allow unlocking
  an entity and restarting iteration over all children at the "next"
  child (all thanks to the eternally unique instance handle);

* Waitsets shifted to using arrays of attached entities instead of
  linked lists; this was a consequence of dealing with some locking
  issues in reading triggers and considering which operations on the
  "triggered" and "observed" sets are actually needed.

* Entity status flags and waitset/condition trigger counts are now
  handled using atomic operations.  Entities are now classified as
  having a "status" with a corresponding mask, or as having a "trigger
  count" (conditions).  As there are fewer than 16 status bits, the
  status and its mask can squeeze into the same 32-bits as the trigger
  count.  These atomic updates avoid the need for a separate lock just
  for the trigger/status values and results in a significant speedup
  with waitsets.

* Create topic now has a more rational behaviour when multiple
  participants attempt to create the same topic: each participant now
  gets its own topic definition, but the underlying type representation
  is shared.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
8ae81db490 Add get_matched_{publication,subscription}_...
The implementation is provisional (too inefficient), but it works.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-10 10:45:53 +02:00
Erik Boasson
13480616e0 Consistent code formatting for the core code
Code formatting was quite a mess (different indentation, completely
different ideas on where opening braces should go, spacing in various
places, early out versus single return or goto-based error handling,
&c.).  This commit cleans it up.

A few doxygen comment fixes allowed turning on Clang's warnings for
doxygen comments, so those are no enabled by default as least on
Xcode-based builds.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-10 10:42:52 +02:00
Erik Boasson
19aec98b8a Clean up return code types
* Remove dds_return_t / dds_retcode_t distinction (now there is only
  dds_return_t and all error codes are always negative)

* Remove Q_ERR_... error codes and replace them by DDS_RETCODE_...
  ones so that there is only one set of error codes

* Replace a whole bunch "int" return types that were used to return
  Q_ERR_... codes by "dds_return_t" return types

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-10 10:42:52 +02:00
Erik Boasson
3067a69c92 validate and normalize received CDR data
The CDR deserializer failed to check it was staying within the bounds of
the received data, and it turns out it also was inconsistent in its
interpretation of the (undocumented) serializer instructions.  This
commit adds some information on the instruction format obtained by
reverse engineering the code and studying the output of the IDL
preprocessor, and furthermore changes a lot of the types used in the
(de)serializer code to have some more compiler support.  The IDL
preprocessor is untouched and the generated instructinos do exactly the
same thing (except where change was needed).

The bulk of this commit replaces the implementation of the
(de)serializer.  It is still rather ugly, but at least the very long
functions with several levels of nested conditions and switch statements
have been split out into multiple functions.  Most of these have single
call-sites, so the compiler hopefully inlines them nicely.

The other important thing is that it adds a "normalize" function that
validates the structure of the CDR and performs byteswapping if
necessary.  This means the deserializer can now assume a well-formed
input in native byte-order.  Checks and conditional byteswaps have been
removed accordingly.

It changes some types to make a compile-time distinction between
read-only, native-endianness input, a native-endianness output, and a
big-endian output for dealing with key hashes.  This should reduce the
risk of accidentally mixing endianness or modifying an input stream.

The preprocessor has been modified to indicate the presence of unions in
a topic type in the descriptor flags.  If a union is present, any
memory allocated in a sample is freed first and the sample is zero'd out
prior to deserializing the new value.  This is to prevent reading
garbage pointers for strings and sequences when switching union cases.

The test tool has been included in the commit but it does not get run by
itself.  Firstly, it requires the presence of OpenSplice DDS as an
alternative implementation to check the CDR processing against.
Secondly, it takes quite a while to run and is of no interest unless one
changes something in the (de)serialization.

Finally, I have no idea why there was a "CDR stream" interface among the
public functions.  The existing interfaces are fundamentally broken by
the removal of arbitrary-endianness streams, and the interfaces were
already incapable of proper error notification.  So, they have been
removed.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-05-24 07:48:45 +02:00
Erik Boasson
2afb578a0a remove name arg from dds_create_topic_arbitrary
The name parameter and the name in the sertopic parameter had to match
because it used the one as a key in a lookup checking whether the topic
exists already, and the other as key for the nodes in that index.  As
the name is (currently) included in the sertopic, it shouldn't be passed
in separately as well.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-05-05 20:46:50 +08:00
Erik Boasson
e965df5db7 add participant instance handle to builtin topics
Extend the endpoint built-in topic data with the participant instance
handle (the GUID was already present).  Having the instance handle
available makes it trivial to look up the participant, whereas a lookup
of the GUID is rather impractical.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-04-24 14:09:30 +02:00
Erik Boasson
9b3a71e1ab lift limits on handle allocation and reuse (#95)
The old entity handle mechanism suffered from a number of problems, the
most terrible one being that it would only ever allocate 1000 handles
(not even have at most 1000 in use at the same time).  Secondarily, it
was protected by a single mutex that actually does show up as a limiting
factor in, say, a polling-based throughput test with small messages.
Thirdly, it tried to provide for various use cases that don't exist in
practice but add complexity and overhead.

This commit totally rewrites the mechanism, by replacing the old array
with a hash table and allowing a near-arbitrary number of handles as
well as reuse of handles.  It also removes the entity "kind" bits in the
most significant bits of the handles, because they only resulted in
incorrect checking of argument validity.  All that is taken out, but
there is still more cleaning up to be done.  It furthermore removes an
indirection in the handle-to-entity lookup by embedding the
"dds_handle_link" structure in the entity.

Handle allocation is randomized to avoid the have a high probability of
quickly finding an available handle (the total number of handles is
limited to a number much smaller than the domain from which they are
allocated).  The likelihood of handle reuse is still dependent on the
number of allocated handles -- the fewer handles there are, the longer
the expected time to reuse.  Non-randomized handles would give a few
guarantees more, though.

It moreover moves the code from the "util" to the "core/ddsc" component,
because it really is only used for entities, and besides the new
implementation relies on the deferred freeing (a.k.a. garbage collection
mechanism) implemented in the core.

The actual handle management has two variants, selectable with a macro:
the preferred embodiment uses a concurrent hash table, the actually used
one performs all operations inside a single mutex and uses a
non-concurrent version of the hash table.  The reason the
less-predeferred embodiment is used is that the concurrent version
requires the freeing of entity objects to be deferred (much like the
GUID-to-entity hash tables in DDSI function, or indeed the key value to
instance handle mapping).  That is a fair bit of work, and the
non-concurrent version is a reasonable intermediate step.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-04-21 16:05:06 +02:00
Jeroen Koekkoek
cd6742ee12 Rearrange and fixup abstraction layer
- Replace os_result by dds_retcode_t and move DDS return code defines down.
  Eliminates the need to convert between different return code types.

- Move dds_time_t down and remove os_time.
  Eliminates the need to convert between different time representations and
  reduces code duplication.

- Remove use of Microsoft source-code annotation language (SAL).
  SAL annotations are Microsoft specific and not very well documented. This
  makes it very difficult for contributers to write.

- Rearrange the abstraction layer to be feature-based. The previous layout
  falsely assumed that the operating system dictates which implementation is
  best suited. For general purpose operating systems this is mostly true, but
  embedded targets require a slightly different approach and may not even offer
  all features. The new layout makes it possible to mix-and-match feature
  implementations and allows for features to not be implemented at all.

- Replace the os prefix by ddsrt to avoid name collisions.

- Remove various portions of unused and unwanted code.

- Export thread names on all supported platforms.

- Return native thread identifier on POSIX compatible platforms.

- Add timed wait for condition variables that takes an absolute time.

- Remove system abstraction for errno. The os_getErrno and os_setErrno were
  incorrect. Functions that might fail now simply return a DDS return code
  instead.

- Remove thread-specific memory abstraction. os_threadMemGet and accompanying
  functions were a mess and their use has been eliminated by other changes in
  this commit.

- Replace attribute (re)defines by ddsrt_ prefixed equivalents to avoid name
  collisions and problems with faulty __nonnull__ attributes.

Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-03-22 15:19:09 +01:00