Merge pull request #424 from eboasson/master-to-security

Update security branch to current master
This commit is contained in:
eboasson 2020-03-19 17:50:01 +01:00 committed by GitHub
commit ab5f51eada
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
110 changed files with 2714 additions and 4540 deletions

View file

@ -170,26 +170,26 @@ if(${CMAKE_GENERATOR} STREQUAL "Xcode")
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_PROTOTYPES YES) set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_PROTOTYPES YES)
endif() endif()
# Make it easy to enable one of Clang's/gcc's analyzers, and default to using
# the address sanitizer for ordinary debug builds; gcc is giving some grief on # Make it easy to enable Clang's/gcc's analyzers
# Travis, so don't enable it for gcc by default set(USE_SANITIZER "" CACHE STRING "Sanitizers to enable on the build.")
if(NOT USE_SANITIZER) if(NOT("${USE_SANITIZER}" STREQUAL ""))
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND foreach(san "${USE_SANITIZER}")
NOT ("${CMAKE_GENERATOR}" STREQUAL "Xcode") AND message(STATUS "Enabling sanitizer: '${san}'")
("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang"
OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")) if("${san}" STREQUAL address)
message(STATUS "Enabling address sanitizer; set USE_SANITIZER=none to prevent this") add_compile_options(-fno-omit-frame-pointer)
set(USE_SANITIZER address) link_libraries(-fno-omit-frame-pointer)
else() endif()
set(USE_SANITIZER none)
endif() if(NOT("${san}" STREQUAL "none"))
endif() add_compile_options("-fsanitize=${san}")
if(NOT ("${USE_SANITIZER}" STREQUAL "none")) link_libraries("-fsanitize=${san}")
message(STATUS "Sanitizer set to ${USE_SANITIZER}") endif()
add_compile_options(-fno-omit-frame-pointer -fsanitize=${USE_SANITIZER}) endforeach()
link_libraries(-fno-omit-frame-pointer -fsanitize=${USE_SANITIZER})
endif() endif()
include(GNUInstallDirs) include(GNUInstallDirs)
include(AnalyzeBuild) include(AnalyzeBuild)
if(APPLE) if(APPLE)

1926
cdds.md

File diff suppressed because it is too large Load diff

View file

@ -475,7 +475,7 @@ sub conv_table {
$fqname1 = "$fqname/$fs->{name}"; $fqname1 = "$fqname/$fs->{name}";
$elems++; $elems++;
} }
my $prefix1 = ($fs->{table} eq "unsupp_cfgelems") ? "<b>Internal</b>" : $prefix; my $prefix1 = ($fs->{table} eq "internal_cfgelems") ? "<b>Internal</b>" : $prefix;
&$convsub ($fh, $fs, $fs->{name}, $fqname1, $indent, $prefix1, $closure); &$convsub ($fh, $fs, $fs->{name}, $fqname1, $indent, $prefix1, $closure);
} }
} }

View file

@ -2002,7 +2002,7 @@ threads exist:
* dq.CHAN: delivery thread for channel CHAN; * dq.CHAN: delivery thread for channel CHAN;
* tev.CHAN: timed-even thread for channel CHAN. * tev.CHAN: timed-event thread for channel CHAN.
##### //CycloneDDS/Domain/Threads/Thread/Scheduling ##### //CycloneDDS/Domain/Threads/Thread/Scheduling

View file

@ -1619,7 +1619,7 @@ handshake;</li>
<li><i>dq.CHAN</i>: delivery thread for channel CHAN;</li> <li><i>dq.CHAN</i>: delivery thread for channel CHAN;</li>
<li><i>tev.CHAN</i>: timed-even thread for channel CHAN.</li></ul>""" ] ] <li><i>tev.CHAN</i>: timed-event thread for channel CHAN.</li></ul>""" ] ]
attribute Name { attribute Name {
text text
} }

View file

@ -2150,7 +2150,7 @@ handshake;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;dq.CHAN&lt;/i&gt;: delivery thread for channel CHAN;&lt;/li&gt; &lt;li&gt;&lt;i&gt;dq.CHAN&lt;/i&gt;: delivery thread for channel CHAN;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;tev.CHAN&lt;/i&gt;: timed-even thread for channel CHAN.&lt;/li&gt;&lt;/ul&gt;</xs:documentation> &lt;li&gt;&lt;i&gt;tev.CHAN&lt;/i&gt;: timed-event thread for channel CHAN.&lt;/li&gt;&lt;/ul&gt;</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
</xs:complexType> </xs:complexType>

View file

@ -28,7 +28,7 @@ int main (int argc, char ** argv)
/* Create a Writer. */ /* Create a Writer. */
writer = dds_create_writer (participant, topic, NULL, NULL); writer = dds_create_writer (participant, topic, NULL, NULL);
if (writer < 0) if (writer < 0)
DDS_FATAL("dds_create_write: %s\n", dds_strretcode(-writer)); DDS_FATAL("dds_create_writer: %s\n", dds_strretcode(-writer));
printf("=== [Publisher] Waiting for a reader to be discovered ...\n"); printf("=== [Publisher] Waiting for a reader to be discovered ...\n");
fflush (stdout); fflush (stdout);

View file

@ -325,7 +325,7 @@ static dds_entity_t prepare_dds(dds_entity_t *reader, const char *partitionName)
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL); participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
if (participant < 0) if (participant < 0)
DDS_FATAL("dds_create_particpant: %s\n", dds_strretcode(-participant)); DDS_FATAL("dds_create_participant: %s\n", dds_strretcode(-participant));
/* A Topic is created for our sample type on the domain participant. */ /* A Topic is created for our sample type on the domain participant. */

View file

@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3"> <package format="3">
<name>cyclonedds</name> <name>cyclonedds</name>
<version>0.1.0</version> <version>0.5.1</version>
<description>Eclipse Cyclone DDS is a very performant and robust open-source DDS implementation. Cyclone DDS is developed completely in the open as an Eclipse IoT project.</description> <description>Eclipse Cyclone DDS is a very performant and robust open-source DDS implementation. Cyclone DDS is developed completely in the open as an Eclipse IoT project.</description>
<maintainer email="cyclonedds-dev@eclipse.org">Eclipse Foundation, Inc.</maintainer> <maintainer email="cyclonedds-dev@eclipse.org">Eclipse Foundation, Inc.</maintainer>
<license>Eclipse Public License 2.0</license> <license>Eclipse Public License 2.0</license>

View file

@ -998,25 +998,29 @@ dds_create_topic(
const dds_qos_t *qos, const dds_qos_t *qos,
const dds_listener_t *listener); const dds_listener_t *listener);
#define DDS_HAS_CREATE_TOPIC_GENERIC 1
/** /**
* @brief Creates a new topic with arbitrary type handling. * @brief Creates a new topic with provided type handling.
* *
* The type name for the topic is taken from the provided "sertopic" object. Topic * The type name for the topic is taken from the provided "sertopic" object. Topic
* matching is done on a combination of topic name and type name. Each successful * matching is done on a combination of topic name and type name. Each successful
* call to dds_create_topic creates a new topic entity sharing the same QoS * call to dds_create_topic creates a new topic entity sharing the same QoS
* settings with all other topics of the same name. * settings with all other topics of the same name.
* *
* If sertopic is not yet known in the domain, it is added and its refcount * In case this function returns a valid handle, the ownership of the provided
* incremented; if an equivalent sertopic object is already known, then the known * sertopic is handed over to Cyclone. On return, the caller gets in the sertopic parameter a
* one is used instead. * pointer to the sertopic that is actually used by the topic. This can be the provided sertopic
* (if this sertopic was not yet known in the domain), or a sertopic thas was
* already known in the domain.
* *
* @param[in] participant Participant on which to create the topic. * @param[in] participant Participant on which to create the topic.
* @param[in] sertopic Internal description of the topic type (includes name). * @param[in,out] sertopic Internal description of the topic type (includes name). On return, the sertopic parameter is set to the actual sertopic that is used by the topic.
* @param[in] qos QoS to set on the new topic (can be NULL). * @param[in] qos QoS to set on the new topic (can be NULL).
* @param[in] listener Any listener functions associated with the new topic (can be NULL). * @param[in] listener Any listener functions associated with the new topic (can be NULL).
* @param[in] sedp_plist Topic description to be published as part of discovery (if NULL, not published). * @param[in] sedp_plist Topic description to be published as part of discovery (if NULL, not published).
* *
* @returns A valid, unique topic handle or an error code. * @returns A valid, unique topic handle or an error code. Iff a valid handle, the domain takes ownership of provided serdata.
* *
* @retval >=0 * @retval >=0
* A valid unique topic handle. * A valid unique topic handle.
@ -1031,6 +1035,14 @@ dds_create_topic(
* topic's type name. * topic's type name.
*/ */
DDS_EXPORT dds_entity_t DDS_EXPORT dds_entity_t
dds_create_topic_generic (
dds_entity_t participant,
struct ddsi_sertopic **sertopic,
const dds_qos_t *qos,
const dds_listener_t *listener,
const struct ddsi_plist *sedp_plist);
DDS_DEPRECATED_EXPORT dds_entity_t
dds_create_topic_arbitrary ( dds_create_topic_arbitrary (
dds_entity_t participant, dds_entity_t participant,
struct ddsi_sertopic *sertopic, struct ddsi_sertopic *sertopic,
@ -3358,6 +3370,40 @@ DDS_EXPORT dds_return_t
dds_assert_liveliness ( dds_assert_liveliness (
dds_entity_t entity); dds_entity_t entity);
/**
* @brief This operation allows making the domain's network stack
* temporarily deaf and/or mute. It is a support function for testing and,
* other special uses and is subject to change.
*
* @param[in] entity A domain entity or an entity bound to a domain, such
* as a participant, reader or writer.
* @param[in] deaf Whether to network stack should pretend to be deaf and
* ignore any incoming packets.
* @param[in] mute Whether to network stack should pretend to be mute and
* discard any outgoing packets where it normally would.
* pass them to the operating system kernel for transmission.
* @param[in] reset_after Any value less than INFINITY will cause it to
* set deaf = mute = false after reset_after ns have passed.
* This is done by an event scheduled for the appropriate
* time and otherwise forgotten. These events are not
* affected by subsequent calls to this function.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* The operation was successful.
* @retval DDS_BAD_PARAMETER
* The entity parameter is not a valid parameter.
* @retval DDS_RETCODE_ILLEGAL_OPERATION
* The operation is invoked on an inappropriate object.
*/
DDS_EXPORT dds_return_t
dds_domain_set_deafmute (
dds_entity_t entity,
bool deaf,
bool mute,
dds_duration_t reset_after);
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif

View file

@ -32,7 +32,7 @@ void dds__builtin_init (struct dds_domain *dom);
void dds__builtin_fini (struct dds_domain *dom); void dds__builtin_fini (struct dds_domain *dom);
struct entity_common; struct entity_common;
struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, nn_wctime_t timestamp, bool alive); struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, ddsrt_wctime_t timestamp, bool alive);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -25,30 +25,29 @@ extern "C" {
QP_DESTINATION_ORDER | QP_HISTORY | QP_RESOURCE_LIMITS) QP_DESTINATION_ORDER | QP_HISTORY | QP_RESOURCE_LIMITS)
#define DDS_PARTICIPANT_QOS_MASK \ #define DDS_PARTICIPANT_QOS_MASK \
(QP_USER_DATA | QP_PRISMTECH_ENTITY_FACTORY | \ (QP_USER_DATA | QP_ADLINK_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST)
QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST)
#define DDS_PUBLISHER_QOS_MASK \ #define DDS_PUBLISHER_QOS_MASK \
(QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | \ (QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | \
QP_PRISMTECH_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL) QP_ADLINK_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL)
#define DDS_READER_QOS_MASK \ #define DDS_READER_QOS_MASK \
(QP_USER_DATA | QP_DURABILITY | QP_DEADLINE | QP_LATENCY_BUDGET | \ (QP_USER_DATA | QP_DURABILITY | QP_DEADLINE | QP_LATENCY_BUDGET | \
QP_OWNERSHIP | QP_LIVELINESS | QP_TIME_BASED_FILTER | \ QP_OWNERSHIP | QP_LIVELINESS | QP_TIME_BASED_FILTER | \
QP_RELIABILITY | QP_DESTINATION_ORDER | QP_HISTORY | \ QP_RELIABILITY | QP_DESTINATION_ORDER | QP_HISTORY | \
QP_RESOURCE_LIMITS | QP_PRISMTECH_READER_DATA_LIFECYCLE | \ QP_RESOURCE_LIMITS | QP_ADLINK_READER_DATA_LIFECYCLE | \
QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST) QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST)
#define DDS_SUBSCRIBER_QOS_MASK \ #define DDS_SUBSCRIBER_QOS_MASK \
(QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | \ (QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | \
QP_PRISMTECH_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL) QP_ADLINK_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL)
#define DDS_WRITER_QOS_MASK \ #define DDS_WRITER_QOS_MASK \
(QP_USER_DATA | QP_DURABILITY | QP_DURABILITY_SERVICE | QP_DEADLINE | \ (QP_USER_DATA | QP_DURABILITY | QP_DURABILITY_SERVICE | QP_DEADLINE | \
QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_OWNERSHIP_STRENGTH | \ QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_OWNERSHIP_STRENGTH | \
QP_LIVELINESS | QP_RELIABILITY | QP_TRANSPORT_PRIORITY | \ QP_LIVELINESS | QP_RELIABILITY | QP_TRANSPORT_PRIORITY | \
QP_LIFESPAN | QP_DESTINATION_ORDER | QP_HISTORY | \ QP_LIFESPAN | QP_DESTINATION_ORDER | QP_HISTORY | \
QP_RESOURCE_LIMITS | QP_PRISMTECH_WRITER_DATA_LIFECYCLE | \ QP_RESOURCE_LIMITS | QP_ADLINK_WRITER_DATA_LIFECYCLE | \
QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST) QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST)
#if defined (__cplusplus) #if defined (__cplusplus)

View file

@ -26,10 +26,10 @@ struct rhc_sample;
DDS_EXPORT struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_domaingv *gv, const struct ddsi_sertopic *topic, bool xchecks); DDS_EXPORT struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_domaingv *gv, const struct ddsi_sertopic *topic, bool xchecks);
DDS_EXPORT struct dds_rhc *dds_rhc_default_new (struct dds_reader *reader, const struct ddsi_sertopic *topic); DDS_EXPORT struct dds_rhc *dds_rhc_default_new (struct dds_reader *reader, const struct ddsi_sertopic *topic);
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
DDS_EXPORT nn_mtime_t dds_rhc_default_sample_expired_cb(void *hc, nn_mtime_t tnow); DDS_EXPORT ddsrt_mtime_t dds_rhc_default_sample_expired_cb(void *hc, ddsrt_mtime_t tnow);
#endif #endif
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
DDS_EXPORT nn_mtime_t dds_rhc_default_deadline_missed_cb(void *hc, nn_mtime_t tnow); DDS_EXPORT ddsrt_mtime_t dds_rhc_default_deadline_missed_cb(void *hc, ddsrt_mtime_t tnow);
#endif #endif
#if defined (__cplusplus) #if defined (__cplusplus)

View file

@ -39,7 +39,7 @@ DDS_EXPORT void dds_topic_set_filter_with_ctx
DDS_EXPORT dds_topic_intern_filter_fn dds_topic_get_filter_with_ctx DDS_EXPORT dds_topic_intern_filter_fn dds_topic_get_filter_with_ctx
(dds_entity_t topic); (dds_entity_t topic);
DDS_EXPORT dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertopic *sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist); DDS_EXPORT dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertopic **sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -77,7 +77,12 @@ dds_entity_t dds__get_builtin_topic (dds_entity_t entity, dds_entity_t topic)
} }
dds_qos_t *qos = dds__create_builtin_qos (); dds_qos_t *qos = dds__create_builtin_qos ();
tp = dds_create_topic_impl (par->m_entity.m_hdllink.hdl, sertopic, qos, NULL, NULL); if ((tp = dds_create_topic_impl (par->m_entity.m_hdllink.hdl, &sertopic, qos, NULL, NULL)) > 0)
{
/* keep ownership for built-in sertopics because there are re-used, lifetime for these
sertopics is bound to domain */
ddsi_sertopic_ref (sertopic);
}
dds_delete_qos (qos); dds_delete_qos (qos);
dds_entity_unpin (e); dds_entity_unpin (e);
return tp; return tp;
@ -185,7 +190,7 @@ static struct ddsi_tkmap_instance *dds__builtin_get_tkmap_entry (const struct dd
return tk; return tk;
} }
struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, nn_wctime_t timestamp, bool alive) struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, ddsrt_wctime_t timestamp, bool alive)
{ {
/* initialize to avoid gcc warning ultimately caused by C's horrible type system */ /* initialize to avoid gcc warning ultimately caused by C's horrible type system */
struct dds_domain *dom = e->gv->builtin_topic_interface->arg; struct dds_domain *dom = e->gv->builtin_topic_interface->arg;
@ -215,7 +220,7 @@ struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, nn
return serdata; return serdata;
} }
static void dds__builtin_write (const struct entity_common *e, nn_wctime_t timestamp, bool alive, void *vdomain) static void dds__builtin_write (const struct entity_common *e, ddsrt_wctime_t timestamp, bool alive, void *vdomain)
{ {
struct dds_domain *dom = vdomain; struct dds_domain *dom = vdomain;
if (dds__builtin_is_visible (&e->guid, get_entity_vendorid (e), dom)) if (dds__builtin_is_visible (&e->guid, get_entity_vendorid (e), dom))

View file

@ -59,7 +59,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
domain->m_entity.m_domain = domain; domain->m_entity.m_domain = domain;
domain->m_entity.m_iid = ddsi_iid_gen (); domain->m_entity.m_iid = ddsi_iid_gen ();
domain->gv.tstart = now (); domain->gv.tstart = ddsrt_time_wallclock ();
/* | domain_id | domain id in config | result /* | domain_id | domain id in config | result
+-----------+---------------------+---------- +-----------+---------------------+----------
@ -286,6 +286,23 @@ static dds_return_t dds_domain_free (dds_entity *vdomain)
return DDS_RETCODE_NO_DATA; return DDS_RETCODE_NO_DATA;
} }
dds_return_t dds_domain_set_deafmute (dds_entity_t entity, bool deaf, bool mute, dds_duration_t reset_after)
{
struct dds_entity *e;
dds_return_t rc;
if ((rc = dds_entity_pin (entity, &e)) < 0)
return rc;
if (e->m_domain == NULL)
rc = DDS_RETCODE_ILLEGAL_OPERATION;
else
{
ddsi_set_deafmute (&e->m_domain->gv, deaf, mute, reset_after);
rc = DDS_RETCODE_OK;
}
dds_entity_unpin (e);
return rc;
}
#include "dds__entity.h" #include "dds__entity.h"
static void pushdown_set_batch (struct dds_entity *e, bool enable) static void pushdown_set_batch (struct dds_entity *e, bool enable)
{ {

View file

@ -677,8 +677,9 @@ dds_return_t dds_get_qos (dds_entity_t entity, dds_qos_t *qos)
return ret; return ret;
} }
static dds_return_t dds_set_qos_locked_raw (dds_entity *e, dds_qos_t **e_qos_ptr, bool e_enabled, const dds_qos_t *qos, uint64_t mask, const struct ddsrt_log_cfg *logcfg, dds_return_t (*set_qos) (struct dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all) static dds_return_t dds_set_qos_locked_raw (dds_entity *e, dds_qos_t **e_qos_ptr, const dds_qos_t *qos, uint64_t mask, const struct ddsrt_log_cfg *logcfg)
{ {
const bool enabled = ((e->m_flags & DDS_ENTITY_ENABLED) != 0);
dds_return_t ret; dds_return_t ret;
/* Any attempt to do this on a topic ends up doing it on the ktopic instead, so that there is /* Any attempt to do this on a topic ends up doing it on the ktopic instead, so that there is
@ -692,7 +693,7 @@ static dds_return_t dds_set_qos_locked_raw (dds_entity *e, dds_qos_t **e_qos_ptr
/* invalid or inconsistent QoS settings */ /* invalid or inconsistent QoS settings */
goto error_or_nochange; goto error_or_nochange;
} }
else if (!e_enabled) else if (!enabled)
{ {
/* do as you please while the entity is not enabled */ /* do as you please while the entity is not enabled */
} }
@ -728,7 +729,7 @@ static dds_return_t dds_set_qos_locked_raw (dds_entity *e, dds_qos_t **e_qos_ptr
} }
assert (ret == DDS_RETCODE_OK); assert (ret == DDS_RETCODE_OK);
if ((ret = set_qos (e, newqos, e_enabled)) != DDS_RETCODE_OK) if ((ret = dds_entity_deriver_set_qos (e, newqos, enabled)) != DDS_RETCODE_OK)
goto error_or_nochange; goto error_or_nochange;
else else
{ {
@ -748,7 +749,7 @@ static dds_return_t dds_set_qos_locked_impl (dds_entity *e, const dds_qos_t *qos
dds_entity_kind_t kind = dds_entity_kind (e); dds_entity_kind_t kind = dds_entity_kind (e);
if (kind != DDS_KIND_TOPIC) if (kind != DDS_KIND_TOPIC)
{ {
return dds_set_qos_locked_raw (e, &e->m_qos, (e->m_flags & DDS_ENTITY_ENABLED) != 0, qos, mask, logcfg, dds_entity_deriver_table[kind]->set_qos); return dds_set_qos_locked_raw (e, &e->m_qos, qos, mask, logcfg);
} }
else else
{ {
@ -767,9 +768,7 @@ static dds_return_t dds_set_qos_locked_impl (dds_entity *e, const dds_qos_t *qos
while (ktp->defer_set_qos != 0) while (ktp->defer_set_qos != 0)
ddsrt_cond_wait (&pp->m_entity.m_cond, &pp->m_entity.m_mutex); ddsrt_cond_wait (&pp->m_entity.m_cond, &pp->m_entity.m_mutex);
/* dds_entity_deriver_table[kind]->set_qos had better avoid looking at the entity! */ rc = dds_set_qos_locked_raw (e, &ktp->qos, qos, mask, logcfg);
rc = dds_set_qos_locked_raw (NULL, &ktp->qos, (e->m_flags & DDS_ENTITY_ENABLED) != 0, qos, mask, logcfg, dds_entity_deriver_table[kind]->set_qos);
ddsrt_mutex_unlock (&pp->m_entity.m_mutex); ddsrt_mutex_unlock (&pp->m_entity.m_mutex);
return rc; return rc;
} }

View file

@ -302,7 +302,7 @@ void dds_qset_writer_data_lifecycle (dds_qos_t * __restrict qos, bool autodispos
if (qos == NULL) if (qos == NULL)
return; return;
qos->writer_data_lifecycle.autodispose_unregistered_instances = autodispose; qos->writer_data_lifecycle.autodispose_unregistered_instances = autodispose;
qos->present |= QP_PRISMTECH_WRITER_DATA_LIFECYCLE; qos->present |= QP_ADLINK_WRITER_DATA_LIFECYCLE;
} }
void dds_qset_reader_data_lifecycle (dds_qos_t * __restrict qos, dds_duration_t autopurge_nowriter_samples_delay, dds_duration_t autopurge_disposed_samples_delay) void dds_qset_reader_data_lifecycle (dds_qos_t * __restrict qos, dds_duration_t autopurge_nowriter_samples_delay, dds_duration_t autopurge_disposed_samples_delay)
@ -311,7 +311,7 @@ void dds_qset_reader_data_lifecycle (dds_qos_t * __restrict qos, dds_duration_t
return; return;
qos->reader_data_lifecycle.autopurge_nowriter_samples_delay = autopurge_nowriter_samples_delay; qos->reader_data_lifecycle.autopurge_nowriter_samples_delay = autopurge_nowriter_samples_delay;
qos->reader_data_lifecycle.autopurge_disposed_samples_delay = autopurge_disposed_samples_delay; qos->reader_data_lifecycle.autopurge_disposed_samples_delay = autopurge_disposed_samples_delay;
qos->present |= QP_PRISMTECH_READER_DATA_LIFECYCLE; qos->present |= QP_ADLINK_READER_DATA_LIFECYCLE;
} }
void dds_qset_durability_service (dds_qos_t * __restrict qos, dds_duration_t service_cleanup_delay, dds_history_kind_t history_kind, int32_t history_depth, int32_t max_samples, int32_t max_instances, int32_t max_samples_per_instance) void dds_qset_durability_service (dds_qos_t * __restrict qos, dds_duration_t service_cleanup_delay, dds_history_kind_t history_kind, int32_t history_depth, int32_t max_samples, int32_t max_instances, int32_t max_samples_per_instance)
@ -626,7 +626,7 @@ bool dds_qget_destination_order (const dds_qos_t * __restrict qos, dds_destinati
bool dds_qget_writer_data_lifecycle (const dds_qos_t * __restrict qos, bool *autodispose) bool dds_qget_writer_data_lifecycle (const dds_qos_t * __restrict qos, bool *autodispose)
{ {
if (qos == NULL || !(qos->present & QP_PRISMTECH_WRITER_DATA_LIFECYCLE)) if (qos == NULL || !(qos->present & QP_ADLINK_WRITER_DATA_LIFECYCLE))
return false; return false;
if (autodispose) if (autodispose)
*autodispose = qos->writer_data_lifecycle.autodispose_unregistered_instances; *autodispose = qos->writer_data_lifecycle.autodispose_unregistered_instances;
@ -635,7 +635,7 @@ bool dds_qget_writer_data_lifecycle (const dds_qos_t * __restrict qos, bool *aut
bool dds_qget_reader_data_lifecycle (const dds_qos_t * __restrict qos, dds_duration_t *autopurge_nowriter_samples_delay, dds_duration_t *autopurge_disposed_samples_delay) bool dds_qget_reader_data_lifecycle (const dds_qos_t * __restrict qos, dds_duration_t *autopurge_nowriter_samples_delay, dds_duration_t *autopurge_disposed_samples_delay)
{ {
if (qos == NULL || !(qos->present & QP_PRISMTECH_READER_DATA_LIFECYCLE)) if (qos == NULL || !(qos->present & QP_ADLINK_READER_DATA_LIFECYCLE))
return false; return false;
if (autopurge_nowriter_samples_delay) if (autopurge_nowriter_samples_delay)
*autopurge_nowriter_samples_delay = qos->reader_data_lifecycle.autopurge_nowriter_samples_delay; *autopurge_nowriter_samples_delay = qos->reader_data_lifecycle.autopurge_nowriter_samples_delay;

View file

@ -274,7 +274,7 @@ struct rhc_instance {
uint32_t no_writers_gen; /* __/ */ uint32_t no_writers_gen; /* __/ */
int32_t strength; /* "current" ownership strength */ int32_t strength; /* "current" ownership strength */
ddsi_guid_t wr_guid; /* guid of last writer (if wr_iid != 0 then wr_guid is the corresponding guid, else undef) */ ddsi_guid_t wr_guid; /* guid of last writer (if wr_iid != 0 then wr_guid is the corresponding guid, else undef) */
nn_wctime_t tstamp; /* source time stamp of last update */ ddsrt_wctime_t tstamp; /* source time stamp of last update */
struct ddsrt_circlist_elem nonempty_list; /* links non-empty instances in arbitrary ordering */ struct ddsrt_circlist_elem nonempty_list; /* links non-empty instances in arbitrary ordering */
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
struct deadline_elem deadline; /* element in deadline missed administration */ struct deadline_elem deadline; /* element in deadline missed administration */
@ -594,11 +594,11 @@ static void drop_expired_samples (struct dds_rhc_default *rhc, struct rhc_sample
TRACE (")\n"); TRACE (")\n");
} }
nn_mtime_t dds_rhc_default_sample_expired_cb(void *hc, nn_mtime_t tnow) ddsrt_mtime_t dds_rhc_default_sample_expired_cb(void *hc, ddsrt_mtime_t tnow)
{ {
struct dds_rhc_default *rhc = hc; struct dds_rhc_default *rhc = hc;
struct rhc_sample *sample; struct rhc_sample *sample;
nn_mtime_t tnext; ddsrt_mtime_t tnext;
ddsrt_mutex_lock (&rhc->lock); ddsrt_mutex_lock (&rhc->lock);
while ((tnext = lifespan_next_expired_locked (&rhc->lifespan, tnow, (void **)&sample)).v == 0) while ((tnext = lifespan_next_expired_locked (&rhc->lifespan, tnow, (void **)&sample)).v == 0)
drop_expired_samples (rhc, sample); drop_expired_samples (rhc, sample);
@ -608,11 +608,11 @@ nn_mtime_t dds_rhc_default_sample_expired_cb(void *hc, nn_mtime_t tnow)
#endif /* DDSI_INCLUDE_LIFESPAN */ #endif /* DDSI_INCLUDE_LIFESPAN */
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
nn_mtime_t dds_rhc_default_deadline_missed_cb(void *hc, nn_mtime_t tnow) ddsrt_mtime_t dds_rhc_default_deadline_missed_cb(void *hc, ddsrt_mtime_t tnow)
{ {
struct dds_rhc_default *rhc = hc; struct dds_rhc_default *rhc = hc;
void *vinst; void *vinst;
nn_mtime_t tnext; ddsrt_mtime_t tnext;
ddsrt_mutex_lock (&rhc->lock); ddsrt_mutex_lock (&rhc->lock);
while ((tnext = deadline_next_missed_locked (&rhc->deadline, tnow, &vinst)).v == 0) while ((tnext = deadline_next_missed_locked (&rhc->deadline, tnow, &vinst)).v == 0)
{ {
@ -630,7 +630,7 @@ nn_mtime_t dds_rhc_default_deadline_missed_cb(void *hc, nn_mtime_t tnow)
dds_reader_status_cb (&rhc->reader->m_entity, &cb_data); dds_reader_status_cb (&rhc->reader->m_entity, &cb_data);
ddsrt_mutex_lock (&rhc->lock); ddsrt_mutex_lock (&rhc->lock);
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
} }
ddsrt_mutex_unlock (&rhc->lock); ddsrt_mutex_unlock (&rhc->lock);
return tnext; return tnext;
@ -837,7 +837,7 @@ static void free_instance_rhc_free_wrap (void *vnode, void *varg)
static void dds_rhc_default_free (struct dds_rhc_default *rhc) static void dds_rhc_default_free (struct dds_rhc_default *rhc)
{ {
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
dds_rhc_default_sample_expired_cb (rhc, NN_MTIME_NEVER); dds_rhc_default_sample_expired_cb (rhc, DDSRT_MTIME_NEVER);
lifespan_fini (&rhc->lifespan); lifespan_fini (&rhc->lifespan);
#endif #endif
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
@ -1067,7 +1067,7 @@ static int inst_accepts_sample (const struct dds_rhc_default *rhc, const struct
return 1; return 1;
} }
static void update_inst (struct rhc_instance *inst, const struct ddsi_writer_info * __restrict wrinfo, bool wr_iid_valid, nn_wctime_t tstamp) static void update_inst (struct rhc_instance *inst, const struct ddsi_writer_info * __restrict wrinfo, bool wr_iid_valid, ddsrt_wctime_t tstamp)
{ {
inst->tstamp = tstamp; inst->tstamp = tstamp;
inst->wr_iid_islive = wr_iid_valid; inst->wr_iid_islive = wr_iid_valid;
@ -1264,7 +1264,7 @@ static int rhc_unregister_isreg_w_sideeffects (struct dds_rhc_default *rhc, cons
} }
} }
static int rhc_unregister_updateinst (struct dds_rhc_default *rhc, struct rhc_instance *inst, const struct ddsi_writer_info * __restrict wrinfo, nn_wctime_t tstamp, struct trigger_info_qcond *trig_qc, bool *nda) static int rhc_unregister_updateinst (struct dds_rhc_default *rhc, struct rhc_instance *inst, const struct ddsi_writer_info * __restrict wrinfo, ddsrt_wctime_t tstamp, struct trigger_info_qcond *trig_qc, bool *nda)
{ {
assert (inst->wrcount > 0); assert (inst->wrcount > 0);
@ -1327,7 +1327,7 @@ static int rhc_unregister_updateinst (struct dds_rhc_default *rhc, struct rhc_in
} }
} }
static bool dds_rhc_unregister (struct dds_rhc_default *rhc, struct rhc_instance *inst, const struct ddsi_writer_info * __restrict wrinfo, nn_wctime_t tstamp, struct trigger_info_post *post, struct trigger_info_qcond *trig_qc) static bool dds_rhc_unregister (struct dds_rhc_default *rhc, struct rhc_instance *inst, const struct ddsi_writer_info * __restrict wrinfo, ddsrt_wctime_t tstamp, struct trigger_info_post *post, struct trigger_info_qcond *trig_qc)
{ {
bool notify_data_available = false; bool notify_data_available = false;
@ -1384,7 +1384,7 @@ static struct rhc_instance *alloc_new_instance (struct dds_rhc_default *rhc, con
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
if (!inst->isdisposed) if (!inst->isdisposed)
deadline_register_instance_locked (&rhc->deadline, &inst->deadline, now_mt ()); deadline_register_instance_locked (&rhc->deadline, &inst->deadline, ddsrt_time_monotonic ());
#endif #endif
return inst; return inst;
@ -1598,7 +1598,7 @@ static bool dds_rhc_default_store (struct dds_rhc_default * __restrict rhc, cons
inst->disposed_gen++; inst->disposed_gen++;
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
if (!is_dispose) if (!is_dispose)
deadline_register_instance_locked (&rhc->deadline, &inst->deadline, now_mt ()); deadline_register_instance_locked (&rhc->deadline, &inst->deadline, ddsrt_time_monotonic ());
#endif #endif
} }
if (is_dispose) if (is_dispose)
@ -1639,7 +1639,7 @@ static bool dds_rhc_default_store (struct dds_rhc_default * __restrict rhc, cons
{ {
inst->isdisposed = 0; inst->isdisposed = 0;
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
deadline_register_instance_locked (&rhc->deadline, &inst->deadline, now_mt ()); deadline_register_instance_locked (&rhc->deadline, &inst->deadline, ddsrt_time_monotonic ());
#endif #endif
} }
goto error_or_nochange; goto error_or_nochange;

View file

@ -171,10 +171,8 @@ static dds_return_t dds_topic_qos_set (dds_entity *e, const dds_qos_t *qos, bool
{ {
/* We never actually set the qos of a struct dds_topic and really shouldn't be here, /* We never actually set the qos of a struct dds_topic and really shouldn't be here,
but the code to check whether set_qos is supported uses the entity's qos_set but the code to check whether set_qos is supported uses the entity's qos_set
function as a proxy. One of the weird things about the topic's set_qos is that function as a proxy. */
this is called with e == NULL. */
(void) e; (void) qos; (void) enabled; (void) e; (void) qos; (void) enabled;
assert (e == NULL);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
@ -279,7 +277,7 @@ static dds_entity_t create_topic_pp_locked (struct dds_participant *pp, struct d
return hdl; return hdl;
} }
dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertopic *sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist) dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertopic **sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
{ {
dds_return_t rc; dds_return_t rc;
dds_participant *pp; dds_participant *pp;
@ -287,7 +285,7 @@ dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertop
dds_entity_t hdl; dds_entity_t hdl;
struct ddsi_sertopic *sertopic_registered; struct ddsi_sertopic *sertopic_registered;
if (sertopic == NULL) if (sertopic == NULL || *sertopic == NULL)
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
{ {
@ -320,7 +318,7 @@ dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertop
if ((rc = ddsi_xqos_valid (&gv->logconfig, new_qos)) != DDS_RETCODE_OK) if ((rc = ddsi_xqos_valid (&gv->logconfig, new_qos)) != DDS_RETCODE_OK)
goto error; goto error;
if (!q_omg_security_check_create_topic (&pp->m_entity.m_domain->gv, &pp->m_entity.m_guid, sertopic->name, new_qos)) if (!q_omg_security_check_create_topic (&pp->m_entity.m_domain->gv, &pp->m_entity.m_guid, (*sertopic)->name, new_qos))
{ {
rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY; rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
goto error; goto error;
@ -328,14 +326,14 @@ dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertop
/* See if we're allowed to create the topic; ktp is returned pinned & locked /* See if we're allowed to create the topic; ktp is returned pinned & locked
so we can be sure it doesn't disappear and its QoS can't change */ so we can be sure it doesn't disappear and its QoS can't change */
GVTRACE ("dds_create_topic_arbitrary (pp %p "PGUIDFMT" sertopic %p reg?%s refc %"PRIu32" %s/%s)\n", GVTRACE ("dds_create_topic_generic (pp %p "PGUIDFMT" sertopic %p reg?%s refc %"PRIu32" %s/%s)\n",
(void *) pp, PGUID (pp->m_entity.m_guid), (void *) sertopic, sertopic->gv ? "yes" : "no", (void *) pp, PGUID (pp->m_entity.m_guid), (void *) (*sertopic), (*sertopic)->gv ? "yes" : "no",
ddsrt_atomic_ld32 (&sertopic->refc), sertopic->name, sertopic->type_name); ddsrt_atomic_ld32 (&(*sertopic)->refc), (*sertopic)->name, (*sertopic)->type_name);
ddsrt_mutex_lock (&pp->m_entity.m_mutex); ddsrt_mutex_lock (&pp->m_entity.m_mutex);
struct dds_ktopic *ktp; struct dds_ktopic *ktp;
if ((rc = lookup_and_check_ktopic (&ktp, pp, sertopic->name, sertopic->type_name, new_qos)) != DDS_RETCODE_OK) if ((rc = lookup_and_check_ktopic (&ktp, pp, (*sertopic)->name, (*sertopic)->type_name, new_qos)) != DDS_RETCODE_OK)
{ {
GVTRACE ("dds_create_topic_arbitrary: failed after compatibility check: %s\n", dds_strretcode (rc)); GVTRACE ("dds_create_topic_generic: failed after compatibility check: %s\n", dds_strretcode (rc));
ddsrt_mutex_unlock (&pp->m_entity.m_mutex); ddsrt_mutex_unlock (&pp->m_entity.m_mutex);
goto error; goto error;
} }
@ -349,8 +347,8 @@ dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertop
ktp->defer_set_qos = 0; ktp->defer_set_qos = 0;
ktp->qos = new_qos; ktp->qos = new_qos;
/* have to copy these because the ktopic can outlast any specific sertopic */ /* have to copy these because the ktopic can outlast any specific sertopic */
ktp->name = ddsrt_strdup (sertopic->name); ktp->name = ddsrt_strdup ((*sertopic)->name);
ktp->type_name = ddsrt_strdup (sertopic->type_name); ktp->type_name = ddsrt_strdup ((*sertopic)->type_name);
ddsrt_avl_insert (&participant_ktopics_treedef, &pp->m_ktopics, ktp); ddsrt_avl_insert (&participant_ktopics_treedef, &pp->m_ktopics, ktp);
GVTRACE ("create_and_lock_ktopic: ktp %p\n", (void *) ktp); GVTRACE ("create_and_lock_ktopic: ktp %p\n", (void *) ktp);
} }
@ -363,13 +361,13 @@ dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertop
/* Sertopic: re-use a previously registered one if possible, else register this one */ /* Sertopic: re-use a previously registered one if possible, else register this one */
{ {
ddsrt_mutex_lock (&gv->sertopics_lock); ddsrt_mutex_lock (&gv->sertopics_lock);
if ((sertopic_registered = ddsi_sertopic_lookup_locked (gv, sertopic)) != NULL) if ((sertopic_registered = ddsi_sertopic_lookup_locked (gv, *sertopic)) != NULL)
GVTRACE ("dds_create_topic_arbitrary: reuse sertopic %p\n", (void *) sertopic_registered); GVTRACE ("dds_create_topic_generic: reuse sertopic %p\n", (void *) sertopic_registered);
else else
{ {
GVTRACE ("dds_create_topic_arbitrary: register new sertopic %p\n", (void *) sertopic); GVTRACE ("dds_create_topic_generic: register new sertopic %p\n", (void *) (*sertopic));
ddsi_sertopic_register_locked (gv, sertopic); ddsi_sertopic_register_locked (gv, *sertopic);
sertopic_registered = sertopic; sertopic_registered = *sertopic;
} }
ddsrt_mutex_unlock (&gv->sertopics_lock); ddsrt_mutex_unlock (&gv->sertopics_lock);
} }
@ -377,8 +375,10 @@ dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertop
/* Create topic referencing ktopic & sertopic_registered */ /* Create topic referencing ktopic & sertopic_registered */
/* FIXME: setting "implicit" based on sertopic->ops is a hack */ /* FIXME: setting "implicit" based on sertopic->ops is a hack */
hdl = create_topic_pp_locked (pp, ktp, (sertopic_registered->ops == &ddsi_sertopic_ops_builtintopic), sertopic_registered, listener, sedp_plist); hdl = create_topic_pp_locked (pp, ktp, (sertopic_registered->ops == &ddsi_sertopic_ops_builtintopic), sertopic_registered, listener, sedp_plist);
ddsi_sertopic_unref (*sertopic);
*sertopic = sertopic_registered;
dds_participant_unlock (pp); dds_participant_unlock (pp);
GVTRACE ("dds_create_topic_arbitrary: new topic %"PRId32"\n", hdl); GVTRACE ("dds_create_topic_generic: new topic %"PRId32"\n", hdl);
return hdl; return hdl;
error: error:
@ -387,18 +387,32 @@ dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertop
return rc; return rc;
} }
dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_sertopic *sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist) dds_entity_t dds_create_topic_generic (dds_entity_t participant, struct ddsi_sertopic **sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
{ {
assert(sertopic); if (sertopic == NULL || *sertopic == NULL || (*sertopic)->name == NULL)
assert(sertopic->name); return DDS_RETCODE_BAD_PARAMETER;
if (!strncmp(sertopic->name, "DCPS", 4)) if (!strncmp((*sertopic)->name, "DCPS", 4))
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
return dds_create_topic_impl (participant, sertopic, qos, listener, sedp_plist); return dds_create_topic_impl (participant, sertopic, qos, listener, sedp_plist);
} }
dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_sertopic *sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
{
if (sertopic == NULL)
return DDS_RETCODE_BAD_PARAMETER;
dds_entity_t ret;
struct ddsi_sertopic *st = sertopic;
ddsi_sertopic_ref (st);
if ((ret = dds_create_topic_generic (participant, &st, qos, listener, sedp_plist)) < 0)
ddsi_sertopic_unref (st);
return ret;
}
dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descriptor_t *desc, const char *name, const dds_qos_t *qos, const dds_listener_t *listener) dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descriptor_t *desc, const char *name, const dds_qos_t *qos, const dds_listener_t *listener)
{ {
struct ddsi_sertopic_default *st; struct ddsi_sertopic_default *st;
struct ddsi_sertopic *st_tmp;
ddsi_plist_t plist; ddsi_plist_t plist;
dds_entity_t hdl; dds_entity_t hdl;
struct dds_entity *ppent; struct dds_entity *ppent;
@ -439,11 +453,11 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
if (desc->m_meta) if (desc->m_meta)
{ {
plist.type_description = dds_string_dup (desc->m_meta); plist.type_description = dds_string_dup (desc->m_meta);
plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION; plist.present |= PP_ADLINK_TYPE_DESCRIPTION;
} }
if (desc->m_nkeys) if (desc->m_nkeys)
{ {
plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS; plist.qos.present |= QP_ADLINK_SUBSCRIPTION_KEYS;
plist.qos.subscription_keys.use_key_list = 1; plist.qos.subscription_keys.use_key_list = 1;
plist.qos.subscription_keys.key_list.n = desc->m_nkeys; plist.qos.subscription_keys.key_list.n = desc->m_nkeys;
plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*)); plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*));
@ -451,8 +465,10 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
plist.qos.subscription_keys.key_list.strs[index] = dds_string_dup (desc->m_keys[index].m_name); plist.qos.subscription_keys.key_list.strs[index] = dds_string_dup (desc->m_keys[index].m_name);
} }
hdl = dds_create_topic_arbitrary (participant, &st->c, qos, listener, &plist); st_tmp = &st->c;
ddsi_sertopic_unref (&st->c); hdl = dds_create_topic_generic (participant, &st_tmp, qos, listener, &plist);
if (hdl < 0)
ddsi_sertopic_unref (st_tmp);
dds_entity_unpin (ppent); dds_entity_unpin (ppent);
ddsi_plist_fini (&plist); ddsi_plist_fini (&plist);
return hdl; return hdl;

View file

@ -28,7 +28,6 @@
#include "dds/ddsi/q_unused.h" #include "dds/ddsi/q_unused.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_rtps.h" #include "dds/ddsi/q_rtps.h"
#include "dds/ddsi/q_freelist.h" #include "dds/ddsi/q_freelist.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
@ -51,7 +50,7 @@ struct whc_node {
struct ddsi_plist *plist; /* 0 if nothing special */ struct ddsi_plist *plist; /* 0 if nothing special */
unsigned unacked: 1; /* counted in whc::unacked_bytes iff 1 */ unsigned unacked: 1; /* counted in whc::unacked_bytes iff 1 */
unsigned borrowed: 1; /* at most one can borrow it at any time */ unsigned borrowed: 1; /* at most one can borrow it at any time */
nn_mtime_t last_rexmit_ts; ddsrt_mtime_t last_rexmit_ts;
uint32_t rexmit_count; uint32_t rexmit_count;
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
struct lifespan_fhnode lifespan; /* fibheap node for lifespan */ struct lifespan_fhnode lifespan; /* fibheap node for lifespan */
@ -155,7 +154,7 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
static uint32_t whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); static uint32_t whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);
static void whc_default_get_state (const struct whc *whc, struct whc_state *st); static void whc_default_get_state (const struct whc *whc, struct whc_state *st);
static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, ddsrt_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq); static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq);
static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample);
static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample);
@ -377,11 +376,11 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
} }
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
static nn_mtime_t whc_sample_expired_cb(void *hc, nn_mtime_t tnow) static ddsrt_mtime_t whc_sample_expired_cb(void *hc, ddsrt_mtime_t tnow)
{ {
struct whc_impl *whc = hc; struct whc_impl *whc = hc;
void *sample; void *sample;
nn_mtime_t tnext; ddsrt_mtime_t tnext;
ddsrt_mutex_lock (&whc->lock); ddsrt_mutex_lock (&whc->lock);
while ((tnext = lifespan_next_expired_locked (&whc->lifespan, tnow, &sample)).v == 0) while ((tnext = lifespan_next_expired_locked (&whc->lifespan, tnow, &sample)).v == 0)
whc_delete_one (whc, sample); whc_delete_one (whc, sample);
@ -392,11 +391,11 @@ static nn_mtime_t whc_sample_expired_cb(void *hc, nn_mtime_t tnow)
#endif #endif
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
static nn_mtime_t whc_deadline_missed_cb(void *hc, nn_mtime_t tnow) static ddsrt_mtime_t whc_deadline_missed_cb(void *hc, ddsrt_mtime_t tnow)
{ {
struct whc_impl *whc = hc; struct whc_impl *whc = hc;
void *vidxnode; void *vidxnode;
nn_mtime_t tnext; ddsrt_mtime_t tnext;
ddsrt_mutex_lock (&whc->lock); ddsrt_mutex_lock (&whc->lock);
while ((tnext = deadline_next_missed_locked (&whc->deadline, tnow, &vidxnode)).v == 0) while ((tnext = deadline_next_missed_locked (&whc->deadline, tnow, &vidxnode)).v == 0)
{ {
@ -412,7 +411,7 @@ static nn_mtime_t whc_deadline_missed_cb(void *hc, nn_mtime_t tnow)
dds_writer_status_cb (&whc->wrinfo.writer->m_entity, &cb_data); dds_writer_status_cb (&whc->wrinfo.writer->m_entity, &cb_data);
ddsrt_mutex_lock (&whc->lock); ddsrt_mutex_lock (&whc->lock);
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
} }
ddsrt_mutex_unlock (&whc->lock); ddsrt_mutex_unlock (&whc->lock);
return tnext; return tnext;
@ -510,7 +509,7 @@ void whc_default_free (struct whc *whc_generic)
check_whc (whc); check_whc (whc);
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
whc_sample_expired_cb (whc, NN_MTIME_NEVER); whc_sample_expired_cb (whc, DDSRT_MTIME_NEVER);
lifespan_fini (&whc->lifespan); lifespan_fini (&whc->lifespan);
#endif #endif
@ -1156,7 +1155,7 @@ static uint32_t whc_default_remove_acked_messages (struct whc *whc_generic, seqn
return cnt; return cnt;
} }
static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata) static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, ddsrt_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata)
{ {
struct whc_node *newn = NULL; struct whc_node *newn = NULL;
@ -1228,7 +1227,7 @@ static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t ma
return newn; return newn;
} }
static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, ddsrt_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk)
{ {
struct whc_impl * const whc = (struct whc_impl *)whc_generic; struct whc_impl * const whc = (struct whc_impl *)whc_generic;
struct whc_node *newn = NULL; struct whc_node *newn = NULL;
@ -1364,7 +1363,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
if (!ddsrt_hh_add (whc->idx_hash, idxn)) if (!ddsrt_hh_add (whc->idx_hash, idxn))
assert (0); assert (0);
#ifdef DDSI_INCLUDE_DEADLINE_MISSED #ifdef DDSI_INCLUDE_DEADLINE_MISSED
deadline_register_instance_locked (&whc->deadline, &idxn->deadline, now_mt ()); deadline_register_instance_locked (&whc->deadline, &idxn->deadline, ddsrt_time_monotonic ());
#endif #endif
} }
else else

View file

@ -143,7 +143,7 @@ static void bwhc_get_state (const struct whc *whc, struct whc_state *st)
st->unacked_bytes = 0; st->unacked_bytes = 0;
} }
static int bwhc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) static int bwhc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, ddsrt_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk)
{ {
(void)whc; (void)whc;
(void)max_drop_seq; (void)max_drop_seq;

View file

@ -90,7 +90,7 @@ struct local_sourceinfo {
const struct ddsi_sertopic *src_topic; const struct ddsi_sertopic *src_topic;
struct ddsi_serdata *src_payload; struct ddsi_serdata *src_payload;
struct ddsi_tkmap_instance *src_tk; struct ddsi_tkmap_instance *src_tk;
nn_mtime_t timeout; ddsrt_mtime_t timeout;
}; };
static struct ddsi_serdata *local_make_sample (struct ddsi_tkmap_instance **tk, struct ddsi_domaingv *gv, struct ddsi_sertopic const * const topic, void *vsourceinfo) static struct ddsi_serdata *local_make_sample (struct ddsi_tkmap_instance **tk, struct ddsi_domaingv *gv, struct ddsi_sertopic const * const topic, void *vsourceinfo)
@ -136,9 +136,9 @@ static dds_return_t local_on_delivery_failure_fastpath (struct entity_common *so
assert (source_entity->kind == EK_WRITER); assert (source_entity->kind == EK_WRITER);
struct writer *wr = (struct writer *) source_entity; struct writer *wr = (struct writer *) source_entity;
struct local_sourceinfo *si = vsourceinfo; struct local_sourceinfo *si = vsourceinfo;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
if (si->timeout.v == 0) if (si->timeout.v == 0)
si->timeout = add_duration_to_mtime (tnow, wr->xqos->reliability.max_blocking_time); si->timeout = ddsrt_mtime_add_duration (tnow, wr->xqos->reliability.max_blocking_time);
if (tnow.v >= si->timeout.v) if (tnow.v >= si->timeout.v)
return DDS_RETCODE_TIMEOUT; return DDS_RETCODE_TIMEOUT;
else else

View file

@ -292,8 +292,6 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
} }
} }
ddsi_tran_conn_t conn = pub->m_entity.m_domain->gv.data_conn_uc;
if ((rc = dds_topic_pin (topic, &tp)) != DDS_RETCODE_OK) if ((rc = dds_topic_pin (topic, &tp)) != DDS_RETCODE_OK)
goto err_pin_topic; goto err_pin_topic;
assert (tp->m_stopic); assert (tp->m_stopic);
@ -331,6 +329,7 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
} }
/* Create writer */ /* Create writer */
ddsi_tran_conn_t conn = pub->m_entity.m_domain->gv.xmit_conn;
struct dds_writer * const wr = dds_alloc (sizeof (*wr)); struct dds_writer * const wr = dds_alloc (sizeof (*wr));
const dds_entity_t writer = dds_entity_init (&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, false, wqos, listener, DDS_WRITER_STATUS_MASK); const dds_entity_t writer = dds_entity_init (&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, false, wqos, listener, DDS_WRITER_STATUS_MASK);
wr->m_topic = tp; wr->m_topic = tp;

View file

@ -597,7 +597,7 @@ static void test_create_delete_writer_stress(bool remote_reader)
{ {
dds_qset_liveliness(wqos, n % 2 ? DDS_LIVELINESS_AUTOMATIC : DDS_LIVELINESS_MANUAL_BY_PARTICIPANT, DDS_MSECS(n % 3 ? ldur + n : ldur - n) + ((n % 3) == 2 ? 1 : 0)); dds_qset_liveliness(wqos, n % 2 ? DDS_LIVELINESS_AUTOMATIC : DDS_LIVELINESS_MANUAL_BY_PARTICIPANT, DDS_MSECS(n % 3 ? ldur + n : ldur - n) + ((n % 3) == 2 ? 1 : 0));
CU_ASSERT_FATAL((writers[n] = dds_create_writer(g_pub_participant, pub_topic, wqos, NULL)) > 0); CU_ASSERT_FATAL((writers[n] = dds_create_writer(g_pub_participant, pub_topic, wqos, NULL)) > 0);
dds_write(writers[n], &sample); CU_ASSERT_EQUAL_FATAL(dds_write(writers[n], &sample), DDS_RETCODE_OK);
if (n % 3 == 2) if (n % 3 == 2)
dds_delete(writers[n]); dds_delete(writers[n]);
else if (n % 2) else if (n % 2)
@ -717,7 +717,7 @@ static void test_status_counts(bool remote_reader)
CU_ASSERT_EQUAL_FATAL(llstatus.total_count_change, 1); CU_ASSERT_EQUAL_FATAL(llstatus.total_count_change, 1);
/* write sample and re-check status counts */ /* write sample and re-check status counts */
dds_write(writer, &sample); CU_ASSERT_EQUAL_FATAL(dds_write(writer, &sample), DDS_RETCODE_OK);
CU_ASSERT_EQUAL_FATAL(dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(5)), 1); CU_ASSERT_EQUAL_FATAL(dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(5)), 1);
dds_get_liveliness_changed_status(reader, &lcstatus); dds_get_liveliness_changed_status(reader, &lcstatus);

View file

@ -37,6 +37,8 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
ddsi_deliver_locally.c ddsi_deliver_locally.c
ddsi_plist.c ddsi_plist.c
ddsi_cdrstream.c ddsi_cdrstream.c
ddsi_time.c
ddsi_ownip.c
q_addrset.c q_addrset.c
q_bitset_inlines.c q_bitset_inlines.c
q_bswap.c q_bswap.c
@ -49,14 +51,12 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
q_lat_estim.c q_lat_estim.c
q_lease.c q_lease.c
q_misc.c q_misc.c
q_nwif.c
q_pcap.c q_pcap.c
q_qosmatch.c q_qosmatch.c
q_radmin.c q_radmin.c
q_receive.c q_receive.c
q_sockwaitset.c q_sockwaitset.c
q_thread.c q_thread.c
q_time.c
q_transmit.c q_transmit.c
q_inverse_uint32_set.c q_inverse_uint32_set.c
q_whc.c q_whc.c
@ -106,6 +106,8 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
ddsi_plist.h ddsi_plist.h
ddsi_xqos.h ddsi_xqos.h
ddsi_cdrstream.h ddsi_cdrstream.h
ddsi_time.h
ddsi_ownip.h
q_addrset.h q_addrset.h
q_bitset.h q_bitset.h
q_bswap.h q_bswap.h
@ -121,7 +123,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
q_lease.h q_lease.h
q_log.h q_log.h
q_misc.h q_misc.h
q_nwif.h
q_pcap.h q_pcap.h
q_protocol.h q_protocol.h
q_qosmatch.h q_qosmatch.h
@ -130,7 +131,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
q_rtps.h q_rtps.h
q_sockwaitset.h q_sockwaitset.h
q_thread.h q_thread.h
q_time.h
q_transmit.h q_transmit.h
q_inverse_uint32_set.h q_inverse_uint32_set.h
q_unused.h q_unused.h

View file

@ -13,7 +13,6 @@
#define _DDSI_BUILTIN_TOPIC_IF_H_ #define _DDSI_BUILTIN_TOPIC_IF_H_
#include "dds/ddsi/ddsi_vendor.h" #include "dds/ddsi/ddsi_vendor.h"
#include "dds/ddsi/q_time.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -30,7 +29,7 @@ struct ddsi_builtin_topic_interface {
bool (*builtintopic_is_builtintopic) (const struct ddsi_sertopic *topic, void *arg); bool (*builtintopic_is_builtintopic) (const struct ddsi_sertopic *topic, void *arg);
bool (*builtintopic_is_visible) (const struct ddsi_guid *guid, nn_vendorid_t vendorid, void *arg); bool (*builtintopic_is_visible) (const struct ddsi_guid *guid, nn_vendorid_t vendorid, void *arg);
struct ddsi_tkmap_instance * (*builtintopic_get_tkmap_entry) (const struct ddsi_guid *guid, void *arg); struct ddsi_tkmap_instance * (*builtintopic_get_tkmap_entry) (const struct ddsi_guid *guid, void *arg);
void (*builtintopic_write) (const struct entity_common *e, nn_wctime_t timestamp, bool alive, void *arg); void (*builtintopic_write) (const struct entity_common *e, ddsrt_wctime_t timestamp, bool alive, void *arg);
}; };
inline bool builtintopic_is_visible (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid, nn_vendorid_t vendorid) { inline bool builtintopic_is_visible (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid, nn_vendorid_t vendorid) {
@ -42,7 +41,7 @@ inline bool builtintopic_is_builtintopic (const struct ddsi_builtin_topic_interf
inline struct ddsi_tkmap_instance *builtintopic_get_tkmap_entry (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid) { inline struct ddsi_tkmap_instance *builtintopic_get_tkmap_entry (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid) {
return btif ? btif->builtintopic_get_tkmap_entry (guid, btif->arg) : NULL; return btif ? btif->builtintopic_get_tkmap_entry (guid, btif->arg) : NULL;
} }
inline void builtintopic_write (const struct ddsi_builtin_topic_interface *btif, const struct entity_common *e, nn_wctime_t timestamp, bool alive) { inline void builtintopic_write (const struct ddsi_builtin_topic_interface *btif, const struct entity_common *e, ddsrt_wctime_t timestamp, bool alive) {
if (btif) btif->builtintopic_write (e, timestamp, alive, btif->arg); if (btif) btif->builtintopic_write (e, timestamp, alive, btif->arg);
} }

View file

@ -13,7 +13,7 @@
#define DDSI_DEADLINE_H #define DDSI_DEADLINE_H
#include "dds/ddsrt/circlist.h" #include "dds/ddsrt/circlist.h"
#include "dds/ddsi/q_time.h" #include "dds/ddsrt/time.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_xevent.h" #include "dds/ddsi/q_xevent.h"
@ -21,7 +21,7 @@
extern "C" { extern "C" {
#endif #endif
typedef nn_mtime_t (*deadline_missed_cb_t)(void *hc, nn_mtime_t tnow); typedef ddsrt_mtime_t (*deadline_missed_cb_t)(void *hc, ddsrt_mtime_t tnow);
struct deadline_adm { struct deadline_adm {
struct ddsrt_circlist list; /* linked list for deadline missed */ struct ddsrt_circlist list; /* linked list for deadline missed */
@ -34,44 +34,44 @@ struct deadline_adm {
struct deadline_elem { struct deadline_elem {
struct ddsrt_circlist_elem e; struct ddsrt_circlist_elem e;
nn_mtime_t t_deadline; ddsrt_mtime_t t_deadline;
}; };
DDS_EXPORT void deadline_init (const struct ddsi_domaingv *gv, struct deadline_adm *deadline_adm, size_t list_offset, size_t elem_offset, deadline_missed_cb_t deadline_missed_cb); DDS_EXPORT void deadline_init (const struct ddsi_domaingv *gv, struct deadline_adm *deadline_adm, size_t list_offset, size_t elem_offset, deadline_missed_cb_t deadline_missed_cb);
DDS_EXPORT void deadline_stop (const struct deadline_adm *deadline_adm); DDS_EXPORT void deadline_stop (const struct deadline_adm *deadline_adm);
DDS_EXPORT void deadline_clear (struct deadline_adm *deadline_adm); DDS_EXPORT void deadline_clear (struct deadline_adm *deadline_adm);
DDS_EXPORT void deadline_fini (const struct deadline_adm *deadline_adm); DDS_EXPORT void deadline_fini (const struct deadline_adm *deadline_adm);
DDS_EXPORT nn_mtime_t deadline_next_missed_locked (struct deadline_adm *deadline_adm, nn_mtime_t tnow, void **instance); DDS_EXPORT ddsrt_mtime_t deadline_next_missed_locked (struct deadline_adm *deadline_adm, ddsrt_mtime_t tnow, void **instance);
DDS_EXPORT void deadline_register_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem, nn_mtime_t tprev, nn_mtime_t tnow); DDS_EXPORT void deadline_register_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem, ddsrt_mtime_t tprev, ddsrt_mtime_t tnow);
DDS_EXPORT void deadline_unregister_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem); DDS_EXPORT void deadline_unregister_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem);
DDS_EXPORT void deadline_renew_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem); DDS_EXPORT void deadline_renew_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem);
inline void deadline_register_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, nn_mtime_t tnow) inline void deadline_register_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, ddsrt_mtime_t tnow)
{ {
if (deadline_adm->dur != T_NEVER) if (deadline_adm->dur != DDS_INFINITY)
deadline_register_instance_real (deadline_adm, elem, tnow, tnow); deadline_register_instance_real (deadline_adm, elem, tnow, tnow);
} }
inline void deadline_reregister_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, nn_mtime_t tnow) inline void deadline_reregister_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, ddsrt_mtime_t tnow)
{ {
if (deadline_adm->dur != T_NEVER) if (deadline_adm->dur != DDS_INFINITY)
deadline_register_instance_real (deadline_adm, elem, elem->t_deadline, tnow); deadline_register_instance_real (deadline_adm, elem, elem->t_deadline, tnow);
} }
inline void deadline_unregister_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem) inline void deadline_unregister_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem)
{ {
if (deadline_adm->dur != T_NEVER) if (deadline_adm->dur != DDS_INFINITY)
{ {
assert (elem->t_deadline.v != T_NEVER); assert (elem->t_deadline.v != DDS_NEVER);
deadline_unregister_instance_real (deadline_adm, elem); deadline_unregister_instance_real (deadline_adm, elem);
} }
} }
inline void deadline_renew_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem) inline void deadline_renew_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem)
{ {
if (deadline_adm->dur != T_NEVER) if (deadline_adm->dur != DDS_INFINITY)
{ {
assert (elem->t_deadline.v != T_NEVER); assert (elem->t_deadline.v != DDS_NEVER);
deadline_renew_instance_real (deadline_adm, elem); deadline_renew_instance_real (deadline_adm, elem);
} }
} }

View file

@ -21,8 +21,8 @@
#include "dds/ddsrt/fibheap.h" #include "dds/ddsrt/fibheap.h"
#include "dds/ddsi/ddsi_plist.h" #include "dds/ddsi/ddsi_plist.h"
#include "dds/ddsi/ddsi_ownip.h"
#include "dds/ddsi/q_protocol.h" #include "dds/ddsi/q_protocol.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsi/q_sockwaitset.h" #include "dds/ddsi/q_sockwaitset.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
@ -118,18 +118,40 @@ struct ddsi_domaingv {
DCPS participant of DDSI2 itself will be mirrored in a DDSI DCPS participant of DDSI2 itself will be mirrored in a DDSI
participant, and in multi-socket mode that one gets its own participant, and in multi-socket mode that one gets its own
socket. */ socket. */
struct ddsi_tran_conn * disc_conn_mc; struct ddsi_tran_conn * disc_conn_mc;
struct ddsi_tran_conn * data_conn_mc; struct ddsi_tran_conn * data_conn_mc;
struct ddsi_tran_conn * disc_conn_uc; struct ddsi_tran_conn * disc_conn_uc;
struct ddsi_tran_conn * data_conn_uc; struct ddsi_tran_conn * data_conn_uc;
/* TCP listener */ /* Connection used for all output (for connectionless transports), this
used to simply be data_conn_uc, but:
- Windows has a quirk that makes multicast delivery within a machine
utterly unreliable if the transmitting socket is bound to 0.0.0.0
(despite all sockets having multicast interfaces set correctly),
but apparently only in the presence of sockets transmitting to the
same multicast group that have been bound to non-0.0.0.0 ...
- At least Fast-RTPS and Connext fail to honour the set of advertised
addresses and substitute 127.0.0.1 for the advertised IP address and
expect it to work.
- Fast-RTPS (at least) binds the socket it uses for transmitting
multicasts to non-0.0.0.0
So binding to 0.0.0.0 means the unicasts from Fast-RTPS & Connext will
arrive but the multicasts from Cyclone get dropped often on Windows
when trying to interoperate; and binding to the IP address means
unicast messages from the others fail to arrive (because they fail to
arrive).
The only work around is to use a separate socket for sending. It is
rather sad that Cyclone needs to work around the bugs of the others,
but it seems the only way to get the users what they expect. */
struct ddsi_tran_conn * xmit_conn;
/* TCP listener */
struct ddsi_tran_listener * listener; struct ddsi_tran_listener * listener;
/* Thread pool */ /* Thread pool */
struct ddsrt_thread_pool_s * thread_pool; struct ddsrt_thread_pool_s * thread_pool;
/* In many sockets mode, the receive threads maintain a local array /* In many sockets mode, the receive threads maintain a local array
@ -221,7 +243,7 @@ struct ddsi_domaingv {
/* Start time of the DDSI2 service, for logging relative time stamps, /* Start time of the DDSI2 service, for logging relative time stamps,
should I ever so desire. */ should I ever so desire. */
nn_wctime_t tstart; ddsrt_wctime_t tstart;
/* Default QoSs for participant, readers and writers (needed for /* Default QoSs for participant, readers and writers (needed for
eliminating default values in outgoing discovery packets, and for eliminating default values in outgoing discovery packets, and for
@ -258,10 +280,6 @@ struct ddsi_domaingv {
delivery queue; currently just SEDP and PMD */ delivery queue; currently just SEDP and PMD */
struct nn_dqueue *builtins_dqueue; struct nn_dqueue *builtins_dqueue;
/* Connection used by general timed-event queue for transmitting data */
struct ddsi_tran_conn * tev_conn;
struct debug_monitor *debmon; struct debug_monitor *debmon;
#ifndef DDSI_INCLUDE_NETWORK_CHANNELS #ifndef DDSI_INCLUDE_NETWORK_CHANNELS

View file

@ -13,14 +13,14 @@
#define DDSI_LIFESPAN_H #define DDSI_LIFESPAN_H
#include "dds/ddsrt/fibheap.h" #include "dds/ddsrt/fibheap.h"
#include "dds/ddsi/q_time.h" #include "dds/ddsrt/time.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
typedef nn_mtime_t (*sample_expired_cb_t)(void *hc, nn_mtime_t tnow); typedef ddsrt_mtime_t (*sample_expired_cb_t)(void *hc, ddsrt_mtime_t tnow);
struct lifespan_adm { struct lifespan_adm {
ddsrt_fibheap_t ls_exp_heap; /* heap for sample expiration (lifespan) */ ddsrt_fibheap_t ls_exp_heap; /* heap for sample expiration (lifespan) */
@ -32,24 +32,24 @@ struct lifespan_adm {
struct lifespan_fhnode { struct lifespan_fhnode {
ddsrt_fibheap_node_t heapnode; ddsrt_fibheap_node_t heapnode;
nn_mtime_t t_expire; ddsrt_mtime_t t_expire;
}; };
DDS_EXPORT void lifespan_init (const struct ddsi_domaingv *gv, struct lifespan_adm *lifespan_adm, size_t fh_offset, size_t fh_node_offset, sample_expired_cb_t sample_expired_cb); DDS_EXPORT void lifespan_init (const struct ddsi_domaingv *gv, struct lifespan_adm *lifespan_adm, size_t fh_offset, size_t fh_node_offset, sample_expired_cb_t sample_expired_cb);
DDS_EXPORT void lifespan_fini (const struct lifespan_adm *lifespan_adm); DDS_EXPORT void lifespan_fini (const struct lifespan_adm *lifespan_adm);
DDS_EXPORT nn_mtime_t lifespan_next_expired_locked (const struct lifespan_adm *lifespan_adm, nn_mtime_t tnow, void **sample); DDS_EXPORT ddsrt_mtime_t lifespan_next_expired_locked (const struct lifespan_adm *lifespan_adm, ddsrt_mtime_t tnow, void **sample);
DDS_EXPORT void lifespan_register_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node); DDS_EXPORT void lifespan_register_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node);
DDS_EXPORT void lifespan_unregister_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node); DDS_EXPORT void lifespan_unregister_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node);
inline void lifespan_register_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node) inline void lifespan_register_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node)
{ {
if (node->t_expire.v != T_NEVER) if (node->t_expire.v != DDS_NEVER)
lifespan_register_sample_real (lifespan_adm, node); lifespan_register_sample_real (lifespan_adm, node);
} }
inline void lifespan_unregister_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node) inline void lifespan_unregister_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node)
{ {
if (node->t_expire.v != T_NEVER) if (node->t_expire.v != DDS_NEVER)
lifespan_unregister_sample_real (lifespan_adm, node); lifespan_unregister_sample_real (lifespan_adm, node);
} }

View file

@ -9,8 +9,8 @@
* *
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/ */
#ifndef Q_NWIF_H #ifndef DDSI_OWNIP_H
#define Q_NWIF_H #define DDSI_OWNIP_H
#include <stdbool.h> #include <stdbool.h>
@ -35,12 +35,10 @@ struct nn_interface {
char *name; char *name;
}; };
int make_socket (ddsrt_socket_t *socket, uint16_t port, bool stream, bool reuse, const struct ddsi_domaingv *gv);
int find_own_ip (struct ddsi_domaingv *gv, const char *requested_address); int find_own_ip (struct ddsi_domaingv *gv, const char *requested_address);
uint32_t locator_to_hopefully_unique_uint32 (const nn_locator_t *src);
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* Q_NWIF_H */ #endif /* DDSI_OWNIP_H */

View file

@ -46,8 +46,8 @@ extern "C" {
#define PP_STATUSINFO ((uint64_t)1 << 22) #define PP_STATUSINFO ((uint64_t)1 << 22)
#define PP_ORIGINAL_WRITER_INFO ((uint64_t)1 << 23) #define PP_ORIGINAL_WRITER_INFO ((uint64_t)1 << 23)
#define PP_ENDPOINT_GUID ((uint64_t)1 << 24) #define PP_ENDPOINT_GUID ((uint64_t)1 << 24)
#define PP_PRISMTECH_PARTICIPANT_VERSION_INFO ((uint64_t)1 << 26) #define PP_ADLINK_PARTICIPANT_VERSION_INFO ((uint64_t)1 << 26)
#define PP_PRISMTECH_TYPE_DESCRIPTION ((uint64_t)1 << 27) #define PP_ADLINK_TYPE_DESCRIPTION ((uint64_t)1 << 27)
#define PP_COHERENT_SET ((uint64_t)1 << 28) #define PP_COHERENT_SET ((uint64_t)1 << 28)
#ifdef DDSI_INCLUDE_SSM #ifdef DDSI_INCLUDE_SSM
#define PP_READER_FAVOURS_SSM ((uint64_t)1 << 29) #define PP_READER_FAVOURS_SSM ((uint64_t)1 << 29)
@ -66,15 +66,15 @@ extern "C" {
PID_UNRECOGNIZED_INCOMPATIBLE_FLAG set (see DDSI 2.1 9.6.2.2.1) */ PID_UNRECOGNIZED_INCOMPATIBLE_FLAG set (see DDSI 2.1 9.6.2.2.1) */
#define PP_INCOMPATIBLE ((uint64_t)1 << 63) #define PP_INCOMPATIBLE ((uint64_t)1 << 63)
#define NN_PRISMTECH_PARTICIPANT_VERSION_INFO_FIXED_CDRSIZE (24) #define NN_ADLINK_PARTICIPANT_VERSION_INFO_FIXED_CDRSIZE (24)
#define NN_PRISMTECH_FL_KERNEL_SEQUENCE_NUMBER (1u << 0) #define NN_ADLINK_FL_KERNEL_SEQUENCE_NUMBER (1u << 0)
#define NN_PRISMTECH_FL_DISCOVERY_INCLUDES_GID (1u << 1) #define NN_ADLINK_FL_DISCOVERY_INCLUDES_GID (1u << 1)
#define NN_PRISMTECH_FL_PTBES_FIXED_0 (1u << 2) #define NN_ADLINK_FL_PTBES_FIXED_0 (1u << 2)
#define NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG (1u << 3) #define NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG (1u << 3)
#define NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2 (1u << 4) #define NN_ADLINK_FL_PARTICIPANT_IS_DDSI2 (1u << 4)
#define NN_PRISMTECH_FL_MINIMAL_BES_MODE (1u << 5) #define NN_ADLINK_FL_MINIMAL_BES_MODE (1u << 5)
#define NN_PRISMTECH_FL_SUPPORTS_STATUSINFOX (1u << 5) #define NN_ADLINK_FL_SUPPORTS_STATUSINFOX (1u << 5)
/* SUPPORTS_STATUSINFOX: when set, also means any combination of /* SUPPORTS_STATUSINFOX: when set, also means any combination of
write/unregister/dispose supported */ write/unregister/dispose supported */
@ -171,19 +171,13 @@ struct nn_security_info;
typedef struct nn_security_info nn_security_info_t; typedef struct nn_security_info nn_security_info_t;
#endif #endif
typedef struct nn_adlink_participant_version_info
typedef struct nn_prismtech_participant_version_info
{ {
uint32_t version; uint32_t version;
uint32_t flags; uint32_t flags;
uint32_t unused[3]; uint32_t unused[3];
char *internals; char *internals;
} nn_prismtech_participant_version_info_t; } nn_adlink_participant_version_info_t;
typedef struct nn_prismtech_eotgroup_tid {
ddsi_entityid_t writer_entityid;
uint32_t transactionId;
} nn_prismtech_eotgroup_tid_t;
typedef struct ddsi_plist { typedef struct ddsi_plist {
uint64_t present; uint64_t present;
@ -217,7 +211,7 @@ typedef struct ddsi_plist {
char *entity_name; char *entity_name;
ddsi_keyhash_t keyhash; ddsi_keyhash_t keyhash;
uint32_t statusinfo; uint32_t statusinfo;
nn_prismtech_participant_version_info_t prismtech_participant_version_info; nn_adlink_participant_version_info_t adlink_participant_version_info;
char *type_description; char *type_description;
nn_sequence_number_t coherent_set_seqno; nn_sequence_number_t coherent_set_seqno;
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY

View file

@ -12,7 +12,7 @@
#ifndef DDSI_PMD_H #ifndef DDSI_PMD_H
#define DDSI_PMD_H #define DDSI_PMD_H
#include "dds/ddsi/q_time.h" #include "dds/ddsrt/time.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -27,7 +27,7 @@ struct receiver_state;
void write_pmd_message_guid (struct ddsi_domaingv * const gv, struct ddsi_guid *pp_guid, unsigned pmd_kind); void write_pmd_message_guid (struct ddsi_domaingv * const gv, struct ddsi_guid *pp_guid, unsigned pmd_kind);
void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, struct participant *pp, unsigned pmd_kind); void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, struct participant *pp, unsigned pmd_kind);
void handle_pmd_message (const struct receiver_state *rst, nn_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len); void handle_pmd_message (const struct receiver_state *rst, ddsrt_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -20,8 +20,8 @@
/* DDS_EXPORT inline i.c.w. __attributes__((visibility...)) and some compilers: */ /* DDS_EXPORT inline i.c.w. __attributes__((visibility...)) and some compilers: */
#include "dds/ddsrt/attributes.h" #include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsi/ddsi_guid.h" #include "dds/ddsi/ddsi_guid.h"
#include "dds/ddsi/q_time.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -40,7 +40,7 @@ struct ddsi_writer_info
int32_t ownership_strength; int32_t ownership_strength;
uint64_t iid; uint64_t iid;
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
nn_mtime_t lifespan_exp; ddsrt_mtime_t lifespan_exp;
#endif #endif
}; };

View file

@ -29,8 +29,8 @@ extern "C" {
#define GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS "dds.sec.datareader_crypto_tokens" #define GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS "dds.sec.datareader_crypto_tokens"
bool write_auth_handshake_message(const struct participant *pp, const struct proxy_participant *proxypp, nn_dataholderseq_t *mdata, bool request, const nn_message_identity_t *related_message_id); bool write_auth_handshake_message(const struct participant *pp, const struct proxy_participant *proxypp, nn_dataholderseq_t *mdata, bool request, const nn_message_identity_t *related_message_id);
void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, size_t len); void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, size_t len);
void handle_crypto_exchange_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len); void handle_crypto_exchange_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len);
void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_t *seq); void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_t *seq);
bool write_crypto_participant_tokens(const struct participant *pp, const struct proxy_participant *proxypp, const nn_dataholderseq_t *tokens); bool write_crypto_participant_tokens(const struct participant *pp, const struct proxy_participant *proxypp, const nn_dataholderseq_t *tokens);
bool write_crypto_writer_tokens(const struct writer *wr, const struct proxy_reader *prd, const nn_dataholderseq_t *tokens); bool write_crypto_writer_tokens(const struct writer *wr, const struct proxy_reader *prd, const nn_dataholderseq_t *tokens);

View file

@ -13,7 +13,6 @@
#define DDSI_SERDATA_H #define DDSI_SERDATA_H
#include "dds/ddsrt/sockets.h" #include "dds/ddsrt/sockets.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/ddsi_sertopic.h" #include "dds/ddsi/ddsi_sertopic.h"
#include "dds/ddsi/ddsi_keyhash.h" #include "dds/ddsi/ddsi_keyhash.h"
@ -37,11 +36,11 @@ struct ddsi_serdata {
const struct ddsi_sertopic *topic; const struct ddsi_sertopic *topic;
/* these get set by generic code after creating the serdata */ /* these get set by generic code after creating the serdata */
nn_wctime_t timestamp; ddsrt_wctime_t timestamp;
uint32_t statusinfo; uint32_t statusinfo;
/* FIXME: can I get rid of this one? */ /* FIXME: can I get rid of this one? */
nn_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ ddsrt_mtime_t twrite; /* write time, not source timestamp, set post-throttling */
}; };
/* Serialised size of sample inclusive of DDSI encoding header /* Serialised size of sample inclusive of DDSI encoding header

View file

@ -0,0 +1,44 @@
/*
* 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
*/
#ifndef DDSI_TIME_H
#define DDSI_TIME_H
#include <stdint.h>
#include "dds/export.h"
#include "dds/ddsrt/time.h"
#if defined (__cplusplus)
extern "C" {
#endif
typedef struct {
int32_t seconds;
uint32_t fraction;
} ddsi_time_t;
#define DDSI_TIME_INFINITE ((ddsi_time_t) { INT32_MAX, UINT32_MAX })
#define DDSI_TIME_INVALID ((ddsi_time_t) { -1, UINT32_MAX })
typedef ddsi_time_t ddsi_duration_t;
bool ddsi_is_valid_timestamp (ddsi_time_t t);
DDS_EXPORT ddsi_time_t ddsi_wctime_to_ddsi_time (ddsrt_wctime_t t);
DDS_EXPORT ddsrt_wctime_t ddsi_wctime_from_ddsi_time (ddsi_time_t x);
DDS_EXPORT ddsi_duration_t ddsi_to_ddsi_duration (dds_duration_t t);
DDS_EXPORT dds_duration_t ddsi_from_ddsi_duration (ddsi_duration_t x);
#if defined (__cplusplus)
}
#endif
#endif /* DDSI_TIME_H */

View file

@ -46,7 +46,7 @@ typedef struct ddsi_tran_base * ddsi_tran_base_t;
typedef struct ddsi_tran_conn * ddsi_tran_conn_t; typedef struct ddsi_tran_conn * ddsi_tran_conn_t;
typedef struct ddsi_tran_listener * ddsi_tran_listener_t; typedef struct ddsi_tran_listener * ddsi_tran_listener_t;
typedef struct ddsi_tran_factory * ddsi_tran_factory_t; typedef struct ddsi_tran_factory * ddsi_tran_factory_t;
typedef struct ddsi_tran_qos * ddsi_tran_qos_t; typedef struct ddsi_tran_qos ddsi_tran_qos_t;
/* Function pointer types */ /* Function pointer types */
@ -60,8 +60,8 @@ typedef void (*ddsi_tran_free_fn_t) (ddsi_tran_factory_t);
typedef void (*ddsi_tran_peer_locator_fn_t) (ddsi_tran_conn_t, nn_locator_t *); typedef void (*ddsi_tran_peer_locator_fn_t) (ddsi_tran_conn_t, nn_locator_t *);
typedef void (*ddsi_tran_disable_multiplexing_fn_t) (ddsi_tran_conn_t); typedef void (*ddsi_tran_disable_multiplexing_fn_t) (ddsi_tran_conn_t);
typedef ddsi_tran_conn_t (*ddsi_tran_accept_fn_t) (ddsi_tran_listener_t); typedef ddsi_tran_conn_t (*ddsi_tran_accept_fn_t) (ddsi_tran_listener_t);
typedef ddsi_tran_conn_t (*ddsi_tran_create_conn_fn_t) (ddsi_tran_factory_t fact, uint32_t, ddsi_tran_qos_t); typedef dds_return_t (*ddsi_tran_create_conn_fn_t) (ddsi_tran_conn_t *conn, ddsi_tran_factory_t fact, uint32_t, const struct ddsi_tran_qos *);
typedef ddsi_tran_listener_t (*ddsi_tran_create_listener_fn_t) (ddsi_tran_factory_t fact, uint32_t port, ddsi_tran_qos_t); typedef dds_return_t (*ddsi_tran_create_listener_fn_t) (ddsi_tran_listener_t *listener, ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *);
typedef void (*ddsi_tran_release_conn_fn_t) (ddsi_tran_conn_t); typedef void (*ddsi_tran_release_conn_fn_t) (ddsi_tran_conn_t);
typedef void (*ddsi_tran_close_conn_fn_t) (ddsi_tran_conn_t); typedef void (*ddsi_tran_close_conn_fn_t) (ddsi_tran_conn_t);
typedef void (*ddsi_tran_unblock_listener_fn_t) (ddsi_tran_listener_t); typedef void (*ddsi_tran_unblock_listener_fn_t) (ddsi_tran_listener_t);
@ -189,11 +189,15 @@ struct ddsi_tran_factory
ddsi_tran_factory_t m_factory; ddsi_tran_factory_t m_factory;
}; };
enum ddsi_tran_qos_purpose {
DDSI_TRAN_QOS_XMIT,
DDSI_TRAN_QOS_RECV_UC,
DDSI_TRAN_QOS_RECV_MC
};
struct ddsi_tran_qos struct ddsi_tran_qos
{ {
/* QoS Data */ enum ddsi_tran_qos_purpose m_purpose;
bool m_multicast;
int m_diffserv; int m_diffserv;
}; };
@ -210,20 +214,20 @@ inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int3
inline int ddsi_is_valid_port (ddsi_tran_factory_t factory, uint32_t port) { inline int ddsi_is_valid_port (ddsi_tran_factory_t factory, uint32_t port) {
return factory->m_is_valid_port_fn (factory, port); return factory->m_is_valid_port_fn (factory, port);
} }
inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos) { inline dds_return_t ddsi_factory_create_conn (ddsi_tran_conn_t *conn, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos) {
*conn = NULL;
if (!ddsi_is_valid_port (factory, port)) if (!ddsi_is_valid_port (factory, port))
return NULL; return DDS_RETCODE_BAD_PARAMETER;
return factory->m_create_conn_fn (factory, port, qos); return factory->m_create_conn_fn (conn, factory, port, qos);
} }
inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos) { inline dds_return_t ddsi_factory_create_listener (ddsi_tran_listener_t *listener, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos) {
*listener = NULL;
if (!ddsi_is_valid_port (factory, port)) if (!ddsi_is_valid_port (factory, port))
return NULL; return DDS_RETCODE_BAD_PARAMETER;
return factory->m_create_listener_fn (factory, port, qos); return factory->m_create_listener_fn (listener, factory, port, qos);
} }
void ddsi_tran_free (ddsi_tran_base_t base); void ddsi_tran_free (ddsi_tran_base_t base);
void ddsi_tran_free_qos (ddsi_tran_qos_t qos);
ddsi_tran_qos_t ddsi_tran_create_qos (void);
inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base) { inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base) {
return base->m_handle_fn (base); return base->m_handle_fn (base);
} }

View file

@ -22,7 +22,7 @@ typedef struct {
/* All existing vendor codes have the major part equal to 1 (and this will probably be true for a long, long time) */ /* All existing vendor codes have the major part equal to 1 (and this will probably be true for a long, long time) */
#define NN_VENDORID_MINOR_RTI 0x01 #define NN_VENDORID_MINOR_RTI 0x01
#define NN_VENDORID_MINOR_PRISMTECH_OSPL 0x02 #define NN_VENDORID_MINOR_ADLINK_OSPL 0x02
#define NN_VENDORID_MINOR_OCI 0x03 #define NN_VENDORID_MINOR_OCI 0x03
#define NN_VENDORID_MINOR_MILSOFT 0x04 #define NN_VENDORID_MINOR_MILSOFT 0x04
#define NN_VENDORID_MINOR_KONGSBERG 0x05 #define NN_VENDORID_MINOR_KONGSBERG 0x05
@ -31,13 +31,13 @@ typedef struct {
#define NN_VENDORID_MINOR_ICOUP 0x08 #define NN_VENDORID_MINOR_ICOUP 0x08
#define NN_VENDORID_MINOR_ETRI 0x09 #define NN_VENDORID_MINOR_ETRI 0x09
#define NN_VENDORID_MINOR_RTI_MICRO 0x0a #define NN_VENDORID_MINOR_RTI_MICRO 0x0a
#define NN_VENDORID_MINOR_PRISMTECH_JAVA 0x0b #define NN_VENDORID_MINOR_ADLINK_JAVA 0x0b
#define NN_VENDORID_MINOR_PRISMTECH_GATEWAY 0x0c #define NN_VENDORID_MINOR_ADLINK_GATEWAY 0x0c
#define NN_VENDORID_MINOR_PRISMTECH_LITE 0x0d #define NN_VENDORID_MINOR_ADLINK_LITE 0x0d
#define NN_VENDORID_MINOR_TECHNICOLOR 0x0e #define NN_VENDORID_MINOR_TECHNICOLOR 0x0e
#define NN_VENDORID_MINOR_EPROSIMA 0x0f #define NN_VENDORID_MINOR_EPROSIMA 0x0f
#define NN_VENDORID_MINOR_ECLIPSE 0x10 #define NN_VENDORID_MINOR_ECLIPSE 0x10
#define NN_VENDORID_MINOR_PRISMTECH_CLOUD 0x20 #define NN_VENDORID_MINOR_ADLINK_CLOUD 0x20
#if defined(_WIN32) && defined(__cplusplus) #if defined(_WIN32) && defined(__cplusplus)
#define NN_VENDORID(vendor) {{ 0x01, NN_VENDORID_MINOR_##vendor }} #define NN_VENDORID(vendor) {{ 0x01, NN_VENDORID_MINOR_##vendor }}
@ -63,7 +63,7 @@ inline bool vendor_is_rti (nn_vendorid_t vendor) {
return vendor_equals (vendor, NN_VENDORID (RTI)); return vendor_equals (vendor, NN_VENDORID (RTI));
} }
inline bool vendor_is_opensplice (nn_vendorid_t vendor) { inline bool vendor_is_opensplice (nn_vendorid_t vendor) {
return vendor_equals (vendor, NN_VENDORID (PRISMTECH_OSPL)); return vendor_equals (vendor, NN_VENDORID (ADLINK_OSPL));
} }
inline bool vendor_is_twinoaks (nn_vendorid_t vendor) { inline bool vendor_is_twinoaks (nn_vendorid_t vendor) {
return vendor_equals (vendor, NN_VENDORID (TWINOAKS)); return vendor_equals (vendor, NN_VENDORID (TWINOAKS));
@ -72,20 +72,20 @@ inline bool vendor_is_eprosima (nn_vendorid_t vendor) {
return vendor_equals (vendor, NN_VENDORID (EPROSIMA)); return vendor_equals (vendor, NN_VENDORID (EPROSIMA));
} }
inline bool vendor_is_cloud (nn_vendorid_t vendor) { inline bool vendor_is_cloud (nn_vendorid_t vendor) {
return vendor_equals (vendor, NN_VENDORID (PRISMTECH_CLOUD)); return vendor_equals (vendor, NN_VENDORID (ADLINK_CLOUD));
} }
inline bool vendor_is_eclipse_or_opensplice (nn_vendorid_t vendor) { inline bool vendor_is_eclipse_or_opensplice (nn_vendorid_t vendor) {
return vendor_is_eclipse (vendor) | vendor_is_opensplice (vendor); return vendor_is_eclipse (vendor) | vendor_is_opensplice (vendor);
} }
inline bool vendor_is_prismtech (nn_vendorid_t vendor) { inline bool vendor_is_adlink (nn_vendorid_t vendor) {
return (vendor_equals (vendor, NN_VENDORID (PRISMTECH_OSPL)) || return (vendor_equals (vendor, NN_VENDORID (ADLINK_OSPL)) ||
vendor_equals (vendor, NN_VENDORID (PRISMTECH_LITE)) || vendor_equals (vendor, NN_VENDORID (ADLINK_LITE)) ||
vendor_equals (vendor, NN_VENDORID (PRISMTECH_GATEWAY)) || vendor_equals (vendor, NN_VENDORID (ADLINK_GATEWAY)) ||
vendor_equals (vendor, NN_VENDORID (PRISMTECH_JAVA)) || vendor_equals (vendor, NN_VENDORID (ADLINK_JAVA)) ||
vendor_equals (vendor, NN_VENDORID (PRISMTECH_CLOUD))); vendor_equals (vendor, NN_VENDORID (ADLINK_CLOUD)));
} }
inline bool vendor_is_eclipse_or_prismtech (nn_vendorid_t vendor) { inline bool vendor_is_eclipse_or_adlink (nn_vendorid_t vendor) {
return vendor_is_eclipse (vendor) || vendor_is_prismtech (vendor); return vendor_is_eclipse (vendor) || vendor_is_adlink (vendor);
} }
#if defined (__cplusplus) #if defined (__cplusplus)

View file

@ -241,11 +241,11 @@ typedef struct dds_ignorelocal_qospolicy {
#define QP_OWNERSHIP ((uint64_t)1 << 18) #define QP_OWNERSHIP ((uint64_t)1 << 18)
#define QP_OWNERSHIP_STRENGTH ((uint64_t)1 << 19) #define QP_OWNERSHIP_STRENGTH ((uint64_t)1 << 19)
#define QP_TIME_BASED_FILTER ((uint64_t)1 << 20) #define QP_TIME_BASED_FILTER ((uint64_t)1 << 20)
#define QP_PRISMTECH_WRITER_DATA_LIFECYCLE ((uint64_t)1 << 21) #define QP_ADLINK_WRITER_DATA_LIFECYCLE ((uint64_t)1 << 21)
#define QP_PRISMTECH_READER_DATA_LIFECYCLE ((uint64_t)1 << 22) #define QP_ADLINK_READER_DATA_LIFECYCLE ((uint64_t)1 << 22)
#define QP_PRISMTECH_READER_LIFESPAN ((uint64_t)1 << 24) #define QP_ADLINK_READER_LIFESPAN ((uint64_t)1 << 24)
#define QP_PRISMTECH_SUBSCRIPTION_KEYS ((uint64_t)1 << 25) #define QP_ADLINK_SUBSCRIPTION_KEYS ((uint64_t)1 << 25)
#define QP_PRISMTECH_ENTITY_FACTORY ((uint64_t)1 << 27) #define QP_ADLINK_ENTITY_FACTORY ((uint64_t)1 << 27)
#define QP_CYCLONE_IGNORELOCAL ((uint64_t)1 << 30) #define QP_CYCLONE_IGNORELOCAL ((uint64_t)1 << 30)
#define QP_PROPERTY_LIST ((uint64_t)1 << 31) #define QP_PROPERTY_LIST ((uint64_t)1 << 31)
@ -254,7 +254,7 @@ typedef struct dds_ignorelocal_qospolicy {
matches. Same for topic and type. Relaxed qos matching is a bit of matches. Same for topic and type. Relaxed qos matching is a bit of
a weird one, but it affects matching, so ... */ a weird one, but it affects matching, so ... */
#define QP_RXO_MASK (QP_DURABILITY | QP_PRESENTATION | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_LIVELINESS | QP_RELIABILITY | QP_DESTINATION_ORDER) #define QP_RXO_MASK (QP_DURABILITY | QP_PRESENTATION | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_LIVELINESS | QP_RELIABILITY | QP_DESTINATION_ORDER)
#define QP_CHANGEABLE_MASK (QP_USER_DATA | QP_TOPIC_DATA | QP_GROUP_DATA | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP_STRENGTH | QP_TIME_BASED_FILTER | QP_PARTITION | QP_TRANSPORT_PRIORITY | QP_LIFESPAN | QP_PRISMTECH_ENTITY_FACTORY | QP_PRISMTECH_WRITER_DATA_LIFECYCLE | QP_PRISMTECH_READER_DATA_LIFECYCLE) #define QP_CHANGEABLE_MASK (QP_USER_DATA | QP_TOPIC_DATA | QP_GROUP_DATA | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP_STRENGTH | QP_TIME_BASED_FILTER | QP_PARTITION | QP_TRANSPORT_PRIORITY | QP_LIFESPAN | QP_ADLINK_ENTITY_FACTORY | QP_ADLINK_WRITER_DATA_LIFECYCLE | QP_ADLINK_READER_DATA_LIFECYCLE)
#define QP_UNRECOGNIZED_INCOMPATIBLE_MASK ((uint64_t) 0) #define QP_UNRECOGNIZED_INCOMPATIBLE_MASK ((uint64_t) 0)
/* readers & writers have an extended qos, hence why it is a separate /* readers & writers have an extended qos, hence why it is a separate

View file

@ -133,9 +133,9 @@ struct wr_prd_match {
ddsi_guid_t arbitrary_unacked_reader; ddsi_guid_t arbitrary_unacked_reader;
nn_count_t next_acknack; /* next acceptable acknack sequence number */ nn_count_t next_acknack; /* next acceptable acknack sequence number */
nn_count_t next_nackfrag; /* next acceptable nackfrag sequence number */ nn_count_t next_nackfrag; /* next acceptable nackfrag sequence number */
nn_etime_t t_acknack_accepted; /* (local) time an acknack was last accepted */ ddsrt_etime_t t_acknack_accepted; /* (local) time an acknack was last accepted */
struct nn_lat_estim hb_to_ack_latency; struct nn_lat_estim hb_to_ack_latency;
nn_wctime_t hb_to_ack_latency_tlastlog; ddsrt_wctime_t hb_to_ack_latency_tlastlog;
uint32_t non_responsive_count; uint32_t non_responsive_count;
uint32_t rexmit_requests; uint32_t rexmit_requests;
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
@ -152,12 +152,12 @@ enum pwr_rd_match_syncstate {
struct pwr_rd_match { struct pwr_rd_match {
ddsrt_avl_node_t avlnode; ddsrt_avl_node_t avlnode;
ddsi_guid_t rd_guid; ddsi_guid_t rd_guid;
nn_mtime_t tcreate; ddsrt_mtime_t tcreate;
nn_count_t count; /* most recent acknack sequence number */ nn_count_t count; /* most recent acknack sequence number */
nn_count_t next_heartbeat; /* next acceptable heartbeat (see also add_proxy_writer_to_reader) */ nn_count_t next_heartbeat; /* next acceptable heartbeat (see also add_proxy_writer_to_reader) */
nn_wctime_t hb_timestamp; /* time of most recent heartbeat that rescheduled the ack event */ ddsrt_wctime_t hb_timestamp; /* time of most recent heartbeat that rescheduled the ack event */
nn_etime_t t_heartbeat_accepted; /* (local) time a heartbeat was last accepted */ ddsrt_etime_t t_heartbeat_accepted; /* (local) time a heartbeat was last accepted */
nn_mtime_t t_last_nack; /* (local) time we last sent a NACK */ /* FIXME: probably elapsed time is better */ ddsrt_mtime_t t_last_nack; /* (local) time we last sent a NACK */ /* FIXME: probably elapsed time is better */
seqno_t seq_last_nack; /* last seq for which we requested a retransmit */ seqno_t seq_last_nack; /* last seq for which we requested a retransmit */
seqno_t last_seq; /* last known sequence number from this writer */ seqno_t last_seq; /* last known sequence number from this writer */
struct xevent *acknack_xevent; /* entry in xevent queue for sending acknacks */ struct xevent *acknack_xevent; /* entry in xevent queue for sending acknacks */
@ -181,7 +181,7 @@ struct ddsi_tkmap_instance;
struct entity_common { struct entity_common {
enum entity_kind kind; enum entity_kind kind;
ddsi_guid_t guid; ddsi_guid_t guid;
nn_wctime_t tupdate; /* timestamp of last update */ ddsrt_wctime_t tupdate; /* timestamp of last update */
char *name; char *name;
uint64_t iid; uint64_t iid;
struct ddsi_tkmap_instance *tk; struct ddsi_tkmap_instance *tk;
@ -298,8 +298,8 @@ struct writer
struct ldur_fhnode *lease_duration; /* fibheap node to keep lease duration for this writer, NULL in case of automatic liveliness with inifite duration */ struct ldur_fhnode *lease_duration; /* fibheap node to keep lease duration for this writer, NULL in case of automatic liveliness with inifite duration */
struct whc *whc; /* WHC tracking history, T-L durability service history + samples by sequence number for retransmit */ struct whc *whc; /* WHC tracking history, T-L durability service history + samples by sequence number for retransmit */
uint32_t whc_low, whc_high; /* watermarks for WHC in bytes (counting only unack'd data) */ uint32_t whc_low, whc_high; /* watermarks for WHC in bytes (counting only unack'd data) */
nn_etime_t t_rexmit_end; /* time of last 1->0 transition of "retransmitting" */ ddsrt_etime_t t_rexmit_end; /* time of last 1->0 transition of "retransmitting" */
nn_etime_t t_whc_high_upd; /* time "whc_high" was last updated for controlled ramp-up of throughput */ ddsrt_etime_t t_whc_high_upd; /* time "whc_high" was last updated for controlled ramp-up of throughput */
uint32_t num_readers; /* total number of matching PROXY readers */ uint32_t num_readers; /* total number of matching PROXY readers */
int32_t num_reliable_readers; /* number of matching reliable PROXY readers */ int32_t num_reliable_readers; /* number of matching reliable PROXY readers */
ddsrt_avl_tree_t readers; /* all matching PROXY readers, see struct wr_prd_match */ ddsrt_avl_tree_t readers; /* all matching PROXY readers, see struct wr_prd_match */
@ -367,7 +367,6 @@ struct proxy_participant
uint32_t refc; /* number of proxy endpoints (both user & built-in; not groups, they don't have a life of their own) */ uint32_t refc; /* number of proxy endpoints (both user & built-in; not groups, they don't have a life of their own) */
nn_vendorid_t vendor; /* vendor code from discovery */ nn_vendorid_t vendor; /* vendor code from discovery */
unsigned bes; /* built-in endpoint set */ unsigned bes; /* built-in endpoint set */
unsigned prismtech_bes; /* prismtech-specific extension of built-in endpoints set */
ddsi_guid_t privileged_pp_guid; /* if this PP depends on another PP for its SEDP writing */ ddsi_guid_t privileged_pp_guid; /* if this PP depends on another PP for its SEDP writing */
struct ddsi_plist *plist; /* settings/QoS for this participant */ struct ddsi_plist *plist; /* settings/QoS for this participant */
ddsrt_atomic_voidp_t minl_auto; /* lease object for shortest automatic liveliness pwr's lease (includes this proxypp's lease) */ ddsrt_atomic_voidp_t minl_auto; /* lease object for shortest automatic liveliness pwr's lease (includes this proxypp's lease) */
@ -703,11 +702,11 @@ int writer_set_notalive (struct writer *wr, bool notify);
/* Set when this proxy participant is not to be announced on the built-in topics yet */ /* Set when this proxy participant is not to be announced on the built-in topics yet */
#define CF_PROXYPP_NO_SPDP (1 << 2) #define CF_PROXYPP_NO_SPDP (1 << 2)
void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct ddsi_plist *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, nn_wctime_t timestamp, seqno_t seq); void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct ddsi_plist *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, seqno_t seq);
int delete_proxy_participant_by_guid (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit); int delete_proxy_participant_by_guid (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit);
int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, nn_wctime_t timestamp); int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, ddsrt_wctime_t timestamp);
int update_proxy_participant_plist (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, nn_wctime_t timestamp); int update_proxy_participant_plist (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, ddsrt_wctime_t timestamp);
void proxy_participant_reassign_lease (struct proxy_participant *proxypp, struct lease *newlease); void proxy_participant_reassign_lease (struct proxy_participant *proxypp, struct lease *newlease);
void purge_proxy_participants (struct ddsi_domaingv *gv, const nn_locator_t *loc, bool delete_from_as_disc); void purge_proxy_participants (struct ddsi_domaingv *gv, const nn_locator_t *loc, bool delete_from_as_disc);
@ -715,8 +714,8 @@ void purge_proxy_participants (struct ddsi_domaingv *gv, const nn_locator_t *loc
/* To create a new proxy writer or reader; the proxy participant is /* To create a new proxy writer or reader; the proxy participant is
determined from the GUID and must exist. */ determined from the GUID and must exist. */
int new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const struct ddsi_plist *plist, struct nn_dqueue *dqueue, struct xeventq *evq, nn_wctime_t timestamp, seqno_t seq); int new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const struct ddsi_plist *plist, struct nn_dqueue *dqueue, struct xeventq *evq, ddsrt_wctime_t timestamp, seqno_t seq);
int new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const struct ddsi_plist *plist, nn_wctime_t timestamp, seqno_t seq int new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const struct ddsi_plist *plist, ddsrt_wctime_t timestamp, seqno_t seq
#ifdef DDSI_INCLUDE_SSM #ifdef DDSI_INCLUDE_SSM
, int favours_ssm , int favours_ssm
#endif #endif
@ -727,19 +726,19 @@ int new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid,
reader or writer. Actual deletion is scheduled in the future, when reader or writer. Actual deletion is scheduled in the future, when
no outstanding references may still exist (determined by checking no outstanding references may still exist (determined by checking
thread progress, &c.). */ thread progress, &c.). */
int delete_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit); int delete_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit);
int delete_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit); int delete_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit);
void update_proxy_reader (struct proxy_reader *prd, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, nn_wctime_t timestamp); void update_proxy_reader (struct proxy_reader *prd, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, ddsrt_wctime_t timestamp);
void update_proxy_writer (struct proxy_writer *pwr, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, nn_wctime_t timestamp); void update_proxy_writer (struct proxy_writer *pwr, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, ddsrt_wctime_t timestamp);
void proxy_writer_set_alive_may_unlock (struct proxy_writer *pwr, bool notify); void proxy_writer_set_alive_may_unlock (struct proxy_writer *pwr, bool notify);
int proxy_writer_set_notalive (struct proxy_writer *pwr, bool notify); int proxy_writer_set_notalive (struct proxy_writer *pwr, bool notify);
int new_proxy_group (const struct ddsi_guid *guid, const char *name, const struct dds_qos *xqos, nn_wctime_t timestamp); int new_proxy_group (const struct ddsi_guid *guid, const char *name, const struct dds_qos *xqos, ddsrt_wctime_t timestamp);
struct entity_index; struct entity_index;
void delete_proxy_group (struct entity_index *entidx, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit); void delete_proxy_group (struct entity_index *entidx, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit);
/* Call this to empty all address sets of all writers to stop all outgoing traffic, or to /* Call this to empty all address sets of all writers to stop all outgoing traffic, or to
rebuild them all (which only makes sense after previously having emptied them all). */ rebuild them all (which only makes sense after previously having emptied them all). */
@ -747,8 +746,8 @@ void rebuild_or_clear_writer_addrsets(struct ddsi_domaingv *gv, int rebuild);
void local_reader_ary_setfastpath_ok (struct local_reader_ary *x, bool fastpath_ok); void local_reader_ary_setfastpath_ok (struct local_reader_ary *x, bool fastpath_ok);
void connect_writer_with_proxy_reader_secure(struct writer *wr, struct proxy_reader *prd, nn_mtime_t tnow, int64_t crypto_handle); void connect_writer_with_proxy_reader_secure(struct writer *wr, struct proxy_reader *prd, ddsrt_mtime_t tnow, int64_t crypto_handle);
void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_writer *pwr, nn_mtime_t tnow, int64_t crypto_handle); void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_writer *pwr, ddsrt_mtime_t tnow, int64_t crypto_handle);
struct ddsi_writer_info; struct ddsi_writer_info;

View file

@ -21,21 +21,21 @@ struct whc_state;
struct proxy_reader; struct proxy_reader;
struct hbcontrol { struct hbcontrol {
nn_mtime_t t_of_last_write; ddsrt_mtime_t t_of_last_write;
nn_mtime_t t_of_last_hb; ddsrt_mtime_t t_of_last_hb;
nn_mtime_t t_of_last_ackhb; ddsrt_mtime_t t_of_last_ackhb;
nn_mtime_t tsched; ddsrt_mtime_t tsched;
uint32_t hbs_since_last_write; uint32_t hbs_since_last_write;
uint32_t last_packetid; uint32_t last_packetid;
}; };
void writer_hbcontrol_init (struct hbcontrol *hbc); void writer_hbcontrol_init (struct hbcontrol *hbc);
int64_t writer_hbcontrol_intv (const struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow); int64_t writer_hbcontrol_intv (const struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow);
void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow); void writer_hbcontrol_note_asyncwrite (struct writer *wr, ddsrt_mtime_t tnow);
int writer_hbcontrol_ack_required (const struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow); int writer_hbcontrol_ack_required (const struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow);
struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow, uint32_t packetid, int *hbansreq); struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow, uint32_t packetid, int *hbansreq);
int writer_hbcontrol_must_send (const struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow); int writer_hbcontrol_must_send (const struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow);
struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow, int hbansreq, int issync); struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow, int hbansreq, int issync);
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
struct nn_xmsg *writer_hbcontrol_p2p(struct writer *wr, const struct whc_state *whcst, int hbansreq, struct proxy_reader *prd); struct nn_xmsg *writer_hbcontrol_p2p(struct writer *wr, const struct whc_state *whcst, int hbansreq, struct proxy_reader *prd);

View file

@ -15,7 +15,6 @@
#include "dds/ddsrt/atomics.h" #include "dds/ddsrt/atomics.h"
#include "dds/ddsrt/fibheap.h" #include "dds/ddsrt/fibheap.h"
#include "dds/ddsrt/time.h" #include "dds/ddsrt/time.h"
#include "dds/ddsi/q_time.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -29,8 +28,8 @@ struct ddsi_domaingv; /* FIXME: make a special for the lease admin */
struct lease { struct lease {
ddsrt_fibheap_node_t heapnode; ddsrt_fibheap_node_t heapnode;
ddsrt_fibheap_node_t pp_heapnode; ddsrt_fibheap_node_t pp_heapnode;
nn_etime_t tsched; /* access guarded by leaseheap_lock */ ddsrt_etime_t tsched; /* access guarded by leaseheap_lock */
ddsrt_atomic_uint64_t tend; /* really an nn_etime_t */ ddsrt_atomic_uint64_t tend; /* really an ddsrt_etime_t */
dds_duration_t tdur; /* constant (renew depends on it) */ dds_duration_t tdur; /* constant (renew depends on it) */
struct entity_common *entity; /* constant */ struct entity_common *entity; /* constant */
}; };
@ -39,14 +38,14 @@ int compare_lease_tsched (const void *va, const void *vb);
int compare_lease_tdur (const void *va, const void *vb); int compare_lease_tdur (const void *va, const void *vb);
void lease_management_init (struct ddsi_domaingv *gv); void lease_management_init (struct ddsi_domaingv *gv);
void lease_management_term (struct ddsi_domaingv *gv); void lease_management_term (struct ddsi_domaingv *gv);
struct lease *lease_new (nn_etime_t texpire, int64_t tdur, struct entity_common *e); struct lease *lease_new (ddsrt_etime_t texpire, int64_t tdur, struct entity_common *e);
struct lease *lease_clone (const struct lease *l); struct lease *lease_clone (const struct lease *l);
void lease_register (struct lease *l); void lease_register (struct lease *l);
void lease_unregister (struct lease *l); void lease_unregister (struct lease *l);
void lease_free (struct lease *l); void lease_free (struct lease *l);
void lease_renew (struct lease *l, nn_etime_t tnow); void lease_renew (struct lease *l, ddsrt_etime_t tnow);
void lease_set_expiry (struct lease *l, nn_etime_t when); void lease_set_expiry (struct lease *l, ddsrt_etime_t when);
int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, nn_etime_t tnow); int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, ddsrt_etime_t tnow);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -15,7 +15,7 @@
#include <stdarg.h> #include <stdarg.h>
#include "dds/ddsrt/log.h" #include "dds/ddsrt/log.h"
#include "dds/ddsi/q_time.h" #include "dds/ddsi/ddsi_time.h"
#include "dds/ddsrt/rusage.h" #include "dds/ddsrt/rusage.h"
#if defined (__cplusplus) #if defined (__cplusplus)
@ -45,7 +45,7 @@ extern "C" {
#define LOG_THREAD_CPUTIME(logcfg, guard) \ #define LOG_THREAD_CPUTIME(logcfg, guard) \
do { \ do { \
if ((logcfg)->c.mask & DDS_LC_TIMING) { \ if ((logcfg)->c.mask & DDS_LC_TIMING) { \
nn_mtime_t tnowlt = now_mt(); \ ddsrt_mtime_t tnowlt = ddsrt_time_monotonic (); \
if (tnowlt.v >= (guard).v) { \ if (tnowlt.v >= (guard).v) { \
ddsrt_rusage_t usage; \ ddsrt_rusage_t usage; \
if (ddsrt_getrusage(DDSRT_RUSAGE_THREAD, &usage) == 0) { \ if (ddsrt_getrusage(DDSRT_RUSAGE_THREAD, &usage) == 0) { \
@ -55,7 +55,7 @@ extern "C" {
"thread_cputime %d.%09d\n", \ "thread_cputime %d.%09d\n", \
(int)(usage.stime / DDS_NSECS_IN_SEC), \ (int)(usage.stime / DDS_NSECS_IN_SEC), \
(int)(usage.stime % DDS_NSECS_IN_SEC)); \ (int)(usage.stime % DDS_NSECS_IN_SEC)); \
(guard).v = tnowlt.v + T_SECOND; \ (guard).v = tnowlt.v + DDS_NSECS_IN_SEC; \
} \ } \
} \ } \
} \ } \

View file

@ -13,7 +13,7 @@
#define Q_PCAP_H #define Q_PCAP_H
#include <stdio.h> #include <stdio.h>
#include "dds/ddsi/q_time.h" #include "dds/ddsrt/time.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -21,10 +21,10 @@ extern "C" {
struct msghdr; struct msghdr;
FILE * new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name); FILE * new_pcap_file (struct ddsi_domaingv *gv, const char *name);
void write_pcap_received (struct ddsi_domaingv *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz); void write_pcap_received (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz);
void write_pcap_sent (struct ddsi_domaingv *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, void write_pcap_sent (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const struct sockaddr_storage *src,
const ddsrt_msghdr_t *hdr, size_t sz); const ddsrt_msghdr_t *hdr, size_t sz);
#if defined (__cplusplus) #if defined (__cplusplus)

View file

@ -17,7 +17,7 @@
#include "dds/ddsi/q_feature_check.h" #include "dds/ddsi/q_feature_check.h"
#include "dds/ddsi/q_rtps.h" #include "dds/ddsi/q_rtps.h"
#include "dds/ddsi/q_time.h" #include "dds/ddsi/ddsi_time.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -164,9 +164,8 @@ typedef enum SubmessageKind {
SMID_SRTPS_PREFIX = 0x33, SMID_SRTPS_PREFIX = 0x33,
SMID_SRTPS_POSTFIX = 0x34, SMID_SRTPS_POSTFIX = 0x34,
/* vendor-specific sub messages (0x80 .. 0xff) */ /* vendor-specific sub messages (0x80 .. 0xff) */
SMID_PT_INFO_CONTAINER = 0x80, SMID_ADLINK_MSG_LEN = 0x81,
SMID_PT_MSG_LEN = 0x81, SMID_ADLINK_ENTITY_ID = 0x82
SMID_PT_ENTITY_ID = 0x82
} SubmessageKind_t; } SubmessageKind_t;
typedef struct InfoTimestamp { typedef struct InfoTimestamp {
@ -305,12 +304,6 @@ DDSRT_WARNING_MSVC_ON(4200)
#define NACKFRAG_SIZE(numbits) (offsetof (NackFrag_t, bits) + NN_FRAGMENT_NUMBER_SET_BITS_SIZE (numbits) + 4) #define NACKFRAG_SIZE(numbits) (offsetof (NackFrag_t, bits) + NN_FRAGMENT_NUMBER_SET_BITS_SIZE (numbits) + 4)
#define NACKFRAG_SIZE_MAX NACKFRAG_SIZE (256u) #define NACKFRAG_SIZE_MAX NACKFRAG_SIZE (256u)
typedef struct PT_InfoContainer {
SubmessageHeader_t smhdr;
uint32_t id;
} PT_InfoContainer_t;
#define PTINFO_ID_ENCRYPT (0x01u)
typedef union Submessage { typedef union Submessage {
SubmessageHeader_t smhdr; SubmessageHeader_t smhdr;
AckNack_t acknack; AckNack_t acknack;
@ -323,7 +316,6 @@ typedef union Submessage {
HeartbeatFrag_t heartbeatfrag; HeartbeatFrag_t heartbeatfrag;
Gap_t gap; Gap_t gap;
NackFrag_t nackfrag; NackFrag_t nackfrag;
PT_InfoContainer_t pt_infocontainer;
} Submessage_t; } Submessage_t;
DDSRT_WARNING_MSVC_OFF(4200) DDSRT_WARNING_MSVC_OFF(4200)
@ -401,7 +393,7 @@ DDSRT_WARNING_MSVC_ON(4200)
#define PID_COHERENT_SET 0x56u #define PID_COHERENT_SET 0x56u
#define PID_DIRECTED_WRITE 0x57u #define PID_DIRECTED_WRITE 0x57u
#define PID_ORIGINAL_WRITER_INFO 0x61u #define PID_ORIGINAL_WRITER_INFO 0x61u
#define PID_ENDPOINT_GUID 0x5au /* !SPEC <=> PRISMTECH_ENDPOINT_GUID */ #define PID_ENDPOINT_GUID 0x5au /* !SPEC <=> ADLINK_ENDPOINT_GUID */
/* Security related PID values. */ /* Security related PID values. */
#define PID_IDENTITY_TOKEN 0x1001u #define PID_IDENTITY_TOKEN 0x1001u
@ -430,43 +422,42 @@ DDSRT_WARNING_MSVC_ON(4200)
#define PID_RECV_QUEUE_SIZE 0x18u #define PID_RECV_QUEUE_SIZE 0x18u
#define PID_RELIABILITY_OFFERED 0x19u #define PID_RELIABILITY_OFFERED 0x19u
#define PID_PRISMTECH_BUILTIN_ENDPOINT_SET (PID_VENDORSPECIFIC_FLAG | 0x0u) #define PID_ADLINK_BUILTIN_ENDPOINT_SET (PID_VENDORSPECIFIC_FLAG | 0x0u)
/* parameter ids for READER_DATA_LIFECYCLE & WRITER_DATA_LIFECYCLE are /* parameter ids for READER_DATA_LIFECYCLE & WRITER_DATA_LIFECYCLE are
undefined, but let's publish them anyway */ undefined, but let's publish them anyway */
#define PID_PRISMTECH_READER_DATA_LIFECYCLE (PID_VENDORSPECIFIC_FLAG | 0x2u) #define PID_ADLINK_READER_DATA_LIFECYCLE (PID_VENDORSPECIFIC_FLAG | 0x2u)
#define PID_PRISMTECH_WRITER_DATA_LIFECYCLE (PID_VENDORSPECIFIC_FLAG | 0x3u) #define PID_ADLINK_WRITER_DATA_LIFECYCLE (PID_VENDORSPECIFIC_FLAG | 0x3u)
/* ENDPOINT_GUID is formally undefined, so in strictly conforming /* ENDPOINT_GUID is formally undefined, so in strictly conforming
mode, we use our own */ mode, we use our own */
#define PID_PRISMTECH_ENDPOINT_GUID (PID_VENDORSPECIFIC_FLAG | 0x4u) #define PID_ADLINK_ENDPOINT_GUID (PID_VENDORSPECIFIC_FLAG | 0x4u)
#define PID_PRISMTECH_SYNCHRONOUS_ENDPOINT (PID_VENDORSPECIFIC_FLAG | 0x5u) #define PID_ADLINK_SYNCHRONOUS_ENDPOINT (PID_VENDORSPECIFIC_FLAG | 0x5u)
/* Relaxed QoS matching readers/writers are best ignored by /* Relaxed QoS matching readers/writers are best ignored by
implementations that don't understand them. This also covers "old" implementations that don't understand them. This also covers "old"
DDSI2's, although they may emit an error. */ DDSI2's, although they may emit an error. */
#define PID_PRISMTECH_RELAXED_QOS_MATCHING (PID_VENDORSPECIFIC_FLAG | PID_UNRECOGNIZED_INCOMPATIBLE_FLAG | 0x6u) #define PID_ADLINK_RELAXED_QOS_MATCHING (PID_VENDORSPECIFIC_FLAG | PID_UNRECOGNIZED_INCOMPATIBLE_FLAG | 0x6u)
#define PID_PRISMTECH_PARTICIPANT_VERSION_INFO (PID_VENDORSPECIFIC_FLAG | 0x7u) #define PID_ADLINK_PARTICIPANT_VERSION_INFO (PID_VENDORSPECIFIC_FLAG | 0x7u)
/* See CMTopics protocol.doc (2013-12-09) */ #define PID_ADLINK_NODE_NAME (PID_VENDORSPECIFIC_FLAG | 0x8u)
#define PID_PRISMTECH_NODE_NAME (PID_VENDORSPECIFIC_FLAG | 0x8u) #define PID_ADLINK_EXEC_NAME (PID_VENDORSPECIFIC_FLAG | 0x9u)
#define PID_PRISMTECH_EXEC_NAME (PID_VENDORSPECIFIC_FLAG | 0x9u) #define PID_ADLINK_PROCESS_ID (PID_VENDORSPECIFIC_FLAG | 0xau)
#define PID_PRISMTECH_PROCESS_ID (PID_VENDORSPECIFIC_FLAG | 0xau) #define PID_ADLINK_SERVICE_TYPE (PID_VENDORSPECIFIC_FLAG | 0xbu)
#define PID_PRISMTECH_SERVICE_TYPE (PID_VENDORSPECIFIC_FLAG | 0xbu) #define PID_ADLINK_ENTITY_FACTORY (PID_VENDORSPECIFIC_FLAG | 0xcu)
#define PID_PRISMTECH_ENTITY_FACTORY (PID_VENDORSPECIFIC_FLAG | 0xcu) #define PID_ADLINK_WATCHDOG_SCHEDULING (PID_VENDORSPECIFIC_FLAG | 0xdu)
#define PID_PRISMTECH_WATCHDOG_SCHEDULING (PID_VENDORSPECIFIC_FLAG | 0xdu) #define PID_ADLINK_LISTENER_SCHEDULING (PID_VENDORSPECIFIC_FLAG | 0xeu)
#define PID_PRISMTECH_LISTENER_SCHEDULING (PID_VENDORSPECIFIC_FLAG | 0xeu) #define PID_ADLINK_SUBSCRIPTION_KEYS (PID_VENDORSPECIFIC_FLAG | 0xfu)
#define PID_PRISMTECH_SUBSCRIPTION_KEYS (PID_VENDORSPECIFIC_FLAG | 0xfu) #define PID_ADLINK_READER_LIFESPAN (PID_VENDORSPECIFIC_FLAG | 0x10u)
#define PID_PRISMTECH_READER_LIFESPAN (PID_VENDORSPECIFIC_FLAG | 0x10u) #define PID_ADLINK_TYPE_DESCRIPTION (PID_VENDORSPECIFIC_FLAG | 0x12u)
#define PID_PRISMTECH_TYPE_DESCRIPTION (PID_VENDORSPECIFIC_FLAG | 0x12u) #define PID_ADLINK_LAN (PID_VENDORSPECIFIC_FLAG | 0x13u)
#define PID_PRISMTECH_LAN (PID_VENDORSPECIFIC_FLAG | 0x13u) #define PID_ADLINK_ENDPOINT_GID (PID_VENDORSPECIFIC_FLAG | 0x14u)
#define PID_PRISMTECH_ENDPOINT_GID (PID_VENDORSPECIFIC_FLAG | 0x14u) #define PID_ADLINK_GROUP_GID (PID_VENDORSPECIFIC_FLAG | 0x15u)
#define PID_PRISMTECH_GROUP_GID (PID_VENDORSPECIFIC_FLAG | 0x15u) #define PID_ADLINK_EOTINFO (PID_VENDORSPECIFIC_FLAG | 0x16u)
#define PID_PRISMTECH_EOTINFO (PID_VENDORSPECIFIC_FLAG | 0x16u) #define PID_ADLINK_PART_CERT_NAME (PID_VENDORSPECIFIC_FLAG | 0x17u);
#define PID_PRISMTECH_PART_CERT_NAME (PID_VENDORSPECIFIC_FLAG | 0x17u); #define PID_ADLINK_LAN_CERT_NAME (PID_VENDORSPECIFIC_FLAG | 0x18u);
#define PID_PRISMTECH_LAN_CERT_NAME (PID_VENDORSPECIFIC_FLAG | 0x18u);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -121,10 +121,9 @@ struct nn_rsample_info {
struct proxy_writer *pwr; struct proxy_writer *pwr;
uint32_t size; uint32_t size;
uint32_t fragsize; uint32_t fragsize;
nn_wctime_t timestamp; ddsrt_wctime_t timestamp;
nn_wctime_t reception_timestamp; /* OpenSplice extension -- but we get it essentially for free, so why not? */ ddsrt_wctime_t reception_timestamp; /* OpenSplice extension -- but we get it essentially for free, so why not? */
unsigned statusinfo: 2; /* just the two defined bits from the status info */ unsigned statusinfo: 2; /* just the two defined bits from the status info */
unsigned pt_wr_info_zoff: 16; /* PrismTech writer info offset */
unsigned bswap: 1; /* so we can extract well formatted writer info quicker */ unsigned bswap: 1; /* so we can extract well formatted writer info quicker */
unsigned complex_qos: 1; /* includes QoS other than keyhash, 2-bit statusinfo, PT writer info */ unsigned complex_qos: 1; /* includes QoS other than keyhash, 2-bit statusinfo, PT writer info */
}; };
@ -157,8 +156,6 @@ struct nn_rdata {
#define NN_ZOFF_TO_OFF(zoff) ((unsigned) (zoff)) #define NN_ZOFF_TO_OFF(zoff) ((unsigned) (zoff))
#define NN_OFF_TO_ZOFF(off) ((unsigned short) (off)) #define NN_OFF_TO_ZOFF(off) ((unsigned short) (off))
#endif #endif
#define NN_SAMPLEINFO_HAS_WRINFO(rsi) ((rsi)->pt_wr_info_zoff != NN_OFF_TO_ZOFF (0))
#define NN_SAMPLEINFO_WRINFO_OFF(rsi) NN_ZOFF_TO_OFF ((rsi)->pt_wr_info_zoff)
#define NN_RDATA_PAYLOAD_OFF(rdata) NN_ZOFF_TO_OFF ((rdata)->payload_zoff) #define NN_RDATA_PAYLOAD_OFF(rdata) NN_ZOFF_TO_OFF ((rdata)->payload_zoff)
#define NN_RDATA_SUBMSG_OFF(rdata) NN_ZOFF_TO_OFF ((rdata)->submsg_zoff) #define NN_RDATA_SUBMSG_OFF(rdata) NN_ZOFF_TO_OFF ((rdata)->submsg_zoff)

View file

@ -12,6 +12,7 @@
#ifndef NN_RTPS_H #ifndef NN_RTPS_H
#define NN_RTPS_H #define NN_RTPS_H
#include "dds/export.h"
#include "dds/ddsi/ddsi_vendor.h" #include "dds/ddsi/ddsi_vendor.h"
#include "dds/ddsi/ddsi_guid.h" #include "dds/ddsi/ddsi_guid.h"
@ -67,18 +68,18 @@ typedef int64_t seqno_t;
#define NN_ENTITYID_KIND_WRITER_NO_KEY 0x03 #define NN_ENTITYID_KIND_WRITER_NO_KEY 0x03
#define NN_ENTITYID_KIND_READER_NO_KEY 0x04 #define NN_ENTITYID_KIND_READER_NO_KEY 0x04
#define NN_ENTITYID_KIND_READER_WITH_KEY 0x07 #define NN_ENTITYID_KIND_READER_WITH_KEY 0x07
#define NN_ENTITYID_KIND_PRISMTECH_SUBSCRIBER 0x0a /* source = VENDOR */
#define NN_ENTITYID_KIND_PRISMTECH_PUBLISHER 0x0b /* source = VENDOR */
#define NN_ENTITYID_ALLOCSTEP 0x100 #define NN_ENTITYID_ALLOCSTEP 0x100
struct cfgst; struct cfgst;
struct ddsi_domaingv; struct ddsi_domaingv;
int rtps_config_prep (struct ddsi_domaingv *config, struct cfgst *cfgst); int rtps_config_prep (struct ddsi_domaingv *gv, struct cfgst *cfgst);
int rtps_config_open_trace (struct ddsi_domaingv *config); int rtps_config_open_trace (struct ddsi_domaingv *gv);
int rtps_init (struct ddsi_domaingv *config); int rtps_init (struct ddsi_domaingv *gv);
int rtps_start (struct ddsi_domaingv *config); int rtps_start (struct ddsi_domaingv *gv);
void rtps_stop (struct ddsi_domaingv *config); void rtps_stop (struct ddsi_domaingv *gv);
void rtps_fini (struct ddsi_domaingv *config); void rtps_fini (struct ddsi_domaingv *gv);
DDS_EXPORT void ddsi_set_deafmute (struct ddsi_domaingv *gv, bool deaf, bool mute, int64_t reset_after);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -50,6 +50,8 @@ typedef int32_t svtime_t; /* signed version */
enum thread_state { enum thread_state {
THREAD_STATE_ZERO, /* known to be dead */ THREAD_STATE_ZERO, /* known to be dead */
THREAD_STATE_STOPPED, /* internal thread, stopped-but-not-reaped */
THREAD_STATE_INIT, /* internal thread, initializing */
THREAD_STATE_LAZILY_CREATED, /* lazily created in response because an application used it. Reclaimed if the thread terminates, but not considered an error if all of Cyclone is shutdown while this thread hasn't terminated yet */ THREAD_STATE_LAZILY_CREATED, /* lazily created in response because an application used it. Reclaimed if the thread terminates, but not considered an error if all of Cyclone is shutdown while this thread hasn't terminated yet */
THREAD_STATE_ALIVE /* known to be alive - for Cyclone internal threads */ THREAD_STATE_ALIVE /* known to be alive - for Cyclone internal threads */
}; };
@ -67,13 +69,34 @@ struct ddsrt_log_cfg;
* *
* gv is constant for internal threads, i.e., for threads with state = ALIVE * gv is constant for internal threads, i.e., for threads with state = ALIVE
* gv is non-NULL for internal threads except thread liveliness monitoring * gv is non-NULL for internal threads except thread liveliness monitoring
*
* Q_THREAD_DEBUG enables some really costly debugging stuff that may not be fully
* portable (I used it once, might as well keep it)
*/ */
#define Q_THREAD_DEBUG 0
#if Q_THREAD_DEBUG
#define Q_THREAD_NSTACKS 20
#define Q_THREAD_STACKDEPTH 10
#define Q_THREAD_BASE_DEBUG \
void *stks[Q_THREAD_NSTACKS][Q_THREAD_STACKDEPTH]; \
int stks_depth[Q_THREAD_NSTACKS]; \
int stks_idx;
struct thread_state1;
void thread_vtime_trace (struct thread_state1 *ts1);
#else /* Q_THREAD_DEBUG */
#define Q_THREAD_BASE_DEBUG
#define thread_vtime_trace(ts1) do { } while (0)
#endif /* Q_THREAD_DEBUG */
#define THREAD_BASE \ #define THREAD_BASE \
ddsrt_atomic_uint32_t vtime; \ ddsrt_atomic_uint32_t vtime; \
ddsrt_atomic_voidp_t gv; \
enum thread_state state; \ enum thread_state state; \
ddsrt_atomic_voidp_t gv; \
ddsrt_thread_t tid; \ ddsrt_thread_t tid; \
ddsrt_thread_t extTid; \ uint32_t (*f) (void *arg); \
void *f_arg; \
Q_THREAD_BASE_DEBUG /* note: no semicolon! */ \
char name[24] /* note: no semicolon! */ char name[24] /* note: no semicolon! */
struct thread_state_base { struct thread_state_base {
@ -107,8 +130,6 @@ DDS_EXPORT dds_return_t create_thread (struct thread_state1 **ts, const struct d
DDS_EXPORT struct thread_state1 *lookup_thread_state_real (void); DDS_EXPORT struct thread_state1 *lookup_thread_state_real (void);
DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1); DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1);
DDS_EXPORT void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv); DDS_EXPORT void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv);
DDS_EXPORT void reset_thread_state (struct thread_state1 *ts1);
DDS_EXPORT int thread_exists (const char *name);
DDS_EXPORT inline struct thread_state1 *lookup_thread_state (void) { DDS_EXPORT inline struct thread_state1 *lookup_thread_state (void) {
struct thread_state1 *ts1 = tsd_thread_state; struct thread_state1 *ts1 = tsd_thread_state;
@ -154,6 +175,7 @@ DDS_EXPORT inline void thread_state_asleep (struct thread_state1 *ts1)
assert (vtime_awake_p (vt)); assert (vtime_awake_p (vt));
/* nested calls a rare and an extra fence doesn't break things */ /* nested calls a rare and an extra fence doesn't break things */
ddsrt_atomic_fence_rel (); ddsrt_atomic_fence_rel ();
thread_vtime_trace (ts1);
if ((vt & VTIME_NEST_MASK) == 1) if ((vt & VTIME_NEST_MASK) == 1)
vt += (1u << VTIME_TIME_SHIFT) - 1u; vt += (1u << VTIME_TIME_SHIFT) - 1u;
else else
@ -167,6 +189,7 @@ DDS_EXPORT inline void thread_state_awake (struct thread_state1 *ts1, const stru
assert ((vt & VTIME_NEST_MASK) < VTIME_NEST_MASK); assert ((vt & VTIME_NEST_MASK) < VTIME_NEST_MASK);
assert (gv != NULL); assert (gv != NULL);
assert (ts1->state != THREAD_STATE_ALIVE || gv == ddsrt_atomic_ldvoidp (&ts1->gv)); assert (ts1->state != THREAD_STATE_ALIVE || gv == ddsrt_atomic_ldvoidp (&ts1->gv));
thread_vtime_trace (ts1);
ddsrt_atomic_stvoidp (&ts1->gv, (struct ddsi_domaingv *) gv); ddsrt_atomic_stvoidp (&ts1->gv, (struct ddsi_domaingv *) gv);
ddsrt_atomic_fence_stst (); ddsrt_atomic_fence_stst ();
ddsrt_atomic_st32 (&ts1->vtime, vt + 1u); ddsrt_atomic_st32 (&ts1->vtime, vt + 1u);
@ -179,6 +202,7 @@ DDS_EXPORT inline void thread_state_awake_domain_ok (struct thread_state1 *ts1)
vtime_t vt = ddsrt_atomic_ld32 (&ts1->vtime); vtime_t vt = ddsrt_atomic_ld32 (&ts1->vtime);
assert ((vt & VTIME_NEST_MASK) < VTIME_NEST_MASK); assert ((vt & VTIME_NEST_MASK) < VTIME_NEST_MASK);
assert (ddsrt_atomic_ldvoidp (&ts1->gv) != NULL); assert (ddsrt_atomic_ldvoidp (&ts1->gv) != NULL);
thread_vtime_trace (ts1);
ddsrt_atomic_st32 (&ts1->vtime, vt + 1u); ddsrt_atomic_st32 (&ts1->vtime, vt + 1u);
/* nested calls a rare and an extra fence doesn't break things */ /* nested calls a rare and an extra fence doesn't break things */
ddsrt_atomic_fence_acq (); ddsrt_atomic_fence_acq ();
@ -196,6 +220,7 @@ DDS_EXPORT inline void thread_state_awake_to_awake_no_nest (struct thread_state1
vtime_t vt = ddsrt_atomic_ld32 (&ts1->vtime); vtime_t vt = ddsrt_atomic_ld32 (&ts1->vtime);
assert ((vt & VTIME_NEST_MASK) == 1); assert ((vt & VTIME_NEST_MASK) == 1);
ddsrt_atomic_fence_rel (); ddsrt_atomic_fence_rel ();
thread_vtime_trace (ts1);
ddsrt_atomic_st32 (&ts1->vtime, vt + (1u << VTIME_TIME_SHIFT)); ddsrt_atomic_st32 (&ts1->vtime, vt + (1u << VTIME_TIME_SHIFT));
ddsrt_atomic_fence_acq (); ddsrt_atomic_fence_acq ();
} }

View file

@ -1,76 +0,0 @@
/*
* 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
*/
#ifndef NN_TIME_H
#define NN_TIME_H
#include <stdint.h>
#include "dds/export.h"
#if defined (__cplusplus)
extern "C" {
#endif
#define T_NEVER 0x7fffffffffffffffll
#define T_MILLISECOND 1000000ll
#define T_SECOND (1000 * T_MILLISECOND)
#define T_MICROSECOND (T_MILLISECOND/1000)
typedef struct {
int32_t seconds;
uint32_t fraction;
} ddsi_time_t;
#define DDSI_TIME_INFINITE ((ddsi_time_t) { INT32_MAX, UINT32_MAX })
#define DDSI_TIME_INVALID ((ddsi_time_t) { -1, UINT32_MAX })
typedef ddsi_time_t ddsi_duration_t;
typedef struct {
int64_t v;
} nn_mtime_t;
typedef struct {
int64_t v;
} nn_wctime_t;
typedef struct {
int64_t v;
} nn_etime_t;
#define NN_MTIME_NEVER ((nn_mtime_t) { T_NEVER })
#define NN_WCTIME_NEVER ((nn_wctime_t) { T_NEVER })
#define NN_ETIME_NEVER ((nn_etime_t) { T_NEVER })
#define NN_WCTIME_INVALID ((nn_wctime_t) { INT64_MIN })
int valid_ddsi_timestamp (ddsi_time_t t);
DDS_EXPORT nn_wctime_t now (void); /* wall clock time */
DDS_EXPORT nn_mtime_t now_mt (void); /* monotonic time */
DDS_EXPORT nn_etime_t now_et (void); /* elapsed time */
DDS_EXPORT void mtime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, nn_mtime_t t);
DDS_EXPORT void wctime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, nn_wctime_t t);
DDS_EXPORT void etime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, nn_etime_t t);
DDS_EXPORT nn_mtime_t mtime_round_up (nn_mtime_t t, int64_t round);
DDS_EXPORT nn_mtime_t add_duration_to_mtime (nn_mtime_t t, int64_t d);
DDS_EXPORT nn_wctime_t add_duration_to_wctime (nn_wctime_t t, int64_t d);
DDS_EXPORT nn_etime_t add_duration_to_etime (nn_etime_t t, int64_t d);
DDS_EXPORT ddsi_time_t nn_wctime_to_ddsi_time (nn_wctime_t t);
DDS_EXPORT nn_wctime_t nn_wctime_from_ddsi_time (ddsi_time_t x);
DDS_EXPORT ddsi_duration_t nn_to_ddsi_duration (int64_t t);
DDS_EXPORT int64_t nn_from_ddsi_duration (ddsi_duration_t x);
#if defined (__cplusplus)
}
#endif
#endif /* NN_TIME_H */

View file

@ -13,7 +13,7 @@
#define Q_WHC_H #define Q_WHC_H
#include <stddef.h> #include <stddef.h>
#include "dds/ddsi/q_time.h" #include "dds/ddsrt/time.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -30,7 +30,7 @@ struct whc_borrowed_sample {
struct ddsi_serdata *serdata; struct ddsi_serdata *serdata;
struct ddsi_plist *plist; struct ddsi_plist *plist;
bool unacked; bool unacked;
nn_mtime_t last_rexmit_ts; ddsrt_mtime_t last_rexmit_ts;
unsigned rexmit_count; unsigned rexmit_count;
}; };
@ -73,7 +73,7 @@ typedef void (*whc_free_t)(struct whc *whc);
reliable readers that have not acknowledged all data */ reliable readers that have not acknowledged all data */
/* max_drop_seq must go soon, it's way too ugly. */ /* max_drop_seq must go soon, it's way too ugly. */
/* plist may be NULL or ddsrt_malloc'd, WHC takes ownership of plist */ /* plist may be NULL or ddsrt_malloc'd, WHC takes ownership of plist */
typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, ddsrt_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
typedef uint32_t (*whc_downgrade_to_volatile_t)(struct whc *whc, struct whc_state *st); typedef uint32_t (*whc_downgrade_to_volatile_t)(struct whc *whc, struct whc_state *st);
typedef uint32_t (*whc_remove_acked_messages_t)(struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); typedef uint32_t (*whc_remove_acked_messages_t)(struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
typedef void (*whc_free_deferred_free_list_t)(struct whc *whc, struct whc_node *deferred_free_list); typedef void (*whc_free_deferred_free_list_t)(struct whc *whc, struct whc_node *deferred_free_list);
@ -121,7 +121,7 @@ inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_
inline void whc_free (struct whc *whc) { inline void whc_free (struct whc *whc) {
whc->ops->free (whc); whc->ops->free (whc);
} }
inline int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) { inline int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, ddsrt_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) {
return whc->ops->insert (whc, max_drop_seq, seq, exp, plist, serdata, tk); return whc->ops->insert (whc, max_drop_seq, seq, exp, plist, serdata, tk);
} }
inline unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st) { inline unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st) {

View file

@ -43,7 +43,7 @@ struct xeventq *xeventq_new
uint32_t auxiliary_bandwidth_limit uint32_t auxiliary_bandwidth_limit
); );
/* xeventq_free calls callback handlers with t = T_NEVER, at which point they are required to free /* xeventq_free calls callback handlers with t = NEVER, at which point they are required to free
whatever memory is claimed for the argument and call delete_xevent. */ whatever memory is claimed for the argument and call delete_xevent. */
DDS_EXPORT void xeventq_free (struct xeventq *evq); DDS_EXPORT void xeventq_free (struct xeventq *evq);
DDS_EXPORT dds_return_t xeventq_start (struct xeventq *evq, const char *name); /* <0 => error, =0 => ok */ DDS_EXPORT dds_return_t xeventq_start (struct xeventq *evq, const char *name); /* <0 => error, =0 => ok */
@ -62,16 +62,16 @@ DDS_EXPORT int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg
/* All of the following lock EVQ for the duration of the operation */ /* All of the following lock EVQ for the duration of the operation */
DDS_EXPORT void delete_xevent (struct xevent *ev); DDS_EXPORT void delete_xevent (struct xevent *ev);
DDS_EXPORT void delete_xevent_callback (struct xevent *ev); DDS_EXPORT void delete_xevent_callback (struct xevent *ev);
DDS_EXPORT int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched); DDS_EXPORT int resched_xevent_if_earlier (struct xevent *ev, ddsrt_mtime_t tsched);
DDS_EXPORT struct xevent *qxev_heartbeat (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *wr_guid); DDS_EXPORT struct xevent *qxev_heartbeat (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *wr_guid);
DDS_EXPORT struct xevent *qxev_acknack (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *pwr_guid, const ddsi_guid_t *rd_guid); DDS_EXPORT struct xevent *qxev_acknack (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *pwr_guid, const ddsi_guid_t *rd_guid);
DDS_EXPORT struct xevent *qxev_spdp (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *pp_guid, const ddsi_guid_t *proxypp_guid); DDS_EXPORT struct xevent *qxev_spdp (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *pp_guid, const ddsi_guid_t *proxypp_guid);
DDS_EXPORT struct xevent *qxev_pmd_update (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *pp_guid); DDS_EXPORT struct xevent *qxev_pmd_update (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *pp_guid);
DDS_EXPORT struct xevent *qxev_delete_writer (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *guid); DDS_EXPORT struct xevent *qxev_delete_writer (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *guid);
/* cb will be called with now = T_NEVER if the event is still enqueued when when xeventq_free starts cleaning up */ /* cb will be called with now = NEVER if the event is still enqueued when when xeventq_free starts cleaning up */
DDS_EXPORT struct xevent *qxev_callback (struct xeventq *evq, nn_mtime_t tsched, void (*cb) (struct xevent *xev, void *arg, nn_mtime_t now), void *arg); DDS_EXPORT struct xevent *qxev_callback (struct xeventq *evq, ddsrt_mtime_t tsched, void (*cb) (struct xevent *xev, void *arg, ddsrt_mtime_t now), void *arg);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -29,7 +29,7 @@ struct proxy_writer;
struct writer; struct writer;
struct participant; struct participant;
struct nn_prismtech_participant_version_info; struct nn_adlink_participant_version_info;
struct nn_xmsgpool; struct nn_xmsgpool;
struct nn_xmsg_data; struct nn_xmsg_data;
struct nn_xmsg; struct nn_xmsg;
@ -126,7 +126,7 @@ void nn_xmsg_submsg_append_refd_payload (struct nn_xmsg *msg, struct nn_xmsg_mar
#endif #endif
void nn_xmsg_submsg_setnext (struct nn_xmsg *msg, struct nn_xmsg_marker marker); void nn_xmsg_submsg_setnext (struct nn_xmsg *msg, struct nn_xmsg_marker marker);
void nn_xmsg_submsg_init (struct nn_xmsg *msg, struct nn_xmsg_marker marker, SubmessageKind_t smkind); void nn_xmsg_submsg_init (struct nn_xmsg *msg, struct nn_xmsg_marker marker, SubmessageKind_t smkind);
void nn_xmsg_add_timestamp (struct nn_xmsg *m, nn_wctime_t t); void nn_xmsg_add_timestamp (struct nn_xmsg *m, ddsrt_wctime_t t);
void nn_xmsg_add_entityid (struct nn_xmsg * m); void nn_xmsg_add_entityid (struct nn_xmsg * m);
void *nn_xmsg_addpar_bo (struct nn_xmsg *m, nn_parameterid_t pid, size_t len, bool be); void *nn_xmsg_addpar_bo (struct nn_xmsg *m, nn_parameterid_t pid, size_t len, bool be);
void *nn_xmsg_addpar (struct nn_xmsg *m, nn_parameterid_t pid, size_t len); void *nn_xmsg_addpar (struct nn_xmsg *m, nn_parameterid_t pid, size_t len);

View file

@ -12,22 +12,22 @@
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include "dds/ddsrt/circlist.h" #include "dds/ddsrt/circlist.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsi/ddsi_deadline.h" #include "dds/ddsi/ddsi_deadline.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_xevent.h" #include "dds/ddsi/q_xevent.h"
static void instance_deadline_missed_cb (struct xevent *xev, void *varg, nn_mtime_t tnow) static void instance_deadline_missed_cb (struct xevent *xev, void *varg, ddsrt_mtime_t tnow)
{ {
struct deadline_adm * const deadline_adm = varg; struct deadline_adm * const deadline_adm = varg;
nn_mtime_t next_valid = deadline_adm->deadline_missed_cb((char *)deadline_adm - deadline_adm->list_offset, tnow); ddsrt_mtime_t next_valid = deadline_adm->deadline_missed_cb((char *)deadline_adm - deadline_adm->list_offset, tnow);
resched_xevent_if_earlier (xev, next_valid); resched_xevent_if_earlier (xev, next_valid);
} }
/* Gets the instance from the list in deadline admin that has the earliest missed deadline and /* Gets the instance from the list in deadline admin that has the earliest missed deadline and
* removes the instance element from the list. If no more instances with missed deadline exist * removes the instance element from the list. If no more instances with missed deadline exist
* in the list, the deadline (nn_mtime_t) for the first instance to 'expire' is returned. If the * in the list, the deadline (ddsrt_mtime_t) for the first instance to 'expire' is returned. If
* list is empty, NN_MTIME_NEVER is returned */ * the list is empty, DDSRT_MTIME_NEVER is returned */
nn_mtime_t deadline_next_missed_locked (struct deadline_adm *deadline_adm, nn_mtime_t tnow, void **instance) ddsrt_mtime_t deadline_next_missed_locked (struct deadline_adm *deadline_adm, ddsrt_mtime_t tnow, void **instance)
{ {
struct deadline_elem *elem = NULL; struct deadline_elem *elem = NULL;
if (!ddsrt_circlist_isempty (&deadline_adm->list)) if (!ddsrt_circlist_isempty (&deadline_adm->list))
@ -39,18 +39,18 @@ nn_mtime_t deadline_next_missed_locked (struct deadline_adm *deadline_adm, nn_mt
ddsrt_circlist_remove (&deadline_adm->list, &elem->e); ddsrt_circlist_remove (&deadline_adm->list, &elem->e);
if (instance != NULL) if (instance != NULL)
*instance = (char *)elem - deadline_adm->elem_offset; *instance = (char *)elem - deadline_adm->elem_offset;
return (nn_mtime_t) { 0 }; return (ddsrt_mtime_t) { 0 };
} }
} }
if (instance != NULL) if (instance != NULL)
*instance = NULL; *instance = NULL;
return (elem != NULL) ? elem->t_deadline : NN_MTIME_NEVER; return (elem != NULL) ? elem->t_deadline : DDSRT_MTIME_NEVER;
} }
void deadline_init (const struct ddsi_domaingv *gv, struct deadline_adm *deadline_adm, size_t list_offset, size_t elem_offset, deadline_missed_cb_t deadline_missed_cb) void deadline_init (const struct ddsi_domaingv *gv, struct deadline_adm *deadline_adm, size_t list_offset, size_t elem_offset, deadline_missed_cb_t deadline_missed_cb)
{ {
ddsrt_circlist_init (&deadline_adm->list); ddsrt_circlist_init (&deadline_adm->list);
deadline_adm->evt = qxev_callback (gv->xevents, NN_MTIME_NEVER, instance_deadline_missed_cb, deadline_adm); deadline_adm->evt = qxev_callback (gv->xevents, DDSRT_MTIME_NEVER, instance_deadline_missed_cb, deadline_adm);
deadline_adm->deadline_missed_cb = deadline_missed_cb; deadline_adm->deadline_missed_cb = deadline_missed_cb;
deadline_adm->list_offset = list_offset; deadline_adm->list_offset = list_offset;
deadline_adm->elem_offset = elem_offset; deadline_adm->elem_offset = elem_offset;
@ -63,7 +63,7 @@ void deadline_stop (const struct deadline_adm *deadline_adm)
void deadline_clear (struct deadline_adm *deadline_adm) void deadline_clear (struct deadline_adm *deadline_adm)
{ {
while ((deadline_next_missed_locked (deadline_adm, NN_MTIME_NEVER, NULL)).v == 0); while ((deadline_next_missed_locked (deadline_adm, DDSRT_MTIME_NEVER, NULL)).v == 0);
} }
void deadline_fini (const struct deadline_adm *deadline_adm) void deadline_fini (const struct deadline_adm *deadline_adm)
@ -72,10 +72,10 @@ void deadline_fini (const struct deadline_adm *deadline_adm)
(void) deadline_adm; (void) deadline_adm;
} }
extern inline void deadline_register_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, nn_mtime_t tnow); extern inline void deadline_register_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, ddsrt_mtime_t tnow);
extern inline void deadline_reregister_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, nn_mtime_t tnow); extern inline void deadline_reregister_instance_locked (struct deadline_adm *deadline_adm, struct deadline_elem *elem, ddsrt_mtime_t tnow);
void deadline_register_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem, nn_mtime_t tprev, nn_mtime_t tnow) void deadline_register_instance_real (struct deadline_adm *deadline_adm, struct deadline_elem *elem, ddsrt_mtime_t tprev, ddsrt_mtime_t tnow)
{ {
ddsrt_circlist_append(&deadline_adm->list, &elem->e); ddsrt_circlist_append(&deadline_adm->list, &elem->e);
elem->t_deadline = (tprev.v + deadline_adm->dur >= tnow.v) ? tprev : tnow; elem->t_deadline = (tprev.v + deadline_adm->dur >= tnow.v) ? tprev : tnow;
@ -92,7 +92,7 @@ void deadline_unregister_instance_real (struct deadline_adm *deadline_adm, struc
* this removed element expires. Only remove the element from the * this removed element expires. Only remove the element from the
* deadline list */ * deadline list */
elem->t_deadline = NN_MTIME_NEVER; elem->t_deadline = DDSRT_MTIME_NEVER;
ddsrt_circlist_remove(&deadline_adm->list, &elem->e); ddsrt_circlist_remove(&deadline_adm->list, &elem->e);
} }
@ -106,7 +106,7 @@ void deadline_renew_instance_real (struct deadline_adm *deadline_adm, struct dea
the callback the deadline (which will be the updated value) will be the callback the deadline (which will be the updated value) will be
checked for expiry */ checked for expiry */
ddsrt_circlist_remove(&deadline_adm->list, &elem->e); ddsrt_circlist_remove(&deadline_adm->list, &elem->e);
elem->t_deadline = now_mt(); elem->t_deadline = ddsrt_time_monotonic();
elem->t_deadline.v += deadline_adm->dur; elem->t_deadline.v += deadline_adm->dur;
ddsrt_circlist_append(&deadline_adm->list, &elem->e); ddsrt_circlist_append(&deadline_adm->list, &elem->e);
} }

View file

@ -17,7 +17,6 @@
#include "dds/ddsrt/log.h" #include "dds/ddsrt/log.h"
#include "dds/ddsrt/sockets.h" #include "dds/ddsrt/sockets.h"
#include "dds/ddsi/ddsi_ipaddr.h" #include "dds/ddsi/ddsi_ipaddr.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"

View file

@ -14,7 +14,6 @@
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/fibheap.h" #include "dds/ddsrt/fibheap.h"
#include "dds/ddsi/ddsi_lifespan.h" #include "dds/ddsi/ddsi_lifespan.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_xevent.h" #include "dds/ddsi/q_xevent.h"
static int compare_lifespan_texp (const void *va, const void *vb) static int compare_lifespan_texp (const void *va, const void *vb)
@ -26,33 +25,33 @@ static int compare_lifespan_texp (const void *va, const void *vb)
const ddsrt_fibheap_def_t lifespan_fhdef = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct lifespan_fhnode, heapnode), compare_lifespan_texp); const ddsrt_fibheap_def_t lifespan_fhdef = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct lifespan_fhnode, heapnode), compare_lifespan_texp);
static void lifespan_rhc_node_exp (struct xevent *xev, void *varg, nn_mtime_t tnow) static void lifespan_rhc_node_exp (struct xevent *xev, void *varg, ddsrt_mtime_t tnow)
{ {
struct lifespan_adm * const lifespan_adm = varg; struct lifespan_adm * const lifespan_adm = varg;
nn_mtime_t next_valid = lifespan_adm->sample_expired_cb((char *)lifespan_adm - lifespan_adm->fh_offset, tnow); ddsrt_mtime_t next_valid = lifespan_adm->sample_expired_cb((char *)lifespan_adm - lifespan_adm->fh_offset, tnow);
resched_xevent_if_earlier (xev, next_valid); resched_xevent_if_earlier (xev, next_valid);
} }
/* Gets the sample from the fibheap in lifespan admin that was expired first. If no more /* Gets the sample from the fibheap in lifespan admin that was expired first. If no more
* expired samples exist in the fibheap, the expiry time (nn_mtime_t) for the next sample to * expired samples exist in the fibheap, the expiry time (ddsrt_mtime_t) for the next sample to
* expire is returned. If the fibheap contains no more samples, NN_MTIME_NEVER is returned */ * expire is returned. If the fibheap contains no more samples, DDSRT_MTIME_NEVER is returned */
nn_mtime_t lifespan_next_expired_locked (const struct lifespan_adm *lifespan_adm, nn_mtime_t tnow, void **sample) ddsrt_mtime_t lifespan_next_expired_locked (const struct lifespan_adm *lifespan_adm, ddsrt_mtime_t tnow, void **sample)
{ {
struct lifespan_fhnode *node; struct lifespan_fhnode *node;
if ((node = ddsrt_fibheap_min(&lifespan_fhdef, &lifespan_adm->ls_exp_heap)) != NULL && node->t_expire.v <= tnow.v) if ((node = ddsrt_fibheap_min(&lifespan_fhdef, &lifespan_adm->ls_exp_heap)) != NULL && node->t_expire.v <= tnow.v)
{ {
*sample = (char *)node - lifespan_adm->fhn_offset; *sample = (char *)node - lifespan_adm->fhn_offset;
return (nn_mtime_t) { 0 }; return (ddsrt_mtime_t) { 0 };
} }
*sample = NULL; *sample = NULL;
return (node != NULL) ? node->t_expire : NN_MTIME_NEVER; return (node != NULL) ? node->t_expire : DDSRT_MTIME_NEVER;
} }
void lifespan_init (const struct ddsi_domaingv *gv, struct lifespan_adm *lifespan_adm, size_t fh_offset, size_t fh_node_offset, sample_expired_cb_t sample_expired_cb) void lifespan_init (const struct ddsi_domaingv *gv, struct lifespan_adm *lifespan_adm, size_t fh_offset, size_t fh_node_offset, sample_expired_cb_t sample_expired_cb)
{ {
ddsrt_fibheap_init (&lifespan_fhdef, &lifespan_adm->ls_exp_heap); ddsrt_fibheap_init (&lifespan_fhdef, &lifespan_adm->ls_exp_heap);
lifespan_adm->evt = qxev_callback (gv->xevents, NN_MTIME_NEVER, lifespan_rhc_node_exp, lifespan_adm); lifespan_adm->evt = qxev_callback (gv->xevents, DDSRT_MTIME_NEVER, lifespan_rhc_node_exp, lifespan_adm);
lifespan_adm->sample_expired_cb = sample_expired_cb; lifespan_adm->sample_expired_cb = sample_expired_cb;
lifespan_adm->fh_offset = fh_offset; lifespan_adm->fh_offset = fh_offset;
lifespan_adm->fhn_offset = fh_node_offset; lifespan_adm->fhn_offset = fh_node_offset;

View file

@ -0,0 +1,304 @@
/*
* 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 <ctype.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "dds/ddsrt/ifaddrs.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/md5.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/sockets.h"
#include "dds/ddsi/q_log.h"
#include "dds/ddsi/ddsi_ownip.h"
#include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_unused.h"
#include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_addrset.h" /* unspec locator */
#include "dds/ddsi/q_feature_check.h"
#include "dds/ddsi/ddsi_ipaddr.h"
#include "dds/ddsrt/avl.h"
static int multicast_override(const char *ifname, const struct config *config)
{
char *copy = ddsrt_strdup (config->assumeMulticastCapable), *cursor = copy, *tok;
int match = 0;
if (copy != NULL)
{
while ((tok = ddsrt_strsep (&cursor, ",")) != NULL)
{
if (ddsi2_patmatch (tok, ifname))
match = 1;
}
}
ddsrt_free (copy);
return match;
}
#ifdef __linux
/* FIMXE: HACK HACK */
#include <linux/if_packet.h>
#endif
int find_own_ip (struct ddsi_domaingv *gv, const char *requested_address)
{
const char *sep = " ";
char last_if_name[80] = "";
int quality = -1;
int i;
ddsrt_ifaddrs_t *ifa, *ifa_root = NULL;
int maxq_list[MAX_INTERFACES];
int maxq_count = 0;
size_t maxq_strlen = 0;
int selected_idx = -1;
char addrbuf[DDSI_LOCSTRLEN];
GVLOG (DDS_LC_CONFIG, "interfaces:");
{
int ret;
ret = ddsi_enumerate_interfaces(gv->m_factory, gv->config.transport_selector, &ifa_root);
if (ret < 0) {
GVERROR ("ddsi_enumerate_interfaces(%s): %d\n", gv->m_factory->m_typename, ret);
return 0;
}
}
gv->n_interfaces = 0;
last_if_name[0] = 0;
for (ifa = ifa_root; ifa != NULL; ifa = ifa->next)
{
char if_name[sizeof (last_if_name)];
int q = 0;
(void) ddsrt_strlcpy(if_name, ifa->name, sizeof(if_name));
if (strcmp (if_name, last_if_name))
GVLOG (DDS_LC_CONFIG, "%s%s", sep, if_name);
(void) ddsrt_strlcpy(last_if_name, if_name, sizeof(last_if_name));
/* interface must be up */
if ((ifa->flags & IFF_UP) == 0) {
GVLOG (DDS_LC_CONFIG, " (interface down)");
continue;
} else if (ddsrt_sockaddr_isunspecified(ifa->addr)) {
GVLOG (DDS_LC_CONFIG, " (address unspecified)");
continue;
}
switch (ifa->type)
{
case DDSRT_IFTYPE_WIFI:
GVLOG (DDS_LC_CONFIG, " wireless");
break;
case DDSRT_IFTYPE_WIRED:
GVLOG (DDS_LC_CONFIG, " wired");
break;
case DDSRT_IFTYPE_UNKNOWN:
break;
}
#if defined(__linux) && !LWIP_SOCKET
if (ifa->addr->sa_family == AF_PACKET)
{
/* FIXME: weirdo warning warranted */
nn_locator_t *l = &gv->interfaces[gv->n_interfaces].loc;
l->kind = NN_LOCATOR_KIND_RAWETH;
l->port = NN_LOCATOR_PORT_INVALID;
memset(l->address, 0, 10);
memcpy(l->address + 10, ((struct sockaddr_ll *)ifa->addr)->sll_addr, 6);
}
else
#endif
{
ddsi_ipaddr_to_loc(gv->m_factory, &gv->interfaces[gv->n_interfaces].loc, ifa->addr, gv->m_factory->m_kind);
}
ddsi_locator_to_string_no_port(addrbuf, sizeof(addrbuf), &gv->interfaces[gv->n_interfaces].loc);
GVLOG (DDS_LC_CONFIG, " %s(", addrbuf);
if (!(ifa->flags & IFF_MULTICAST) && multicast_override (if_name, &gv->config))
{
GVLOG (DDS_LC_CONFIG, "assume-mc:");
ifa->flags |= IFF_MULTICAST;
}
if (ifa->flags & IFF_LOOPBACK)
{
/* Loopback device has the lowest priority of every interface
available, because the other interfaces at least in principle
allow communicating with other machines. */
q += 0;
#if DDSRT_HAVE_IPV6
if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *)ifa->addr)->sin6_addr)))
q += 1;
#endif
}
else
{
#if DDSRT_HAVE_IPV6
/* We accept link-local IPv6 addresses, but an interface with a
link-local address will end up lower in the ordering than one
with a global address. When forced to use a link-local
address, we restrict ourselves to operating on that one
interface only and assume any advertised (incoming) link-local
address belongs to that interface. FIXME: this is wrong, and
should be changed to tag addresses with the interface over
which it was received. But that means proper multi-homing
support and has quite an impact in various places, not least of
which is the abstraction layer. */
if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *)ifa->addr)->sin6_addr)))
q += 5;
#endif
/* We strongly prefer a multicast capable interface, if that's
not available anything that's not point-to-point, or else we
hope IP routing will take care of the issues. */
if (ifa->flags & IFF_MULTICAST)
q += 4;
else if (!(ifa->flags & IFF_POINTOPOINT))
q += 3;
else
q += 2;
}
GVLOG (DDS_LC_CONFIG, "q%d)", q);
if (q == quality) {
maxq_list[maxq_count] = gv->n_interfaces;
maxq_strlen += 2 + strlen (if_name);
maxq_count++;
} else if (q > quality) {
maxq_list[0] = gv->n_interfaces;
maxq_strlen += 2 + strlen (if_name);
maxq_count = 1;
quality = q;
}
if (ifa->addr->sa_family == AF_INET && ifa->netmask)
{
ddsi_ipaddr_to_loc(gv->m_factory, &gv->interfaces[gv->n_interfaces].netmask, ifa->netmask, gv->m_factory->m_kind);
}
else
{
gv->interfaces[gv->n_interfaces].netmask.kind = gv->m_factory->m_kind;
gv->interfaces[gv->n_interfaces].netmask.port = NN_LOCATOR_PORT_INVALID;
memset(&gv->interfaces[gv->n_interfaces].netmask.address, 0, sizeof(gv->interfaces[gv->n_interfaces].netmask.address));
}
gv->interfaces[gv->n_interfaces].mc_capable = ((ifa->flags & IFF_MULTICAST) != 0);
gv->interfaces[gv->n_interfaces].mc_flaky = ((ifa->type == DDSRT_IFTYPE_WIFI) != 0);
gv->interfaces[gv->n_interfaces].point_to_point = ((ifa->flags & IFF_POINTOPOINT) != 0);
gv->interfaces[gv->n_interfaces].if_index = ifa->index;
gv->interfaces[gv->n_interfaces].name = ddsrt_strdup (if_name);
gv->n_interfaces++;
}
GVLOG (DDS_LC_CONFIG, "\n");
ddsrt_freeifaddrs (ifa_root);
if (requested_address == NULL)
{
if (maxq_count > 1)
{
const int idx = maxq_list[0];
char *names;
int p;
ddsi_locator_to_string_no_port (addrbuf, sizeof(addrbuf), &gv->interfaces[idx].loc);
names = ddsrt_malloc (maxq_strlen + 1);
p = 0;
for (i = 0; i < maxq_count && (size_t) p < maxq_strlen; i++)
p += snprintf (names + p, maxq_strlen - (size_t) p, ", %s", gv->interfaces[maxq_list[i]].name);
GVWARNING ("using network interface %s (%s) selected arbitrarily from: %s\n",
gv->interfaces[idx].name, addrbuf, names + 2);
ddsrt_free (names);
}
if (maxq_count > 0)
selected_idx = maxq_list[0];
else
GVERROR ("failed to determine default own IP address\n");
}
else
{
nn_locator_t req;
/* Presumably an interface name */
for (i = 0; i < gv->n_interfaces; i++)
{
if (strcmp (gv->interfaces[i].name, gv->config.networkAddressString) == 0)
break;
}
if (i < gv->n_interfaces)
; /* got a match */
else if (ddsi_locator_from_string(gv, &req, gv->config.networkAddressString, gv->m_factory) != AFSR_OK)
; /* not good, i = gv->n_interfaces, so error handling will kick in */
else
{
/* Try an exact match on the address */
for (i = 0; i < gv->n_interfaces; i++)
if (compare_locators(&gv->interfaces[i].loc, &req) == 0)
break;
if (i == gv->n_interfaces && req.kind == NN_LOCATOR_KIND_UDPv4)
{
/* Try matching on network portion only, where the network
portion is based on the netmask of the interface under
consideration */
for (i = 0; i < gv->n_interfaces; i++)
{
uint32_t req1, ip1, nm1;
memcpy (&req1, req.address + 12, sizeof (req1));
memcpy (&ip1, gv->interfaces[i].loc.address + 12, sizeof (ip1));
memcpy (&nm1, gv->interfaces[i].netmask.address + 12, sizeof (nm1));
/* If the host portion of the requested address is non-zero,
skip this interface */
if (req1 & ~nm1)
continue;
if ((req1 & nm1) == (ip1 & nm1))
break;
}
}
}
if (i < gv->n_interfaces)
selected_idx = i;
else
GVERROR ("%s: does not match an available interface\n", gv->config.networkAddressString);
}
if (selected_idx < 0)
return 0;
else
{
gv->ownloc = gv->interfaces[selected_idx].loc;
gv->selected_interface = selected_idx;
gv->interfaceNo = gv->interfaces[selected_idx].if_index;
#if DDSRT_HAVE_IPV6
if (gv->extloc.kind == NN_LOCATOR_KIND_TCPv6 || gv->extloc.kind == NN_LOCATOR_KIND_UDPv6)
{
struct sockaddr_in6 addr;
memcpy(&addr.sin6_addr, gv->ownloc.address, sizeof(addr.sin6_addr));
gv->ipv6_link_local = IN6_IS_ADDR_LINKLOCAL (&addr.sin6_addr) != 0;
}
else
{
gv->ipv6_link_local = 0;
}
#endif
GVLOG (DDS_LC_CONFIG, "selected interface: %s (index %u)\n",
gv->interfaces[selected_idx].name, gv->interfaceNo);
return 1;
}
}

View file

@ -25,7 +25,7 @@
#include "dds/ddsi/q_bswap.h" #include "dds/ddsi/q_bswap.h"
#include "dds/ddsi/q_unused.h" #include "dds/ddsi/q_unused.h"
#include "dds/ddsi/ddsi_plist.h" #include "dds/ddsi/ddsi_plist.h"
#include "dds/ddsi/q_time.h" #include "dds/ddsi/ddsi_time.h"
#include "dds/ddsi/q_xmsg.h" #include "dds/ddsi/q_xmsg.h"
#include "dds/ddsi/ddsi_xqos.h" #include "dds/ddsi/ddsi_xqos.h"
#include "dds/ddsi/ddsi_vendor.h" #include "dds/ddsi/ddsi_vendor.h"
@ -283,7 +283,7 @@ static dds_return_t deser_reliability (void * __restrict dst, size_t * __restric
if (validate_external_duration (&mbt) < 0) if (validate_external_duration (&mbt) < 0)
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
x->kind = (enum dds_reliability_kind) (kind - 1); x->kind = (enum dds_reliability_kind) (kind - 1);
x->max_blocking_time = nn_from_ddsi_duration (mbt); x->max_blocking_time = ddsi_from_ddsi_duration (mbt);
*dstoff += sizeof (*x); *dstoff += sizeof (*x);
*flagset->present |= flag; *flagset->present |= flag;
return 0; return 0;
@ -295,7 +295,7 @@ static dds_return_t ser_reliability (struct nn_xmsg *xmsg, nn_parameterid_t pid,
DDSRT_STATIC_ASSERT (DDS_EXTERNAL_RELIABILITY_BEST_EFFORT == 1 && DDS_EXTERNAL_RELIABILITY_RELIABLE == 2 && DDSRT_STATIC_ASSERT (DDS_EXTERNAL_RELIABILITY_BEST_EFFORT == 1 && DDS_EXTERNAL_RELIABILITY_RELIABLE == 2 &&
DDS_RELIABILITY_BEST_EFFORT == 0 && DDS_RELIABILITY_RELIABLE == 1); DDS_RELIABILITY_BEST_EFFORT == 0 && DDS_RELIABILITY_RELIABLE == 1);
dds_reliability_qospolicy_t const * const x = deser_generic_src (src, &srcoff, alignof (dds_reliability_qospolicy_t)); dds_reliability_qospolicy_t const * const x = deser_generic_src (src, &srcoff, alignof (dds_reliability_qospolicy_t));
ddsi_duration_t mbt = nn_to_ddsi_duration (x->max_blocking_time); ddsi_duration_t mbt = ddsi_to_ddsi_duration (x->max_blocking_time);
uint32_t * const p = nn_xmsg_addpar_bo (xmsg, pid, 3 * sizeof (uint32_t), be); uint32_t * const p = nn_xmsg_addpar_bo (xmsg, pid, 3 * sizeof (uint32_t), be);
p[0] = BO4U(1 + (uint32_t) x->kind); p[0] = BO4U(1 + (uint32_t) x->kind);
p[1] = BO4U((uint32_t) mbt.seconds); p[1] = BO4U((uint32_t) mbt.seconds);
@ -660,7 +660,7 @@ static dds_return_t deser_generic_r (void * __restrict dst, size_t * __restrict
goto fail; goto fail;
if (validate_external_duration (&tmp)) if (validate_external_duration (&tmp))
goto fail; goto fail;
x[i] = nn_from_ddsi_duration (tmp); x[i] = ddsi_from_ddsi_duration (tmp);
} }
*dstoff += cnt * sizeof (*x); *dstoff += cnt * sizeof (*x);
break; break;
@ -931,7 +931,7 @@ static dds_return_t ser_generic_embeddable (char * const data, size_t *dstoff, c
uint32_t * const p = ser_generic_align4 (data, dstoff); uint32_t * const p = ser_generic_align4 (data, dstoff);
for (uint32_t i = 0; i < cnt; i++) for (uint32_t i = 0; i < cnt; i++)
{ {
ddsi_duration_t tmp = nn_to_ddsi_duration (x[i]); ddsi_duration_t tmp = ddsi_to_ddsi_duration (x[i]);
p[2 * i + 0] = BO4U((uint32_t) tmp.seconds); p[2 * i + 0] = BO4U((uint32_t) tmp.seconds);
p[2 * i + 1] = BO4U(tmp.fraction); p[2 * i + 1] = BO4U(tmp.fraction);
} }
@ -1611,28 +1611,28 @@ static const struct piddesc piddesc_omg[] = {
/* Understood parameters for Eclipse Foundation (Cyclone DDS) vendor code */ /* Understood parameters for Eclipse Foundation (Cyclone DDS) vendor code */
static const struct piddesc piddesc_eclipse[] = { static const struct piddesc piddesc_eclipse[] = {
QP (PRISMTECH_ENTITY_FACTORY, entity_factory, Xb), QP (ADLINK_ENTITY_FACTORY, entity_factory, Xb),
QP (PRISMTECH_READER_LIFESPAN, reader_lifespan, Xb, XD), QP (ADLINK_READER_LIFESPAN, reader_lifespan, Xb, XD),
QP (PRISMTECH_WRITER_DATA_LIFECYCLE, writer_data_lifecycle, Xb), QP (ADLINK_WRITER_DATA_LIFECYCLE, writer_data_lifecycle, Xb),
QP (PRISMTECH_READER_DATA_LIFECYCLE, reader_data_lifecycle, XDx2), QP (ADLINK_READER_DATA_LIFECYCLE, reader_data_lifecycle, XDx2),
QP (PRISMTECH_SUBSCRIPTION_KEYS, subscription_keys, XbCOND, XQ, XS, XSTOP), QP (ADLINK_SUBSCRIPTION_KEYS, subscription_keys, XbCOND, XQ, XS, XSTOP),
{ PID_PAD, PDF_QOS, QP_CYCLONE_IGNORELOCAL, "CYCLONE_IGNORELOCAL", { PID_PAD, PDF_QOS, QP_CYCLONE_IGNORELOCAL, "CYCLONE_IGNORELOCAL",
offsetof (struct ddsi_plist, qos.ignorelocal), membersize (struct ddsi_plist, qos.ignorelocal), offsetof (struct ddsi_plist, qos.ignorelocal), membersize (struct ddsi_plist, qos.ignorelocal),
{ .desc = { XE2, XSTOP } }, 0 }, { .desc = { XE2, XSTOP } }, 0 },
PP (PRISMTECH_PARTICIPANT_VERSION_INFO, prismtech_participant_version_info, Xux5, XS), PP (ADLINK_PARTICIPANT_VERSION_INFO, adlink_participant_version_info, Xux5, XS),
PP (PRISMTECH_TYPE_DESCRIPTION, type_description, XS), PP (ADLINK_TYPE_DESCRIPTION, type_description, XS),
{ PID_SENTINEL, 0, 0, NULL, 0, 0, { .desc = { XSTOP } }, 0 } { PID_SENTINEL, 0, 0, NULL, 0, 0, { .desc = { XSTOP } }, 0 }
}; };
/* Understood parameters for PrismTech vendor code */ /* Understood parameters for Adlink vendor code */
static const struct piddesc piddesc_prismtech[] = { static const struct piddesc piddesc_adlink[] = {
QP (PRISMTECH_ENTITY_FACTORY, entity_factory, Xb), QP (ADLINK_ENTITY_FACTORY, entity_factory, Xb),
QP (PRISMTECH_READER_LIFESPAN, reader_lifespan, Xb, XD), QP (ADLINK_READER_LIFESPAN, reader_lifespan, Xb, XD),
QP (PRISMTECH_WRITER_DATA_LIFECYCLE, writer_data_lifecycle, Xb), QP (ADLINK_WRITER_DATA_LIFECYCLE, writer_data_lifecycle, Xb),
QP (PRISMTECH_READER_DATA_LIFECYCLE, reader_data_lifecycle, XDx2), QP (ADLINK_READER_DATA_LIFECYCLE, reader_data_lifecycle, XDx2),
QP (PRISMTECH_SUBSCRIPTION_KEYS, subscription_keys, XbCOND, XQ, XS, XSTOP), QP (ADLINK_SUBSCRIPTION_KEYS, subscription_keys, XbCOND, XQ, XS, XSTOP),
PP (PRISMTECH_PARTICIPANT_VERSION_INFO, prismtech_participant_version_info, Xux5, XS), PP (ADLINK_PARTICIPANT_VERSION_INFO, adlink_participant_version_info, Xux5, XS),
PP (PRISMTECH_TYPE_DESCRIPTION, type_description, XS), PP (ADLINK_TYPE_DESCRIPTION, type_description, XS),
{ PID_SENTINEL, 0, 0, NULL, 0, 0, { .desc = { XSTOP } }, 0 } { PID_SENTINEL, 0, 0, NULL, 0, 0, { .desc = { XSTOP } }, 0 }
}; };
@ -1696,7 +1696,7 @@ struct piddesc_index {
static const struct piddesc *piddesc_omg_index[DEFAULT_OMG_PIDS_ARRAY_SIZE + SECURITY_OMG_PIDS_ARRAY_SIZE]; static const struct piddesc *piddesc_omg_index[DEFAULT_OMG_PIDS_ARRAY_SIZE + SECURITY_OMG_PIDS_ARRAY_SIZE];
static const struct piddesc *piddesc_eclipse_index[19]; static const struct piddesc *piddesc_eclipse_index[19];
static const struct piddesc *piddesc_prismtech_index[19]; static const struct piddesc *piddesc_adlink_index[19];
#define INDEX_ANY(vendorid_, tab_) [vendorid_] = { \ #define INDEX_ANY(vendorid_, tab_) [vendorid_] = { \
.index_max = sizeof (piddesc_##tab_##_index) / sizeof (piddesc_##tab_##_index[0]) - 1, \ .index_max = sizeof (piddesc_##tab_##_index) / sizeof (piddesc_##tab_##_index[0]) - 1, \
@ -1707,11 +1707,11 @@ static const struct piddesc *piddesc_prismtech_index[19];
static const struct piddesc_index piddesc_vendor_index[] = { static const struct piddesc_index piddesc_vendor_index[] = {
INDEX_ANY (0, omg), INDEX_ANY (0, omg),
INDEX (ECLIPSE, eclipse), INDEX (ECLIPSE, eclipse),
INDEX (PRISMTECH_OSPL, prismtech), INDEX (ADLINK_OSPL, adlink),
INDEX (PRISMTECH_JAVA, prismtech), INDEX (ADLINK_JAVA, adlink),
INDEX (PRISMTECH_LITE, prismtech), INDEX (ADLINK_LITE, adlink),
INDEX (PRISMTECH_GATEWAY, prismtech), INDEX (ADLINK_GATEWAY, adlink),
INDEX (PRISMTECH_CLOUD, prismtech) INDEX (ADLINK_CLOUD, adlink)
}; };
#undef INDEX #undef INDEX
@ -2869,7 +2869,6 @@ unsigned char *ddsi_plist_quickscan (struct nn_rsample_info *dest, const struct
const unsigned char *pl; const unsigned char *pl;
(void)rmsg; (void)rmsg;
dest->statusinfo = 0; dest->statusinfo = 0;
dest->pt_wr_info_zoff = NN_OFF_TO_ZOFF (0);
dest->complex_qos = 0; dest->complex_qos = 0;
switch (src->encoding) switch (src->encoding)
{ {
@ -2965,7 +2964,7 @@ void ddsi_plist_init_default_participant (ddsi_plist_t *plist)
{ {
ddsi_plist_init_empty (plist); ddsi_plist_init_empty (plist);
plist->qos.present |= QP_PRISMTECH_ENTITY_FACTORY; plist->qos.present |= QP_ADLINK_ENTITY_FACTORY;
plist->qos.entity_factory.autoenable_created_entities = 0; plist->qos.entity_factory.autoenable_created_entities = 0;
plist->qos.present |= QP_USER_DATA; plist->qos.present |= QP_USER_DATA;
@ -2986,14 +2985,14 @@ static void xqos_init_default_common (dds_qos_t *xqos)
xqos->durability.kind = DDS_DURABILITY_VOLATILE; xqos->durability.kind = DDS_DURABILITY_VOLATILE;
xqos->present |= QP_DEADLINE; xqos->present |= QP_DEADLINE;
xqos->deadline.deadline = T_NEVER; xqos->deadline.deadline = DDS_INFINITY;
xqos->present |= QP_LATENCY_BUDGET; xqos->present |= QP_LATENCY_BUDGET;
xqos->latency_budget.duration = 0; xqos->latency_budget.duration = 0;
xqos->present |= QP_LIVELINESS; xqos->present |= QP_LIVELINESS;
xqos->liveliness.kind = DDS_LIVELINESS_AUTOMATIC; xqos->liveliness.kind = DDS_LIVELINESS_AUTOMATIC;
xqos->liveliness.lease_duration = T_NEVER; xqos->liveliness.lease_duration = DDS_INFINITY;
xqos->present |= QP_DESTINATION_ORDER; xqos->present |= QP_DESTINATION_ORDER;
xqos->destination_order.kind = DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP; xqos->destination_order.kind = DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP;
@ -3048,15 +3047,15 @@ void ddsi_xqos_init_default_reader (dds_qos_t *xqos)
xqos->present |= QP_TIME_BASED_FILTER; xqos->present |= QP_TIME_BASED_FILTER;
xqos->time_based_filter.minimum_separation = 0; xqos->time_based_filter.minimum_separation = 0;
xqos->present |= QP_PRISMTECH_READER_DATA_LIFECYCLE; xqos->present |= QP_ADLINK_READER_DATA_LIFECYCLE;
xqos->reader_data_lifecycle.autopurge_nowriter_samples_delay = T_NEVER; xqos->reader_data_lifecycle.autopurge_nowriter_samples_delay = DDS_INFINITY;
xqos->reader_data_lifecycle.autopurge_disposed_samples_delay = T_NEVER; xqos->reader_data_lifecycle.autopurge_disposed_samples_delay = DDS_INFINITY;
xqos->present |= QP_PRISMTECH_READER_LIFESPAN; xqos->present |= QP_ADLINK_READER_LIFESPAN;
xqos->reader_lifespan.use_lifespan = 0; xqos->reader_lifespan.use_lifespan = 0;
xqos->reader_lifespan.duration = T_NEVER; xqos->reader_lifespan.duration = DDS_INFINITY;
xqos->present |= QP_PRISMTECH_SUBSCRIPTION_KEYS; xqos->present |= QP_ADLINK_SUBSCRIPTION_KEYS;
xqos->subscription_keys.use_key_list = 0; xqos->subscription_keys.use_key_list = 0;
xqos->subscription_keys.key_list.n = 0; xqos->subscription_keys.key_list.n = 0;
xqos->subscription_keys.key_list.strs = NULL; xqos->subscription_keys.key_list.strs = NULL;
@ -3076,7 +3075,7 @@ void ddsi_xqos_init_default_writer (dds_qos_t *xqos)
xqos->present |= QP_RELIABILITY; xqos->present |= QP_RELIABILITY;
xqos->reliability.kind = DDS_RELIABILITY_RELIABLE; xqos->reliability.kind = DDS_RELIABILITY_RELIABLE;
xqos->reliability.max_blocking_time = 100 * T_MILLISECOND; xqos->reliability.max_blocking_time = DDS_MSECS (100);
xqos->present |= QP_OWNERSHIP_STRENGTH; xqos->present |= QP_OWNERSHIP_STRENGTH;
xqos->ownership_strength.value = 0; xqos->ownership_strength.value = 0;
@ -3085,9 +3084,9 @@ void ddsi_xqos_init_default_writer (dds_qos_t *xqos)
xqos->transport_priority.value = 0; xqos->transport_priority.value = 0;
xqos->present |= QP_LIFESPAN; xqos->present |= QP_LIFESPAN;
xqos->lifespan.duration = T_NEVER; xqos->lifespan.duration = DDS_INFINITY;
xqos->present |= QP_PRISMTECH_WRITER_DATA_LIFECYCLE; xqos->present |= QP_ADLINK_WRITER_DATA_LIFECYCLE;
xqos->writer_data_lifecycle.autodispose_unregistered_instances = 1; xqos->writer_data_lifecycle.autodispose_unregistered_instances = 1;
} }
@ -3111,15 +3110,15 @@ void ddsi_xqos_init_default_topic (dds_qos_t *xqos)
xqos->present |= QP_RELIABILITY; xqos->present |= QP_RELIABILITY;
xqos->reliability.kind = DDS_RELIABILITY_BEST_EFFORT; xqos->reliability.kind = DDS_RELIABILITY_BEST_EFFORT;
xqos->reliability.max_blocking_time = 100 * T_MILLISECOND; xqos->reliability.max_blocking_time = DDS_MSECS (100);
xqos->present |= QP_TRANSPORT_PRIORITY; xqos->present |= QP_TRANSPORT_PRIORITY;
xqos->transport_priority.value = 0; xqos->transport_priority.value = 0;
xqos->present |= QP_LIFESPAN; xqos->present |= QP_LIFESPAN;
xqos->lifespan.duration = T_NEVER; xqos->lifespan.duration = DDS_INFINITY;
xqos->present |= QP_PRISMTECH_SUBSCRIPTION_KEYS; xqos->present |= QP_ADLINK_SUBSCRIPTION_KEYS;
xqos->subscription_keys.use_key_list = 0; xqos->subscription_keys.use_key_list = 0;
xqos->subscription_keys.key_list.n = 0; xqos->subscription_keys.key_list.n = 0;
xqos->subscription_keys.key_list.strs = NULL; xqos->subscription_keys.key_list.strs = NULL;
@ -3133,7 +3132,7 @@ static void ddsi_xqos_init_default_publisher_subscriber (dds_qos_t *xqos)
xqos->group_data.length = 0; xqos->group_data.length = 0;
xqos->group_data.value = NULL; xqos->group_data.value = NULL;
xqos->present |= QP_PRISMTECH_ENTITY_FACTORY; xqos->present |= QP_ADLINK_ENTITY_FACTORY;
xqos->entity_factory.autoenable_created_entities = 1; xqos->entity_factory.autoenable_created_entities = 1;
xqos->present |= QP_PARTITION; xqos->present |= QP_PARTITION;

View file

@ -25,7 +25,6 @@
#include "dds/ddsi/q_protocol.h" #include "dds/ddsi/q_protocol.h"
#include "dds/ddsi/q_radmin.h" #include "dds/ddsi/q_radmin.h"
#include "dds/ddsi/q_rtps.h" #include "dds/ddsi/q_rtps.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_transmit.h" #include "dds/ddsi/q_transmit.h"
#include "dds/ddsi/q_xmsg.h" #include "dds/ddsi/q_xmsg.h"
@ -57,7 +56,7 @@ void write_pmd_message_guid (struct ddsi_domaingv * const gv, struct ddsi_guid *
else else
{ {
if ((lease = ddsrt_atomic_ldvoidp (&pp->minl_man)) != NULL) if ((lease = ddsrt_atomic_ldvoidp (&pp->minl_man)) != NULL)
lease_renew (lease, now_et()); lease_renew (lease, ddsrt_time_elapsed());
write_pmd_message (ts1, NULL, pp, pmd_kind); write_pmd_message (ts1, NULL, pp, pmd_kind);
} }
thread_state_asleep (ts1); thread_state_asleep (ts1);
@ -93,7 +92,7 @@ void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, s
.keysize = 16 .keysize = 16
}; };
serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw); serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw);
serdata->timestamp = now (); serdata->timestamp = ddsrt_time_wallclock ();
tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata);
write_sample_nogc (ts1, xp, wr, serdata, tk); write_sample_nogc (ts1, xp, wr, serdata, tk);
@ -101,7 +100,7 @@ void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, s
#undef PMD_DATA_LENGTH #undef PMD_DATA_LENGTH
} }
void handle_pmd_message (const struct receiver_state *rst, nn_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len) void handle_pmd_message (const struct receiver_state *rst, ddsrt_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len)
{ {
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
const int bswap = (data->identifier == CDR_LE) ^ (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN); const int bswap = (data->identifier == CDR_LE) ^ (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN);
@ -139,7 +138,7 @@ void handle_pmd_message (const struct receiver_state *rst, nn_wctime_t timestamp
(l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL) (l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL)
{ {
/* Renew lease for entity with shortest manual-by-participant lease */ /* Renew lease for entity with shortest manual-by-participant lease */
lease_renew (l, now_et ()); lease_renew (l, ddsrt_time_elapsed ());
} }
} }
break; break;

View file

@ -13,7 +13,6 @@
#include "dds/ddsi/ddsi_raweth.h" #include "dds/ddsi/ddsi_raweth.h"
#include "dds/ddsi/ddsi_ipaddr.h" #include "dds/ddsi/ddsi_ipaddr.h"
#include "dds/ddsi/ddsi_mcgroup.h" #include "dds/ddsi/ddsi_mcgroup.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_pcap.h" #include "dds/ddsi/q_pcap.h"
@ -175,27 +174,27 @@ static int ddsi_raweth_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t
return ret; return ret;
} }
static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint32_t port, ddsi_tran_qos_t qos) static dds_return_t ddsi_raweth_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *qos)
{ {
ddsrt_socket_t sock; ddsrt_socket_t sock;
dds_return_t rc; dds_return_t rc;
ddsi_raweth_conn_t uc = NULL; ddsi_raweth_conn_t uc = NULL;
struct sockaddr_ll addr; struct sockaddr_ll addr;
bool mcast = (bool) (qos ? qos->m_multicast : 0); bool mcast = (qos->m_purpose == DDSI_TRAN_QOS_RECV_MC);
/* If port is zero, need to create dynamic port */ /* If port is zero, need to create dynamic port */
if (port == 0 || port > 65535) if (port == 0 || port > 65535)
{ {
DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u - using port number as ethernet type, %u won't do\n", mcast ? "multicast" : "unicast", port, port); DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u - using port number as ethernet type, %u won't do\n", mcast ? "multicast" : "unicast", port, port);
return NULL; return DDS_RETCODE_ERROR;
} }
rc = ddsrt_socket(&sock, PF_PACKET, SOCK_DGRAM, htons((uint16_t)port)); rc = ddsrt_socket(&sock, PF_PACKET, SOCK_DGRAM, htons((uint16_t)port));
if (rc != DDS_RETCODE_OK) if (rc != DDS_RETCODE_OK)
{ {
DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc); DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
return NULL; return DDS_RETCODE_ERROR;
} }
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
@ -208,13 +207,13 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
{ {
ddsrt_close(sock); ddsrt_close(sock);
DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s bind port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc); DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s bind port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
return NULL; return DDS_RETCODE_ERROR;
} }
if ((uc = (ddsi_raweth_conn_t) ddsrt_malloc (sizeof (*uc))) == NULL) if ((uc = (ddsi_raweth_conn_t) ddsrt_malloc (sizeof (*uc))) == NULL)
{ {
ddsrt_close(sock); ddsrt_close(sock);
return NULL; return DDS_RETCODE_ERROR;
} }
memset (uc, 0, sizeof (*uc)); memset (uc, 0, sizeof (*uc));
@ -231,7 +230,8 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
uc->m_base.m_disable_multiplexing_fn = 0; uc->m_base.m_disable_multiplexing_fn = 0;
DDS_CTRACE (&fact->gv->logconfig, "ddsi_raweth_create_conn %s socket %d port %u\n", mcast ? "multicast" : "unicast", uc->m_sock, uc->m_base.m_base.m_port); DDS_CTRACE (&fact->gv->logconfig, "ddsi_raweth_create_conn %s socket %d port %u\n", mcast ? "multicast" : "unicast", uc->m_sock, uc->m_base.m_base.m_port);
return &uc->m_base; *conn_out = &uc->m_base;
return DDS_RETCODE_OK;
} }
static int isbroadcast(const nn_locator_t *loc) static int isbroadcast(const nn_locator_t *loc)

View file

@ -144,7 +144,7 @@ bool write_auth_handshake_message(const struct participant *pp, const struct pro
.keysize = 0 .keysize = 0
}; };
serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw); serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw);
serdata->timestamp = now (); serdata->timestamp = ddsrt_time_wallclock ();
result = enqueue_sample_wrlock_held (wr, seq, NULL, serdata, prd, 1) == 0; result = enqueue_sample_wrlock_held (wr, seq, NULL, serdata, prd, 1) == 0;
ddsi_serdata_unref (serdata); ddsi_serdata_unref (serdata);
@ -173,7 +173,7 @@ void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_
nn_xmsg_free (mpayload); nn_xmsg_free (mpayload);
} }
void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, size_t len) void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, size_t len)
{ {
const struct CDRHeader *hdr = vdata; /* built-ins not deserialized (yet) */ const struct CDRHeader *hdr = vdata; /* built-ins not deserialized (yet) */
const bool bswap = (hdr->identifier == CDR_LE) ^ DDSRT_LITTLE_ENDIAN; const bool bswap = (hdr->identifier == CDR_LE) ^ DDSRT_LITTLE_ENDIAN;
@ -331,7 +331,7 @@ bool write_crypto_reader_tokens(const struct reader *rd, const struct proxy_writ
return write_crypto_exchange_message(pp, &proxypp->e.guid, &rd->e.guid, &pwr->e.guid, GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS, tokens); return write_crypto_exchange_message(pp, &proxypp->e.guid, &rd->e.guid, &pwr->e.guid, GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS, tokens);
} }
void handle_crypto_exchange_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) void handle_crypto_exchange_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len)
{ {
struct ddsi_domaingv *gv = rst->gv; struct ddsi_domaingv *gv = rst->gv;
const struct CDRHeader *hdr = vdata; /* built-ins not deserialized (yet) */ const struct CDRHeader *hdr = vdata; /* built-ins not deserialized (yet) */

View file

@ -2524,7 +2524,7 @@ void q_omg_security_set_remote_writer_crypto_tokens(struct reader *rd, const dds
ddsrt_mutex_unlock(&rd->e.lock); ddsrt_mutex_unlock(&rd->e.lock);
if (match->matched) if (match->matched)
connect_reader_with_proxy_writer_secure(rd, pwr, now_mt (), match->crypto_handle); connect_reader_with_proxy_writer_secure(rd, pwr, ddsrt_time_monotonic (), match->crypto_handle);
if (pwr) if (pwr)
notify_handshake_recv_token(rd->c.pp, pwr->c.proxypp); notify_handshake_recv_token(rd->c.pp, pwr->c.proxypp);
@ -2571,7 +2571,7 @@ void q_omg_security_set_remote_reader_crypto_tokens(struct writer *wr, const dds
ddsrt_mutex_unlock(&wr->e.lock); ddsrt_mutex_unlock(&wr->e.lock);
if (match->matched) if (match->matched)
connect_writer_with_proxy_reader_secure(wr, prd, now_mt (), match->crypto_handle); connect_writer_with_proxy_reader_secure(wr, prd, ddsrt_time_monotonic (), match->crypto_handle);
if (prd) if (prd)
notify_handshake_recv_token(wr->c.pp, prd->c.proxypp); notify_handshake_recv_token(wr->c.pp, prd->c.proxypp);

View file

@ -74,7 +74,6 @@ struct ddsi_sertopic *ddsi_sertopic_lookup_locked (struct ddsi_domaingv *gv, con
void ddsi_sertopic_register_locked (struct ddsi_domaingv *gv, struct ddsi_sertopic *sertopic) void ddsi_sertopic_register_locked (struct ddsi_domaingv *gv, struct ddsi_sertopic *sertopic)
{ {
assert (sertopic->gv == NULL); assert (sertopic->gv == NULL);
assert (ddsrt_atomic_ld32 (&sertopic->refc) == 1);
(void) ddsi_sertopic_ref (sertopic); (void) ddsi_sertopic_ref (sertopic);
sertopic->gv = gv; sertopic->gv = gv;

View file

@ -38,11 +38,15 @@ static bool sertopic_default_equal (const struct ddsi_sertopic *acmn, const stru
return false; return false;
if (a->type.m_nkeys != b->type.m_nkeys) if (a->type.m_nkeys != b->type.m_nkeys)
return false; return false;
if (memcmp (a->type.m_keys, b->type.m_keys, a->type.m_nkeys * sizeof (*a->type.m_keys)) != 0) if (
(a->type.m_nkeys > 0) &&
memcmp (a->type.m_keys, b->type.m_keys, a->type.m_nkeys * sizeof (*a->type.m_keys)) != 0)
return false; return false;
if (a->type.m_nops != b->type.m_nops) if (a->type.m_nops != b->type.m_nops)
return false; return false;
if (memcmp (a->type.m_ops, b->type.m_ops, a->type.m_nops * sizeof (*a->type.m_ops)) != 0) if (
(a->type.m_nops > 0) &&
memcmp (a->type.m_ops, b->type.m_ops, a->type.m_nops * sizeof (*a->type.m_ops)) != 0)
return false; return false;
assert (a->opt_size == b->opt_size); assert (a->opt_size == b->opt_size);
return true; return true;
@ -52,7 +56,7 @@ static uint32_t sertopic_default_hash (const struct ddsi_sertopic *tpcmn)
{ {
const struct ddsi_sertopic_default *tp = (struct ddsi_sertopic_default *) tpcmn; const struct ddsi_sertopic_default *tp = (struct ddsi_sertopic_default *) tpcmn;
uint32_t h = 0; uint32_t h = 0;
h = ddsrt_mh3 (&tp->native_encoding_identifier, sizeof (tp->native_encoding_identifier), 0); h = ddsrt_mh3 (&tp->native_encoding_identifier, sizeof (tp->native_encoding_identifier), h);
h = ddsrt_mh3 (&tp->type.m_size, sizeof (tp->type.m_size), h); h = ddsrt_mh3 (&tp->type.m_size, sizeof (tp->type.m_size), h);
h = ddsrt_mh3 (&tp->type.m_align, sizeof (tp->type.m_align), h); h = ddsrt_mh3 (&tp->type.m_align, sizeof (tp->type.m_align), h);
h = ddsrt_mh3 (&tp->type.m_flagset, sizeof (tp->type.m_flagset), h); h = ddsrt_mh3 (&tp->type.m_flagset, sizeof (tp->type.m_flagset), h);

View file

@ -21,7 +21,6 @@
#include "dds/ddsi/ddsi_tcp.h" #include "dds/ddsi/ddsi_tcp.h"
#include "dds/ddsi/ddsi_ipaddr.h" #include "dds/ddsi/ddsi_ipaddr.h"
#include "dds/ddsrt/avl.h" #include "dds/ddsrt/avl.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
@ -40,9 +39,15 @@
wait set that manages their lifecycle. wait set that manages their lifecycle.
*/ */
union addr {
struct sockaddr a;
struct sockaddr_in a4;
struct sockaddr_in6 a6;
};
typedef struct ddsi_tcp_conn { typedef struct ddsi_tcp_conn {
struct ddsi_tran_conn m_base; struct ddsi_tran_conn m_base;
struct sockaddr_storage m_peer_addr; union addr m_peer_addr;
uint32_t m_peer_port; uint32_t m_peer_port;
ddsrt_mutex_t m_mutex; ddsrt_mutex_t m_mutex;
ddsrt_socket_t m_sock; ddsrt_socket_t m_sock;
@ -71,8 +76,8 @@ struct ddsi_tran_factory_tcp {
static int ddsi_tcp_cmp_conn (const struct ddsi_tcp_conn *c1, const struct ddsi_tcp_conn *c2) static int ddsi_tcp_cmp_conn (const struct ddsi_tcp_conn *c1, const struct ddsi_tcp_conn *c2)
{ {
const struct sockaddr *a1s = (struct sockaddr *)&c1->m_peer_addr; const struct sockaddr *a1s = &c1->m_peer_addr.a;
const struct sockaddr *a2s = (struct sockaddr *)&c2->m_peer_addr; const struct sockaddr *a2s = &c2->m_peer_addr.a;
if (a1s->sa_family != a2s->sa_family) if (a1s->sa_family != a2s->sa_family)
return (a1s->sa_family < a2s->sa_family) ? -1 : 1; return (a1s->sa_family < a2s->sa_family) ? -1 : 1;
else if (c1->m_peer_port != c2->m_peer_port) else if (c1->m_peer_port != c2->m_peer_port)
@ -133,44 +138,103 @@ static void ddsi_tcp_cache_dump (void)
} }
*/ */
static unsigned short get_socket_port (struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket) static uint16_t get_socket_port (struct ddsi_domaingv const * const gv, ddsrt_socket_t socket)
{ {
struct sockaddr_storage addr; union addr addr;
socklen_t addrlen = sizeof (addr); socklen_t addrlen = sizeof (addr);
dds_return_t ret; dds_return_t ret;
ret = ddsrt_getsockname(socket, (struct sockaddr *)&addr, &addrlen); ret = ddsrt_getsockname(socket, &addr.a, &addrlen);
if (ret != DDS_RETCODE_OK) { if (ret != DDS_RETCODE_OK) {
DDS_CERROR (logcfg, "ddsi_tcp_get_socket_port: ddsrt_getsockname retcode %"PRId32"\n", ret); GVERROR ("ddsi_tcp_get_socket_port: ddsrt_getsockname retcode %"PRId32"\n", ret);
return 0; return 0;
} }
return ddsrt_sockaddr_get_port((struct sockaddr *)&addr); return ddsrt_sockaddr_get_port (&addr.a);
} }
static void ddsi_tcp_conn_set_socket (ddsi_tcp_conn_t conn, ddsrt_socket_t sock) static void ddsi_tcp_conn_set_socket (ddsi_tcp_conn_t conn, ddsrt_socket_t sock)
{ {
struct ddsi_domaingv const * const gv = conn->m_base.m_base.gv;
conn->m_sock = sock; conn->m_sock = sock;
conn->m_base.m_base.m_port = (sock == DDSRT_INVALID_SOCKET) ? INVALID_PORT : get_socket_port (&conn->m_base.m_base.gv->logconfig, sock); conn->m_base.m_base.m_port = (sock == DDSRT_INVALID_SOCKET) ? INVALID_PORT : get_socket_port (gv, sock);
} }
static void ddsi_tcp_sock_free (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, const char *msg) static void ddsi_tcp_sock_free (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const char *msg)
{ {
if (sock != DDSRT_INVALID_SOCKET) if (sock != DDSRT_INVALID_SOCKET)
{ {
if (msg) if (msg)
{ GVLOG (DDS_LC_TCP, "tcp %s free socket %"PRIdSOCK"\n", msg, sock);
DDS_CLOG (DDS_LC_TCP, logcfg, "tcp %s free socket %"PRIdSOCK"\n", msg, sock);
}
ddsrt_close (sock); ddsrt_close (sock);
} }
} }
static void ddsi_tcp_sock_new (ddsrt_socket_t *sock, unsigned short port, const struct ddsi_domaingv *gv) static dds_return_t ddsi_tcp_sock_new (struct ddsi_tran_factory_tcp * const fact, ddsrt_socket_t *sock, uint16_t port)
{ {
if (make_socket (sock, port, true, true, gv) != 0) struct ddsi_domaingv const * const gv = fact->fact.gv;
const int one = 1;
union addr socketname;
dds_return_t rc;
memset (&socketname, 0, sizeof (socketname));
switch (fact->fact.m_kind)
{ {
*sock = DDSRT_INVALID_SOCKET; case NN_LOCATOR_KIND_TCPv4:
socketname.a4.sin_family = AF_INET;
socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
socketname.a4.sin_port = htons (port);
break;
#if DDSRT_HAVE_IPV6
case NN_LOCATOR_KIND_TCPv6:
socketname.a6.sin6_family = AF_INET6;
socketname.a6.sin6_addr = ddsrt_in6addr_any;
socketname.a6.sin6_port = htons (port);
break;
#endif
default:
DDS_FATAL ("ddsi_tcp_sock_new: unsupported kind %"PRId32"\n", fact->fact.m_kind);
} }
if ((rc = ddsrt_socket (sock, socketname.a.sa_family, SOCK_STREAM, 0)) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_tcp_sock_new: failed to create socket: %s\n", dds_strretcode (rc));
goto fail;
}
/* REUSEADDR if we're binding to a port number */
if (port && (rc = ddsrt_setsockopt (*sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one))) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_tcp_sock_new: failed to enable address reuse: %s\n", dds_strretcode (rc));
goto fail_w_socket;
}
if ((rc = ddsrt_bind (*sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_tcp_sock_new: failed to bind to ANY:%"PRIu16": %s\n", port,
(rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc));
goto fail_w_socket;
}
#ifdef SO_NOSIGPIPE
if (ddsrt_setsockopt (*sock, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof (one)) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_tcp_sock_new: failed to set NOSIGPIPE: %s\n", dds_strretcode (rc));
goto fail_w_socket;
}
#endif
#ifdef TCP_NODELAY
if (gv->config.tcp_nodelay && (rc = ddsrt_setsockopt (*sock, IPPROTO_TCP, TCP_NODELAY, &one, sizeof (one))) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_tcp_sock_new: failed to set NODELAY: %s\n", dds_strretcode (rc));
goto fail_w_socket;
}
#endif
return DDS_RETCODE_OK;
fail_w_socket:
ddsrt_close (*sock);
fail:
*sock = DDSRT_INVALID_SOCKET;
return rc;
} }
static void ddsi_tcp_node_free (void * ptr) static void ddsi_tcp_node_free (void * ptr)
@ -183,56 +247,57 @@ static void ddsi_tcp_node_free (void * ptr)
static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t * msg) static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t * msg)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
struct ddsi_domaingv const * const gv = fact->fact.gv;
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
ddsrt_socket_t sock; ddsrt_socket_t sock;
dds_return_t ret; dds_return_t ret;
ddsi_tcp_sock_new (&sock, 0, conn->m_base.m_base.gv); if (ddsi_tcp_sock_new (fact, &sock, 0) != DDS_RETCODE_OK)
if (sock != DDSRT_INVALID_SOCKET)
{ {
/* Attempt to connect, expected that may fail */ /* error messages are logged by ddsi_tcp_sock_new */
return;
}
do /* Attempt to connect, expected that may fail */
{ do {
ret = ddsrt_connect(sock, msg->msg_name, msg->msg_namelen); ret = ddsrt_connect(sock, msg->msg_name, msg->msg_namelen);
} } while (ret == DDS_RETCODE_INTERRUPTED);
while (ret == DDS_RETCODE_INTERRUPTED); if (ret != DDS_RETCODE_OK)
goto fail_w_socket;
if (ret != DDS_RETCODE_OK)
{
ddsi_tcp_sock_free (&conn->m_base.m_base.gv->logconfig, sock, NULL);
return;
}
ddsi_tcp_conn_set_socket (conn, sock);
ddsi_tcp_conn_set_socket (conn, sock);
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
if (fact->ddsi_tcp_ssl_plugin.connect) if (fact->ddsi_tcp_ssl_plugin.connect)
{
conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (conn->m_base.m_base.gv, sock);
if (conn->m_ssl == NULL)
{ {
conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (conn->m_base.m_base.gv, sock); ddsi_tcp_conn_set_socket (conn, DDSRT_INVALID_SOCKET);
if (conn->m_ssl == NULL) goto fail_w_socket;
{
ddsi_tcp_conn_set_socket (conn, DDSRT_INVALID_SOCKET);
return;
}
} }
}
#endif #endif
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *) msg->msg_name); sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *) msg->msg_name);
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp connect socket %"PRIdSOCK" port %u to %s\n", sock, get_socket_port (&conn->m_base.m_base.gv->logconfig, sock), buff); GVLOG (DDS_LC_TCP, "tcp connect socket %"PRIdSOCK" port %u to %s\n", sock, get_socket_port (gv, sock), buff);
/* Also may need to receive on connection so add to waitset */ /* Also may need to receive on connection so add to waitset */
(void)ddsrt_setsocknonblocking(conn->m_sock, true); (void)ddsrt_setsocknonblocking(conn->m_sock, true);
assert (conn->m_base.m_base.gv->n_recv_threads > 0); assert (conn->m_base.m_base.gv->n_recv_threads > 0);
assert (conn->m_base.m_base.gv->recv_threads[0].arg.mode == RTM_MANY); assert (conn->m_base.m_base.gv->recv_threads[0].arg.mode == RTM_MANY);
os_sockWaitsetAdd (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws, &conn->m_base); os_sockWaitsetAdd (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws, &conn->m_base);
os_sockWaitsetTrigger (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws); os_sockWaitsetTrigger (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws);
} return;
fail_w_socket:
ddsi_tcp_sock_free (gv, sock, NULL);
} }
static void ddsi_tcp_cache_add (struct ddsi_tran_factory_tcp *fact, ddsi_tcp_conn_t conn, ddsrt_avl_ipath_t * path) static void ddsi_tcp_cache_add (struct ddsi_tran_factory_tcp *fact, ddsi_tcp_conn_t conn, ddsrt_avl_ipath_t * path)
{ {
struct ddsi_domaingv * const gv = fact->fact.gv;
const char * action = "added"; const char * action = "added";
ddsi_tcp_node_t node; ddsi_tcp_node_t node;
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
@ -265,13 +330,14 @@ static void ddsi_tcp_cache_add (struct ddsi_tran_factory_tcp *fact, ddsi_tcp_con
} }
} }
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr); sockaddr_to_string_with_port(fact, buff, sizeof(buff), &conn->m_peer_addr.a);
DDS_CLOG (DDS_LC_TCP, &fact->fact.gv->logconfig, "tcp cache %s %s socket %"PRIdSOCK" to %s\n", action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff); GVLOG (DDS_LC_TCP, "tcp cache %s %s socket %"PRIdSOCK" to %s\n", action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
} }
static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn) static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
struct ddsi_domaingv * const gv = fact->fact.gv;
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
ddsi_tcp_node_t node; ddsi_tcp_node_t node;
ddsrt_avl_dpath_t path; ddsrt_avl_dpath_t path;
@ -280,8 +346,8 @@ static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
node = ddsrt_avl_lookup_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, conn, &path); node = ddsrt_avl_lookup_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, conn, &path);
if (node) if (node)
{ {
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr); sockaddr_to_string_with_port(fact, buff, sizeof(buff), &conn->m_peer_addr.a);
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp cache removed socket %"PRIdSOCK" to %s\n", conn->m_sock, buff); GVLOG (DDS_LC_TCP, "tcp cache removed socket %"PRIdSOCK" to %s\n", conn->m_sock, buff);
ddsrt_avl_delete_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node, &path); ddsrt_avl_delete_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node, &path);
ddsi_tcp_node_free (node); ddsi_tcp_node_free (node);
} }
@ -322,7 +388,7 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (struct ddsi_tran_factory_tcp *fact,
} }
if (ret == NULL) if (ret == NULL)
{ {
ret = ddsi_tcp_new_conn (fact, DDSRT_INVALID_SOCKET, false, (struct sockaddr *)&key.m_peer_addr); ret = ddsi_tcp_new_conn (fact, DDSRT_INVALID_SOCKET, false, &key.m_peer_addr.a);
ddsi_tcp_cache_add (fact, ret, &path); ddsi_tcp_cache_add (fact, ret, &path);
} }
ddsrt_mutex_unlock (&fact->ddsi_tcp_cache_lock_g); ddsrt_mutex_unlock (&fact->ddsi_tcp_cache_lock_g);
@ -348,7 +414,7 @@ static ssize_t ddsi_tcp_conn_read_ssl (ddsi_tcp_conn_t tcp, void * buf, size_t l
} }
#endif #endif
static bool ddsi_tcp_select (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, bool read, size_t pos, int64_t timeout) static bool ddsi_tcp_select (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, bool read, size_t pos, int64_t timeout)
{ {
dds_return_t rc; dds_return_t rc;
fd_set fds; fd_set fds;
@ -366,22 +432,29 @@ static bool ddsi_tcp_select (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t
DDSRT_WARNING_GNUC_ON(sign-conversion) DDSRT_WARNING_GNUC_ON(sign-conversion)
#endif #endif
DDS_CLOG (DDS_LC_TCP, logcfg, "tcp blocked %s: sock %d\n", read ? "read" : "write", (int) sock); GVLOG (DDS_LC_TCP, "tcp blocked %s: sock %d\n", read ? "read" : "write", (int) sock);
do { do {
rc = ddsrt_select (sock + 1, rdset, wrset, NULL, tval, &ready); rc = ddsrt_select (sock + 1, rdset, wrset, NULL, tval, &ready);
} while (rc == DDS_RETCODE_INTERRUPTED); } while (rc == DDS_RETCODE_INTERRUPTED);
if (rc != DDS_RETCODE_OK) if (rc != DDS_RETCODE_OK)
{ {
DDS_CWARNING (logcfg, "tcp abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n", read ? "read" : "write", (int) sock, pos); GVWARNING ("tcp abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n", read ? "read" : "write", (int) sock, pos);
} }
return (ready > 0); return (ready > 0);
} }
static int32_t addrfam_to_locator_kind (int af)
{
assert (af == AF_INET || af == AF_INET6);
return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6;
}
static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, nn_locator_t *srcloc) static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_factory; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_factory;
struct ddsi_domaingv const * const gv = fact->fact.gv;
dds_return_t rc; dds_return_t rc;
ddsi_tcp_conn_t tcp = (ddsi_tcp_conn_t) conn; ddsi_tcp_conn_t tcp = (ddsi_tcp_conn_t) conn;
ssize_t (*rd) (ddsi_tcp_conn_t, void *, size_t, dds_return_t * err) = ddsi_tcp_conn_read_plain; ssize_t (*rd) (ddsi_tcp_conn_t, void *, size_t, dds_return_t * err) = ddsi_tcp_conn_read_plain;
@ -405,14 +478,15 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, si
{ {
if (srcloc) if (srcloc)
{ {
ddsi_ipaddr_to_loc(&fact->fact, srcloc, (struct sockaddr *)&tcp->m_peer_addr, tcp->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6); const int32_t kind = addrfam_to_locator_kind (tcp->m_peer_addr.a.sa_family);
ddsi_ipaddr_to_loc(&fact->fact, srcloc, &tcp->m_peer_addr.a, kind);
} }
return (ssize_t) pos; return (ssize_t) pos;
} }
} }
else if (n == 0) else if (n == 0)
{ {
DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "tcp read: sock %"PRIdSOCK" closed-by-peer\n", tcp->m_sock); GVLOG (DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" closed-by-peer\n", tcp->m_sock);
break; break;
} }
else else
@ -423,13 +497,13 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, si
{ {
if (allow_spurious && pos == 0) if (allow_spurious && pos == 0)
return 0; return 0;
const int64_t timeout = conn->m_base.gv->config.tcp_read_timeout; const int64_t timeout = gv->config.tcp_read_timeout;
if (ddsi_tcp_select (&conn->m_base.gv->logconfig, tcp->m_sock, true, pos, timeout) == false) if (ddsi_tcp_select (gv, tcp->m_sock, true, pos, timeout) == false)
break; break;
} }
else else
{ {
DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "tcp read: sock %"PRIdSOCK" error %"PRId32"\n", tcp->m_sock, rc); GVLOG (DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" error %"PRId32"\n", tcp->m_sock, rc);
break; break;
} }
} }
@ -465,6 +539,7 @@ static ssize_t ddsi_tcp_block_write (ssize_t (*wr) (ddsi_tcp_conn_t, const void
{ {
/* Write all bytes of buf even in the presence of signals, /* Write all bytes of buf even in the presence of signals,
partial writes and blocking (typically write buffer full) */ partial writes and blocking (typically write buffer full) */
struct ddsi_domaingv const * const gv = conn->m_base.m_base.gv;
dds_return_t rc; dds_return_t rc;
size_t pos = 0; size_t pos = 0;
ssize_t n = -1; ssize_t n = -1;
@ -482,15 +557,15 @@ static ssize_t ddsi_tcp_block_write (ssize_t (*wr) (ddsi_tcp_conn_t, const void
{ {
if (rc == DDS_RETCODE_TRY_AGAIN) if (rc == DDS_RETCODE_TRY_AGAIN)
{ {
const int64_t timeout = conn->m_base.m_base.gv->config.tcp_write_timeout; const int64_t timeout = gv->config.tcp_write_timeout;
if (ddsi_tcp_select (&conn->m_base.m_base.gv->logconfig, conn->m_sock, false, pos, timeout) == false) if (ddsi_tcp_select (gv, conn->m_sock, false, pos, timeout) == false)
{ {
break; break;
} }
} }
else else
{ {
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" error %"PRId32"\n", conn->m_sock, rc); GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" error %"PRId32"\n", conn->m_sock, rc);
break; break;
} }
} }
@ -517,6 +592,7 @@ static void set_msghdr_iov (ddsrt_msghdr_t *mhdr, ddsrt_iovec_t *iov, size_t iov
static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags) static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) base->m_factory; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) base->m_factory;
struct ddsi_domaingv const * const gv = fact->fact.gv;
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
char msgbuf[4096]; /* stack buffer for merging smallish writes without requiring allocations */ char msgbuf[4096]; /* stack buffer for merging smallish writes without requiring allocations */
ddsrt_iovec_t iovec; /* iovec used for msgbuf */ ddsrt_iovec_t iovec; /* iovec used for msgbuf */
@ -527,13 +603,16 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
int piecewise; int piecewise;
bool connect = false; bool connect = false;
ddsrt_msghdr_t msg; ddsrt_msghdr_t msg;
struct sockaddr_storage dstaddr; union {
struct sockaddr_storage x;
union addr a;
} dstaddr;
assert(niov <= INT_MAX); assert(niov <= INT_MAX);
ddsi_ipaddr_from_loc(&dstaddr, dst); ddsi_ipaddr_from_loc(&dstaddr.x, dst);
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
set_msghdr_iov (&msg, (ddsrt_iovec_t *) iov, niov); set_msghdr_iov (&msg, (ddsrt_iovec_t *) iov, niov);
msg.msg_name = &dstaddr; msg.msg_name = &dstaddr;
msg.msg_namelen = (socklen_t) ddsrt_sockaddr_get_size((struct sockaddr *) &dstaddr); msg.msg_namelen = ddsrt_sockaddr_get_size(&dstaddr.a.a);
#if DDSRT_MSGHDR_FLAGS #if DDSRT_MSGHDR_FLAGS
msg.msg_flags = (int) flags; msg.msg_flags = (int) flags;
#endif #endif
@ -566,13 +645,13 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
if (!connect && ((flags & DDSI_TRAN_ON_CONNECT) != 0)) if (!connect && ((flags & DDSI_TRAN_ON_CONNECT) != 0))
{ {
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" message filtered\n", conn->m_sock); GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" message filtered\n", conn->m_sock);
ddsrt_mutex_unlock (&conn->m_mutex); ddsrt_mutex_unlock (&conn->m_mutex);
return (ssize_t) len; return (ssize_t) len;
} }
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
if (base->m_base.gv->config.ssl_enable) if (gv->config.ssl_enable)
{ {
/* SSL doesn't have sendmsg, ret = 0 so writing starts at first byte. /* SSL doesn't have sendmsg, ret = 0 so writing starts at first byte.
Rumor is that it is much better to merge small writes, which do here Rumor is that it is much better to merge small writes, which do here
@ -625,11 +704,11 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
{ {
case DDS_RETCODE_NO_CONNECTION: case DDS_RETCODE_NO_CONNECTION:
case DDS_RETCODE_ILLEGAL_OPERATION: case DDS_RETCODE_ILLEGAL_OPERATION:
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", conn->m_sock); GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", conn->m_sock);
break; break;
default: default:
if (! conn->m_base.m_closed && (conn->m_sock != DDSRT_INVALID_SOCKET)) if (! conn->m_base.m_closed && (conn->m_sock != DDSRT_INVALID_SOCKET))
DDS_CWARNING (&conn->m_base.m_base.gv->logconfig, "tcp write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", conn->m_sock, rc); GVWARNING ("tcp write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", conn->m_sock, rc);
break; break;
} }
} }
@ -638,7 +717,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
{ {
if (ret == 0) if (ret == 0)
{ {
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" eof\n", conn->m_sock); GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" eof\n", conn->m_sock);
} }
piecewise = (ret > 0 && (size_t) ret < len); piecewise = (ret > 0 && (size_t) ret < len);
} }
@ -706,12 +785,13 @@ static int ddsi_tcp_locator (struct ddsi_tran_factory *fact_cmn, ddsi_tran_base_
return 0; return 0;
} }
static ddsi_tran_conn_t ddsi_tcp_create_conn (struct ddsi_tran_factory *fact_cmn, uint32_t port, ddsi_tran_qos_t qos) static dds_return_t ddsi_tcp_create_conn (ddsi_tran_conn_t *conn_out, struct ddsi_tran_factory *fact_cmn, uint32_t port, const struct ddsi_tran_qos *qos)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn;
(void) qos; (void) qos;
(void) port; (void) port;
return &fact->ddsi_tcp_conn_client.m_base; *conn_out = &fact->ddsi_tcp_conn_client.m_base;
return DDS_RETCODE_OK;
} }
static int ddsi_tcp_listen (ddsi_tran_listener_t listener) static int ddsi_tcp_listen (ddsi_tran_listener_t listener)
@ -735,10 +815,11 @@ static int ddsi_tcp_listen (ddsi_tran_listener_t listener)
static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener) static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
struct ddsi_domaingv const * const gv = fact->fact.gv;
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener; ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
ddsi_tcp_conn_t tcp = NULL; ddsi_tcp_conn_t tcp = NULL;
ddsrt_socket_t sock = DDSRT_INVALID_SOCKET; ddsrt_socket_t sock = DDSRT_INVALID_SOCKET;
struct sockaddr_storage addr; union addr addr;
socklen_t addrlen = sizeof (addr); socklen_t addrlen = sizeof (addr);
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
dds_return_t rc = DDS_RETCODE_OK; dds_return_t rc = DDS_RETCODE_OK;
@ -762,31 +843,31 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
{ {
rc = ddsrt_accept(tl->m_sock, NULL, NULL, &sock); rc = ddsrt_accept(tl->m_sock, NULL, NULL, &sock);
} }
if (!ddsrt_atomic_ld32(&listener->m_base.gv->rtps_keepgoing)) if (!ddsrt_atomic_ld32(&gv->rtps_keepgoing))
{ {
ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, sock, NULL); ddsi_tcp_sock_free (gv, sock, NULL);
return NULL; return NULL;
} }
} while (rc == DDS_RETCODE_INTERRUPTED || rc == DDS_RETCODE_TRY_AGAIN); } while (rc == DDS_RETCODE_INTERRUPTED || rc == DDS_RETCODE_TRY_AGAIN);
if (sock == DDSRT_INVALID_SOCKET) if (sock == DDSRT_INVALID_SOCKET)
{ {
(void)ddsrt_getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen); (void)ddsrt_getsockname (tl->m_sock, &addr.a, &addrlen);
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&addr); sockaddr_to_string_with_port(fact, buff, sizeof(buff), &addr.a);
DDS_CLOG ((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, &listener->m_base.gv->logconfig, "tcp accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", tl->m_sock, buff, rc); GVLOG ((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, "tcp accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", tl->m_sock, buff, rc);
} }
else if (getpeername (sock, (struct sockaddr *) &addr, &addrlen) == -1) else if (getpeername (sock, &addr.a, &addrlen) == -1)
{ {
DDS_CWARNING (&listener->m_base.gv->logconfig, "tcp accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", sock, tl->m_sock, rc); GVWARNING ("tcp accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", sock, tl->m_sock, rc);
ddsrt_close (sock); ddsrt_close (sock);
} }
else else
{ {
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&addr); sockaddr_to_string_with_port(fact, buff, sizeof(buff), &addr.a);
DDS_CLOG (DDS_LC_TCP, &listener->m_base.gv->logconfig, "tcp accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", sock, tl->m_sock, buff); GVLOG (DDS_LC_TCP, "tcp accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", sock, tl->m_sock, buff);
(void)ddsrt_setsocknonblocking (sock, true); (void)ddsrt_setsocknonblocking (sock, true);
tcp = ddsi_tcp_new_conn (fact, sock, true, (struct sockaddr *)&addr); tcp = ddsi_tcp_new_conn (fact, sock, true, &addr.a);
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
tcp->m_ssl = ssl; tcp->m_ssl = ssl;
#endif #endif
@ -814,14 +895,20 @@ static ddsrt_socket_t ddsi_tcp_listener_handle (ddsi_tran_base_t base)
caller (supporting call back over NAT). caller (supporting call back over NAT).
*/ */
static void addr_to_loc (const struct ddsi_tran_factory *fact, nn_locator_t *loc, const union addr *addr)
{
ddsi_ipaddr_to_loc (fact, loc, &addr->a, addrfam_to_locator_kind (addr->a.sa_family));
}
static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * loc) static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * loc)
{ {
struct ddsi_domaingv const * const gv = conn->m_base.gv;
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn; ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn;
assert (tc->m_sock != DDSRT_INVALID_SOCKET); assert (tc->m_sock != DDSRT_INVALID_SOCKET);
ddsi_ipaddr_to_loc (conn->m_factory, loc, (struct sockaddr *)&tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6); addr_to_loc (conn->m_factory, loc, &tc->m_peer_addr);
ddsi_locator_to_string(buff, sizeof(buff), loc); ddsi_locator_to_string(buff, sizeof(buff), loc);
DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "(tcp EP:%s)", buff); GVLOG (DDS_LC_TCP, "(tcp EP:%s)", buff);
} }
static void ddsi_tcp_base_init (const struct ddsi_tran_factory_tcp *fact, struct ddsi_tran_conn *base) static void ddsi_tcp_base_init (const struct ddsi_tran_factory_tcp *fact, struct ddsi_tran_conn *base)
@ -838,7 +925,7 @@ static void ddsi_tcp_base_init (const struct ddsi_tran_factory_tcp *fact, struct
static ddsi_tcp_conn_t ddsi_tcp_new_conn (struct ddsi_tran_factory_tcp *fact, ddsrt_socket_t sock, bool server, struct sockaddr * peer) static ddsi_tcp_conn_t ddsi_tcp_new_conn (struct ddsi_tran_factory_tcp *fact, ddsrt_socket_t sock, bool server, struct sockaddr * peer)
{ {
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) ddsrt_malloc (sizeof (*conn)); ddsi_tcp_conn_t conn = ddsrt_malloc (sizeof (*conn));
memset (conn, 0, sizeof (*conn)); memset (conn, 0, sizeof (*conn));
ddsi_tcp_base_init (fact, &conn->m_base); ddsi_tcp_base_init (fact, &conn->m_base);
@ -853,58 +940,54 @@ static ddsi_tcp_conn_t ddsi_tcp_new_conn (struct ddsi_tran_factory_tcp *fact, dd
return conn; return conn;
} }
static ddsi_tran_listener_t ddsi_tcp_create_listener (ddsi_tran_factory_t fact, uint32_t port, ddsi_tran_qos_t qos) static dds_return_t ddsi_tcp_create_listener (ddsi_tran_listener_t *listener_out, ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *qos)
{ {
char buff[DDSI_LOCSTRLEN];
ddsrt_socket_t sock;
struct sockaddr_storage addr;
socklen_t addrlen = sizeof (addr);
ddsi_tcp_listener_t tl = NULL;
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) fact; struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) fact;
struct ddsi_domaingv const * const gv = fact_tcp->fact.gv;
ddsrt_socket_t sock;
(void) qos; (void) qos;
ddsi_tcp_sock_new (&sock, (unsigned short) port, fact->gv); if (ddsi_tcp_sock_new (fact_tcp, &sock, (uint16_t) port) != DDS_RETCODE_OK)
return DDS_RETCODE_ERROR;
if (sock != DDSRT_INVALID_SOCKET) char buff[DDSI_LOCSTRLEN];
union addr addr;
socklen_t addrlen = sizeof (addr);
dds_return_t ret;
if ((ret = ddsrt_getsockname (sock, &addr.a, &addrlen)) != DDS_RETCODE_OK)
{ {
dds_return_t ret; GVERROR ("ddsi_tcp_create_listener: ddsrt_getsockname returned %"PRId32"\n", ret);
tl = (ddsi_tcp_listener_t) ddsrt_malloc (sizeof (*tl)); ddsi_tcp_sock_free (gv, sock, NULL);
memset (tl, 0, sizeof (*tl)); return DDS_RETCODE_ERROR;
tl->m_sock = sock;
tl->m_base.m_base.gv = fact->gv;
tl->m_base.m_listen_fn = ddsi_tcp_listen;
tl->m_base.m_accept_fn = ddsi_tcp_accept;
tl->m_base.m_factory = fact;
tl->m_base.m_base.m_port = get_socket_port (&fact->gv->logconfig, sock);
tl->m_base.m_base.m_trantype = DDSI_TRAN_LISTENER;
tl->m_base.m_base.m_handle_fn = ddsi_tcp_listener_handle;
tl->m_base.m_locator_fn = ddsi_tcp_locator;
ret = ddsrt_getsockname(sock, (struct sockaddr *)&addr, &addrlen);
if (ret != DDS_RETCODE_OK) {
DDS_CERROR (&fact->gv->logconfig, "ddsi_tcp_create_listener: ddsrt_getsockname returned %"PRId32"\n", ret);
ddsi_tcp_sock_free(&fact->gv->logconfig, sock, NULL);
ddsrt_free(tl);
return NULL;
}
sockaddr_to_string_with_port(fact_tcp, buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_CLOG (DDS_LC_TCP, &fact->gv->logconfig, "tcp create listener socket %"PRIdSOCK" on %s\n", sock, buff);
} }
sockaddr_to_string_with_port (fact_tcp, buff, sizeof (buff), &addr.a);
GVLOG (DDS_LC_TCP, "tcp create listener socket %"PRIdSOCK" on %s\n", sock, buff);
return tl ? &tl->m_base : NULL; ddsi_tcp_listener_t tl = ddsrt_malloc (sizeof (*tl));
memset (tl, 0, sizeof (*tl));
tl->m_sock = sock;
tl->m_base.m_base.gv = fact->gv;
tl->m_base.m_listen_fn = ddsi_tcp_listen;
tl->m_base.m_accept_fn = ddsi_tcp_accept;
tl->m_base.m_factory = fact;
tl->m_base.m_base.m_port = get_socket_port (gv, sock);
tl->m_base.m_base.m_trantype = DDSI_TRAN_LISTENER;
tl->m_base.m_base.m_handle_fn = ddsi_tcp_listener_handle;
tl->m_base.m_locator_fn = ddsi_tcp_locator;
*listener_out = &tl->m_base;
return DDS_RETCODE_OK;
} }
static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn) static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
struct ddsi_domaingv const * const gv = fact->fact.gv;
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr); sockaddr_to_string_with_port(fact, buff, sizeof(buff), &conn->m_peer_addr.a);
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp free %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff); GVLOG (DDS_LC_TCP, "tcp free %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
if (fact->ddsi_tcp_ssl_plugin.ssl_free) if (fact->ddsi_tcp_ssl_plugin.ssl_free)
@ -914,7 +997,7 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
else else
#endif #endif
{ {
ddsi_tcp_sock_free (&conn->m_base.m_base.gv->logconfig, conn->m_sock, "connection"); ddsi_tcp_sock_free (gv, conn->m_sock, "connection");
} }
ddsrt_mutex_destroy (&conn->m_mutex); ddsrt_mutex_destroy (&conn->m_mutex);
ddsrt_free (conn); ddsrt_free (conn);
@ -923,17 +1006,18 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc) static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
{ {
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) tc->m_factory; struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) tc->m_factory;
struct ddsi_domaingv * const gv = fact_tcp->fact.gv;
if (tc != &fact_tcp->ddsi_tcp_conn_client.m_base) if (tc != &fact_tcp->ddsi_tcp_conn_client.m_base)
{ {
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
nn_locator_t loc; nn_locator_t loc;
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc; ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc;
sockaddr_to_string_with_port(fact_tcp, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr); sockaddr_to_string_with_port(fact_tcp, buff, sizeof(buff), &conn->m_peer_addr.a);
DDS_CLOG (DDS_LC_TCP, &tc->m_base.gv->logconfig, "tcp close %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff); GVLOG (DDS_LC_TCP, "tcp close %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
(void) shutdown (conn->m_sock, 2); (void) shutdown (conn->m_sock, 2);
ddsi_ipaddr_to_loc(&fact_tcp->fact, &loc, (struct sockaddr *)&conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6); ddsi_ipaddr_to_loc(&fact_tcp->fact, &loc, &conn->m_peer_addr.a, addrfam_to_locator_kind(conn->m_peer_addr.a.sa_family));
loc.port = conn->m_peer_port; loc.port = conn->m_peer_port;
purge_proxy_participants (conn->m_base.m_base.gv, &loc, conn->m_base.m_server); purge_proxy_participants (gv, &loc, conn->m_base.m_server);
} }
} }
@ -948,60 +1032,58 @@ static void ddsi_tcp_release_conn (ddsi_tran_conn_t conn)
static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener) static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
{ {
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) listener->m_factory;
struct ddsi_domaingv const * const gv = fact_tcp->fact.gv;
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener; ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
ddsrt_socket_t sock; ddsrt_socket_t sock;
dds_return_t ret; dds_return_t ret;
/* Connect to own listener socket to wake listener from blocking 'accept()' */ /* Connect to own listener socket to wake listener from blocking 'accept()' */
ddsi_tcp_sock_new (&sock, 0, listener->m_base.gv); if (ddsi_tcp_sock_new (fact_tcp, &sock, 0) != DDS_RETCODE_OK)
if (sock != DDSRT_INVALID_SOCKET) goto fail;
{
struct sockaddr_storage addr;
socklen_t addrlen = sizeof (addr);
ret = ddsrt_getsockname(tl->m_sock, (struct sockaddr *)&addr, &addrlen); union addr addr;
if (ret != DDS_RETCODE_OK) { socklen_t addrlen = sizeof (addr);
DDS_CWARNING (&listener->m_base.gv->logconfig, "tcp failed to get listener address error %"PRId32"\n", ret); if ((ret = ddsrt_getsockname (tl->m_sock, &addr.a, &addrlen)) != DDS_RETCODE_OK)
} else { {
switch (addr.ss_family) { GVWARNING ("tcp failed to get listener address error %"PRId32"\n", ret);
case AF_INET: goto fail_w_socket;
{
struct sockaddr_in *socketname = (struct sockaddr_in*)&addr;
if (socketname->sin_addr.s_addr == htonl (INADDR_ANY)) {
socketname->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
}
}
break;
#if DDSRT_HAVE_IPV6
case AF_INET6:
{
struct sockaddr_in6 *socketname = (struct sockaddr_in6*)&addr;
if (memcmp(&socketname->sin6_addr, &ddsrt_in6addr_any, sizeof(socketname->sin6_addr)) == 0) {
socketname->sin6_addr = ddsrt_in6addr_loopback;
}
}
break;
#endif
}
do
{
ret = ddsrt_connect(sock, (struct sockaddr *)&addr, ddsrt_sockaddr_get_size((struct sockaddr *)&addr));
} while (ret == DDS_RETCODE_INTERRUPTED);
if (ret != DDS_RETCODE_OK)
{
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
char buff[DDSI_LOCSTRLEN];
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&addr);
DDS_CWARNING (&listener->m_base.gv->logconfig, "tcp failed to connect to own listener (%s) error %"PRId32"\n", buff, ret);
}
}
ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, sock, NULL);
} }
switch (addr.a.sa_family)
{
case AF_INET:
if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY))
addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
break;
#if DDSRT_HAVE_IPV6
case AF_INET6:
if (memcmp (&addr.a6.sin6_addr, &ddsrt_in6addr_any, sizeof (addr.a6.sin6_addr)) == 0)
addr.a6.sin6_addr = ddsrt_in6addr_loopback;
break;
#endif
}
do {
ret = ddsrt_connect (sock, &addr.a, ddsrt_sockaddr_get_size (&addr.a));
} while (ret == DDS_RETCODE_INTERRUPTED);
if (ret != DDS_RETCODE_OK)
{
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
char buff[DDSI_LOCSTRLEN];
sockaddr_to_string_with_port (fact, buff, sizeof (buff), &addr.a);
GVWARNING ("tcp failed to connect to own listener (%s) error %"PRId32"\n", buff, ret);
}
fail_w_socket:
ddsi_tcp_sock_free (gv, sock, NULL);
fail:
return;
} }
static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener) static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
{ {
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener; ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
struct ddsi_domaingv const * const gv = tl->m_base.m_base.gv;
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
if (fact->ddsi_tcp_ssl_plugin.bio_vfree) if (fact->ddsi_tcp_ssl_plugin.bio_vfree)
@ -1009,13 +1091,14 @@ static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
(fact->ddsi_tcp_ssl_plugin.bio_vfree) (tl->m_bio); (fact->ddsi_tcp_ssl_plugin.bio_vfree) (tl->m_bio);
} }
#endif #endif
ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, tl->m_sock, "listener"); ddsi_tcp_sock_free (gv, tl->m_sock, "listener");
ddsrt_free (tl); ddsrt_free (tl);
} }
static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn) static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn)
{ {
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn; struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn;
struct ddsi_domaingv const * const gv = fact->fact.gv;
ddsrt_avl_free (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, ddsi_tcp_node_free); ddsrt_avl_free (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, ddsi_tcp_node_free);
ddsrt_mutex_destroy (&fact->ddsi_tcp_cache_lock_g); ddsrt_mutex_destroy (&fact->ddsi_tcp_cache_lock_g);
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
@ -1024,7 +1107,7 @@ static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn)
(fact->ddsi_tcp_ssl_plugin.fini) (); (fact->ddsi_tcp_ssl_plugin.fini) ();
} }
#endif #endif
DDS_CLOG (DDS_LC_CONFIG, &fact_cmn->gv->logconfig, "tcp de-initialized\n"); GVLOG (DDS_LC_CONFIG, "tcp de-initialized\n");
ddsrt_free (fact); ddsrt_free (fact);
} }

View file

@ -13,6 +13,7 @@
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/threads.h" #include "dds/ddsrt/threads.h"
#include "dds/ddsrt/hopscotch.h" #include "dds/ddsrt/hopscotch.h"
@ -20,7 +21,6 @@
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_unused.h" #include "dds/ddsi/q_unused.h"
#include "dds/ddsi/ddsi_domaingv.h" /* for mattr, cattr */ #include "dds/ddsi/ddsi_domaingv.h" /* for mattr, cattr */
#include "dds/ddsi/q_receive.h" #include "dds/ddsi/q_receive.h"
@ -64,7 +64,7 @@ static uint32_t threadmon_thread (struct ddsi_threadmon *sl)
reason why it has to be 100ms), regardless of the lease settings. reason why it has to be 100ms), regardless of the lease settings.
Note: can't trust sl->self, may have been scheduled before the Note: can't trust sl->self, may have been scheduled before the
assignment. */ assignment. */
nn_mtime_t tlast = { 0 }; ddsrt_mtime_t tlast = { 0 };
bool was_alive = true; bool was_alive = true;
for (uint32_t i = 0; i < thread_states.nthreads; i++) for (uint32_t i = 0; i < thread_states.nthreads; i++)
{ {
@ -80,7 +80,7 @@ static uint32_t threadmon_thread (struct ddsi_threadmon *sl)
/* Check progress only if enough time has passed: there is no /* Check progress only if enough time has passed: there is no
guarantee that os_cond_timedwait wont ever return early, and we guarantee that os_cond_timedwait wont ever return early, and we
do want to avoid spurious warnings. */ do want to avoid spurious warnings. */
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
if (tnow.v < tlast.v) if (tnow.v < tlast.v)
continue; continue;

View file

@ -0,0 +1,70 @@
/*
* 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 "dds/ddsrt/time.h"
#include "dds/ddsi/ddsi_time.h"
bool ddsi_is_valid_timestamp (ddsi_time_t t)
{
return t.seconds != DDSI_TIME_INVALID.seconds && t.fraction != DDSI_TIME_INVALID.fraction;
}
static ddsi_time_t to_ddsi_time (int64_t t)
{
if (t == DDS_NEVER)
return DDSI_TIME_INFINITE;
else
{
/* ceiling(ns * 2^32/10^9) -- can't change the ceiling to round-to-nearest
because that would break backwards compatibility, but round-to-nearest
of the inverse is correctly rounded anyway, so it shouldn't ever matter. */
ddsi_time_t x;
int ns = (int) (t % DDS_NSECS_IN_SEC);
x.seconds = (int) (t / DDS_NSECS_IN_SEC);
x.fraction = (unsigned) (((DDS_NSECS_IN_SEC-1) + ((int64_t) ns << 32)) / DDS_NSECS_IN_SEC);
return x;
}
}
ddsi_time_t ddsi_wctime_to_ddsi_time (ddsrt_wctime_t t)
{
return to_ddsi_time (t.v);
}
static int64_t from_ddsi_time (ddsi_time_t x)
{
if (x.seconds == DDSI_TIME_INFINITE.seconds && x.fraction == DDSI_TIME_INFINITE.fraction)
return DDS_NEVER;
else
{
/* Round-to-nearest conversion of DDSI time fraction to nanoseconds */
int ns = (int) (((int64_t) 2147483648u + (int64_t) x.fraction * DDS_NSECS_IN_SEC) >> 32);
return x.seconds * DDS_NSECS_IN_SEC + ns;
}
}
ddsrt_wctime_t ddsi_wctime_from_ddsi_time (ddsi_time_t x)
{
return (ddsrt_wctime_t) { from_ddsi_time (x) };
}
ddsi_duration_t ddsi_to_ddsi_duration (dds_duration_t x)
{
return to_ddsi_time (x);
}
dds_duration_t ddsi_from_ddsi_duration (ddsi_duration_t x)
{
return from_ddsi_time (x);
}

View file

@ -24,13 +24,13 @@
extern inline uint32_t ddsi_conn_type (ddsi_tran_conn_t conn); extern inline uint32_t ddsi_conn_type (ddsi_tran_conn_t conn);
extern inline uint32_t ddsi_conn_port (ddsi_tran_conn_t conn); extern inline uint32_t ddsi_conn_port (ddsi_tran_conn_t conn);
extern inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos); extern inline dds_return_t ddsi_factory_create_listener (ddsi_tran_listener_t *listener, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos);
extern inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int32_t kind); extern inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int32_t kind);
extern inline int ddsi_is_valid_port (ddsi_tran_factory_t factory, uint32_t port); extern inline int ddsi_is_valid_port (ddsi_tran_factory_t factory, uint32_t port);
extern inline ddsrt_socket_t ddsi_conn_handle (ddsi_tran_conn_t conn); extern inline ddsrt_socket_t ddsi_conn_handle (ddsi_tran_conn_t conn);
extern inline int ddsi_conn_locator (ddsi_tran_conn_t conn, nn_locator_t * loc); extern inline int ddsi_conn_locator (ddsi_tran_conn_t conn, nn_locator_t * loc);
extern inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base); extern inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base);
extern inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, ddsi_tran_qos_t qos); extern inline dds_return_t ddsi_factory_create_conn (ddsi_tran_conn_t *conn, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos);
extern inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc); extern inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc);
extern inline int ddsi_listener_listen (ddsi_tran_listener_t listener); extern inline int ddsi_listener_listen (ddsi_tran_listener_t listener);
extern inline ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener); extern inline ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);
@ -182,11 +182,6 @@ bool ddsi_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * loc)
return false; return false;
} }
void ddsi_tran_free_qos (ddsi_tran_qos_t qos)
{
ddsrt_free (qos);
}
int ddsi_conn_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf) int ddsi_conn_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
{ {
return conn->m_factory->m_join_mc_fn (conn, srcloc, mcloc, interf); return conn->m_factory->m_join_mc_fn (conn, srcloc, mcloc, interf);
@ -197,14 +192,6 @@ int ddsi_conn_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const
return conn->m_factory->m_leave_mc_fn (conn, srcloc, mcloc, interf); return conn->m_factory->m_leave_mc_fn (conn, srcloc, mcloc, interf);
} }
ddsi_tran_qos_t ddsi_tran_create_qos (void)
{
ddsi_tran_qos_t qos;
qos = (ddsi_tran_qos_t) ddsrt_malloc (sizeof (*qos));
memset (qos, 0, sizeof (*qos));
return qos;
}
void ddsi_tran_free (ddsi_tran_base_t base) void ddsi_tran_free (ddsi_tran_base_t base)
{ {
if (base) if (base)

View file

@ -21,12 +21,18 @@
#include "dds/ddsi/ddsi_udp.h" #include "dds/ddsi/ddsi_udp.h"
#include "dds/ddsi/ddsi_ipaddr.h" #include "dds/ddsi/ddsi_ipaddr.h"
#include "dds/ddsi/ddsi_mcgroup.h" #include "dds/ddsi/ddsi_mcgroup.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_pcap.h" #include "dds/ddsi/q_pcap.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
union addr {
struct sockaddr_storage x;
struct sockaddr a;
struct sockaddr_in a4;
struct sockaddr_in6 a6;
};
typedef struct ddsi_udp_conn { typedef struct ddsi_udp_conn {
struct ddsi_tran_conn m_base; struct ddsi_tran_conn m_base;
ddsrt_socket_t m_sock; ddsrt_socket_t m_sock;
@ -36,20 +42,27 @@ typedef struct ddsi_udp_conn {
int m_diffserv; int m_diffserv;
} *ddsi_udp_conn_t; } *ddsi_udp_conn_t;
static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, bool allow_spurious, nn_locator_t *srcloc) static void addr_to_loc (const struct ddsi_tran_factory *tran, nn_locator_t *dst, const union addr *src)
{ {
ddsi_ipaddr_to_loc (tran, dst, &src->a, (src->a.sa_family == AF_INET) ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
}
static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
{
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
struct ddsi_domaingv * const gv = conn->m_base.m_base.gv;
dds_return_t rc; dds_return_t rc;
ssize_t ret = 0; ssize_t ret = 0;
ddsrt_msghdr_t msghdr; ddsrt_msghdr_t msghdr;
struct sockaddr_storage src; union addr src;
ddsrt_iovec_t msg_iov; ddsrt_iovec_t msg_iov;
socklen_t srclen = (socklen_t) sizeof (src); socklen_t srclen = (socklen_t) sizeof (src);
(void) allow_spurious; (void) allow_spurious;
msg_iov.iov_base = (void*) buf; msg_iov.iov_base = (void *) buf;
msg_iov.iov_len = (ddsrt_iov_len_t)len; /* Windows uses unsigned, POSIX (except Linux) int */ msg_iov.iov_len = (ddsrt_iov_len_t) len; /* Windows uses unsigned, POSIX (except Linux) int */
msghdr.msg_name = &src; msghdr.msg_name = &src.x;
msghdr.msg_namelen = srclen; msghdr.msg_namelen = srclen;
msghdr.msg_iov = &msg_iov; msghdr.msg_iov = &msg_iov;
msghdr.msg_iovlen = 1; msghdr.msg_iovlen = 1;
@ -62,65 +75,67 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
#endif #endif
do { do {
rc = ddsrt_recvmsg(((ddsi_udp_conn_t) conn)->m_sock, &msghdr, 0, &ret); rc = ddsrt_recvmsg (conn->m_sock, &msghdr, 0, &ret);
} while (rc == DDS_RETCODE_INTERRUPTED); } while (rc == DDS_RETCODE_INTERRUPTED);
if (ret > 0) if (ret > 0)
{ {
if (srcloc) if (srcloc)
ddsi_ipaddr_to_loc(conn->m_factory, srcloc, (struct sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6); addr_to_loc (conn->m_base.m_factory, srcloc, &src);
if(conn->m_base.gv->pcap_fp) if (gv->pcap_fp)
{ {
struct sockaddr_storage dest; union addr dest;
socklen_t dest_len = sizeof (dest); socklen_t dest_len = sizeof (dest);
if (ddsrt_getsockname (((ddsi_udp_conn_t) conn)->m_sock, (struct sockaddr *) &dest, &dest_len) != DDS_RETCODE_OK) if (ddsrt_getsockname (conn->m_sock, &dest.a, &dest_len) != DDS_RETCODE_OK)
memset(&dest, 0, sizeof(dest)); memset (&dest, 0, sizeof (dest));
write_pcap_received(conn->m_base.gv, now(), &src, &dest, buf, (size_t) ret); write_pcap_received (gv, ddsrt_time_wallclock (), &src.x, &dest.x, buf, (size_t) ret);
} }
/* Check for udp packet truncation */ /* Check for udp packet truncation */
if ((((size_t) ret) > len)
#if DDSRT_MSGHDR_FLAGS #if DDSRT_MSGHDR_FLAGS
|| (msghdr.msg_flags & MSG_TRUNC) const bool trunc_flag = (msghdr.msg_flags & MSG_TRUNC) != 0;
#else
const bool trunc_flag = false;
#endif #endif
) if ((size_t) ret > len || trunc_flag)
{ {
char addrbuf[DDSI_LOCSTRLEN]; char addrbuf[DDSI_LOCSTRLEN];
nn_locator_t tmp; nn_locator_t tmp;
ddsi_ipaddr_to_loc(conn->m_factory, &tmp, (struct sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6); addr_to_loc (conn->m_base.m_factory, &tmp, &src);
ddsi_locator_to_string(addrbuf, sizeof(addrbuf), &tmp); ddsi_locator_to_string (addrbuf, sizeof (addrbuf), &tmp);
DDS_CWARNING(&conn->m_base.gv->logconfig, "%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len); GVWARNING ("%s => %d truncated to %d\n", addrbuf, (int) ret, (int) len);
} }
} }
else if (rc != DDS_RETCODE_BAD_PARAMETER && else if (rc != DDS_RETCODE_BAD_PARAMETER && rc != DDS_RETCODE_NO_CONNECTION)
rc != DDS_RETCODE_NO_CONNECTION)
{ {
DDS_CERROR(&conn->m_base.gv->logconfig, "UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) ((ddsi_udp_conn_t) conn)->m_sock, (int) ret, rc); GVERROR ("UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) conn->m_sock, (int) ret, rc);
ret = -1; ret = -1;
} }
return ret; return ret;
} }
static void set_msghdr_iov (ddsrt_msghdr_t *mhdr, ddsrt_iovec_t *iov, size_t iovlen) static void set_msghdr_iov (ddsrt_msghdr_t *mhdr, const ddsrt_iovec_t *iov, size_t iovlen)
{ {
mhdr->msg_iov = iov; mhdr->msg_iov = (ddsrt_iovec_t *) iov;
mhdr->msg_iovlen = (ddsrt_msg_iovlen_t)iovlen; mhdr->msg_iovlen = (ddsrt_msg_iovlen_t) iovlen;
} }
static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags) static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags)
{ {
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
struct ddsi_domaingv * const gv = conn->m_base.m_base.gv;
dds_return_t rc; dds_return_t rc;
ssize_t ret = -1; ssize_t ret = -1;
unsigned retry = 2; unsigned retry = 2;
int sendflags = 0; int sendflags = 0;
ddsrt_msghdr_t msg; ddsrt_msghdr_t msg;
struct sockaddr_storage dstaddr; union addr dstaddr;
assert(niov <= INT_MAX); assert (niov <= INT_MAX);
ddsi_ipaddr_from_loc(&dstaddr, dst); ddsi_ipaddr_from_loc (&dstaddr.x, dst);
set_msghdr_iov (&msg, (ddsrt_iovec_t *) iov, niov); set_msghdr_iov (&msg, iov, niov);
msg.msg_name = &dstaddr; msg.msg_name = &dstaddr.x;
msg.msg_namelen = (socklen_t) ddsrt_sockaddr_get_size((struct sockaddr *) &dstaddr); msg.msg_namelen = (socklen_t) ddsrt_sockaddr_get_size (&dstaddr.a);
#if defined(__sun) && !defined(_XPG4_2) #if defined(__sun) && !defined(_XPG4_2)
msg.msg_accrights = NULL; msg.msg_accrights = NULL;
msg.msg_accrightslen = 0; msg.msg_accrightslen = 0;
@ -131,56 +146,53 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *d
#if DDSRT_MSGHDR_FLAGS #if DDSRT_MSGHDR_FLAGS
msg.msg_flags = (int) flags; msg.msg_flags = (int) flags;
#else #else
DDSRT_UNUSED_ARG(flags); DDSRT_UNUSED_ARG (flags);
#endif #endif
#if MSG_NOSIGNAL && !LWIP_SOCKET #if MSG_NOSIGNAL && !LWIP_SOCKET
sendflags |= MSG_NOSIGNAL; sendflags |= MSG_NOSIGNAL;
#endif #endif
do { do {
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn; rc = ddsrt_sendmsg (conn->m_sock, &msg, sendflags, &ret);
rc = ddsrt_sendmsg (uc->m_sock, &msg, sendflags, &ret);
#if defined _WIN32 && !defined WINCE #if defined _WIN32 && !defined WINCE
if (rc == DDS_RETCODE_TRY_AGAIN) { if (rc == DDS_RETCODE_TRY_AGAIN)
{
WSANETWORKEVENTS ev; WSANETWORKEVENTS ev;
WaitForSingleObject(uc->m_sockEvent, INFINITE); WaitForSingleObject (conn->m_sockEvent, INFINITE);
WSAEnumNetworkEvents(uc->m_sock, uc->m_sockEvent, &ev); WSAEnumNetworkEvents (conn->m_sock, conn->m_sockEvent, &ev);
} }
#endif #endif
} while ((rc == DDS_RETCODE_INTERRUPTED) || } while (rc == DDS_RETCODE_INTERRUPTED || rc == DDS_RETCODE_TRY_AGAIN || (rc == DDS_RETCODE_NOT_ALLOWED && retry-- > 0));
(rc == DDS_RETCODE_TRY_AGAIN) || if (ret > 0 && gv->pcap_fp)
(rc == DDS_RETCODE_NOT_ALLOWED && retry-- > 0));
if (ret > 0 && conn->m_base.gv->pcap_fp)
{ {
struct sockaddr_storage sa; union addr sa;
socklen_t alen = sizeof (sa); socklen_t alen = sizeof (sa);
if (ddsrt_getsockname (((ddsi_udp_conn_t) conn)->m_sock, (struct sockaddr *) &sa, &alen) != DDS_RETCODE_OK) if (ddsrt_getsockname (conn->m_sock, &sa.a, &alen) != DDS_RETCODE_OK)
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
write_pcap_sent (conn->m_base.gv, now (), &sa, &msg, (size_t) ret); write_pcap_sent (gv, ddsrt_time_wallclock (), &sa.x, &msg, (size_t) ret);
} }
else if (rc != DDS_RETCODE_OK && else if (rc != DDS_RETCODE_OK && rc != DDS_RETCODE_NOT_ALLOWED && rc != DDS_RETCODE_NO_CONNECTION)
rc != DDS_RETCODE_NOT_ALLOWED &&
rc != DDS_RETCODE_NO_CONNECTION)
{ {
DDS_CERROR(&conn->m_base.gv->logconfig, "ddsi_udp_conn_write failed with retcode %"PRId32"\n", rc); GVERROR ("ddsi_udp_conn_write failed with retcode %"PRId32"\n", rc);
} }
return (rc == DDS_RETCODE_OK ? ret : -1); return (rc == DDS_RETCODE_OK) ? ret : -1;
} }
static void ddsi_udp_disable_multiplexing (ddsi_tran_conn_t base) static void ddsi_udp_disable_multiplexing (ddsi_tran_conn_t conn_cmn)
{ {
#if defined _WIN32 && !defined WINCE #if defined _WIN32 && !defined WINCE
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) base; ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
uint32_t zero = 0, dummy; uint32_t zero = 0, dummy;
WSAEventSelect(uc->m_sock, 0, 0); WSAEventSelect (conn->m_sock, 0, 0);
WSAIoctl(uc->m_sock, FIONBIO, &zero,sizeof(zero), NULL,0, &dummy, NULL,NULL); WSAIoctl (conn->m_sock, FIONBIO, &zero,sizeof(zero), NULL,0, &dummy, NULL,NULL);
#else #else
(void)base; (void) conn_cmn;
#endif #endif
} }
static ddsrt_socket_t ddsi_udp_conn_handle (ddsi_tran_base_t base) static ddsrt_socket_t ddsi_udp_conn_handle (ddsi_tran_base_t conn_cmn)
{ {
return ((ddsi_udp_conn_t) base)->m_sock; ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
return conn->m_sock;
} }
static bool ddsi_udp_supports (const struct ddsi_tran_factory *fact, int32_t kind) static bool ddsi_udp_supports (const struct ddsi_tran_factory *fact, int32_t kind)
@ -188,107 +200,366 @@ static bool ddsi_udp_supports (const struct ddsi_tran_factory *fact, int32_t kin
return kind == fact->m_kind || (kind == NN_LOCATOR_KIND_UDPv4MCGEN && fact->m_kind == NN_LOCATOR_KIND_UDPv4); return kind == fact->m_kind || (kind == NN_LOCATOR_KIND_UDPv4MCGEN && fact->m_kind == NN_LOCATOR_KIND_UDPv4);
} }
static int ddsi_udp_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t base, nn_locator_t *loc) static int ddsi_udp_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t conn_cmn, nn_locator_t *loc)
{ {
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
int ret = -1; int ret = -1;
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) base; if (conn->m_sock != DDSRT_INVALID_SOCKET)
if (uc->m_sock != DDSRT_INVALID_SOCKET)
{ {
loc->kind = fact->m_kind; loc->kind = fact->m_kind;
loc->port = uc->m_base.m_base.m_port; loc->port = conn->m_base.m_base.m_port;
memcpy(loc->address, uc->m_base.m_base.gv->extloc.address, sizeof (loc->address)); memcpy (loc->address, conn->m_base.m_base.gv->extloc.address, sizeof (loc->address));
ret = 0; ret = 0;
} }
return ret; return ret;
} }
static unsigned short get_socket_port (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket) static uint16_t get_socket_port (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
{ {
dds_return_t ret; dds_return_t ret;
struct sockaddr_storage addr; union addr addr;
socklen_t addrlen = sizeof (addr); socklen_t addrlen = sizeof (addr);
ret = ddsrt_getsockname (sock, &addr.a, &addrlen);
ret = ddsrt_getsockname (socket, (struct sockaddr *)&addr, &addrlen);
if (ret != DDS_RETCODE_OK) if (ret != DDS_RETCODE_OK)
{ {
DDS_CERROR (logcfg, "ddsi_udp_get_socket_port: getsockname returned %"PRId32"\n", ret); GVERROR ("ddsi_udp_get_socket_port: getsockname returned %"PRId32"\n", ret);
return 0; return 0;
} }
return ddsrt_sockaddr_get_port (&addr.a);
return ddsrt_sockaddr_get_port((struct sockaddr *)&addr);
} }
static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t port, ddsi_tran_qos_t qos) static dds_return_t set_dont_route (struct ddsi_domaingv const * const gv, ddsrt_socket_t socket, bool ipv6)
{ {
int ret; dds_return_t rc;
#if DDSRT_HAVE_IPV6
if (ipv6)
{
const unsigned uone = 1;
if ((rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &uone, sizeof (uone))) != DDS_RETCODE_OK)
GVERROR ("ddsi_udp_create_conn: set IPV6_UNICAST_HOPS = 1 failed: %s\n", dds_strretcode (rc));
return rc;
}
#else
(void) ipv6;
#endif
const int one = 1;
if ((rc = ddsrt_setsockopt (socket, SOL_SOCKET, SO_DONTROUTE, &one, sizeof (one))) != DDS_RETCODE_OK)
GVERROR ("ddsi_udp_create_conn: set SO_DONTROUTE = 1 failed: %s\n", dds_strretcode (rc));
return rc;
}
static dds_return_t set_rcvbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const struct config_maybe_uint32 *min_size)
{
uint32_t size;
socklen_t optlen = (socklen_t) sizeof (size);
uint32_t socket_min_rcvbuf_size;
dds_return_t rc;
socket_min_rcvbuf_size = min_size->isdefault ? 1048576 : min_size->value;
rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_RCVBUF, &size, &optlen);
if (rc == DDS_RETCODE_BAD_PARAMETER)
{
/* not all stacks support getting/setting RCVBUF */
GVLOG (DDS_LC_CONFIG, "cannot retrieve socket receive buffer size\n");
return DDS_RETCODE_OK;
}
else if (rc != DDS_RETCODE_OK)
{
GVERROR ("ddsi_udp_create_conn: get SO_RCVBUF failed: %s\n", dds_strretcode (rc));
return rc;
}
if (size < socket_min_rcvbuf_size)
{
/* make sure the receive buffersize is at least the minimum required */
size = socket_min_rcvbuf_size;
(void) ddsrt_setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
/* We don't check the return code from setsockopt, because some O/Ss tend
to silently cap the buffer size. The only way to make sure is to read
the option value back and check it is now set correctly. */
if ((rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_RCVBUF, &size, &optlen)) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_udp_create_conn: get SO_RCVBUF failed: %s\n", dds_strretcode (rc));
return rc;
}
if (size >= socket_min_rcvbuf_size)
GVLOG (DDS_LC_CONFIG, "socket receive buffer size set to %"PRIu32" bytes\n", size);
else if (min_size->isdefault)
GVLOG (DDS_LC_CONFIG,
"failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n",
socket_min_rcvbuf_size, size);
else
{
/* If the configuration states it must be >= X, then error out if the
kernel doesn't give us at least X */
GVLOG (DDS_LC_CONFIG | DDS_LC_ERROR,
"failed to increase socket receive buffer size to %"PRIu32" bytes, maximum is %"PRIu32" bytes\n",
socket_min_rcvbuf_size, size);
rc = DDS_RETCODE_NOT_ENOUGH_SPACE;
}
}
return rc;
}
static dds_return_t set_sndbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, uint32_t min_size)
{
unsigned size;
socklen_t optlen = (socklen_t) sizeof(size);
dds_return_t rc;
rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_SNDBUF, &size, &optlen);
if (rc == DDS_RETCODE_BAD_PARAMETER)
{
/* not all stacks support getting/setting SNDBUF */
GVLOG (DDS_LC_CONFIG, "cannot retrieve socket send buffer size\n");
return DDS_RETCODE_OK;
}
else if (rc != DDS_RETCODE_OK)
{
GVERROR ("ddsi_udp_create_conn: get SO_SNDBUF failed: %s\n", dds_strretcode (rc));
return rc;
}
if (size < min_size)
{
/* make sure the send buffersize is at least the minimum required */
size = min_size;
if ((rc = ddsrt_setsockopt (sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size))) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_udp_create_conn: set SO_SNDBUF failed: %s\n", dds_strretcode (rc));
return rc;
}
}
return DDS_RETCODE_OK;
}
static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
{
/* Function is a never-called no-op if IPv6 is not supported to keep the call-site a bit cleaner */
#if DDSRT_HAVE_IPV6
const unsigned ifno = gv->interfaceNo;
const unsigned ttl = (unsigned) gv->config.multicast_ttl;
const unsigned loop = (unsigned) !!gv->config.enableMulticastLoopback;
dds_return_t rc;
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifno, sizeof (ifno))) != DDS_RETCODE_OK) {
GVERROR ("ddsi_udp_create_conn: set IPV6_MULTICAST_IF failed: %s\n", dds_strretcode (rc));
return rc;
}
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof (ttl))) != DDS_RETCODE_OK) {
GVERROR ("ddsi_udp_create_conn: set IPV6_MULTICAST_HOPS failed: %s\n", dds_strretcode (rc));
return rc;
}
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof (loop))) != DDS_RETCODE_OK) {
GVERROR ("ddsi_udp_create_conn: set IPV6_MULTICAST_LOOP failed: %s\n", dds_strretcode (rc));
return rc;
}
return DDS_RETCODE_OK;
#else
(void) gv; (void) sock;
return DDS_RETCODE_ERROR;
#endif
}
static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
{
#if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET
if (gv->config.use_multicast_if_mreqn)
{
struct ip_mreqn mreqn;
memset (&mreqn, 0, sizeof (mreqn));
/* looks like imr_multiaddr is not relevant, not sure about imr_address */
mreqn.imr_multiaddr.s_addr = htonl (INADDR_ANY);
if (gv->config.use_multicast_if_mreqn > 1)
memcpy (&mreqn.imr_address.s_addr, gv->ownloc.address + 12, 4);
else
mreqn.imr_address.s_addr = htonl (INADDR_ANY);
mreqn.imr_ifindex = (int) gv->interfaceNo;
return ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof (mreqn));
}
#endif
return ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, gv->ownloc.address + 12, 4);
}
static dds_return_t set_mc_options_transmit_ipv4 (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
{
const unsigned char ttl = (unsigned char) gv->config.multicast_ttl;
const unsigned char loop = (unsigned char) !!gv->config.enableMulticastLoopback;
dds_return_t rc;
if ((rc = set_mc_options_transmit_ipv4_if (gv, sock)) != DDS_RETCODE_OK) {
GVERROR ("ddsi_udp_create_conn: set IP_MULTICAST_IF failed: %s\n", dds_strretcode (rc));
return rc;
}
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof (ttl))) != DDS_RETCODE_OK) {
GVERROR ("ddsi_udp_create_conn: set IP_MULTICAST_TTL failed: %s\n", dds_strretcode (rc));
return rc;
}
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof (loop))) != DDS_RETCODE_OK) {
GVERROR ("ddsi_udp_create_conn: set IP_MULTICAST_LOOP failed: %s\n", dds_strretcode (rc));
return rc;
}
return DDS_RETCODE_OK;
}
static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_factory_t fact, uint32_t port, const ddsi_tran_qos_t *qos)
{
struct ddsi_domaingv const * const gv = fact->gv;
const int one = 1;
dds_return_t rc;
ddsrt_socket_t sock; ddsrt_socket_t sock;
ddsi_udp_conn_t uc = NULL; bool reuse_addr = false, bind_to_any = false, ipv6 = false;
bool mcast = (bool) (qos ? qos->m_multicast : false); const char *purpose_str = NULL;
/* If port is zero, need to create dynamic port */ switch (qos->m_purpose)
ret = make_socket (&sock, (unsigned short) port, false, mcast, fact->gv);
if (ret == 0)
{ {
uc = (ddsi_udp_conn_t) ddsrt_malloc (sizeof (*uc)); case DDSI_TRAN_QOS_XMIT:
memset (uc, 0, sizeof (*uc)); reuse_addr = false;
bind_to_any = false;
purpose_str = "transmit";
break;
case DDSI_TRAN_QOS_RECV_UC:
reuse_addr = false;
bind_to_any = true;
purpose_str = "unicast";
break;
case DDSI_TRAN_QOS_RECV_MC:
reuse_addr = true;
bind_to_any = true;
purpose_str = "multicast";
break;
}
assert (purpose_str != NULL);
uc->m_sock = sock; union addr socketname;
uc->m_diffserv = qos ? qos->m_diffserv : 0; nn_locator_t ownloc_w_port = gv->ownloc;
#if defined _WIN32 && !defined WINCE assert (ownloc_w_port.port == NN_LOCATOR_PORT_INVALID);
uc->m_sockEvent = WSACreateEvent(); if (port) {
WSAEventSelect(uc->m_sock, uc->m_sockEvent, FD_WRITE); /* PORT_INVALID maps to 0 in ipaddr_from_loc */
ownloc_w_port.port = port;
}
ddsi_ipaddr_from_loc (&socketname.x, &ownloc_w_port);
switch (fact->m_kind)
{
case NN_LOCATOR_KIND_UDPv4:
if (bind_to_any)
socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
break;
#if DDSRT_HAVE_IPV6
case NN_LOCATOR_KIND_UDPv6:
ipv6 = true;
if (bind_to_any)
socketname.a6.sin6_addr = ddsrt_in6addr_any;
break;
#endif #endif
default:
DDS_FATAL ("ddsi_udp_create_conn: unsupported kind %"PRId32"\n", fact->m_kind);
}
if ((rc = ddsrt_socket (&sock, socketname.a.sa_family, SOCK_DGRAM, 0)) != DDS_RETCODE_OK)
{
GVERROR ("ddsi_udp_create_conn: failed to create socket: %s\n", dds_strretcode (rc));
goto fail;
}
ddsi_factory_conn_init (fact, &uc->m_base); if (reuse_addr && (rc = ddsrt_setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one))) != DDS_RETCODE_OK)
uc->m_base.m_base.m_port = get_socket_port (&fact->gv->logconfig, sock); {
uc->m_base.m_base.m_trantype = DDSI_TRAN_CONN; GVERROR ("ddsi_udp_create_conn: failed to enable address reuse: %s\n", dds_strretcode (rc));
uc->m_base.m_base.m_multicast = mcast; if (rc != DDS_RETCODE_BAD_PARAMETER)
uc->m_base.m_base.m_handle_fn = ddsi_udp_conn_handle; {
/* There must at some point have been an implementation that refused to do SO_REUSEADDR, but I
don't know which */
goto fail_w_socket;
}
}
uc->m_base.m_read_fn = ddsi_udp_conn_read; if ((rc = set_rcvbuf (gv, sock, &gv->config.socket_min_rcvbuf_size)) != DDS_RETCODE_OK)
uc->m_base.m_write_fn = ddsi_udp_conn_write; goto fail_w_socket;
uc->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing; if ((rc = set_sndbuf (gv, sock, gv->config.socket_min_sndbuf_size)) != DDS_RETCODE_OK)
uc->m_base.m_locator_fn = ddsi_udp_conn_locator; goto fail_w_socket;
if (gv->config.dontRoute && (rc = set_dont_route (gv, sock, ipv6)) != DDS_RETCODE_OK)
goto fail_w_socket;
if ((rc = ddsrt_bind (sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK)
{
/* PRECONDITION_NOT_MET (= EADDRINUSE) is expected if reuse_addr isn't set, should be handled at
a higher level and therefore needs to return a specific error message */
if (!reuse_addr && rc == DDS_RETCODE_PRECONDITION_NOT_MET)
goto fail_addrinuse;
char buf[DDSI_LOCATORSTRLEN];
if (bind_to_any)
snprintf (buf, sizeof (buf), "ANY:%"PRIu32, port);
else
ddsi_locator_to_string (buf, sizeof (buf), &ownloc_w_port);
GVERROR ("ddsi_udp_create_conn: failed to bind to %s: %s\n", buf,
(rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc));
goto fail_w_socket;
}
rc = ipv6 ? set_mc_options_transmit_ipv6 (gv, sock) : set_mc_options_transmit_ipv4 (gv, sock);
if (rc != DDS_RETCODE_OK)
goto fail_w_socket;
DDS_CTRACE (&fact->gv->logconfig,
"ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
mcast ? "multicast" : "unicast",
uc->m_sock,
uc->m_base.m_base.m_port);
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS #ifdef DDSI_INCLUDE_NETWORK_CHANNELS
if ((uc->m_diffserv != 0) && (fact->m_kind == NN_LOCATOR_KIND_UDPv4)) if (qos->m_diffserv != 0 && fact->m_kind == NN_LOCATOR_KIND_UDPv4)
{
dds_return_t rc;
rc = ddsrt_setsockopt(sock, IPPROTO_IP, IP_TOS, (char *)&uc->m_diffserv, sizeof(uc->m_diffserv));
if (rc != DDS_RETCODE_OK)
DDS_CERROR (fact->gv->logconfig, "ddsi_udp_create_conn: set diffserv retcode %"PRId32"\n", rc);
}
#endif
}
else
{ {
if (fact->gv->config.participantIndex != PARTICIPANT_INDEX_AUTO) if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_TOS, &qos->m_diffserv, sizeof (qos->m_diffserv))) != DDS_RETCODE_OK)
{ {
DDS_CERROR (&fact->gv->logconfig, "UDP make_socket failed for %s port %"PRIu32"\n", mcast ? "multicast" : "unicast", port); GVERROR ("ddsi_udp_create_conn: set diffserv retcode %"PRId32"\n", rc);
goto fail_w_socket;
} }
} }
#endif
return uc ? &uc->m_base : NULL; ddsi_udp_conn_t conn = ddsrt_malloc (sizeof (*conn));
memset (conn, 0, sizeof (*conn));
conn->m_sock = sock;
conn->m_diffserv = qos->m_diffserv;
#if defined _WIN32 && !defined WINCE
conn->m_sockEvent = WSACreateEvent ();
WSAEventSelect (conn->m_sock, conn->m_sockEvent, FD_WRITE);
#endif
ddsi_factory_conn_init (fact, &conn->m_base);
conn->m_base.m_base.m_port = get_socket_port (gv, sock);
conn->m_base.m_base.m_trantype = DDSI_TRAN_CONN;
conn->m_base.m_base.m_multicast = (qos->m_purpose == DDSI_TRAN_QOS_RECV_MC);
conn->m_base.m_base.m_handle_fn = ddsi_udp_conn_handle;
conn->m_base.m_read_fn = ddsi_udp_conn_read;
conn->m_base.m_write_fn = ddsi_udp_conn_write;
conn->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing;
conn->m_base.m_locator_fn = ddsi_udp_conn_locator;
GVTRACE ("ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port);
*conn_out = &conn->m_base;
return DDS_RETCODE_OK;
fail_w_socket:
ddsrt_close (sock);
fail:
return DDS_RETCODE_ERROR;
fail_addrinuse:
ddsrt_close (sock);
return DDS_RETCODE_PRECONDITION_NOT_MET;
} }
static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_locator_t *mcloc, const struct nn_interface *interf) static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_locator_t *mcloc, const struct nn_interface *interf)
{ {
dds_return_t rc; dds_return_t rc;
struct sockaddr_storage mcip; union addr mcip;
ddsi_ipaddr_from_loc(&mcip, mcloc); ddsi_ipaddr_from_loc (&mcip.x, mcloc);
#if DDSRT_HAVE_IPV6 #if DDSRT_HAVE_IPV6
if (mcloc->kind == NN_LOCATOR_KIND_UDPv6) if (mcloc->kind == NN_LOCATOR_KIND_UDPv6)
{ {
struct ipv6_mreq ipv6mreq; struct ipv6_mreq ipv6mreq;
memset (&ipv6mreq, 0, sizeof (ipv6mreq)); memset (&ipv6mreq, 0, sizeof (ipv6mreq));
memcpy (&ipv6mreq.ipv6mr_multiaddr, &((struct sockaddr_in6 *) &mcip)->sin6_addr, sizeof (ipv6mreq.ipv6mr_multiaddr)); memcpy (&ipv6mreq.ipv6mr_multiaddr, &mcip.a6, sizeof (ipv6mreq.ipv6mr_multiaddr));
ipv6mreq.ipv6mr_interface = interf ? interf->if_index : 0; ipv6mreq.ipv6mr_interface = interf ? interf->if_index : 0;
rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &ipv6mreq, sizeof (ipv6mreq)); rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &ipv6mreq, sizeof (ipv6mreq));
} }
@ -296,12 +567,12 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
#endif #endif
{ {
struct ip_mreq mreq; struct ip_mreq mreq;
mreq.imr_multiaddr = ((struct sockaddr_in *) &mcip)->sin_addr; mreq.imr_multiaddr = mcip.a4.sin_addr;
if (interf) if (interf)
memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface));
else else
mreq.imr_interface.s_addr = htonl (INADDR_ANY); mreq.imr_interface.s_addr = htonl (INADDR_ANY);
rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof (mreq)); rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof (mreq));
} }
return (rc == DDS_RETCODE_OK) ? 0 : -1; return (rc == DDS_RETCODE_OK) ? 0 : -1;
} }
@ -310,17 +581,17 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf) static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
{ {
dds_return_t rc; dds_return_t rc;
struct sockaddr_storage mcip, srcip; union addr mcip, srcip;
ddsi_ipaddr_from_loc(&mcip, mcloc); ddsi_ipaddr_from_loc (&mcip.x, mcloc);
ddsi_ipaddr_from_loc(&srcip, srcloc); ddsi_ipaddr_from_loc (&srcip.x, srcloc);
#if DDSRT_HAVE_IPV6 #if DDSRT_HAVE_IPV6
if (mcloc->kind == NN_LOCATOR_KIND_UDPv6) if (mcloc->kind == NN_LOCATOR_KIND_UDPv6)
{ {
struct group_source_req gsr; struct group_source_req gsr;
memset (&gsr, 0, sizeof (gsr)); memset (&gsr, 0, sizeof (gsr));
gsr.gsr_interface = interf ? interf->if_index : 0; gsr.gsr_interface = interf ? interf->if_index : 0;
memcpy (&gsr.gsr_group, &mcip, sizeof (gsr.gsr_group)); memcpy (&gsr.gsr_group, &mcip.a6, sizeof (gsr.gsr_group));
memcpy (&gsr.gsr_source, &srcip, sizeof (gsr.gsr_source)); memcpy (&gsr.gsr_source, &srcip.a6, sizeof (gsr.gsr_source));
rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP, &gsr, sizeof (gsr)); rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP, &gsr, sizeof (gsr));
} }
else else
@ -328,8 +599,8 @@ static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
{ {
struct ip_mreq_source mreq; struct ip_mreq_source mreq;
memset (&mreq, 0, sizeof (mreq)); memset (&mreq, 0, sizeof (mreq));
mreq.imr_sourceaddr = ((struct sockaddr_in *) &srcip)->sin_addr; mreq.imr_sourceaddr = srcip.a4.sin_addr;
mreq.imr_multiaddr = ((struct sockaddr_in *) &mcip)->sin_addr; mreq.imr_multiaddr = mcip.a4.sin_addr;
if (interf) if (interf)
memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface));
else else
@ -340,43 +611,42 @@ static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
} }
#endif #endif
static int ddsi_udp_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf) static int ddsi_udp_join_mc (ddsi_tran_conn_t conn_cmn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
{ {
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn; ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
(void)srcloc; (void) srcloc;
#ifdef DDSI_INCLUDE_SSM #ifdef DDSI_INCLUDE_SSM
if (srcloc) if (srcloc)
return joinleave_ssm_mcgroup(uc->m_sock, 1, srcloc, mcloc, interf); return joinleave_ssm_mcgroup (conn->m_sock, 1, srcloc, mcloc, interf);
else else
#endif #endif
return joinleave_asm_mcgroup(uc->m_sock, 1, mcloc, interf); return joinleave_asm_mcgroup (conn->m_sock, 1, mcloc, interf);
} }
static int ddsi_udp_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf) static int ddsi_udp_leave_mc (ddsi_tran_conn_t conn_cmn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
{ {
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn; ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
(void)srcloc; (void) srcloc;
#ifdef DDSI_INCLUDE_SSM #ifdef DDSI_INCLUDE_SSM
if (srcloc) if (srcloc)
return joinleave_ssm_mcgroup(uc->m_sock, 0, srcloc, mcloc, interf); return joinleave_ssm_mcgroup (conn->m_sock, 0, srcloc, mcloc, interf);
else else
#endif #endif
return joinleave_asm_mcgroup(uc->m_sock, 0, mcloc, interf); return joinleave_asm_mcgroup (conn->m_sock, 0, mcloc, interf);
} }
static void ddsi_udp_release_conn (ddsi_tran_conn_t conn) static void ddsi_udp_release_conn (ddsi_tran_conn_t conn_cmn)
{ {
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn; ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
DDS_CTRACE (&conn->m_base.gv->logconfig, struct ddsi_domaingv const * const gv = conn->m_base.m_base.gv;
"ddsi_udp_release_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", GVTRACE ("ddsi_udp_release_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
conn->m_base.m_multicast ? "multicast" : "unicast", conn_cmn->m_base.m_multicast ? "multicast" : "unicast",
uc->m_sock, conn->m_sock, conn->m_base.m_base.m_port);
uc->m_base.m_base.m_port); ddsrt_close (conn->m_sock);
ddsrt_close (uc->m_sock);
#if defined _WIN32 && !defined WINCE #if defined _WIN32 && !defined WINCE
WSACloseEvent(uc->m_sockEvent); WSACloseEvent (conn->m_sockEvent);
#endif #endif
ddsrt_free (conn); ddsrt_free (conn_cmn);
} }
static int ddsi_udp_is_mcaddr (const ddsi_tran_factory_t tran, const nn_locator_t *loc) static int ddsi_udp_is_mcaddr (const ddsi_tran_factory_t tran, const nn_locator_t *loc)
@ -462,7 +732,8 @@ static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const nn_
static void ddsi_udp_fini (ddsi_tran_factory_t fact) static void ddsi_udp_fini (ddsi_tran_factory_t fact)
{ {
DDS_CLOG (DDS_LC_CONFIG, &fact->gv->logconfig, "udp finalized\n"); struct ddsi_domaingv const * const gv = fact->gv;
GVLOG (DDS_LC_CONFIG, "udp finalized\n");
ddsrt_free (fact); ddsrt_free (fact);
} }
@ -472,7 +743,7 @@ static int ddsi_udp_is_valid_port (ddsi_tran_factory_t fact, uint32_t port)
return (port <= 65535); return (port <= 65535);
} }
int ddsi_udp_init (struct ddsi_domaingv *gv) int ddsi_udp_init (struct ddsi_domaingv*gv)
{ {
struct ddsi_tran_factory *fact = ddsrt_malloc (sizeof (*fact)); struct ddsi_tran_factory *fact = ddsrt_malloc (sizeof (*fact));
memset (fact, 0, sizeof (*fact)); memset (fact, 0, sizeof (*fact));

View file

@ -17,9 +17,9 @@ extern inline bool vendor_equals (nn_vendorid_t a, nn_vendorid_t b);
extern inline bool vendor_is_rti (nn_vendorid_t vendor); extern inline bool vendor_is_rti (nn_vendorid_t vendor);
extern inline bool vendor_is_twinoaks (nn_vendorid_t vendor); extern inline bool vendor_is_twinoaks (nn_vendorid_t vendor);
extern inline bool vendor_is_eprosima (nn_vendorid_t vendor); extern inline bool vendor_is_eprosima (nn_vendorid_t vendor);
extern inline bool vendor_is_prismtech (nn_vendorid_t vendor); extern inline bool vendor_is_adlink (nn_vendorid_t vendor);
extern inline bool vendor_is_opensplice (nn_vendorid_t vendor); extern inline bool vendor_is_opensplice (nn_vendorid_t vendor);
extern inline bool vendor_is_cloud (nn_vendorid_t vendor); extern inline bool vendor_is_cloud (nn_vendorid_t vendor);
extern inline bool vendor_is_eclipse (nn_vendorid_t vendor); extern inline bool vendor_is_eclipse (nn_vendorid_t vendor);
extern inline bool vendor_is_eclipse_or_opensplice (nn_vendorid_t vendor); extern inline bool vendor_is_eclipse_or_opensplice (nn_vendorid_t vendor);
extern inline bool vendor_is_eclipse_or_prismtech (nn_vendorid_t vendor); extern inline bool vendor_is_eclipse_or_adlink (nn_vendorid_t vendor);

View file

@ -30,7 +30,6 @@
#include "dds/ddsi/q_unused.h" #include "dds/ddsi/q_unused.h"
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_addrset.h" #include "dds/ddsi/q_addrset.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsrt/xmlparser.h" #include "dds/ddsrt/xmlparser.h"
@ -532,7 +531,7 @@ static const struct cfgelem thread_properties_cfgattrs[] = {
<li><i>fsm</i>: finite state machine thread for handling security handshake;</li>\n\ <li><i>fsm</i>: finite state machine thread for handling security handshake;</li>\n\
<li><i>xmit.CHAN</i>: transmit thread for channel CHAN;</li>\n\ <li><i>xmit.CHAN</i>: transmit thread for channel CHAN;</li>\n\
<li><i>dq.CHAN</i>: delivery thread for channel CHAN;</li>\n\ <li><i>dq.CHAN</i>: delivery thread for channel CHAN;</li>\n\
<li><i>tev.CHAN</i>: timed-even thread for channel CHAN.</li></ul>") }, <li><i>tev.CHAN</i>: timed-event thread for channel CHAN.</li></ul>") },
END_MARKER END_MARKER
}; };
@ -568,13 +567,13 @@ static const struct cfgelem compatibility_cfgelems[] = {
END_MARKER END_MARKER
}; };
static const struct cfgelem unsupp_test_cfgelems[] = { static const struct cfgelem internal_test_cfgelems[] = {
{ LEAF("XmitLossiness"), 1, "0", ABSOFF(xmit_lossiness), 0, uf_int, 0, pf_int, { LEAF("XmitLossiness"), 1, "0", ABSOFF(xmit_lossiness), 0, uf_int, 0, pf_int,
BLURB("<p>This element controls the fraction of outgoing packets to drop, specified as samples per thousand.</p>") }, BLURB("<p>This element controls the fraction of outgoing packets to drop, specified as samples per thousand.</p>") },
END_MARKER END_MARKER
}; };
static const struct cfgelem unsupp_watermarks_cfgelems[] = { static const struct cfgelem internal_watermarks_cfgelems[] = {
{ LEAF("WhcLow"), 1, "1 kB", ABSOFF(whc_lowwater_mark), 0, uf_memsize, 0, pf_memsize, { LEAF("WhcLow"), 1, "1 kB", ABSOFF(whc_lowwater_mark), 0, uf_memsize, 0, pf_memsize,
BLURB("<p>This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.</p>") }, BLURB("<p>This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.</p>") },
{ LEAF("WhcHigh"), 1, "100 kB", ABSOFF(whc_highwater_mark), 0, uf_memsize, 0, pf_memsize, { LEAF("WhcHigh"), 1, "100 kB", ABSOFF(whc_highwater_mark), 0, uf_memsize, 0, pf_memsize,
@ -632,7 +631,7 @@ static const struct cfgelem multiple_recv_threads_attrs[] = {
END_MARKER END_MARKER
}; };
static const struct cfgelem unsupp_cfgelems[] = { static const struct cfgelem internal_cfgelems[] = {
{ MOVED("MaxMessageSize", "CycloneDDS/General/MaxMessageSize") }, { MOVED("MaxMessageSize", "CycloneDDS/General/MaxMessageSize") },
{ MOVED("FragmentSize", "CycloneDDS/General/FragmentSize") }, { MOVED("FragmentSize", "CycloneDDS/General/FragmentSize") },
{ LEAF("DeliveryQueueMaxSamples"), 1, "256", ABSOFF(delivery_queue_maxsamples), 0, uf_uint, 0, pf_uint, { LEAF("DeliveryQueueMaxSamples"), 1, "256", ABSOFF(delivery_queue_maxsamples), 0, uf_uint, 0, pf_uint,
@ -733,9 +732,9 @@ static const struct cfgelem unsupp_cfgelems[] = {
BLURB("<p>This element controls whether all traffic is handled by a single receive thread (false) or whether multiple receive threads may be used to improve latency (true). By default it is disabled on Windows because it appears that one cannot count on being able to send packets to oneself, which is necessary to stop the thread during shutdown. Currently multiple receive threads are only used for connectionless transport (e.g., UDP) and ManySocketsMode not set to single (the default).</p>") }, BLURB("<p>This element controls whether all traffic is handled by a single receive thread (false) or whether multiple receive threads may be used to improve latency (true). By default it is disabled on Windows because it appears that one cannot count on being able to send packets to oneself, which is necessary to stop the thread during shutdown. Currently multiple receive threads are only used for connectionless transport (e.g., UDP) and ManySocketsMode not set to single (the default).</p>") },
{ MGROUP("ControlTopic", control_topic_cfgelems, control_topic_cfgattrs), 1, 0, 0, 0, 0, 0, 0, 0, { MGROUP("ControlTopic", control_topic_cfgelems, control_topic_cfgattrs), 1, 0, 0, 0, 0, 0, 0, 0,
BLURB("<p>The ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not.<p>") }, BLURB("<p>The ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not.<p>") },
{ GROUP("Test", unsupp_test_cfgelems), { GROUP("Test", internal_test_cfgelems),
BLURB("<p>Testing options.</p>") }, BLURB("<p>Testing options.</p>") },
{ GROUP("Watermarks", unsupp_watermarks_cfgelems), { GROUP("Watermarks", internal_watermarks_cfgelems),
BLURB("<p>Watermarks for flow-control.</p>") }, BLURB("<p>Watermarks for flow-control.</p>") },
{ LEAF("EnableExpensiveChecks"), 1, "", ABSOFF(enabled_xchecks), 0, uf_xcheck, 0, pf_xcheck, { LEAF("EnableExpensiveChecks"), 1, "", ABSOFF(enabled_xchecks), 0, uf_xcheck, 0, pf_xcheck,
BLURB("<p>This element enables expensive checks in builds with assertions enabled and is ignored otherwise. Recognised categories are:</p>\n\ BLURB("<p>This element enables expensive checks in builds with assertions enabled and is ignored otherwise. Recognised categories are:</p>\n\
@ -943,7 +942,7 @@ static const struct cfgelem domain_cfgelems[] = {
BLURB("<p>The Discovery element allows specifying various parameters related to the discovery of peers.</p>") }, BLURB("<p>The Discovery element allows specifying various parameters related to the discovery of peers.</p>") },
{ GROUP("Tracing", tracing_cfgelems), { GROUP("Tracing", tracing_cfgelems),
BLURB("<p>The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.</p>") }, BLURB("<p>The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.</p>") },
{ GROUP("Internal|Unsupported", unsupp_cfgelems), { GROUP("Internal|Unsupported", internal_cfgelems),
BLURB("<p>The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options.</p>") }, BLURB("<p>The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options.</p>") },
{ GROUP("TCP", tcp_cfgelems), { GROUP("TCP", tcp_cfgelems),
BLURB("<p>The TCP element allows specifying various parameters related to running DDSI over TCP.</p>") }, BLURB("<p>The TCP element allows specifying various parameters related to running DDSI over TCP.</p>") },
@ -1014,12 +1013,12 @@ static const struct cfgelem root_cfgelem = {
static const struct unit unittab_duration[] = { static const struct unit unittab_duration[] = {
{ "ns", 1 }, { "ns", 1 },
{ "us", 1000 }, { "us", DDS_USECS (1) },
{ "ms", T_MILLISECOND }, { "ms", DDS_MSECS (1) },
{ "s", T_SECOND }, { "s", DDS_SECS (1) },
{ "min", 60 * T_SECOND }, { "min", DDS_SECS (60) },
{ "hr", 3600 * T_SECOND }, { "hr", DDS_SECS (3600) },
{ "day", 24 * 3600 * T_SECOND }, { "day", DDS_SECS (24 * 3600) },
{ NULL, 0 } { NULL, 0 }
}; };
@ -2075,37 +2074,37 @@ static enum update_result uf_duration_inf (struct cfgst *cfgst, void *parent, st
{ {
if (ddsrt_strcasecmp (value, "inf") == 0) { if (ddsrt_strcasecmp (value, "inf") == 0) {
int64_t * const elem = cfg_address (cfgst, parent, cfgelem); int64_t * const elem = cfg_address (cfgst, parent, cfgelem);
*elem = T_NEVER; *elem = DDS_INFINITY;
return URES_SUCCESS; return URES_SUCCESS;
} else { } else {
return uf_duration_gen (cfgst, parent, cfgelem, value, 0, 0, T_NEVER - 1); return uf_duration_gen (cfgst, parent, cfgelem, value, 0, 0, DDS_INFINITY - 1);
} }
} }
static enum update_result uf_duration_ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) static enum update_result uf_duration_ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{ {
return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, 0, 3600 * T_SECOND); return uf_duration_gen (cfgst, parent, cfgelem, value, DDS_MSECS (1), 0, DDS_SECS (3600));
} }
static enum update_result uf_duration_ms_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) static enum update_result uf_duration_ms_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{ {
return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, 0, T_SECOND); return uf_duration_gen (cfgst, parent, cfgelem, value, DDS_MSECS (1), 0, DDS_SECS (1));
} }
static enum update_result uf_duration_us_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) static enum update_result uf_duration_us_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{ {
return uf_duration_gen (cfgst, parent, cfgelem, value, 1000, 0, T_SECOND); return uf_duration_gen (cfgst, parent, cfgelem, value, DDS_USECS (1), 0, DDS_SECS (1));
} }
static enum update_result uf_duration_100ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) static enum update_result uf_duration_100ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{ {
return uf_duration_gen (cfgst, parent, cfgelem, value, 0, 100 * T_MILLISECOND, 3600 * T_SECOND); return uf_duration_gen (cfgst, parent, cfgelem, value, 0, DDS_MSECS (100), DDS_SECS (3600));
} }
static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources) static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
{ {
int64_t const * const elem = cfg_address (cfgst, parent, cfgelem); int64_t const * const elem = cfg_address (cfgst, parent, cfgelem);
if (*elem == T_NEVER) if (*elem == DDS_INFINITY)
cfg_logelem (cfgst, sources, "inf"); cfg_logelem (cfgst, sources, "inf");
else else
pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s"); pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s");
@ -2743,7 +2742,7 @@ static int set_default_channel (struct config *cfg)
c->next = NULL; c->next = NULL;
c->name = ddsrt_strdup ("user"); c->name = ddsrt_strdup ("user");
c->priority = 0; c->priority = 0;
c->resolution = 1 * T_MILLISECOND; c->resolution = DDS_MSECS (1);
#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING #ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING
c->data_bandwidth_limit = 0; c->data_bandwidth_limit = 0;
c->auxiliary_bandwidth_limit = 0; c->auxiliary_bandwidth_limit = 0;

View file

@ -183,7 +183,7 @@ static int write_mpayload (struct writer *wr, int alive, nn_parameterid_t keypar
nn_xmsg_payload_to_plistsample (&plist_sample, keyparam, mpayload); nn_xmsg_payload_to_plistsample (&plist_sample, keyparam, mpayload);
serdata = ddsi_serdata_from_sample (wr->e.gv->plist_topic, alive ? SDK_DATA : SDK_KEY, &plist_sample); serdata = ddsi_serdata_from_sample (wr->e.gv->plist_topic, alive ? SDK_DATA : SDK_KEY, &plist_sample);
serdata->statusinfo = alive ? 0 : NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER; serdata->statusinfo = alive ? 0 : NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER;
serdata->timestamp = now (); serdata->timestamp = ddsrt_time_wallclock ();
return write_sample_nogc_notk (ts1, NULL, wr, serdata); return write_sample_nogc_notk (ts1, NULL, wr, serdata);
} }
@ -276,28 +276,28 @@ void get_participant_builtin_topic_data(const struct participant *pp, struct nn_
} }
ps.participant_lease_duration = pp->lease_duration; ps.participant_lease_duration = pp->lease_duration;
/* Add PrismTech specific version information */ /* Add Adlink specific version information */
{ {
ps.present |= PP_PRISMTECH_PARTICIPANT_VERSION_INFO; ps.present |= PP_ADLINK_PARTICIPANT_VERSION_INFO;
memset (&ps.prismtech_participant_version_info, 0, sizeof (ps.prismtech_participant_version_info)); memset (&ps.adlink_participant_version_info, 0, sizeof (ps.adlink_participant_version_info));
ps.prismtech_participant_version_info.version = 0; ps.adlink_participant_version_info.version = 0;
ps.prismtech_participant_version_info.flags = ps.adlink_participant_version_info.flags =
NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG | NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG |
NN_PRISMTECH_FL_PTBES_FIXED_0 | NN_ADLINK_FL_PTBES_FIXED_0 |
NN_PRISMTECH_FL_SUPPORTS_STATUSINFOX; NN_ADLINK_FL_SUPPORTS_STATUSINFOX;
if (pp->e.gv->config.besmode == BESMODE_MINIMAL) if (pp->e.gv->config.besmode == BESMODE_MINIMAL)
ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_MINIMAL_BES_MODE; ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_MINIMAL_BES_MODE;
ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock); ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock);
if (pp->is_ddsi2_pp) if (pp->is_ddsi2_pp)
ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2; ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_PARTICIPANT_IS_DDSI2;
ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock); ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock);
if (ddsrt_gethostname(node, sizeof(node)-1) < 0) if (ddsrt_gethostname(node, sizeof(node)-1) < 0)
(void) ddsrt_strlcpy (node, "unknown", sizeof (node)); (void) ddsrt_strlcpy (node, "unknown", sizeof (node));
size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */ size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */
ps.prismtech_participant_version_info.internals = ddsrt_malloc(size); ps.adlink_participant_version_info.internals = ddsrt_malloc(size);
(void) snprintf(ps.prismtech_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME); (void) snprintf(ps.adlink_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME);
ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.prismtech_participant_version_info.internals); ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.adlink_participant_version_info.internals);
} }
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
@ -308,7 +308,7 @@ void get_participant_builtin_topic_data(const struct participant *pp, struct nn_
} }
#endif #endif
/* Participant QoS's insofar as they are set, different from the default, and mapped to the SPDP data, rather than to the PrismTech-specific CMParticipant endpoint. Currently, that means just USER_DATA. */ /* Participant QoS's insofar as they are set, different from the default, and mapped to the SPDP data, rather than to the Adlink-specific CMParticipant endpoint. Currently, that means just USER_DATA. */
qosdiff = ddsi_xqos_delta (&pp->plist->qos, &pp->e.gv->default_plist_pp.qos, QP_USER_DATA); qosdiff = ddsi_xqos_delta (&pp->plist->qos, &pp->e.gv->default_plist_pp.qos, QP_USER_DATA);
if (pp->e.gv->config.explicitly_publish_qos_set_to_default) if (pp->e.gv->config.explicitly_publish_qos_set_to_default)
qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK; qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
@ -472,28 +472,28 @@ int spdp_write (struct participant *pp)
} }
ps.participant_lease_duration = pp->lease_duration; ps.participant_lease_duration = pp->lease_duration;
/* Add PrismTech specific version information */ /* Add Adlink specific version information */
{ {
ps.present |= PP_PRISMTECH_PARTICIPANT_VERSION_INFO; ps.present |= PP_ADLINK_PARTICIPANT_VERSION_INFO;
memset (&ps.prismtech_participant_version_info, 0, sizeof (ps.prismtech_participant_version_info)); memset (&ps.adlink_participant_version_info, 0, sizeof (ps.adlink_participant_version_info));
ps.prismtech_participant_version_info.version = 0; ps.adlink_participant_version_info.version = 0;
ps.prismtech_participant_version_info.flags = ps.adlink_participant_version_info.flags =
NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG | NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG |
NN_PRISMTECH_FL_PTBES_FIXED_0 | NN_ADLINK_FL_PTBES_FIXED_0 |
NN_PRISMTECH_FL_SUPPORTS_STATUSINFOX; NN_ADLINK_FL_SUPPORTS_STATUSINFOX;
if (pp->e.gv->config.besmode == BESMODE_MINIMAL) if (pp->e.gv->config.besmode == BESMODE_MINIMAL)
ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_MINIMAL_BES_MODE; ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_MINIMAL_BES_MODE;
ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock); ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock);
if (pp->is_ddsi2_pp) if (pp->is_ddsi2_pp)
ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2; ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_PARTICIPANT_IS_DDSI2;
ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock); ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock);
if (ddsrt_gethostname(node, sizeof(node)-1) < 0) if (ddsrt_gethostname(node, sizeof(node)-1) < 0)
(void) ddsrt_strlcpy (node, "unknown", sizeof (node)); (void) ddsrt_strlcpy (node, "unknown", sizeof (node));
size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */ size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */
ps.prismtech_participant_version_info.internals = ddsrt_malloc(size); ps.adlink_participant_version_info.internals = ddsrt_malloc(size);
(void) snprintf(ps.prismtech_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME); (void) snprintf(ps.adlink_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME);
ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.prismtech_participant_version_info.internals); ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.adlink_participant_version_info.internals);
} }
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
@ -504,7 +504,7 @@ int spdp_write (struct participant *pp)
} }
#endif #endif
/* Participant QoS's insofar as they are set, different from the default, and mapped to the SPDP data, rather than to the PrismTech-specific CMParticipant endpoint. Currently, that means just USER_DATA. */ /* Participant QoS's insofar as they are set, different from the default. Currently, that means just USER_DATA. */
qosdiff = ddsi_xqos_delta (&pp->plist->qos, &pp->e.gv->default_plist_pp.qos, QP_USER_DATA); qosdiff = ddsi_xqos_delta (&pp->plist->qos, &pp->e.gv->default_plist_pp.qos, QP_USER_DATA);
if (pp->e.gv->config.explicitly_publish_qos_set_to_default) if (pp->e.gv->config.explicitly_publish_qos_set_to_default)
qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK; qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
@ -568,7 +568,7 @@ int spdp_dispose_unregister (struct participant *pp)
return ret; return ret;
} }
static unsigned pseudo_random_delay (const ddsi_guid_t *x, const ddsi_guid_t *y, nn_mtime_t tnow) static unsigned pseudo_random_delay (const ddsi_guid_t *x, const ddsi_guid_t *y, ddsrt_mtime_t tnow)
{ {
/* You know, an ordinary random generator would be even better, but /* You know, an ordinary random generator would be even better, but
the C library doesn't have a reentrant one and I don't feel like the C library doesn't have a reentrant one and I don't feel like
@ -601,7 +601,7 @@ static void respond_to_spdp (const struct ddsi_domaingv *gv, const ddsi_guid_t *
{ {
struct entidx_enum_participant est; struct entidx_enum_participant est;
struct participant *pp; struct participant *pp;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
entidx_enum_participant_init (&est, gv->entity_index); entidx_enum_participant_init (&est, gv->entity_index);
while ((pp = entidx_enum_participant_next (&est)) != NULL) while ((pp = entidx_enum_participant_next (&est)) != NULL)
{ {
@ -611,7 +611,7 @@ static void respond_to_spdp (const struct ddsi_domaingv *gv, const ddsi_guid_t *
unsigned delay_norm = delay_base >> 2; unsigned delay_norm = delay_base >> 2;
int64_t delay_max_ms = gv->config.spdp_response_delay_max / 1000000; int64_t delay_max_ms = gv->config.spdp_response_delay_max / 1000000;
int64_t delay = (int64_t) delay_norm * delay_max_ms / 1000; int64_t delay = (int64_t) delay_norm * delay_max_ms / 1000;
nn_mtime_t tsched = add_duration_to_mtime (tnow, delay); ddsrt_mtime_t tsched = ddsrt_mtime_add_duration (tnow, delay);
GVTRACE (" %"PRId64, delay); GVTRACE (" %"PRId64, delay);
if (!pp->e.gv->config.unicast_response_to_spdp_messages) if (!pp->e.gv->config.unicast_response_to_spdp_messages)
/* pp can't reach gc_delete_participant => can safely reschedule */ /* pp can't reach gc_delete_participant => can safely reschedule */
@ -622,7 +622,7 @@ static void respond_to_spdp (const struct ddsi_domaingv *gv, const ddsi_guid_t *
entidx_enum_participant_fini (&est); entidx_enum_participant_fini (&est);
} }
static int handle_SPDP_dead (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, nn_wctime_t timestamp, const ddsi_plist_t *datap, unsigned statusinfo) static int handle_SPDP_dead (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, ddsrt_wctime_t timestamp, const ddsi_plist_t *datap, unsigned statusinfo)
{ {
struct ddsi_domaingv * const gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
ddsi_guid_t guid; ddsi_guid_t guid;
@ -691,7 +691,7 @@ static struct proxy_participant *find_ddsi2_proxy_participant (const struct enti
return pp; return pp;
} }
static void make_participants_dependent_on_ddsi2 (struct ddsi_domaingv *gv, const ddsi_guid_t *ddsi2guid, nn_wctime_t timestamp) static void make_participants_dependent_on_ddsi2 (struct ddsi_domaingv *gv, const ddsi_guid_t *ddsi2guid, ddsrt_wctime_t timestamp)
{ {
struct entidx_enum_proxy_participant it; struct entidx_enum_proxy_participant it;
struct proxy_participant *pp, *d2pp; struct proxy_participant *pp, *d2pp;
@ -727,7 +727,7 @@ static void make_participants_dependent_on_ddsi2 (struct ddsi_domaingv *gv, cons
} }
} }
static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_wctime_t timestamp, const ddsi_plist_t *datap) static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, ddsrt_wctime_t timestamp, const ddsi_plist_t *datap)
{ {
struct ddsi_domaingv * const gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
const unsigned bes_sedp_announcer_mask = const unsigned bes_sedp_announcer_mask =
@ -809,7 +809,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
that are not alive are not set alive here. This is done only when that are not alive are not set alive here. This is done only when
data is received from a particular pwr (in handle_regular) */ data is received from a particular pwr (in handle_regular) */
if ((lease = ddsrt_atomic_ldvoidp (&proxypp->minl_auto)) != NULL) if ((lease = ddsrt_atomic_ldvoidp (&proxypp->minl_auto)) != NULL)
lease_renew (lease, now_et ()); lease_renew (lease, ddsrt_time_elapsed ());
ddsrt_mutex_lock (&proxypp->e.lock); ddsrt_mutex_lock (&proxypp->e.lock);
if (proxypp->implicitly_created || seq > proxypp->seq) if (proxypp->implicitly_created || seq > proxypp->seq)
{ {
@ -850,21 +850,21 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
else else
{ {
GVLOGDISC (" (PARTICIPANT_LEASE_DURATION defaulting to 100s)"); GVLOGDISC (" (PARTICIPANT_LEASE_DURATION defaulting to 100s)");
lease_duration = 100 * T_SECOND; lease_duration = DDS_SECS (100);
} }
if (datap->present & PP_PRISMTECH_PARTICIPANT_VERSION_INFO) { if (datap->present & PP_ADLINK_PARTICIPANT_VERSION_INFO) {
if ((datap->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG) && if ((datap->adlink_participant_version_info.flags & NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG) &&
(datap->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2)) (datap->adlink_participant_version_info.flags & NN_ADLINK_FL_PARTICIPANT_IS_DDSI2))
custom_flags |= CF_PARTICIPANT_IS_DDSI2; custom_flags |= CF_PARTICIPANT_IS_DDSI2;
GVLOGDISC (" (0x%08x-0x%08x-0x%08x-0x%08x-0x%08x %s)", GVLOGDISC (" (0x%08x-0x%08x-0x%08x-0x%08x-0x%08x %s)",
datap->prismtech_participant_version_info.version, datap->adlink_participant_version_info.version,
datap->prismtech_participant_version_info.flags, datap->adlink_participant_version_info.flags,
datap->prismtech_participant_version_info.unused[0], datap->adlink_participant_version_info.unused[0],
datap->prismtech_participant_version_info.unused[1], datap->adlink_participant_version_info.unused[1],
datap->prismtech_participant_version_info.unused[2], datap->adlink_participant_version_info.unused[2],
datap->prismtech_participant_version_info.internals); datap->adlink_participant_version_info.internals);
} }
/* If any of the SEDP announcer are missing AND the guid prefix of /* If any of the SEDP announcer are missing AND the guid prefix of
@ -881,7 +881,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
GVLOGDISC (" (depends on "PGUIDFMT")", PGUID (privileged_pp_guid)); GVLOGDISC (" (depends on "PGUIDFMT")", PGUID (privileged_pp_guid));
/* never expire lease for this proxy: it won't actually expire /* never expire lease for this proxy: it won't actually expire
until the "privileged" one expires anyway */ until the "privileged" one expires anyway */
lease_duration = T_NEVER; lease_duration = DDS_INFINITY;
} }
else if (vendor_is_eclipse_or_opensplice (rst->vendor) && !(custom_flags & CF_PARTICIPANT_IS_DDSI2)) else if (vendor_is_eclipse_or_opensplice (rst->vendor) && !(custom_flags & CF_PARTICIPANT_IS_DDSI2))
{ {
@ -893,7 +893,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
else else
{ {
privileged_pp_guid.prefix = ddsi2->e.guid.prefix; privileged_pp_guid.prefix = ddsi2->e.guid.prefix;
lease_duration = T_NEVER; lease_duration = DDS_INFINITY;
GVLOGDISC (" (depends on "PGUIDFMT")", PGUID (privileged_pp_guid)); GVLOGDISC (" (depends on "PGUIDFMT")", PGUID (privileged_pp_guid));
} }
} }
@ -1016,7 +1016,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
return 1; return 1;
} }
static void handle_SPDP (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, seqno_t seq, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len) static void handle_SPDP (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, seqno_t seq, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len)
{ {
struct ddsi_domaingv * const gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
@ -1299,7 +1299,7 @@ static const char *durability_to_string (dds_durability_kind_t k)
return "undefined-durability"; return "undefined-durability";
} }
static struct proxy_participant *implicitly_create_proxypp (struct ddsi_domaingv *gv, const ddsi_guid_t *ppguid, ddsi_plist_t *datap /* note: potentially modifies datap */, const ddsi_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp, seqno_t seq) static struct proxy_participant *implicitly_create_proxypp (struct ddsi_domaingv *gv, const ddsi_guid_t *ppguid, ddsi_plist_t *datap /* note: potentially modifies datap */, const ddsi_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, ddsrt_wctime_t timestamp, seqno_t seq)
{ {
ddsi_guid_t privguid; ddsi_guid_t privguid;
ddsi_plist_t pp_plist; ddsi_plist_t pp_plist;
@ -1336,7 +1336,7 @@ static struct proxy_participant *implicitly_create_proxypp (struct ddsi_domaingv
doing anything about (1). That means we fall back to the legacy mode of locally generating doing anything about (1). That means we fall back to the legacy mode of locally generating
GIDs but leaving the system id unchanged if the remote is OSPL. */ GIDs but leaving the system id unchanged if the remote is OSPL. */
actual_vendorid = (datap->present & PP_VENDORID) ? datap->vendorid : vendorid; actual_vendorid = (datap->present & PP_VENDORID) ? datap->vendorid : vendorid;
new_proxy_participant(gv, ppguid, 0, &privguid, new_addrset(), new_addrset(), &pp_plist, T_NEVER, actual_vendorid, CF_IMPLICITLY_CREATED_PROXYPP, timestamp, seq); new_proxy_participant(gv, ppguid, 0, &privguid, new_addrset(), new_addrset(), &pp_plist, DDS_INFINITY, actual_vendorid, CF_IMPLICITLY_CREATED_PROXYPP, timestamp, seq);
} }
else if (ppguid->prefix.u[0] == src_guid_prefix->u[0] && vendor_is_eclipse_or_opensplice (vendorid)) else if (ppguid->prefix.u[0] == src_guid_prefix->u[0] && vendor_is_eclipse_or_opensplice (vendorid))
{ {
@ -1364,13 +1364,13 @@ static struct proxy_participant *implicitly_create_proxypp (struct ddsi_domaingv
as_meta = ref_addrset(privpp->as_meta); as_meta = ref_addrset(privpp->as_meta);
/* copy just what we need */ /* copy just what we need */
tmp_plist = *privpp->plist; tmp_plist = *privpp->plist;
tmp_plist.present = PP_PARTICIPANT_GUID | PP_PRISMTECH_PARTICIPANT_VERSION_INFO; tmp_plist.present = PP_PARTICIPANT_GUID | PP_ADLINK_PARTICIPANT_VERSION_INFO;
tmp_plist.participant_guid = *ppguid; tmp_plist.participant_guid = *ppguid;
ddsi_plist_mergein_missing (&pp_plist, &tmp_plist, ~(uint64_t)0, ~(uint64_t)0); ddsi_plist_mergein_missing (&pp_plist, &tmp_plist, ~(uint64_t)0, ~(uint64_t)0);
ddsrt_mutex_unlock (&privpp->e.lock); ddsrt_mutex_unlock (&privpp->e.lock);
pp_plist.prismtech_participant_version_info.flags &= ~NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2; pp_plist.adlink_participant_version_info.flags &= ~NN_ADLINK_FL_PARTICIPANT_IS_DDSI2;
new_proxy_participant (gv, ppguid, 0, &privguid, as_default, as_meta, &pp_plist, T_NEVER, vendorid, CF_IMPLICITLY_CREATED_PROXYPP | CF_PROXYPP_NO_SPDP, timestamp, seq); new_proxy_participant (gv, ppguid, 0, &privguid, as_default, as_meta, &pp_plist, DDS_INFINITY, vendorid, CF_IMPLICITLY_CREATED_PROXYPP | CF_PROXYPP_NO_SPDP, timestamp, seq);
} }
} }
@ -1379,7 +1379,7 @@ static struct proxy_participant *implicitly_create_proxypp (struct ddsi_domaingv
return entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid); return entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid);
} }
static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, ddsi_plist_t *datap /* note: potentially modifies datap */, const ddsi_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp) static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, ddsi_plist_t *datap /* note: potentially modifies datap */, const ddsi_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, ddsrt_wctime_t timestamp)
{ {
#define E(msg, lbl) do { GVLOGDISC (msg); goto lbl; } while (0) #define E(msg, lbl) do { GVLOGDISC (msg); goto lbl; } while (0)
struct ddsi_domaingv * const gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
@ -1429,7 +1429,7 @@ static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, dd
is_writer = is_writer_entityid (datap->endpoint_guid.entityid); is_writer = is_writer_entityid (datap->endpoint_guid.entityid);
if (!is_writer) if (!is_writer)
ddsi_xqos_mergein_missing (xqos, &gv->default_xqos_rd, ~(uint64_t)0); ddsi_xqos_mergein_missing (xqos, &gv->default_xqos_rd, ~(uint64_t)0);
else if (vendor_is_eclipse_or_prismtech(vendorid)) else if (vendor_is_eclipse_or_adlink(vendorid))
ddsi_xqos_mergein_missing (xqos, &gv->default_xqos_wr, ~(uint64_t)0); ddsi_xqos_mergein_missing (xqos, &gv->default_xqos_wr, ~(uint64_t)0);
else else
ddsi_xqos_mergein_missing (xqos, &gv->default_xqos_wr_nad, ~(uint64_t)0); ddsi_xqos_mergein_missing (xqos, &gv->default_xqos_wr_nad, ~(uint64_t)0);
@ -1481,7 +1481,7 @@ static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, dd
GVLOGDISC (" "PGUIDFMT" attach-to-DS "PGUIDFMT, PGUID(pp->e.guid), PGUIDPREFIX(*src_guid_prefix), pp->privileged_pp_guid.entityid.u); GVLOGDISC (" "PGUIDFMT" attach-to-DS "PGUIDFMT, PGUID(pp->e.guid), PGUIDPREFIX(*src_guid_prefix), pp->privileged_pp_guid.entityid.u);
ddsrt_mutex_lock (&pp->e.lock); ddsrt_mutex_lock (&pp->e.lock);
pp->privileged_pp_guid.prefix = *src_guid_prefix; pp->privileged_pp_guid.prefix = *src_guid_prefix;
lease_set_expiry(pp->lease, NN_ETIME_NEVER); lease_set_expiry(pp->lease, DDSRT_ETIME_NEVER);
ddsrt_mutex_unlock (&pp->e.lock); ddsrt_mutex_unlock (&pp->e.lock);
} }
GVLOGDISC ("\n"); GVLOGDISC ("\n");
@ -1529,7 +1529,7 @@ static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, dd
ddsi_xqos_log (DDS_LC_DISCOVERY, &gv->logconfig, xqos); ddsi_xqos_log (DDS_LC_DISCOVERY, &gv->logconfig, xqos);
GVLOGDISC ("}\n"); GVLOGDISC ("}\n");
if ((datap->endpoint_guid.entityid.u & NN_ENTITYID_SOURCE_MASK) == NN_ENTITYID_SOURCE_VENDOR && !vendor_is_eclipse_or_prismtech (vendorid)) if ((datap->endpoint_guid.entityid.u & NN_ENTITYID_SOURCE_MASK) == NN_ENTITYID_SOURCE_VENDOR && !vendor_is_eclipse_or_adlink (vendorid))
{ {
GVLOGDISC ("ignoring vendor-specific endpoint "PGUIDFMT"\n", PGUID (datap->endpoint_guid)); GVLOGDISC ("ignoring vendor-specific endpoint "PGUIDFMT"\n", PGUID (datap->endpoint_guid));
} }
@ -1580,7 +1580,7 @@ err:
#undef E #undef E
} }
static void handle_SEDP_dead (const struct receiver_state *rst, ddsi_plist_t *datap, nn_wctime_t timestamp) static void handle_SEDP_dead (const struct receiver_state *rst, ddsi_plist_t *datap, ddsrt_wctime_t timestamp)
{ {
struct ddsi_domaingv * const gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
int res; int res;
@ -1597,7 +1597,7 @@ static void handle_SEDP_dead (const struct receiver_state *rst, ddsi_plist_t *da
GVLOGDISC (" %s\n", (res < 0) ? " unknown" : " delete"); GVLOGDISC (" %s\n", (res < 0) ? " unknown" : " delete");
} }
static void handle_SEDP (const struct receiver_state *rst, seqno_t seq, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len) static void handle_SEDP (const struct receiver_state *rst, seqno_t seq, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len)
{ {
struct ddsi_domaingv * const gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
@ -1733,7 +1733,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
unsigned char *datap; unsigned char *datap;
int needs_free; int needs_free;
uint32_t datasz = sampleinfo->size; uint32_t datasz = sampleinfo->size;
nn_wctime_t timestamp; ddsrt_wctime_t timestamp;
needs_free = defragment (&datap, fragchain, sampleinfo->size); needs_free = defragment (&datap, fragchain, sampleinfo->size);
@ -1890,10 +1890,10 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
goto done_upd_deliv; goto done_upd_deliv;
} }
if (sampleinfo->timestamp.v != NN_WCTIME_INVALID.v) if (sampleinfo->timestamp.v != DDSRT_WCTIME_INVALID.v)
timestamp = sampleinfo->timestamp; timestamp = sampleinfo->timestamp;
else else
timestamp = now (); timestamp = ddsrt_time_wallclock ();
switch (srcguid.entityid.u) switch (srcguid.entityid.u)
{ {
case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER: case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER:

View file

@ -22,7 +22,6 @@
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/ddsi_plist.h" #include "dds/ddsi/ddsi_plist.h"
@ -370,8 +369,7 @@ struct debug_monitor *new_debug_monitor (struct ddsi_domaingv *gv, int32_t port)
goto err_invalid_port; goto err_invalid_port;
} }
dm->servsock = ddsi_factory_create_listener (dm->tran_factory, (uint32_t) port, NULL); if (ddsi_factory_create_listener (&dm->servsock, dm->tran_factory, (uint32_t) port, NULL) != DDS_RETCODE_OK)
if (dm->servsock == NULL)
{ {
GVWARNING ("debmon: can't create socket\n"); GVWARNING ("debmon: can't create socket\n");
goto err_servsock; goto err_servsock;

View file

@ -23,7 +23,6 @@
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_bswap.h" #include "dds/ddsi/q_bswap.h"
@ -60,7 +59,7 @@ struct deleted_participant {
ddsrt_avl_node_t avlnode; ddsrt_avl_node_t avlnode;
ddsi_guid_t guid; ddsi_guid_t guid;
unsigned for_what; unsigned for_what;
nn_mtime_t t_prune; ddsrt_mtime_t t_prune;
}; };
struct deleted_participants_admin { struct deleted_participants_admin {
@ -123,7 +122,7 @@ static int gcreq_proxy_reader (struct proxy_reader *prd);
extern inline bool builtintopic_is_visible (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid, nn_vendorid_t vendorid); extern inline bool builtintopic_is_visible (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid, nn_vendorid_t vendorid);
extern inline bool builtintopic_is_builtintopic (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_sertopic *topic); extern inline bool builtintopic_is_builtintopic (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_sertopic *topic);
extern inline struct ddsi_tkmap_instance *builtintopic_get_tkmap_entry (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid); extern inline struct ddsi_tkmap_instance *builtintopic_get_tkmap_entry (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid);
extern inline void builtintopic_write (const struct ddsi_builtin_topic_interface *btif, const struct entity_common *e, nn_wctime_t timestamp, bool alive); extern inline void builtintopic_write (const struct ddsi_builtin_topic_interface *btif, const struct entity_common *e, ddsrt_wctime_t timestamp, bool alive);
extern inline seqno_t writer_read_seq_xmit (const struct writer *wr); extern inline seqno_t writer_read_seq_xmit (const struct writer *wr);
extern inline void writer_update_seq_xmit (struct writer *wr, seqno_t nv); extern inline void writer_update_seq_xmit (struct writer *wr, seqno_t nv);
@ -190,7 +189,7 @@ int is_builtin_entityid (ddsi_entityid_t id, nn_vendorid_t vendorid)
return 1; return 1;
else if ((id.u & NN_ENTITYID_SOURCE_MASK) != NN_ENTITYID_SOURCE_VENDOR) else if ((id.u & NN_ENTITYID_SOURCE_MASK) != NN_ENTITYID_SOURCE_VENDOR)
return 0; return 0;
else if (!vendor_is_eclipse_or_prismtech (vendorid)) else if (!vendor_is_eclipse_or_adlink (vendorid))
return 0; return 0;
else else
{ {
@ -245,7 +244,7 @@ const ddsrt_fibheap_def_t ldur_fhdef = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (st
/* used in (proxy)participant for writer liveliness monitoring */ /* used in (proxy)participant for writer liveliness monitoring */
const ddsrt_fibheap_def_t lease_fhdef_pp = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct lease, pp_heapnode), compare_lease_tdur); const ddsrt_fibheap_def_t lease_fhdef_pp = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct lease, pp_heapnode), compare_lease_tdur);
static void entity_common_init (struct entity_common *e, struct ddsi_domaingv *gv, const struct ddsi_guid *guid, const char *name, enum entity_kind kind, nn_wctime_t tcreate, nn_vendorid_t vendorid, bool onlylocal) static void entity_common_init (struct entity_common *e, struct ddsi_domaingv *gv, const struct ddsi_guid *guid, const char *name, enum entity_kind kind, ddsrt_wctime_t tcreate, nn_vendorid_t vendorid, bool onlylocal)
{ {
e->guid = *guid; e->guid = *guid;
e->kind = kind; e->kind = kind;
@ -391,9 +390,9 @@ void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct entity_
wrinfo->iid = e->iid; wrinfo->iid = e->iid;
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
if (xqos->lifespan.duration != DDS_INFINITY && (statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0) if (xqos->lifespan.duration != DDS_INFINITY && (statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0)
wrinfo->lifespan_exp = add_duration_to_mtime(now_mt(), xqos->lifespan.duration); wrinfo->lifespan_exp = ddsrt_mtime_add_duration(ddsrt_time_monotonic(), xqos->lifespan.duration);
else else
wrinfo->lifespan_exp = NN_MTIME_NEVER; wrinfo->lifespan_exp = DDSRT_MTIME_NEVER;
#endif #endif
} }
@ -416,7 +415,7 @@ void deleted_participants_admin_free (struct deleted_participants_admin *admin)
ddsrt_free (admin); ddsrt_free (admin);
} }
static void prune_deleted_participant_guids_unlocked (struct deleted_participants_admin *admin, nn_mtime_t tnow) static void prune_deleted_participant_guids_unlocked (struct deleted_participants_admin *admin, ddsrt_mtime_t tnow)
{ {
/* Could do a better job of finding prunable ones efficiently under /* Could do a better job of finding prunable ones efficiently under
all circumstances, but I expect the tree to be very small at all all circumstances, but I expect the tree to be very small at all
@ -436,7 +435,7 @@ static void prune_deleted_participant_guids_unlocked (struct deleted_participant
} }
} }
static void prune_deleted_participant_guids (struct deleted_participants_admin *admin, nn_mtime_t tnow) static void prune_deleted_participant_guids (struct deleted_participants_admin *admin, ddsrt_mtime_t tnow)
{ {
ddsrt_mutex_lock (&admin->deleted_participants_lock); ddsrt_mutex_lock (&admin->deleted_participants_lock);
prune_deleted_participant_guids_unlocked (admin, tnow); prune_deleted_participant_guids_unlocked (admin, tnow);
@ -453,7 +452,7 @@ static void remember_deleted_participant_guid (struct deleted_participants_admin
if ((n = ddsrt_malloc (sizeof (*n))) != NULL) if ((n = ddsrt_malloc (sizeof (*n))) != NULL)
{ {
n->guid = *guid; n->guid = *guid;
n->t_prune.v = T_NEVER; n->t_prune = DDSRT_MTIME_NEVER;
n->for_what = DPG_LOCAL | DPG_REMOTE; n->for_what = DPG_LOCAL | DPG_REMOTE;
ddsrt_avl_insert_ipath (&deleted_participants_treedef, &admin->deleted_participants, n, &path); ddsrt_avl_insert_ipath (&deleted_participants_treedef, &admin->deleted_participants, n, &path);
} }
@ -466,7 +465,7 @@ int is_deleted_participant_guid (struct deleted_participants_admin *admin, const
struct deleted_participant *n; struct deleted_participant *n;
int known; int known;
ddsrt_mutex_lock (&admin->deleted_participants_lock); ddsrt_mutex_lock (&admin->deleted_participants_lock);
prune_deleted_participant_guids_unlocked (admin, now_mt ()); prune_deleted_participant_guids_unlocked (admin, ddsrt_time_monotonic ());
if ((n = ddsrt_avl_lookup (&deleted_participants_treedef, &admin->deleted_participants, guid)) == NULL) if ((n = ddsrt_avl_lookup (&deleted_participants_treedef, &admin->deleted_participants, guid)) == NULL)
known = 0; known = 0;
else else
@ -481,12 +480,12 @@ static void remove_deleted_participant_guid (struct deleted_participants_admin *
DDS_CLOG (DDS_LC_DISCOVERY, admin->logcfg, "remove_deleted_participant_guid("PGUIDFMT" for_what=%x)\n", PGUID (*guid), for_what); DDS_CLOG (DDS_LC_DISCOVERY, admin->logcfg, "remove_deleted_participant_guid("PGUIDFMT" for_what=%x)\n", PGUID (*guid), for_what);
ddsrt_mutex_lock (&admin->deleted_participants_lock); ddsrt_mutex_lock (&admin->deleted_participants_lock);
if ((n = ddsrt_avl_lookup (&deleted_participants_treedef, &admin->deleted_participants, guid)) != NULL) if ((n = ddsrt_avl_lookup (&deleted_participants_treedef, &admin->deleted_participants, guid)) != NULL)
n->t_prune = add_duration_to_mtime (now_mt (), admin->delay); n->t_prune = ddsrt_mtime_add_duration (ddsrt_time_monotonic (), admin->delay);
ddsrt_mutex_unlock (&admin->deleted_participants_lock); ddsrt_mutex_unlock (&admin->deleted_participants_lock);
} }
/* PARTICIPANT ------------------------------------------------------ */ /* PARTICIPANT ------------------------------------------------------ */
static bool update_qos_locked (struct entity_common *e, dds_qos_t *ent_qos, const dds_qos_t *xqos, nn_wctime_t timestamp) static bool update_qos_locked (struct entity_common *e, dds_qos_t *ent_qos, const dds_qos_t *xqos, ddsrt_wctime_t timestamp)
{ {
uint64_t mask; uint64_t mask;
@ -708,7 +707,7 @@ static void participant_add_wr_lease_locked (struct participant * pp, const stru
/* if inserted lease is new shortest lease */ /* if inserted lease is new shortest lease */
if (minl_prev != minl_new) if (minl_prev != minl_new)
{ {
nn_etime_t texp = add_duration_to_etime (now_et (), minl_new->tdur); ddsrt_etime_t texp = ddsrt_etime_add_duration (ddsrt_time_elapsed (), minl_new->tdur);
struct lease *lnew = lease_new (texp, minl_new->tdur, minl_new->entity); struct lease *lnew = lease_new (texp, minl_new->tdur, minl_new->entity);
if (minl_prev == NULL) if (minl_prev == NULL)
{ {
@ -738,7 +737,7 @@ static void participant_remove_wr_lease_locked (struct participant * pp, struct
{ {
dds_duration_t trem = minl->tdur - wr->lease->tdur; dds_duration_t trem = minl->tdur - wr->lease->tdur;
assert (trem >= 0); assert (trem >= 0);
nn_etime_t texp = add_duration_to_etime (now_et(), trem); ddsrt_etime_t texp = ddsrt_etime_add_duration (ddsrt_time_elapsed(), trem);
struct lease *lnew = lease_new (texp, minl->tdur, minl->entity); struct lease *lnew = lease_new (texp, minl->tdur, minl->entity);
participant_replace_minl (pp, lnew); participant_replace_minl (pp, lnew);
lease_register (lnew); lease_register (lnew);
@ -756,13 +755,14 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
ddsi_guid_t subguid, group_guid; ddsi_guid_t subguid, group_guid;
struct whc_writer_info *wrinfo; struct whc_writer_info *wrinfo;
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret = DDS_RETCODE_OK;
ddsi_tran_conn_t ppconn;
/* no reserved bits may be set */ /* no reserved bits may be set */
assert ((flags & ~(RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP | RTPS_PF_ONLY_LOCAL)) == 0); assert ((flags & ~(RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP | RTPS_PF_ONLY_LOCAL)) == 0);
/* privileged participant MUST have builtin readers and writers */ /* privileged participant MUST have builtin readers and writers */
assert (!(flags & RTPS_PF_PRIVILEGED_PP) || (flags & (RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS)) == 0); assert (!(flags & RTPS_PF_PRIVILEGED_PP) || (flags & (RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS)) == 0);
prune_deleted_participant_guids (gv->deleted_participants, now_mt ()); prune_deleted_participant_guids (gv->deleted_participants, ddsrt_time_monotonic ());
/* FIXME: FULL LOCKING AROUND NEW_XXX FUNCTIONS, JUST SO EXISTENCE TESTS ARE PRECISE */ /* FIXME: FULL LOCKING AROUND NEW_XXX FUNCTIONS, JUST SO EXISTENCE TESTS ARE PRECISE */
@ -772,6 +772,18 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
if (entidx_lookup_participant_guid (gv->entity_index, ppguid) != NULL) if (entidx_lookup_participant_guid (gv->entity_index, ppguid) != NULL)
return DDS_RETCODE_PRECONDITION_NOT_MET; return DDS_RETCODE_PRECONDITION_NOT_MET;
if (gv->config.many_sockets_mode != MSM_MANY_UNICAST)
ppconn = NULL;
else
{
const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_RECV_UC, .m_diffserv = 0 };
if (ddsi_factory_create_conn (&ppconn, gv->m_factory, 0, &qos) != DDS_RETCODE_OK)
{
GVERROR ("new_participant("PGUIDFMT", %x) failed: could not create network endpoint\n", PGUID (*ppguid), flags);
return DDS_RETCODE_OUT_OF_RESOURCES;
}
}
if (gv->config.max_participants == 0) if (gv->config.max_participants == 0)
{ {
ddsrt_mutex_lock (&gv->participant_set_lock); ddsrt_mutex_lock (&gv->participant_set_lock);
@ -790,6 +802,8 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
{ {
ddsrt_mutex_unlock (&gv->participant_set_lock); ddsrt_mutex_unlock (&gv->participant_set_lock);
GVERROR ("new_participant("PGUIDFMT", %x) failed: max participants reached\n", PGUID (*ppguid), flags); GVERROR ("new_participant("PGUIDFMT", %x) failed: max participants reached\n", PGUID (*ppguid), flags);
if (ppconn)
ddsi_conn_free (ppconn);
ret = DDS_RETCODE_OUT_OF_RESOURCES; ret = DDS_RETCODE_OUT_OF_RESOURCES;
goto new_pp_err; goto new_pp_err;
} }
@ -799,7 +813,7 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
pp = ddsrt_malloc (sizeof (*pp)); pp = ddsrt_malloc (sizeof (*pp));
entity_common_init (&pp->e, gv, ppguid, "", EK_PARTICIPANT, now (), NN_VENDORID_ECLIPSE, ((flags & RTPS_PF_ONLY_LOCAL) != 0)); entity_common_init (&pp->e, gv, ppguid, "", EK_PARTICIPANT, ddsrt_time_wallclock (), NN_VENDORID_ECLIPSE, ((flags & RTPS_PF_ONLY_LOCAL) != 0));
pp->user_refc = 1; pp->user_refc = 1;
pp->builtin_refc = 0; pp->builtin_refc = 0;
pp->builtins_deleted = 0; pp->builtins_deleted = 0;
@ -895,15 +909,9 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
GVLOGDISC ("}\n"); GVLOGDISC ("}\n");
} }
pp->m_conn = ppconn;
if (gv->config.many_sockets_mode == MSM_MANY_UNICAST) if (gv->config.many_sockets_mode == MSM_MANY_UNICAST)
{
pp->m_conn = ddsi_factory_create_conn (gv->m_factory, 0, NULL);
ddsi_conn_locator (pp->m_conn, &pp->m_locator); ddsi_conn_locator (pp->m_conn, &pp->m_locator);
}
else
{
pp->m_conn = NULL;
}
ddsrt_fibheap_init (&lease_fhdef_pp, &pp->leaseheap_man); ddsrt_fibheap_init (&lease_fhdef_pp, &pp->leaseheap_man);
ddsrt_atomic_stvoidp (&pp->minl_man, NULL); ddsrt_atomic_stvoidp (&pp->minl_man, NULL);
@ -1032,7 +1040,7 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
trigger_recv_threads (gv); trigger_recv_threads (gv);
} }
builtintopic_write (gv->builtin_topic_interface, &pp->e, now(), true); builtintopic_write (gv->builtin_topic_interface, &pp->e, ddsrt_time_wallclock(), true);
/* SPDP periodic broadcast uses the retransmit path, so the initial /* SPDP periodic broadcast uses the retransmit path, so the initial
publication must be done differently. Must be later than making publication must be done differently. Must be later than making
@ -1048,12 +1056,12 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
fire before the calls return. If the initial sample wasn't fire before the calls return. If the initial sample wasn't
accepted, all is lost, but we continue nonetheless, even though accepted, all is lost, but we continue nonetheless, even though
the participant won't be able to discover or be discovered. */ the participant won't be able to discover or be discovered. */
pp->spdp_xevent = qxev_spdp (gv->xevents, add_duration_to_mtime (now_mt (), 100 * T_MILLISECOND), &pp->e.guid, NULL); pp->spdp_xevent = qxev_spdp (gv->xevents, ddsrt_mtime_add_duration (ddsrt_time_monotonic (), DDS_MSECS (100)), &pp->e.guid, NULL);
} }
{ {
nn_mtime_t tsched; ddsrt_mtime_t tsched;
tsched.v = (pp->lease_duration == T_NEVER) ? T_NEVER : 0; tsched = (pp->lease_duration == DDS_INFINITY) ? DDSRT_MTIME_NEVER : (ddsrt_mtime_t){0};
pp->pmd_update_xevent = qxev_pmd_update (gv->xevents, tsched, &pp->e.guid); pp->pmd_update_xevent = qxev_pmd_update (gv->xevents, tsched, &pp->e.guid);
} }
@ -1098,7 +1106,7 @@ dds_return_t new_participant (ddsi_guid_t *p_ppguid, struct ddsi_domaingv *gv, u
void update_participant_plist (struct participant *pp, const ddsi_plist_t *plist) void update_participant_plist (struct participant *pp, const ddsi_plist_t *plist)
{ {
ddsrt_mutex_lock (&pp->e.lock); ddsrt_mutex_lock (&pp->e.lock);
if (update_qos_locked (&pp->e, &pp->plist->qos, &plist->qos, now ())) if (update_qos_locked (&pp->e, &pp->plist->qos, &plist->qos, ddsrt_time_wallclock ()))
spdp_write (pp); spdp_write (pp);
ddsrt_mutex_unlock (&pp->e.lock); ddsrt_mutex_unlock (&pp->e.lock);
} }
@ -1297,7 +1305,7 @@ dds_return_t delete_participant (struct ddsi_domaingv *gv, const struct ddsi_gui
GVLOGDISC ("delete_participant("PGUIDFMT")\n", PGUID (*ppguid)); GVLOGDISC ("delete_participant("PGUIDFMT")\n", PGUID (*ppguid));
if ((pp = entidx_lookup_participant_guid (gv->entity_index, ppguid)) == NULL) if ((pp = entidx_lookup_participant_guid (gv->entity_index, ppguid)) == NULL)
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
builtintopic_write (gv->builtin_topic_interface, &pp->e, now(), false); builtintopic_write (gv->builtin_topic_interface, &pp->e, ddsrt_time_wallclock(), false);
remember_deleted_participant_guid (gv->deleted_participants, &pp->e.guid); remember_deleted_participant_guid (gv->deleted_participants, &pp->e.guid);
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
disconnect_participant_secure (pp); disconnect_participant_secure (pp);
@ -1391,7 +1399,7 @@ dds_duration_t pp_get_pmd_interval (struct participant *pp)
dds_duration_t intv; dds_duration_t intv;
ddsrt_mutex_lock (&pp->e.lock); ddsrt_mutex_lock (&pp->e.lock);
ldur_node = ddsrt_fibheap_min (&ldur_fhdef, &pp->ldur_auto_wr); ldur_node = ddsrt_fibheap_min (&ldur_fhdef, &pp->ldur_auto_wr);
intv = (ldur_node != NULL) ? ldur_node->ldur : T_NEVER; intv = (ldur_node != NULL) ? ldur_node->ldur : DDS_INFINITY;
if (pp->lease_duration < intv) if (pp->lease_duration < intv)
intv = pp->lease_duration; intv = pp->lease_duration;
ddsrt_mutex_unlock (&pp->e.lock); ddsrt_mutex_unlock (&pp->e.lock);
@ -2191,7 +2199,7 @@ static void writer_add_connection (struct writer *wr, struct proxy_reader *prd,
m->next_acknack = DDSI_COUNT_MIN; m->next_acknack = DDSI_COUNT_MIN;
m->next_nackfrag = DDSI_COUNT_MIN; m->next_nackfrag = DDSI_COUNT_MIN;
nn_lat_estim_init (&m->hb_to_ack_latency); nn_lat_estim_init (&m->hb_to_ack_latency);
m->hb_to_ack_latency_tlastlog = now (); m->hb_to_ack_latency_tlastlog = ddsrt_time_wallclock ();
m->t_acknack_accepted.v = 0; m->t_acknack_accepted.v = 0;
ddsrt_mutex_lock (&wr->e.lock); ddsrt_mutex_lock (&wr->e.lock);
@ -2237,8 +2245,8 @@ static void writer_add_connection (struct writer *wr, struct proxy_reader *prd,
ensure a heartbeat is scheduled soon. */ ensure a heartbeat is scheduled soon. */
if (wr->heartbeat_xevent) if (wr->heartbeat_xevent)
{ {
const int64_t delta = 1 * T_MILLISECOND; const int64_t delta = DDS_MSECS (1);
const nn_mtime_t tnext = add_duration_to_mtime (now_mt (), delta); const ddsrt_mtime_t tnext = ddsrt_mtime_add_duration (ddsrt_time_monotonic (), delta);
ddsrt_mutex_lock (&wr->e.lock); ddsrt_mutex_lock (&wr->e.lock);
/* To make sure that we keep sending heartbeats at a higher rate /* To make sure that we keep sending heartbeats at a higher rate
at the start of this discovery, reset the hbs_since_last_write at the start of this discovery, reset the hbs_since_last_write
@ -2433,7 +2441,7 @@ static void reader_add_local_connection (struct reader *rd, struct writer *wr, c
} }
} }
static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader *rd, nn_mtime_t tnow, nn_count_t init_count, int64_t crypto_handle) static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader *rd, ddsrt_mtime_t tnow, nn_count_t init_count, int64_t crypto_handle)
{ {
struct pwr_rd_match *m = ddsrt_malloc (sizeof (*m)); struct pwr_rd_match *m = ddsrt_malloc (sizeof (*m));
ddsrt_avl_ipath_t path; ddsrt_avl_ipath_t path;
@ -2452,7 +2460,7 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader
ELOGDISC (pwr, " proxy_writer_add_connection(pwr "PGUIDFMT" rd "PGUIDFMT")", ELOGDISC (pwr, " proxy_writer_add_connection(pwr "PGUIDFMT" rd "PGUIDFMT")",
PGUID (pwr->e.guid), PGUID (rd->e.guid)); PGUID (pwr->e.guid), PGUID (rd->e.guid));
m->rd_guid = rd->e.guid; m->rd_guid = rd->e.guid;
m->tcreate = now_mt (); m->tcreate = ddsrt_time_monotonic ();
/* We track the last heartbeat count value per reader--proxy-writer /* We track the last heartbeat count value per reader--proxy-writer
pair, so that we can correctly handle directed heartbeats. The pair, so that we can correctly handle directed heartbeats. The
@ -2529,11 +2537,10 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader
} }
m->count = init_count; m->count = init_count;
/* Spec says we may send a pre-emptive AckNack (8.4.2.3.4), hence we /* Spec says we may send a pre-emptive AckNack (8.4.2.3.4), hence we
schedule it for the configured delay * T_MILLISECOND. From then schedule it for the configured delay. From then on it it'll keep
on it it'll keep sending pre-emptive ones until the proxy writer sending pre-emptive ones until the proxy writer receives a heartbeat.
receives a heartbeat. (We really only need a pre-emptive AckNack (We really only need a pre-emptive AckNack per proxy writer, but
per proxy writer, but hopefully it won't make that much of a hopefully it won't make that much of a difference in practice.) */
difference in practice.) */
if (rd->reliable) if (rd->reliable)
{ {
uint32_t secondary_reorder_maxsamples = pwr->e.gv->config.secondary_reorder_maxsamples; uint32_t secondary_reorder_maxsamples = pwr->e.gv->config.secondary_reorder_maxsamples;
@ -2543,7 +2550,7 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader
secondary_reorder_maxsamples = pwr->e.gv->config.primary_reorder_maxsamples; secondary_reorder_maxsamples = pwr->e.gv->config.primary_reorder_maxsamples;
m->filtered = 1; m->filtered = 1;
} }
m->acknack_xevent = qxev_acknack (pwr->evq, add_duration_to_mtime (tnow, pwr->e.gv->config.preemptive_ack_delay), &pwr->e.guid, &rd->e.guid); m->acknack_xevent = qxev_acknack (pwr->evq, ddsrt_mtime_add_duration (tnow, pwr->e.gv->config.preemptive_ack_delay), &pwr->e.guid, &rd->e.guid);
m->u.not_in_sync.reorder = m->u.not_in_sync.reorder =
nn_reorder_new (&pwr->e.gv->logconfig, NN_REORDER_MODE_NORMAL, secondary_reorder_maxsamples, pwr->e.gv->config.late_ack_mode); nn_reorder_new (&pwr->e.gv->logconfig, NN_REORDER_MODE_NORMAL, secondary_reorder_maxsamples, pwr->e.gv->config.late_ack_mode);
pwr->n_reliable_readers++; pwr->n_reliable_readers++;
@ -2736,14 +2743,14 @@ static bool topickind_qos_match_p_lock (struct entity_common *rd, const dds_qos_
return ret; return ret;
} }
void connect_writer_with_proxy_reader_secure(struct writer *wr, struct proxy_reader *prd, nn_mtime_t tnow, int64_t crypto_handle) void connect_writer_with_proxy_reader_secure(struct writer *wr, struct proxy_reader *prd, ddsrt_mtime_t tnow, int64_t crypto_handle)
{ {
DDSRT_UNUSED_ARG(tnow); DDSRT_UNUSED_ARG(tnow);
proxy_reader_add_connection (prd, wr, crypto_handle); proxy_reader_add_connection (prd, wr, crypto_handle);
writer_add_connection (wr, prd, crypto_handle); writer_add_connection (wr, prd, crypto_handle);
} }
void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_writer *pwr, nn_mtime_t tnow, int64_t crypto_handle) void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_writer *pwr, ddsrt_mtime_t tnow, int64_t crypto_handle)
{ {
nn_count_t init_count; nn_count_t init_count;
struct alive_state alive_state; struct alive_state alive_state;
@ -2761,7 +2768,7 @@ void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_wri
reader_update_notify_pwr_alive_state (rd, pwr, &alive_state); reader_update_notify_pwr_alive_state (rd, pwr, &alive_state);
} }
static void connect_writer_with_proxy_reader (struct writer *wr, struct proxy_reader *prd, nn_mtime_t tnow) static void connect_writer_with_proxy_reader (struct writer *wr, struct proxy_reader *prd, ddsrt_mtime_t tnow)
{ {
const int isb0 = (is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) != 0); const int isb0 = (is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) != 0);
const int isb1 = (is_builtin_entityid (prd->e.guid.entityid, prd->c.vendor) != 0); const int isb1 = (is_builtin_entityid (prd->e.guid.entityid, prd->c.vendor) != 0);
@ -2797,7 +2804,7 @@ static void connect_writer_with_proxy_reader (struct writer *wr, struct proxy_re
} }
} }
static void connect_proxy_writer_with_reader (struct proxy_writer *pwr, struct reader *rd, nn_mtime_t tnow) static void connect_proxy_writer_with_reader (struct proxy_writer *pwr, struct reader *rd, ddsrt_mtime_t tnow)
{ {
const int isb0 = (is_builtin_entityid (pwr->e.guid.entityid, pwr->c.vendor) != 0); const int isb0 = (is_builtin_entityid (pwr->e.guid.entityid, pwr->c.vendor) != 0);
const int isb1 = (is_builtin_entityid (rd->e.guid.entityid, NN_VENDORID_ECLIPSE) != 0); const int isb1 = (is_builtin_entityid (rd->e.guid.entityid, NN_VENDORID_ECLIPSE) != 0);
@ -2867,7 +2874,7 @@ static bool ignore_local_p (const ddsi_guid_t *guid1, const ddsi_guid_t *guid2,
return false; return false;
} }
static void connect_writer_with_reader (struct writer *wr, struct reader *rd, nn_mtime_t tnow) static void connect_writer_with_reader (struct writer *wr, struct reader *rd, ddsrt_mtime_t tnow)
{ {
dds_qos_policy_id_t reason; dds_qos_policy_id_t reason;
struct alive_state alive_state; struct alive_state alive_state;
@ -2895,7 +2902,7 @@ static void connect_writer_with_reader (struct writer *wr, struct reader *rd, nn
reader_update_notify_wr_alive_state (rd, wr, &alive_state); reader_update_notify_wr_alive_state (rd, wr, &alive_state);
} }
static void connect_writer_with_proxy_reader_wrapper (struct entity_common *vwr, struct entity_common *vprd, nn_mtime_t tnow) static void connect_writer_with_proxy_reader_wrapper (struct entity_common *vwr, struct entity_common *vprd, ddsrt_mtime_t tnow)
{ {
struct writer *wr = (struct writer *) vwr; struct writer *wr = (struct writer *) vwr;
struct proxy_reader *prd = (struct proxy_reader *) vprd; struct proxy_reader *prd = (struct proxy_reader *) vprd;
@ -2905,7 +2912,7 @@ static void connect_writer_with_proxy_reader_wrapper (struct entity_common *vwr,
connect_writer_with_proxy_reader (wr, prd, tnow); connect_writer_with_proxy_reader (wr, prd, tnow);
} }
static void connect_proxy_writer_with_reader_wrapper (struct entity_common *vpwr, struct entity_common *vrd, nn_mtime_t tnow) static void connect_proxy_writer_with_reader_wrapper (struct entity_common *vpwr, struct entity_common *vrd, ddsrt_mtime_t tnow)
{ {
struct proxy_writer *pwr = (struct proxy_writer *) vpwr; struct proxy_writer *pwr = (struct proxy_writer *) vpwr;
struct reader *rd = (struct reader *) vrd; struct reader *rd = (struct reader *) vrd;
@ -2915,7 +2922,7 @@ static void connect_proxy_writer_with_reader_wrapper (struct entity_common *vpwr
connect_proxy_writer_with_reader (pwr, rd, tnow); connect_proxy_writer_with_reader (pwr, rd, tnow);
} }
static void connect_writer_with_reader_wrapper (struct entity_common *vwr, struct entity_common *vrd, nn_mtime_t tnow) static void connect_writer_with_reader_wrapper (struct entity_common *vwr, struct entity_common *vrd, ddsrt_mtime_t tnow)
{ {
struct writer *wr = (struct writer *) vwr; struct writer *wr = (struct writer *) vwr;
struct reader *rd = (struct reader *) vrd; struct reader *rd = (struct reader *) vrd;
@ -2943,7 +2950,7 @@ static enum entity_kind generic_do_match_mkind (enum entity_kind kind, bool loca
return EK_WRITER; return EK_WRITER;
} }
static void generic_do_match_connect (struct entity_common *e, struct entity_common *em, nn_mtime_t tnow, bool local) static void generic_do_match_connect (struct entity_common *e, struct entity_common *em, ddsrt_mtime_t tnow, bool local)
{ {
switch (e->kind) switch (e->kind)
{ {
@ -2991,7 +2998,7 @@ static const char *entity_topic_name (const struct entity_common *e)
return ""; return "";
} }
static void generic_do_match (struct entity_common *e, nn_mtime_t tnow, bool local) static void generic_do_match (struct entity_common *e, ddsrt_mtime_t tnow, bool local)
{ {
static const struct { const char *full; const char *full_us; const char *abbrev; } kindstr[] = { static const struct { const char *full; const char *full_us; const char *abbrev; } kindstr[] = {
[EK_WRITER] = { "writer", "writer", "wr" }, [EK_WRITER] = { "writer", "writer", "wr" },
@ -3057,32 +3064,32 @@ static void generic_do_match (struct entity_common *e, nn_mtime_t tnow, bool loc
} }
} }
static void match_writer_with_proxy_readers (struct writer *wr, nn_mtime_t tnow) static void match_writer_with_proxy_readers (struct writer *wr, ddsrt_mtime_t tnow)
{ {
generic_do_match (&wr->e, tnow, false); generic_do_match (&wr->e, tnow, false);
} }
static void match_writer_with_local_readers (struct writer *wr, nn_mtime_t tnow) static void match_writer_with_local_readers (struct writer *wr, ddsrt_mtime_t tnow)
{ {
generic_do_match (&wr->e, tnow, true); generic_do_match (&wr->e, tnow, true);
} }
static void match_reader_with_proxy_writers (struct reader *rd, nn_mtime_t tnow) static void match_reader_with_proxy_writers (struct reader *rd, ddsrt_mtime_t tnow)
{ {
generic_do_match (&rd->e, tnow, false); generic_do_match (&rd->e, tnow, false);
} }
static void match_reader_with_local_writers (struct reader *rd, nn_mtime_t tnow) static void match_reader_with_local_writers (struct reader *rd, ddsrt_mtime_t tnow)
{ {
generic_do_match (&rd->e, tnow, true); generic_do_match (&rd->e, tnow, true);
} }
static void match_proxy_writer_with_readers (struct proxy_writer *pwr, nn_mtime_t tnow) static void match_proxy_writer_with_readers (struct proxy_writer *pwr, ddsrt_mtime_t tnow)
{ {
generic_do_match (&pwr->e, tnow, false); generic_do_match (&pwr->e, tnow, false);
} }
static void match_proxy_reader_with_writers (struct proxy_reader *prd, nn_mtime_t tnow) static void match_proxy_reader_with_writers (struct proxy_reader *prd, ddsrt_mtime_t tnow)
{ {
generic_do_match(&prd->e, tnow, false); generic_do_match(&prd->e, tnow, false);
} }
@ -3096,7 +3103,7 @@ static void match_volatile_secure_endpoints (struct participant *pp, struct prox
struct proxy_reader *prd; struct proxy_reader *prd;
struct proxy_writer *pwr; struct proxy_writer *pwr;
ddsi_guid_t guid; ddsi_guid_t guid;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
EELOGDISC (&pp->e, "match volatile endpoints (pp "PGUIDFMT") with (proxypp "PGUIDFMT")\n", EELOGDISC (&pp->e, "match volatile endpoints (pp "PGUIDFMT") with (proxypp "PGUIDFMT")\n",
PGUID(pp->e.guid), PGUID(proxypp->e.guid)); PGUID(pp->e.guid), PGUID(proxypp->e.guid));
@ -3149,7 +3156,7 @@ static void update_proxy_participant_endpoint_matching (struct proxy_participant
ddsi_guid_t guid; ddsi_guid_t guid;
ddsi_entityid_t *endpoint_ids; ddsi_entityid_t *endpoint_ids;
uint32_t num = 0, i; uint32_t num = 0, i;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
EELOGDISC (&proxypp->e, "update_proxy_participant_endpoint_matching (proxypp "PGUIDFMT" pp "PGUIDFMT")\n", EELOGDISC (&proxypp->e, "update_proxy_participant_endpoint_matching (proxypp "PGUIDFMT" pp "PGUIDFMT")\n",
PGUID (proxypp->e.guid), PGUID (pp->e.guid)); PGUID (proxypp->e.guid), PGUID (pp->e.guid));
@ -3239,7 +3246,7 @@ static void new_reader_writer_common (const struct ddsrt_log_cfg *logcfg, const
static void endpoint_common_init (struct entity_common *e, struct endpoint_common *c, struct ddsi_domaingv *gv, enum entity_kind kind, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, bool onlylocal) static void endpoint_common_init (struct entity_common *e, struct endpoint_common *c, struct ddsi_domaingv *gv, enum entity_kind kind, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, bool onlylocal)
{ {
entity_common_init (e, gv, guid, NULL, kind, now (), NN_VENDORID_ECLIPSE, pp->e.onlylocal || onlylocal); entity_common_init (e, gv, guid, NULL, kind, ddsrt_time_wallclock (), NN_VENDORID_ECLIPSE, pp->e.onlylocal || onlylocal);
c->pp = ref_participant (pp, &e->guid); c->pp = ref_participant (pp, &e->guid);
if (group_guid) if (group_guid)
c->group_guid = *group_guid; c->group_guid = *group_guid;
@ -3440,7 +3447,7 @@ void writer_set_retransmitting (struct writer *wr)
void writer_clear_retransmitting (struct writer *wr) void writer_clear_retransmitting (struct writer *wr)
{ {
wr->retransmitting = 0; wr->retransmitting = 0;
wr->t_whc_high_upd = wr->t_rexmit_end = now_et(); wr->t_whc_high_upd = wr->t_rexmit_end = ddsrt_time_elapsed();
ddsrt_cond_broadcast (&wr->throttle_cond); ddsrt_cond_broadcast (&wr->throttle_cond);
} }
@ -3498,12 +3505,12 @@ void writer_set_alive_may_unlock (struct writer *wr, bool notify)
ddsrt_mutex_lock (&wr->c.pp->e.lock); ddsrt_mutex_lock (&wr->c.pp->e.lock);
wr->alive = true; wr->alive = true;
wr->alive_vclock++; wr->alive_vclock++;
if (wr->xqos->liveliness.lease_duration != T_NEVER) if (wr->xqos->liveliness.lease_duration != DDS_INFINITY)
{ {
if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT) if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT)
participant_add_wr_lease_locked (wr->c.pp, wr); participant_add_wr_lease_locked (wr->c.pp, wr);
else if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC) else if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC)
lease_set_expiry (wr->lease, add_duration_to_etime (now_et (), wr->lease->tdur)); lease_set_expiry (wr->lease, ddsrt_etime_add_duration (ddsrt_time_elapsed (), wr->lease->tdur));
} }
ddsrt_mutex_unlock (&wr->c.pp->e.lock); ddsrt_mutex_unlock (&wr->c.pp->e.lock);
@ -3521,7 +3528,7 @@ static int writer_set_notalive_locked (struct writer *wr, bool notify)
ddsrt_mutex_lock (&wr->c.pp->e.lock); ddsrt_mutex_lock (&wr->c.pp->e.lock);
wr->alive = false; wr->alive = false;
wr->alive_vclock++; wr->alive_vclock++;
if (wr->xqos->liveliness.lease_duration != T_NEVER && wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT) if (wr->xqos->liveliness.lease_duration != DDS_INFINITY && wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT)
participant_remove_wr_lease_locked (wr->c.pp, wr); participant_remove_wr_lease_locked (wr->c.pp, wr);
ddsrt_mutex_unlock (&wr->c.pp->e.lock); ddsrt_mutex_unlock (&wr->c.pp->e.lock);
@ -3674,22 +3681,16 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se
} }
/* heartbeat event will be deleted when the handler can't find a /* heartbeat event will be deleted when the handler can't find a
writer for it in the hash table. T_NEVER => won't ever be writer for it in the hash table. NEVER => won't ever be
scheduled, and this can only change by writing data, which won't scheduled, and this can only change by writing data, which won't
happen until after it becomes visible. */ happen until after it becomes visible. */
if (wr->reliable) if (wr->reliable)
{ wr->heartbeat_xevent = qxev_heartbeat (wr->evq, DDSRT_MTIME_NEVER, &wr->e.guid);
nn_mtime_t tsched;
tsched.v = T_NEVER;
wr->heartbeat_xevent = qxev_heartbeat (wr->evq, tsched, &wr->e.guid);
}
else else
{
wr->heartbeat_xevent = NULL; wr->heartbeat_xevent = NULL;
}
assert (wr->xqos->present & QP_LIVELINESS); assert (wr->xqos->present & QP_LIVELINESS);
if (wr->xqos->liveliness.lease_duration != T_NEVER) if (wr->xqos->liveliness.lease_duration != DDS_INFINITY)
{ {
wr->lease_duration = ddsrt_malloc (sizeof(*wr->lease_duration)); wr->lease_duration = ddsrt_malloc (sizeof(*wr->lease_duration));
wr->lease_duration->ldur = wr->xqos->liveliness.lease_duration; wr->lease_duration->ldur = wr->xqos->liveliness.lease_duration;
@ -3726,7 +3727,7 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se
static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc *whc, status_cb_t status_cb, void *status_entity) static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc *whc, status_cb_t status_cb, void *status_entity)
{ {
struct writer *wr; struct writer *wr;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
assert (is_writer_entityid (guid->entityid)); assert (is_writer_entityid (guid->entityid));
assert (entidx_lookup_writer_guid (pp->e.gv->entity_index, guid) == NULL); assert (entidx_lookup_writer_guid (pp->e.gv->entity_index, guid) == NULL);
@ -3756,7 +3757,7 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
the other. */ the other. */
ddsrt_mutex_lock (&wr->e.lock); ddsrt_mutex_lock (&wr->e.lock);
entidx_insert_writer_guid (pp->e.gv->entity_index, wr); entidx_insert_writer_guid (pp->e.gv->entity_index, wr);
builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, now(), true); builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, ddsrt_time_wallclock(), true);
ddsrt_mutex_unlock (&wr->e.lock); ddsrt_mutex_unlock (&wr->e.lock);
/* once it exists, match it with proxy writers and broadcast /* once it exists, match it with proxy writers and broadcast
@ -3771,7 +3772,7 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
if (wr->lease_duration != NULL) if (wr->lease_duration != NULL)
{ {
assert (wr->lease_duration->ldur != T_NEVER); assert (wr->lease_duration->ldur != DDS_INFINITY);
assert (!is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE)); assert (!is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE));
if (wr->xqos->liveliness.kind == DDS_LIVELINESS_AUTOMATIC) if (wr->xqos->liveliness.kind == DDS_LIVELINESS_AUTOMATIC)
{ {
@ -3781,11 +3782,11 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
ddsrt_mutex_unlock (&pp->e.lock); ddsrt_mutex_unlock (&pp->e.lock);
/* Trigger pmd update */ /* Trigger pmd update */
(void) resched_xevent_if_earlier (pp->pmd_update_xevent, now_mt ()); (void) resched_xevent_if_earlier (pp->pmd_update_xevent, ddsrt_time_monotonic ());
} }
else else
{ {
nn_etime_t texpire = add_duration_to_etime (now_et (), wr->lease_duration->ldur); ddsrt_etime_t texpire = ddsrt_etime_add_duration (ddsrt_time_elapsed (), wr->lease_duration->ldur);
wr->lease = lease_new (texpire, wr->lease_duration->ldur, &wr->e); wr->lease = lease_new (texpire, wr->lease_duration->ldur, &wr->e);
if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT) if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT)
{ {
@ -3840,7 +3841,7 @@ struct local_orphan_writer *new_local_orphan_writer (struct ddsi_domaingv *gv, d
ddsi_guid_t guid; ddsi_guid_t guid;
struct local_orphan_writer *lowr; struct local_orphan_writer *lowr;
struct writer *wr; struct writer *wr;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
GVLOGDISC ("new_local_orphan_writer(%s/%s)\n", topic->name, topic->type_name); GVLOGDISC ("new_local_orphan_writer(%s/%s)\n", topic->name, topic->type_name);
lowr = ddsrt_malloc (sizeof (*lowr)); lowr = ddsrt_malloc (sizeof (*lowr));
@ -3848,12 +3849,12 @@ struct local_orphan_writer *new_local_orphan_writer (struct ddsi_domaingv *gv, d
memset (&guid.prefix, 0, sizeof (guid.prefix)); memset (&guid.prefix, 0, sizeof (guid.prefix));
guid.entityid = entityid; guid.entityid = entityid;
entity_common_init (&wr->e, gv, &guid, NULL, EK_WRITER, now (), NN_VENDORID_ECLIPSE, true); entity_common_init (&wr->e, gv, &guid, NULL, EK_WRITER, ddsrt_time_wallclock (), NN_VENDORID_ECLIPSE, true);
wr->c.pp = NULL; wr->c.pp = NULL;
memset (&wr->c.group_guid, 0, sizeof (wr->c.group_guid)); memset (&wr->c.group_guid, 0, sizeof (wr->c.group_guid));
new_writer_guid_common_init (wr, topic, xqos, whc, 0, NULL); new_writer_guid_common_init (wr, topic, xqos, whc, 0, NULL);
entidx_insert_writer_guid (gv->entity_index, wr); entidx_insert_writer_guid (gv->entity_index, wr);
builtintopic_write (gv->builtin_topic_interface, &wr->e, now(), true); builtintopic_write (gv->builtin_topic_interface, &wr->e, ddsrt_time_wallclock(), true);
match_writer_with_local_readers (wr, tnow); match_writer_with_local_readers (wr, tnow);
return lowr; return lowr;
} }
@ -3861,7 +3862,7 @@ struct local_orphan_writer *new_local_orphan_writer (struct ddsi_domaingv *gv, d
void update_writer_qos (struct writer *wr, const dds_qos_t *xqos) void update_writer_qos (struct writer *wr, const dds_qos_t *xqos)
{ {
ddsrt_mutex_lock (&wr->e.lock); ddsrt_mutex_lock (&wr->e.lock);
if (update_qos_locked (&wr->e, wr->xqos, xqos, now ())) if (update_qos_locked (&wr->e, wr->xqos, xqos, ddsrt_time_wallclock ()))
sedp_write_writer (wr); sedp_write_writer (wr);
ddsrt_mutex_unlock (&wr->e.lock); ddsrt_mutex_unlock (&wr->e.lock);
} }
@ -3878,7 +3879,7 @@ static void gc_delete_writer (struct gcreq *gcreq)
if (wr->heartbeat_xevent) if (wr->heartbeat_xevent)
{ {
wr->hbcontrol.tsched.v = T_NEVER; wr->hbcontrol.tsched = DDSRT_MTIME_NEVER;
delete_xevent (wr->heartbeat_xevent); delete_xevent (wr->heartbeat_xevent);
} }
@ -3998,7 +3999,7 @@ dds_return_t delete_writer_nolinger_locked (struct writer *wr)
{ {
ELOGDISC (wr, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid)); ELOGDISC (wr, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid));
ASSERT_MUTEX_HELD (&wr->e.lock); ASSERT_MUTEX_HELD (&wr->e.lock);
builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, now(), false); builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, ddsrt_time_wallclock(), false);
local_reader_ary_setinvalid (&wr->rdary); local_reader_ary_setinvalid (&wr->rdary);
entidx_remove_writer_guid (wr->e.gv->entity_index, wr); entidx_remove_writer_guid (wr->e.gv->entity_index, wr);
writer_set_state (wr, WRST_DELETING); writer_set_state (wr, WRST_DELETING);
@ -4009,7 +4010,7 @@ dds_return_t delete_writer_nolinger_locked (struct writer *wr)
ddsrt_mutex_lock (&wr->c.pp->e.lock); ddsrt_mutex_lock (&wr->c.pp->e.lock);
ddsrt_fibheap_delete (&ldur_fhdef, &wr->c.pp->ldur_auto_wr, wr->lease_duration); ddsrt_fibheap_delete (&ldur_fhdef, &wr->c.pp->ldur_auto_wr, wr->lease_duration);
ddsrt_mutex_unlock (&wr->c.pp->e.lock); ddsrt_mutex_unlock (&wr->c.pp->e.lock);
resched_xevent_if_earlier (wr->c.pp->pmd_update_xevent, now_mt ()); resched_xevent_if_earlier (wr->c.pp->pmd_update_xevent, ddsrt_time_monotonic ());
} }
else else
{ {
@ -4081,12 +4082,12 @@ dds_return_t delete_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *gu
} }
else else
{ {
nn_mtime_t tsched; ddsrt_mtime_t tsched;
int32_t tsec, tusec; int32_t tsec, tusec;
writer_set_state (wr, WRST_LINGERING); writer_set_state (wr, WRST_LINGERING);
ddsrt_mutex_unlock (&wr->e.lock); ddsrt_mutex_unlock (&wr->e.lock);
tsched = add_duration_to_mtime (now_mt (), wr->e.gv->config.writer_linger_duration); tsched = ddsrt_mtime_add_duration (ddsrt_time_monotonic (), wr->e.gv->config.writer_linger_duration);
mtime_to_sec_usec (&tsec, &tusec, tsched); ddsrt_mtime_to_sec_usec (&tsec, &tusec, tsched);
GVLOGDISC ("delete_writer(guid "PGUIDFMT") - unack'ed samples, will delete when ack'd or at t = %"PRId32".%06"PRId32"\n", GVLOGDISC ("delete_writer(guid "PGUIDFMT") - unack'ed samples, will delete when ack'd or at t = %"PRId32".%06"PRId32"\n",
PGUID (*guid), tsec, tusec); PGUID (*guid), tsec, tusec);
qxev_delete_writer (gv->xevents, tsched, &wr->e.guid); qxev_delete_writer (gv->xevents, tsched, &wr->e.guid);
@ -4217,7 +4218,7 @@ static dds_return_t new_reader_guid
/* see new_writer_guid for commenets */ /* see new_writer_guid for commenets */
struct reader *rd; struct reader *rd;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
assert (!is_writer_entityid (guid->entityid)); assert (!is_writer_entityid (guid->entityid));
assert (entidx_lookup_reader_guid (pp->e.gv->entity_index, guid) == NULL); assert (entidx_lookup_reader_guid (pp->e.gv->entity_index, guid) == NULL);
@ -4344,7 +4345,7 @@ static dds_return_t new_reader_guid
ddsrt_mutex_lock (&rd->e.lock); ddsrt_mutex_lock (&rd->e.lock);
entidx_insert_reader_guid (pp->e.gv->entity_index, rd); entidx_insert_reader_guid (pp->e.gv->entity_index, rd);
builtintopic_write (pp->e.gv->builtin_topic_interface, &rd->e, now(), true); builtintopic_write (pp->e.gv->builtin_topic_interface, &rd->e, ddsrt_time_wallclock(), true);
ddsrt_mutex_unlock (&rd->e.lock); ddsrt_mutex_unlock (&rd->e.lock);
match_reader_with_proxy_writers (rd, tnow); match_reader_with_proxy_writers (rd, tnow);
@ -4460,7 +4461,7 @@ dds_return_t delete_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *gu
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
} }
GVLOGDISC ("delete_reader_guid(guid "PGUIDFMT") ...\n", PGUID (*guid)); GVLOGDISC ("delete_reader_guid(guid "PGUIDFMT") ...\n", PGUID (*guid));
builtintopic_write (rd->e.gv->builtin_topic_interface, &rd->e, now(), false); builtintopic_write (rd->e.gv->builtin_topic_interface, &rd->e, ddsrt_time_wallclock(), false);
entidx_remove_reader_guid (gv->entity_index, rd); entidx_remove_reader_guid (gv->entity_index, rd);
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
q_omg_security_deregister_reader(rd); q_omg_security_deregister_reader(rd);
@ -4472,7 +4473,7 @@ dds_return_t delete_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *gu
void update_reader_qos (struct reader *rd, const dds_qos_t *xqos) void update_reader_qos (struct reader *rd, const dds_qos_t *xqos)
{ {
ddsrt_mutex_lock (&rd->e.lock); ddsrt_mutex_lock (&rd->e.lock);
if (update_qos_locked (&rd->e, rd->xqos, xqos, now ())) if (update_qos_locked (&rd->e, rd->xqos, xqos, ddsrt_time_wallclock ()))
sedp_write_reader (rd); sedp_write_reader (rd);
ddsrt_mutex_unlock (&rd->e.lock); ddsrt_mutex_unlock (&rd->e.lock);
} }
@ -4505,7 +4506,7 @@ void proxy_participant_reassign_lease (struct proxy_participant *proxypp, struct
{ {
dds_duration_t trem = minl->tdur - proxypp->lease->tdur; dds_duration_t trem = minl->tdur - proxypp->lease->tdur;
assert (trem >= 0); assert (trem >= 0);
nn_etime_t texp = add_duration_to_etime (now_et(), trem); ddsrt_etime_t texp = ddsrt_etime_add_duration (ddsrt_time_elapsed(), trem);
struct lease *lnew = lease_new (texp, minl->tdur, minl->entity); struct lease *lnew = lease_new (texp, minl->tdur, minl->entity);
proxy_participant_replace_minl (proxypp, false, lnew); proxy_participant_replace_minl (proxypp, false, lnew);
lease_register (lnew); lease_register (lnew);
@ -4541,7 +4542,6 @@ void proxy_participant_reassign_lease (struct proxy_participant *proxypp, struct
struct bestab { struct bestab {
unsigned besflag; unsigned besflag;
unsigned prismtech_besflag;
unsigned entityid; unsigned entityid;
}; };
@ -4551,7 +4551,7 @@ static void create_proxy_builtin_endpoints(
int nbes, int nbes,
const struct ddsi_guid *ppguid, const struct ddsi_guid *ppguid,
struct proxy_participant *proxypp, struct proxy_participant *proxypp,
nn_wctime_t timestamp, ddsrt_wctime_t timestamp,
dds_qos_t *xqos_wr, dds_qos_t *xqos_wr,
dds_qos_t *xqos_rd) dds_qos_t *xqos_rd)
{ {
@ -4568,7 +4568,7 @@ static void create_proxy_builtin_endpoints(
for (i = 0; i < nbes; i++) for (i = 0; i < nbes; i++)
{ {
const struct bestab *te = &bestab[i]; const struct bestab *te = &bestab[i];
if ((proxypp->bes & te->besflag) || (proxypp->prismtech_bes & te->prismtech_besflag)) if (proxypp->bes & te->besflag)
{ {
ddsi_guid_t guid1; ddsi_guid_t guid1;
guid1.prefix = proxypp->e.guid.prefix; guid1.prefix = proxypp->e.guid.prefix;
@ -4598,13 +4598,12 @@ static void add_proxy_builtin_endpoints(
struct ddsi_domaingv *gv, struct ddsi_domaingv *gv,
const struct ddsi_guid *ppguid, const struct ddsi_guid *ppguid,
struct proxy_participant *proxypp, struct proxy_participant *proxypp,
nn_wctime_t timestamp) ddsrt_wctime_t timestamp)
{ {
/* Add proxy endpoints based on the advertised (& possibly augmented /* Add proxy endpoints based on the advertised (& possibly augmented
...) built-in endpoint set. */ ...) built-in endpoint set. */
#define PT_TE(ap_, a_, bp_, b_) { 0, NN_##ap_##BUILTIN_ENDPOINT_##a_, NN_ENTITYID_##bp_##_BUILTIN_##b_ } #define TE(ap_, a_, bp_, b_) { NN_##ap_##BUILTIN_ENDPOINT_##a_, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
#define TE(ap_, a_, bp_, b_) { NN_##ap_##BUILTIN_ENDPOINT_##a_, 0, NN_ENTITYID_##bp_##_BUILTIN_##b_ } #define LTE(a_, bp_, b_) { NN_##BUILTIN_ENDPOINT_##a_, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
#define LTE(a_, bp_, b_) { NN_##BUILTIN_ENDPOINT_##a_, 0, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
/* 'Default' proxy endpoints. */ /* 'Default' proxy endpoints. */
static const struct bestab bestab_default[] = { static const struct bestab bestab_default[] = {
@ -4682,7 +4681,6 @@ static void add_proxy_builtin_endpoints(
&gv->builtin_stateless_xqos_rd); &gv->builtin_stateless_xqos_rd);
#endif #endif
#undef PT_TE
#undef TE #undef TE
#undef LTE #undef LTE
} }
@ -4703,7 +4701,7 @@ static void proxy_participant_add_pwr_lease_locked (struct proxy_participant * p
/* if inserted lease is new shortest lease */ /* if inserted lease is new shortest lease */
if (proxypp->owns_lease && minl_prev != minl_new) if (proxypp->owns_lease && minl_prev != minl_new)
{ {
nn_etime_t texp = add_duration_to_etime (now_et (), minl_new->tdur); ddsrt_etime_t texp = ddsrt_etime_add_duration (ddsrt_time_elapsed (), minl_new->tdur);
struct lease *lnew = lease_new (texp, minl_new->tdur, minl_new->entity); struct lease *lnew = lease_new (texp, minl_new->tdur, minl_new->entity);
if (minl_prev == NULL) if (minl_prev == NULL)
{ {
@ -4737,7 +4735,7 @@ static void proxy_participant_remove_pwr_lease_locked (struct proxy_participant
{ {
dds_duration_t trem = minl->tdur - pwr->lease->tdur; dds_duration_t trem = minl->tdur - pwr->lease->tdur;
assert (trem >= 0); assert (trem >= 0);
nn_etime_t texp = add_duration_to_etime (now_et(), trem); ddsrt_etime_t texp = ddsrt_etime_add_duration (ddsrt_time_elapsed(), trem);
struct lease *lnew = lease_new (texp, minl->tdur, minl->entity); struct lease *lnew = lease_new (texp, minl->tdur, minl->entity);
proxy_participant_replace_minl (proxypp, manbypp, lnew); proxy_participant_replace_minl (proxypp, manbypp, lnew);
lease_register (lnew); lease_register (lnew);
@ -4879,7 +4877,7 @@ static void free_proxy_participant(struct proxy_participant *proxypp)
ddsrt_free (proxypp); ddsrt_free (proxypp);
} }
void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const ddsi_plist_t *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, nn_wctime_t timestamp, seqno_t seq) void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const ddsi_plist_t *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, seqno_t seq)
{ {
/* No locking => iff all participants use unique guids, and sedp /* No locking => iff all participants use unique guids, and sedp
runs on a single thread, it can't go wrong. FIXME, maybe? The runs on a single thread, it can't go wrong. FIXME, maybe? The
@ -4893,7 +4891,7 @@ void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *pp
assert (entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid) == NULL); assert (entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid) == NULL);
assert (privileged_pp_guid == NULL || privileged_pp_guid->entityid.u == NN_ENTITYID_PARTICIPANT); assert (privileged_pp_guid == NULL || privileged_pp_guid->entityid.u == NN_ENTITYID_PARTICIPANT);
prune_deleted_participant_guids (gv->deleted_participants, now_mt ()); prune_deleted_participant_guids (gv->deleted_participants, ddsrt_time_monotonic ());
proxypp = ddsrt_malloc (sizeof (*proxypp)); proxypp = ddsrt_malloc (sizeof (*proxypp));
@ -4910,14 +4908,14 @@ void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *pp
memset (&proxypp->privileged_pp_guid.prefix, 0, sizeof (proxypp->privileged_pp_guid.prefix)); memset (&proxypp->privileged_pp_guid.prefix, 0, sizeof (proxypp->privileged_pp_guid.prefix));
proxypp->privileged_pp_guid.entityid.u = NN_ENTITYID_PARTICIPANT; proxypp->privileged_pp_guid.entityid.u = NN_ENTITYID_PARTICIPANT;
} }
if ((plist->present & PP_PRISMTECH_PARTICIPANT_VERSION_INFO) && if ((plist->present & PP_ADLINK_PARTICIPANT_VERSION_INFO) &&
(plist->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG) && (plist->adlink_participant_version_info.flags & NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG) &&
(plist->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2)) (plist->adlink_participant_version_info.flags & NN_ADLINK_FL_PARTICIPANT_IS_DDSI2))
proxypp->is_ddsi2_pp = 1; proxypp->is_ddsi2_pp = 1;
else else
proxypp->is_ddsi2_pp = 0; proxypp->is_ddsi2_pp = 0;
if ((plist->present & PP_PRISMTECH_PARTICIPANT_VERSION_INFO) && if ((plist->present & PP_ADLINK_PARTICIPANT_VERSION_INFO) &&
(plist->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_MINIMAL_BES_MODE)) (plist->adlink_participant_version_info.flags & NN_ADLINK_FL_MINIMAL_BES_MODE))
proxypp->minimal_bes_mode = 1; proxypp->minimal_bes_mode = 1;
else else
proxypp->minimal_bes_mode = 0; proxypp->minimal_bes_mode = 0;
@ -4948,8 +4946,8 @@ void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *pp
no further triggers for deleting it. Instead, we take tlease_dur == NEVER as a special value meaning a no further triggers for deleting it. Instead, we take tlease_dur == NEVER as a special value meaning a
lease that doesn't expire now and that has a "reasonable" lease duration. That way the lease renewal in lease that doesn't expire now and that has a "reasonable" lease duration. That way the lease renewal in
the data path is fine, and we only need to do something special in SEDP handling. */ the data path is fine, and we only need to do something special in SEDP handling. */
nn_etime_t texp = add_duration_to_etime (now_et(), tlease_dur); ddsrt_etime_t texp = ddsrt_etime_add_duration (ddsrt_time_elapsed(), tlease_dur);
dds_duration_t dur = (tlease_dur == T_NEVER) ? gv->config.lease_duration : tlease_dur; dds_duration_t dur = (tlease_dur == DDS_INFINITY) ? gv->config.lease_duration : tlease_dur;
proxypp->lease = lease_new (texp, dur, &proxypp->e); proxypp->lease = lease_new (texp, dur, &proxypp->e);
proxypp->owns_lease = 1; proxypp->owns_lease = 1;
@ -5012,7 +5010,7 @@ void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *pp
#endif #endif
} }
int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, nn_wctime_t timestamp) int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, ddsrt_wctime_t timestamp)
{ {
if (seq > proxypp->seq) if (seq > proxypp->seq)
{ {
@ -5033,7 +5031,7 @@ int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, se
return 0; return 0;
} }
int update_proxy_participant_plist (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, nn_wctime_t timestamp) int update_proxy_participant_plist (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, ddsrt_wctime_t timestamp)
{ {
ddsrt_mutex_lock (&proxypp->e.lock); ddsrt_mutex_lock (&proxypp->e.lock);
update_proxy_participant_plist_locked (proxypp, seq, datap, timestamp); update_proxy_participant_plist_locked (proxypp, seq, datap, timestamp);
@ -5067,7 +5065,7 @@ static int ref_proxy_participant (struct proxy_participant *proxypp, struct prox
static void unref_proxy_participant (struct proxy_participant *proxypp, struct proxy_endpoint_common *c) static void unref_proxy_participant (struct proxy_participant *proxypp, struct proxy_endpoint_common *c)
{ {
uint32_t refc; uint32_t refc;
const nn_wctime_t tnow = now(); const ddsrt_wctime_t tnow = ddsrt_time_wallclock();
ddsrt_mutex_lock (&proxypp->e.lock); ddsrt_mutex_lock (&proxypp->e.lock);
refc = --proxypp->refc; refc = --proxypp->refc;
@ -5127,7 +5125,7 @@ static struct entity_common *entity_common_from_proxy_endpoint_common (const str
return (struct entity_common *) ((char *) c - offsetof (struct proxy_writer, c)); return (struct entity_common *) ((char *) c - offsetof (struct proxy_writer, c));
} }
static void delete_or_detach_dependent_pp (struct proxy_participant *p, struct proxy_participant *proxypp, nn_wctime_t timestamp, int isimplicit) static void delete_or_detach_dependent_pp (struct proxy_participant *p, struct proxy_participant *proxypp, ddsrt_wctime_t timestamp, int isimplicit)
{ {
ddsrt_mutex_lock (&p->e.lock); ddsrt_mutex_lock (&p->e.lock);
if (memcmp (&p->privileged_pp_guid, &proxypp->e.guid, sizeof (proxypp->e.guid)) != 0) if (memcmp (&p->privileged_pp_guid, &proxypp->e.guid, sizeof (proxypp->e.guid)) != 0)
@ -5144,7 +5142,7 @@ static void delete_or_detach_dependent_pp (struct proxy_participant *p, struct p
} }
else else
{ {
nn_etime_t texp = add_duration_to_etime (now_et(), p->e.gv->config.ds_grace_period); ddsrt_etime_t texp = ddsrt_etime_add_duration (ddsrt_time_elapsed(), p->e.gv->config.ds_grace_period);
/* Clear dependency (but don't touch entity id, which must be 0x1c1) and set the lease ticking */ /* Clear dependency (but don't touch entity id, which must be 0x1c1) and set the lease ticking */
ELOGDISC (p, PGUIDFMT" detach-from-DS "PGUIDFMT"\n", PGUID(p->e.guid), PGUID(proxypp->e.guid)); ELOGDISC (p, PGUIDFMT" detach-from-DS "PGUIDFMT"\n", PGUID(p->e.guid), PGUID(proxypp->e.guid));
memset (&p->privileged_pp_guid.prefix, 0, sizeof (p->privileged_pp_guid.prefix)); memset (&p->privileged_pp_guid.prefix, 0, sizeof (p->privileged_pp_guid.prefix));
@ -5154,7 +5152,7 @@ static void delete_or_detach_dependent_pp (struct proxy_participant *p, struct p
} }
} }
static void delete_ppt (struct proxy_participant *proxypp, nn_wctime_t timestamp, int isimplicit) static void delete_ppt (struct proxy_participant *proxypp, ddsrt_wctime_t timestamp, int isimplicit)
{ {
ddsi_entityid_t *eps; ddsi_entityid_t *eps;
ddsi_guid_t ep_guid; ddsi_guid_t ep_guid;
@ -5216,7 +5214,7 @@ struct setab {
static void downgrade_to_nonsecure(struct proxy_participant *proxypp) static void downgrade_to_nonsecure(struct proxy_participant *proxypp)
{ {
const nn_wctime_t tnow = now(); const ddsrt_wctime_t tnow = ddsrt_time_wallclock ();
struct ddsi_guid guid; struct ddsi_guid guid;
static const struct setab setab[] = { static const struct setab setab[] = {
{EK_PROXY_WRITER, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER}, {EK_PROXY_WRITER, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER},
@ -5264,7 +5262,7 @@ static void downgrade_to_nonsecure(struct proxy_participant *proxypp)
typedef struct proxy_purge_data { typedef struct proxy_purge_data {
struct proxy_participant *proxypp; struct proxy_participant *proxypp;
const nn_locator_t *loc; const nn_locator_t *loc;
nn_wctime_t timestamp; ddsrt_wctime_t timestamp;
} *proxy_purge_data_t; } *proxy_purge_data_t;
static void purge_helper (const nn_locator_t *n, void * varg) static void purge_helper (const nn_locator_t *n, void * varg)
@ -5284,7 +5282,7 @@ void purge_proxy_participants (struct ddsi_domaingv *gv, const nn_locator_t *loc
thread_state_awake_fixed_domain (ts1); thread_state_awake_fixed_domain (ts1);
data.loc = loc; data.loc = loc;
data.timestamp = now(); data.timestamp = ddsrt_time_wallclock();
entidx_enum_proxy_participant_init (&est, gv->entity_index); entidx_enum_proxy_participant_init (&est, gv->entity_index);
while ((data.proxypp = entidx_enum_proxy_participant_next (&est)) != NULL) while ((data.proxypp = entidx_enum_proxy_participant_next (&est)) != NULL)
addrset_forall (data.proxypp->as_meta, purge_helper, &data); addrset_forall (data.proxypp->as_meta, purge_helper, &data);
@ -5297,7 +5295,7 @@ void purge_proxy_participants (struct ddsi_domaingv *gv, const nn_locator_t *loc
thread_state_asleep (ts1); thread_state_asleep (ts1);
} }
int delete_proxy_participant_by_guid (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit) int delete_proxy_participant_by_guid (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit)
{ {
struct proxy_participant *ppt; struct proxy_participant *ppt;
@ -5334,7 +5332,7 @@ uint64_t get_entity_instance_id (const struct ddsi_domaingv *gv, const struct dd
/* PROXY-ENDPOINT --------------------------------------------------- */ /* PROXY-ENDPOINT --------------------------------------------------- */
static int proxy_endpoint_common_init (struct entity_common *e, struct proxy_endpoint_common *c, enum entity_kind kind, const struct ddsi_guid *guid, nn_wctime_t tcreate, seqno_t seq, struct proxy_participant *proxypp, struct addrset *as, const ddsi_plist_t *plist) static int proxy_endpoint_common_init (struct entity_common *e, struct proxy_endpoint_common *c, enum entity_kind kind, const struct ddsi_guid *guid, ddsrt_wctime_t tcreate, seqno_t seq, struct proxy_participant *proxypp, struct addrset *as, const ddsi_plist_t *plist)
{ {
const char *name; const char *name;
int ret; int ret;
@ -5398,12 +5396,12 @@ get_proxy_writer_reorder_mode(const ddsi_entityid_t pwr_entityid, int isreliable
return NN_REORDER_MODE_MONOTONICALLY_INCREASING; return NN_REORDER_MODE_MONOTONICALLY_INCREASING;
} }
int new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const ddsi_plist_t *plist, struct nn_dqueue *dqueue, struct xeventq *evq, nn_wctime_t timestamp, seqno_t seq) int new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const ddsi_plist_t *plist, struct nn_dqueue *dqueue, struct xeventq *evq, ddsrt_wctime_t timestamp, seqno_t seq)
{ {
struct proxy_participant *proxypp; struct proxy_participant *proxypp;
struct proxy_writer *pwr; struct proxy_writer *pwr;
int isreliable; int isreliable;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
enum nn_reorder_mode reorder_mode; enum nn_reorder_mode reorder_mode;
int ret; int ret;
@ -5456,9 +5454,9 @@ int new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid,
#endif #endif
assert (pwr->c.xqos->present & QP_LIVELINESS); assert (pwr->c.xqos->present & QP_LIVELINESS);
if (pwr->c.xqos->liveliness.lease_duration != T_NEVER) if (pwr->c.xqos->liveliness.lease_duration != DDS_INFINITY)
{ {
nn_etime_t texpire = add_duration_to_etime (now_et (), pwr->c.xqos->liveliness.lease_duration); ddsrt_etime_t texpire = ddsrt_etime_add_duration (ddsrt_time_elapsed (), pwr->c.xqos->liveliness.lease_duration);
pwr->lease = lease_new (texpire, pwr->c.xqos->liveliness.lease_duration, &pwr->e); pwr->lease = lease_new (texpire, pwr->c.xqos->liveliness.lease_duration, &pwr->e);
if (pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_MANUAL_BY_TOPIC) if (pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_MANUAL_BY_TOPIC)
{ {
@ -5526,7 +5524,7 @@ int new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid,
return 0; return 0;
} }
void update_proxy_writer (struct proxy_writer *pwr, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, nn_wctime_t timestamp) void update_proxy_writer (struct proxy_writer *pwr, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, ddsrt_wctime_t timestamp)
{ {
struct reader * rd; struct reader * rd;
struct pwr_rd_match * m; struct pwr_rd_match * m;
@ -5563,7 +5561,7 @@ void update_proxy_writer (struct proxy_writer *pwr, seqno_t seq, struct addrset
ddsrt_mutex_unlock (&pwr->e.lock); ddsrt_mutex_unlock (&pwr->e.lock);
} }
void update_proxy_reader (struct proxy_reader *prd, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, nn_wctime_t timestamp) void update_proxy_reader (struct proxy_reader *prd, seqno_t seq, struct addrset *as, const struct dds_qos *xqos, ddsrt_wctime_t timestamp)
{ {
struct prd_wr_match * m; struct prd_wr_match * m;
ddsi_guid_t wrguid; ddsi_guid_t wrguid;
@ -5635,7 +5633,7 @@ static void gc_delete_proxy_writer (struct gcreq *gcreq)
free_pwr_rd_match (m); free_pwr_rd_match (m);
} }
local_reader_ary_fini (&pwr->rdary); local_reader_ary_fini (&pwr->rdary);
if (pwr->c.xqos->liveliness.lease_duration != T_NEVER) if (pwr->c.xqos->liveliness.lease_duration != DDS_INFINITY)
lease_free (pwr->lease); lease_free (pwr->lease);
proxy_endpoint_common_fini (&pwr->e, &pwr->c); proxy_endpoint_common_fini (&pwr->e, &pwr->c);
nn_defrag_free (pwr->defrag); nn_defrag_free (pwr->defrag);
@ -5645,7 +5643,7 @@ static void gc_delete_proxy_writer (struct gcreq *gcreq)
/* First stage in deleting the proxy writer. In this function the pwr and its member pointers /* First stage in deleting the proxy writer. In this function the pwr and its member pointers
will remain valid. The real cleaning-up is done async in gc_delete_proxy_writer. */ will remain valid. The real cleaning-up is done async in gc_delete_proxy_writer. */
int delete_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit) int delete_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit)
{ {
struct proxy_writer *pwr; struct proxy_writer *pwr;
DDSRT_UNUSED_ARG (isimplicit); DDSRT_UNUSED_ARG (isimplicit);
@ -5668,7 +5666,7 @@ int delete_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *guid,
builtintopic_write (gv->builtin_topic_interface, &pwr->e, timestamp, false); builtintopic_write (gv->builtin_topic_interface, &pwr->e, timestamp, false);
entidx_remove_proxy_writer_guid (gv->entity_index, pwr); entidx_remove_proxy_writer_guid (gv->entity_index, pwr);
ddsrt_mutex_unlock (&gv->lock); ddsrt_mutex_unlock (&gv->lock);
if (pwr->c.xqos->liveliness.lease_duration != T_NEVER && if (pwr->c.xqos->liveliness.lease_duration != DDS_INFINITY &&
pwr->c.xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC) pwr->c.xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC)
lease_unregister (pwr->lease); lease_unregister (pwr->lease);
if (proxy_writer_set_notalive (pwr, false) != DDS_RETCODE_OK) if (proxy_writer_set_notalive (pwr, false) != DDS_RETCODE_OK)
@ -5714,12 +5712,12 @@ void proxy_writer_set_alive_may_unlock (struct proxy_writer *pwr, bool notify)
ddsrt_mutex_lock (&pwr->c.proxypp->e.lock); ddsrt_mutex_lock (&pwr->c.proxypp->e.lock);
pwr->alive = true; pwr->alive = true;
pwr->alive_vclock++; pwr->alive_vclock++;
if (pwr->c.xqos->liveliness.lease_duration != T_NEVER) if (pwr->c.xqos->liveliness.lease_duration != DDS_INFINITY)
{ {
if (pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_MANUAL_BY_TOPIC) if (pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_MANUAL_BY_TOPIC)
proxy_participant_add_pwr_lease_locked (pwr->c.proxypp, pwr); proxy_participant_add_pwr_lease_locked (pwr->c.proxypp, pwr);
else else
lease_set_expiry (pwr->lease, add_duration_to_etime (now_et (), pwr->lease->tdur)); lease_set_expiry (pwr->lease, ddsrt_etime_add_duration (ddsrt_time_elapsed (), pwr->lease->tdur));
} }
ddsrt_mutex_unlock (&pwr->c.proxypp->e.lock); ddsrt_mutex_unlock (&pwr->c.proxypp->e.lock);
@ -5741,7 +5739,7 @@ int proxy_writer_set_notalive (struct proxy_writer *pwr, bool notify)
ddsrt_mutex_lock (&pwr->c.proxypp->e.lock); ddsrt_mutex_lock (&pwr->c.proxypp->e.lock);
pwr->alive = false; pwr->alive = false;
pwr->alive_vclock++; pwr->alive_vclock++;
if (pwr->c.xqos->liveliness.lease_duration != T_NEVER && pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_MANUAL_BY_TOPIC) if (pwr->c.xqos->liveliness.lease_duration != DDS_INFINITY && pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_MANUAL_BY_TOPIC)
proxy_participant_remove_pwr_lease_locked (pwr->c.proxypp, pwr); proxy_participant_remove_pwr_lease_locked (pwr->c.proxypp, pwr);
ddsrt_mutex_unlock (&pwr->c.proxypp->e.lock); ddsrt_mutex_unlock (&pwr->c.proxypp->e.lock);
@ -5753,7 +5751,7 @@ int proxy_writer_set_notalive (struct proxy_writer *pwr, bool notify)
/* PROXY-READER ----------------------------------------------------- */ /* PROXY-READER ----------------------------------------------------- */
int new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const ddsi_plist_t *plist, nn_wctime_t timestamp, seqno_t seq int new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const ddsi_plist_t *plist, ddsrt_wctime_t timestamp, seqno_t seq
#ifdef DDSI_INCLUDE_SSM #ifdef DDSI_INCLUDE_SSM
, int favours_ssm , int favours_ssm
#endif #endif
@ -5761,7 +5759,7 @@ int new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid,
{ {
struct proxy_participant *proxypp; struct proxy_participant *proxypp;
struct proxy_reader *prd; struct proxy_reader *prd;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
int ret; int ret;
assert (!is_writer_entityid (guid->entityid)); assert (!is_writer_entityid (guid->entityid));
@ -5877,7 +5875,7 @@ static void gc_delete_proxy_reader (struct gcreq *gcreq)
ddsrt_free (prd); ddsrt_free (prd);
} }
int delete_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit) int delete_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit)
{ {
struct proxy_reader *prd; struct proxy_reader *prd;
(void)isimplicit; (void)isimplicit;

View file

@ -19,7 +19,6 @@
#include "dds/ddsi/q_gc.h" #include "dds/ddsi/q_gc.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
#include "dds/ddsi/ddsi_entity_index.h" #include "dds/ddsi/ddsi_entity_index.h"
#include "dds/ddsi/q_unused.h" #include "dds/ddsi/q_unused.h"
@ -89,10 +88,10 @@ static int threads_vtime_check (uint32_t *nivs, struct idx_vtime *ivs)
static uint32_t gcreq_queue_thread (struct gcreq_queue *q) static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
nn_mtime_t next_thread_cputime = { 0 }; ddsrt_mtime_t next_thread_cputime = { 0 };
nn_mtime_t t_trigger_recv_threads = { 0 }; ddsrt_mtime_t t_trigger_recv_threads = { 0 };
int64_t shortsleep = 1 * T_MILLISECOND; int64_t shortsleep = DDS_MSECS (1);
int64_t delay = T_MILLISECOND; /* force evaluation after startup */ int64_t delay = DDS_MSECS (1); /* force evaluation after startup */
struct gcreq *gcreq = NULL; struct gcreq *gcreq = NULL;
int trace_shortsleep = 1; int trace_shortsleep = 1;
ddsrt_mutex_lock (&q->lock); ddsrt_mutex_lock (&q->lock);
@ -105,7 +104,7 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
groups. Do rate-limit it a bit. */ groups. Do rate-limit it a bit. */
if (q->gv->deaf) if (q->gv->deaf)
{ {
nn_mtime_t tnow_mt = now_mt (); ddsrt_mtime_t tnow_mt = ddsrt_time_monotonic ();
if (tnow_mt.v > t_trigger_recv_threads.v) if (tnow_mt.v > t_trigger_recv_threads.v)
{ {
trigger_recv_threads (q->gv); trigger_recv_threads (q->gv);
@ -149,7 +148,7 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
burden on the system than having a separate thread or adding it burden on the system than having a separate thread or adding it
to the workload of the data handling threads. */ to the workload of the data handling threads. */
thread_state_awake_fixed_domain (ts1); thread_state_awake_fixed_domain (ts1);
delay = check_and_handle_lease_expiration (q->gv, now_et ()); delay = check_and_handle_lease_expiration (q->gv, ddsrt_time_elapsed ());
thread_state_asleep (ts1); thread_state_asleep (ts1);
if (gcreq) if (gcreq)

View file

@ -41,7 +41,7 @@
#include "dds/ddsi/q_lease.h" #include "dds/ddsi/q_lease.h"
#include "dds/ddsi/q_gc.h" #include "dds/ddsi/q_gc.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_nwif.h" #include "dds/ddsi/ddsi_ownip.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_xmsg.h" #include "dds/ddsi/q_xmsg.h"
#include "dds/ddsi/q_receive.h" #include "dds/ddsi/q_receive.h"
@ -75,13 +75,16 @@ static void add_peer_addresses (const struct ddsi_domaingv *gv, struct addrset *
} }
enum make_uc_sockets_ret { enum make_uc_sockets_ret {
MUSRET_SUCCESS, MUSRET_SUCCESS, /* unicast socket(s) created */
MUSRET_INVALID_PORTS, MUSRET_INVALID_PORTS, /* specified port numbers are invalid */
MUSRET_NOSOCKET MUSRET_PORTS_IN_USE, /* ports were in use, keep trying */
MUSRET_ERROR /* generic error, no use continuing */
}; };
static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint32_t * pdisc, uint32_t * pdata, int ppid) static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint32_t * pdisc, uint32_t * pdata, int ppid)
{ {
dds_return_t rc;
if (gv->config.many_sockets_mode == MSM_NO_UNICAST) if (gv->config.many_sockets_mode == MSM_NO_UNICAST)
{ {
assert (ppid == PARTICIPANT_INDEX_NONE); assert (ppid == PARTICIPANT_INDEX_NONE);
@ -99,40 +102,37 @@ static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint3
if (!ddsi_is_valid_port (gv->m_factory, *pdisc) || !ddsi_is_valid_port (gv->m_factory, *pdata)) if (!ddsi_is_valid_port (gv->m_factory, *pdisc) || !ddsi_is_valid_port (gv->m_factory, *pdata))
return MUSRET_INVALID_PORTS; return MUSRET_INVALID_PORTS;
gv->disc_conn_uc = ddsi_factory_create_conn (gv->m_factory, *pdisc, NULL); const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_RECV_UC, .m_diffserv = 0 };
if (gv->disc_conn_uc) rc = ddsi_factory_create_conn (&gv->disc_conn_uc, gv->m_factory, *pdisc, &qos);
if (rc != DDS_RETCODE_OK)
goto fail_disc;
if (*pdata == 0 || *pdata == *pdisc)
gv->data_conn_uc = gv->disc_conn_uc;
else
{ {
/* Check not configured to use same unicast port for data and discovery */ rc = ddsi_factory_create_conn (&gv->data_conn_uc, gv->m_factory, *pdata, &qos);
if (rc != DDS_RETCODE_OK)
if (*pdata != 0 && (*pdata != *pdisc)) goto fail_data;
{
gv->data_conn_uc = ddsi_factory_create_conn (gv->m_factory, *pdata, NULL);
}
else
{
gv->data_conn_uc = gv->disc_conn_uc;
}
if (gv->data_conn_uc == NULL)
{
ddsi_conn_free (gv->disc_conn_uc);
gv->disc_conn_uc = NULL;
}
else
{
/* Set unicast locators */
ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc);
ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc);
}
} }
ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc);
ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc);
return MUSRET_SUCCESS;
return gv->data_conn_uc ? MUSRET_SUCCESS : MUSRET_NOSOCKET; fail_data:
ddsi_conn_free (gv->disc_conn_uc);
gv->disc_conn_uc = NULL;
fail_disc:
if (rc == DDS_RETCODE_PRECONDITION_NOT_MET)
return MUSRET_PORTS_IN_USE;
return MUSRET_ERROR;
} }
static void make_builtin_endpoint_xqos (dds_qos_t *q, const dds_qos_t *template) static void make_builtin_endpoint_xqos (dds_qos_t *q, const dds_qos_t *template)
{ {
ddsi_xqos_copy (q, template); ddsi_xqos_copy (q, template);
q->reliability.kind = DDS_RELIABILITY_RELIABLE; q->reliability.kind = DDS_RELIABILITY_RELIABLE;
q->reliability.max_blocking_time = 100 * T_MILLISECOND; q->reliability.max_blocking_time = DDS_MSECS (100);
q->durability.kind = DDS_DURABILITY_TRANSIENT_LOCAL; q->durability.kind = DDS_DURABILITY_TRANSIENT_LOCAL;
} }
@ -141,7 +141,7 @@ static void make_builtin_volatile_endpoint_xqos (dds_qos_t *q, const dds_qos_t *
{ {
ddsi_xqos_copy (q, template); ddsi_xqos_copy (q, template);
q->reliability.kind = DDS_RELIABILITY_RELIABLE; q->reliability.kind = DDS_RELIABILITY_RELIABLE;
q->reliability.max_blocking_time = 100 * T_MILLISECOND; q->reliability.max_blocking_time = DDS_MSECS (100);
q->durability.kind = DDS_DURABILITY_VOLATILE; q->durability.kind = DDS_DURABILITY_VOLATILE;
q->history.kind = DDS_HISTORY_KEEP_ALL; q->history.kind = DDS_HISTORY_KEEP_ALL;
} }
@ -689,10 +689,9 @@ int joinleave_spdp_defmcip (struct ddsi_domaingv *gv, int dojoin)
int create_multicast_sockets (struct ddsi_domaingv *gv) int create_multicast_sockets (struct ddsi_domaingv *gv)
{ {
ddsi_tran_qos_t qos = ddsi_tran_create_qos (); const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_RECV_MC, .m_diffserv = 0 };
ddsi_tran_conn_t disc, data; ddsi_tran_conn_t disc, data;
uint32_t port; uint32_t port;
qos->m_multicast = 1;
port = ddsi_get_port (&gv->config, DDSI_PORT_MULTI_DISC, 0); port = ddsi_get_port (&gv->config, DDSI_PORT_MULTI_DISC, 0);
if (!ddsi_is_valid_port (gv->m_factory, port)) if (!ddsi_is_valid_port (gv->m_factory, port))
@ -701,7 +700,7 @@ int create_multicast_sockets (struct ddsi_domaingv *gv)
gv->config.extDomainId.value, port); gv->config.extDomainId.value, port);
goto err_disc; goto err_disc;
} }
if ((disc = ddsi_factory_create_conn (gv->m_factory, port, qos)) == NULL) if (ddsi_factory_create_conn (&disc, gv->m_factory, port, &qos) != DDS_RETCODE_OK)
goto err_disc; goto err_disc;
if (gv->config.many_sockets_mode == MSM_NO_UNICAST) if (gv->config.many_sockets_mode == MSM_NO_UNICAST)
{ {
@ -717,12 +716,9 @@ int create_multicast_sockets (struct ddsi_domaingv *gv)
gv->config.extDomainId.value, port); gv->config.extDomainId.value, port);
goto err_disc; goto err_disc;
} }
if ((data = ddsi_factory_create_conn (gv->m_factory, port, qos)) == NULL) if (ddsi_factory_create_conn (&data, gv->m_factory, port, &qos) != DDS_RETCODE_OK)
{
goto err_data; goto err_data;
}
} }
ddsi_tran_free_qos (qos);
gv->disc_conn_mc = disc; gv->disc_conn_mc = disc;
gv->data_conn_mc = data; gv->data_conn_mc = data;
@ -733,7 +729,6 @@ int create_multicast_sockets (struct ddsi_domaingv *gv)
err_data: err_data:
ddsi_conn_free (disc); ddsi_conn_free (disc);
err_disc: err_disc:
ddsi_tran_free_qos (qos);
return 0; return 0;
} }
@ -756,13 +751,13 @@ struct wait_for_receive_threads_helper_arg {
unsigned count; unsigned count;
}; };
static void wait_for_receive_threads_helper (struct xevent *xev, void *varg, nn_mtime_t tnow) static void wait_for_receive_threads_helper (struct xevent *xev, void *varg, ddsrt_mtime_t tnow)
{ {
struct wait_for_receive_threads_helper_arg * const arg = varg; struct wait_for_receive_threads_helper_arg * const arg = varg;
if (arg->count++ == arg->gv->config.recv_thread_stop_maxretries) if (arg->count++ == arg->gv->config.recv_thread_stop_maxretries)
abort (); abort ();
trigger_recv_threads (arg->gv); trigger_recv_threads (arg->gv);
(void) resched_xevent_if_earlier (xev, add_duration_to_mtime (tnow, T_SECOND)); (void) resched_xevent_if_earlier (xev, ddsrt_mtime_add_duration (tnow, DDS_SECS (1)));
} }
static void wait_for_receive_threads (struct ddsi_domaingv *gv) static void wait_for_receive_threads (struct ddsi_domaingv *gv)
@ -771,7 +766,7 @@ static void wait_for_receive_threads (struct ddsi_domaingv *gv)
struct wait_for_receive_threads_helper_arg cbarg; struct wait_for_receive_threads_helper_arg cbarg;
cbarg.gv = gv; cbarg.gv = gv;
cbarg.count = 0; cbarg.count = 0;
if ((trigev = qxev_callback (gv->xevents, add_duration_to_mtime (now_mt (), T_SECOND), wait_for_receive_threads_helper, &cbarg)) == NULL) if ((trigev = qxev_callback (gv->xevents, ddsrt_mtime_add_duration (ddsrt_time_monotonic (), DDS_SECS (1)), wait_for_receive_threads_helper, &cbarg)) == NULL)
{ {
/* retrying is to deal a packet geting lost because the socket buffer is full or because the /* retrying is to deal a packet geting lost because the socket buffer is full or because the
macOS firewall (and perhaps others) likes to ask if the process is allowed to receive data, macOS firewall (and perhaps others) likes to ask if the process is allowed to receive data,
@ -952,13 +947,37 @@ static uint32_t ddsi_sertopic_hash_wrap (const void *tp)
return ddsi_sertopic_hash (tp); return ddsi_sertopic_hash (tp);
} }
static void reset_deaf_mute (struct xevent *xev, void *varg, UNUSED_ARG (ddsrt_mtime_t tnow))
{
struct ddsi_domaingv *gv = varg;
gv->deaf = 0;
gv->mute = 0;
GVLOGDISC ("DEAFMUTE auto-reset to [deaf, mute]=[%d, %d]\n", gv->deaf, gv->mute);
delete_xevent (xev);
}
void ddsi_set_deafmute (struct ddsi_domaingv *gv, bool deaf, bool mute, int64_t reset_after)
{
gv->deaf = deaf;
gv->mute = mute;
GVLOGDISC (" DEAFMUTE set [deaf, mute]=[%d, %d]", gv->deaf, gv->mute);
if (reset_after < DDS_INFINITY)
{
ddsrt_mtime_t when = ddsrt_mtime_add_duration (ddsrt_time_monotonic (), reset_after);
GVTRACE (" reset after %"PRId64".%09u ns", reset_after / DDS_NSECS_IN_SEC, (unsigned) (reset_after % DDS_NSECS_IN_SEC));
qxev_callback (gv->xevents, when, reset_deaf_mute, gv);
}
GVLOGDISC ("\n");
}
int rtps_init (struct ddsi_domaingv *gv) int rtps_init (struct ddsi_domaingv *gv)
{ {
uint32_t port_disc_uc = 0; uint32_t port_disc_uc = 0;
uint32_t port_data_uc = 0; uint32_t port_data_uc = 0;
bool mc_available = true; bool mc_available = true;
ddsrt_mtime_t reset_deaf_mute_time = DDSRT_MTIME_NEVER;
gv->tstart = now (); /* wall clock time, used in logs */ gv->tstart = ddsrt_time_wallclock (); /* wall clock time, used in logs */
ddsi_plist_init_tables (); ddsi_plist_init_tables ();
@ -966,7 +985,7 @@ int rtps_init (struct ddsi_domaingv *gv)
gv->data_conn_uc = NULL; gv->data_conn_uc = NULL;
gv->disc_conn_mc = NULL; gv->disc_conn_mc = NULL;
gv->data_conn_mc = NULL; gv->data_conn_mc = NULL;
gv->tev_conn = NULL; gv->xmit_conn = NULL;
gv->listener = NULL; gv->listener = NULL;
gv->thread_pool = NULL; gv->thread_pool = NULL;
gv->debmon = NULL; gv->debmon = NULL;
@ -980,6 +999,15 @@ int rtps_init (struct ddsi_domaingv *gv)
GVLOG (DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str); GVLOG (DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str);
} }
/* Allow configuration to set "deaf_mute" in case we want to start out that way */
gv->deaf = gv->config.initial_deaf;
gv->mute = gv->config.initial_mute;
if (gv->deaf || gv->mute)
{
GVLOG (DDS_LC_CONFIG | DDS_LC_DISCOVERY, "DEAFMUTE initial deaf=%d mute=%d reset after %"PRId64"d ns\n", gv->deaf, gv->mute, gv->config.initial_deaf_mute_reset);
reset_deaf_mute_time = ddsrt_mtime_add_duration (ddsrt_time_monotonic (), gv->config.initial_deaf_mute_reset);
}
/* Initialize thread pool */ /* Initialize thread pool */
if (gv->config.tp_enable) if (gv->config.tp_enable)
{ {
@ -1202,18 +1230,21 @@ int rtps_init (struct ddsi_domaingv *gv)
GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n", GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n",
gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc); gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc);
goto err_unicast_sockets; goto err_unicast_sockets;
case MUSRET_NOSOCKET: case MUSRET_PORTS_IN_USE:
GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n", gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc); GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n", gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc);
goto err_unicast_sockets; goto err_unicast_sockets;
case MUSRET_ERROR:
/* something bad happened; assume make_uc_sockets logged the error */
goto err_unicast_sockets;
} }
} }
else if (gv->config.participantIndex == PARTICIPANT_INDEX_AUTO) else if (gv->config.participantIndex == PARTICIPANT_INDEX_AUTO)
{ {
/* try to find a free one, and update gv->config.participantIndex */ /* try to find a free one, and update gv->config.participantIndex */
enum make_uc_sockets_ret musret = MUSRET_NOSOCKET; enum make_uc_sockets_ret musret = MUSRET_PORTS_IN_USE;
int ppid; int ppid;
GVLOG (DDS_LC_CONFIG, "rtps_init: trying to find a free participant index\n"); GVLOG (DDS_LC_CONFIG, "rtps_init: trying to find a free participant index\n");
for (ppid = 0; ppid <= gv->config.maxAutoParticipantIndex && musret == MUSRET_NOSOCKET; ppid++) for (ppid = 0; ppid <= gv->config.maxAutoParticipantIndex && musret == MUSRET_PORTS_IN_USE; ppid++)
{ {
musret = make_uc_sockets (gv, &port_disc_uc, &port_data_uc, ppid); musret = make_uc_sockets (gv, &port_disc_uc, &port_data_uc, ppid);
switch (musret) switch (musret)
@ -1224,8 +1255,11 @@ int rtps_init (struct ddsi_domaingv *gv)
GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n", GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n",
gv->config.extDomainId.value, ppid, port_disc_uc, port_data_uc); gv->config.extDomainId.value, ppid, port_disc_uc, port_data_uc);
goto err_unicast_sockets; goto err_unicast_sockets;
case MUSRET_NOSOCKET: /* Try next one */ case MUSRET_PORTS_IN_USE: /* Try next one */
break; break;
case MUSRET_ERROR:
/* something bad happened; assume make_uc_sockets logged the error */
goto err_unicast_sockets;
} }
} }
if (ppid > gv->config.maxAutoParticipantIndex) if (ppid > gv->config.maxAutoParticipantIndex)
@ -1245,7 +1279,7 @@ int rtps_init (struct ddsi_domaingv *gv)
if (gv->config.pcap_file && *gv->config.pcap_file) if (gv->config.pcap_file && *gv->config.pcap_file)
{ {
gv->pcap_fp = new_pcap_file (&gv->logconfig, gv->config.pcap_file); gv->pcap_fp = new_pcap_file (gv, gv->config.pcap_file);
if (gv->pcap_fp) if (gv->pcap_fp)
{ {
ddsrt_mutex_init (&gv->pcap_lock); ddsrt_mutex_init (&gv->pcap_lock);
@ -1288,9 +1322,6 @@ int rtps_init (struct ddsi_domaingv *gv)
} }
else else
{ {
/* Must have a data_conn_uc/tev_conn/transmit_conn */
gv->data_conn_uc = ddsi_factory_create_conn (gv->m_factory, 0, NULL);
if (gv->config.tcp_port == -1) if (gv->config.tcp_port == -1)
; /* nop */ ; /* nop */
else if (!ddsi_is_valid_port (gv->m_factory, (uint32_t) gv->config.tcp_port)) else if (!ddsi_is_valid_port (gv->m_factory, (uint32_t) gv->config.tcp_port))
@ -1299,8 +1330,9 @@ int rtps_init (struct ddsi_domaingv *gv)
} }
else else
{ {
gv->listener = ddsi_factory_create_listener (gv->m_factory, (uint32_t) gv->config.tcp_port, NULL); dds_return_t rc;
if (gv->listener == NULL || ddsi_listener_listen (gv->listener) != 0) rc = ddsi_factory_create_listener (&gv->listener, gv->m_factory, (uint32_t) gv->config.tcp_port, NULL);
if (rc != DDS_RETCODE_OK || ddsi_listener_listen (gv->listener) != 0)
{ {
GVERROR ("Failed to create %s listener\n", gv->m_factory->m_typename); GVERROR ("Failed to create %s listener\n", gv->m_factory->m_typename);
if (gv->listener) if (gv->listener)
@ -1319,9 +1351,13 @@ int rtps_init (struct ddsi_domaingv *gv)
} }
/* Create shared transmit connection */ /* Create shared transmit connection */
{
gv->tev_conn = gv->data_conn_uc; const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_XMIT, .m_diffserv = 0 };
GVLOG (DDS_LC_CONFIG, "Timed event transmit port: %d\n", (int) ddsi_conn_port (gv->tev_conn)); dds_return_t rc;
rc = ddsi_factory_create_conn (&gv->xmit_conn, gv->m_factory, 0, &qos);
if (rc != DDS_RETCODE_OK)
goto err_mc_conn;
}
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS #ifdef DDSI_INCLUDE_NETWORK_CHANNELS
{ {
@ -1384,7 +1420,7 @@ int rtps_init (struct ddsi_domaingv *gv)
gv->xevents = xeventq_new gv->xevents = xeventq_new
( (
gv->tev_conn, gv->xmit_conn,
gv->config.max_queued_rexmit_bytes, gv->config.max_queued_rexmit_bytes,
gv->config.max_queued_rexmit_msgs, gv->config.max_queued_rexmit_msgs,
#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING #ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING
@ -1441,9 +1477,13 @@ int rtps_init (struct ddsi_domaingv *gv)
gv->user_dqueue = nn_dqueue_new ("user", gv, gv->config.delivery_queue_maxsamples, user_dqueue_handler, NULL); gv->user_dqueue = nn_dqueue_new ("user", gv, gv->config.delivery_queue_maxsamples, user_dqueue_handler, NULL);
#endif #endif
if (reset_deaf_mute_time.v < DDS_NEVER)
qxev_callback (gv->xevents, reset_deaf_mute_time, reset_deaf_mute, gv);
return 0; return 0;
err_mc_conn: err_mc_conn:
if (gv->xmit_conn)
ddsi_conn_free (gv->xmit_conn);
if (gv->disc_conn_mc) if (gv->disc_conn_mc)
ddsi_conn_free (gv->disc_conn_mc); ddsi_conn_free (gv->disc_conn_mc);
if (gv->data_conn_mc && gv->data_conn_mc != gv->disc_conn_mc) if (gv->data_conn_mc && gv->data_conn_mc != gv->disc_conn_mc)
@ -1657,7 +1697,7 @@ void rtps_stop (struct ddsi_domaingv *gv)
{ {
struct entidx_enum_proxy_participant est; struct entidx_enum_proxy_participant est;
struct proxy_participant *proxypp; struct proxy_participant *proxypp;
const nn_wctime_t tnow = now(); const ddsrt_wctime_t tnow = ddsrt_time_wallclock();
/* Clean up proxy readers, proxy writers and proxy /* Clean up proxy readers, proxy writers and proxy
participants. Deleting a proxy participants deletes all its participants. Deleting a proxy participants deletes all its
readers and writers automatically */ readers and writers automatically */
@ -1777,6 +1817,7 @@ void rtps_fini (struct ddsi_domaingv *gv)
(void) joinleave_spdp_defmcip (gv, 0); (void) joinleave_spdp_defmcip (gv, 0);
ddsi_conn_free (gv->xmit_conn);
ddsi_conn_free (gv->disc_conn_mc); ddsi_conn_free (gv->disc_conn_mc);
if (gv->data_conn_mc != gv->disc_conn_mc) if (gv->data_conn_mc != gv->disc_conn_mc)
ddsi_conn_free (gv->data_conn_mc); ddsi_conn_free (gv->data_conn_mc);
@ -1785,8 +1826,6 @@ void rtps_fini (struct ddsi_domaingv *gv)
if (gv->data_conn_uc != gv->disc_conn_uc) if (gv->data_conn_uc != gv->disc_conn_uc)
ddsi_conn_free (gv->data_conn_uc); ddsi_conn_free (gv->data_conn_uc);
/* Not freeing gv->tev_conn: it aliases data_conn_uc */
free_group_membership(gv->mship); free_group_membership(gv->mship);
ddsi_tran_factories_fini (gv); ddsi_tran_factories_fini (gv);

View file

@ -76,7 +76,7 @@ void lease_management_term (struct ddsi_domaingv *gv)
ddsrt_mutex_destroy (&gv->leaseheap_lock); ddsrt_mutex_destroy (&gv->leaseheap_lock);
} }
struct lease *lease_new (nn_etime_t texpire, dds_duration_t tdur, struct entity_common *e) struct lease *lease_new (ddsrt_etime_t texpire, dds_duration_t tdur, struct entity_common *e)
{ {
struct lease *l; struct lease *l;
if ((l = ddsrt_malloc (sizeof (*l))) == NULL) if ((l = ddsrt_malloc (sizeof (*l))) == NULL)
@ -96,7 +96,7 @@ struct lease *lease_new (nn_etime_t texpire, dds_duration_t tdur, struct entity_
*/ */
struct lease *lease_clone (const struct lease *l) struct lease *lease_clone (const struct lease *l)
{ {
nn_etime_t texp; ddsrt_etime_t texp;
dds_duration_t tdur; dds_duration_t tdur;
texp.v = (int64_t) ddsrt_atomic_ld64 (&l->tend); texp.v = (int64_t) ddsrt_atomic_ld64 (&l->tend);
tdur = l->tdur; tdur = l->tdur;
@ -110,7 +110,7 @@ void lease_register (struct lease *l) /* FIXME: make lease admin struct */
ddsrt_mutex_lock (&gv->leaseheap_lock); ddsrt_mutex_lock (&gv->leaseheap_lock);
assert (l->tsched.v == TSCHED_NOT_ON_HEAP); assert (l->tsched.v == TSCHED_NOT_ON_HEAP);
int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend); int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
if (tend != T_NEVER) if (tend != DDS_NEVER)
{ {
l->tsched.v = tend; l->tsched.v = tend;
ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l); ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
@ -144,7 +144,7 @@ void lease_free (struct lease *l)
ddsrt_free (l); ddsrt_free (l);
} }
static void trace_lease_renew (const struct lease *l, const char *tag, nn_etime_t tend_new) static void trace_lease_renew (const struct lease *l, const char *tag, ddsrt_etime_t tend_new)
{ {
struct ddsi_domaingv const * gv = l->entity->gv; struct ddsi_domaingv const * gv = l->entity->gv;
if (gv->logconfig.c.mask & DDS_LC_TRACE) if (gv->logconfig.c.mask & DDS_LC_TRACE)
@ -155,14 +155,14 @@ static void trace_lease_renew (const struct lease *l, const char *tag, nn_etime_
GVTRACE (":%"PRIx32, l->entity->guid.entityid.u); GVTRACE (":%"PRIx32, l->entity->guid.entityid.u);
else else
GVTRACE (""PGUIDFMT"", PGUID (l->entity->guid)); GVTRACE (""PGUIDFMT"", PGUID (l->entity->guid));
etime_to_sec_usec (&tsec, &tusec, tend_new); ddsrt_etime_to_sec_usec (&tsec, &tusec, tend_new);
GVTRACE (" %"PRId32".%06"PRId32")", tsec, tusec); GVTRACE (" %"PRId32".%06"PRId32")", tsec, tusec);
} }
} }
void lease_renew (struct lease *l, nn_etime_t tnowE) void lease_renew (struct lease *l, ddsrt_etime_t tnowE)
{ {
nn_etime_t tend_new = add_duration_to_etime (tnowE, l->tdur); ddsrt_etime_t tend_new = ddsrt_etime_add_duration (tnowE, l->tdur);
/* do not touch tend if moving forward or if already expired */ /* do not touch tend if moving forward or if already expired */
int64_t tend; int64_t tend;
@ -175,11 +175,11 @@ void lease_renew (struct lease *l, nn_etime_t tnowE)
/* Only at this point we can assume that gv can be recovered from the entity in the /* Only at this point we can assume that gv can be recovered from the entity in the
* lease (i.e. the entity still exists). In cases where dereferencing l->entity->gv * lease (i.e. the entity still exists). In cases where dereferencing l->entity->gv
* is not safe (e.g. the deletion of entities), the early out in the loop above * is not safe (e.g. the deletion of entities), the early out in the loop above
* will be the case because tend is set to T_NEVER. */ * will be the case because tend is set to DDS_NEVER. */
trace_lease_renew (l, "", tend_new); trace_lease_renew (l, "", tend_new);
} }
void lease_set_expiry (struct lease *l, nn_etime_t when) void lease_set_expiry (struct lease *l, ddsrt_etime_t when)
{ {
struct ddsi_domaingv * const gv = l->entity->gv; struct ddsi_domaingv * const gv = l->entity->gv;
bool trigger = false; bool trigger = false;
@ -197,7 +197,7 @@ void lease_set_expiry (struct lease *l, nn_etime_t when)
trace_lease_renew (l, "earlier ", when); trace_lease_renew (l, "earlier ", when);
trigger = true; trigger = true;
} }
else if (l->tsched.v == TSCHED_NOT_ON_HEAP && when.v < T_NEVER) else if (l->tsched.v == TSCHED_NOT_ON_HEAP && when.v < DDS_NEVER)
{ {
/* not currently scheduled, with a finite new expiry time */ /* not currently scheduled, with a finite new expiry time */
l->tsched = when; l->tsched = when;
@ -212,7 +212,7 @@ void lease_set_expiry (struct lease *l, nn_etime_t when)
force_lease_check (gv->gcreq_queue); force_lease_check (gv->gcreq_queue);
} }
int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, nn_etime_t tnowE) int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, ddsrt_etime_t tnowE)
{ {
struct lease *l; struct lease *l;
int64_t delay; int64_t delay;
@ -229,7 +229,7 @@ int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, nn_etime_t
int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend); int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
if (tnowE.v < tend) if (tnowE.v < tend)
{ {
if (tend == T_NEVER) { if (tend == DDS_NEVER) {
/* don't reinsert if it won't expire */ /* don't reinsert if it won't expire */
l->tsched.v = TSCHED_NOT_ON_HEAP; l->tsched.v = TSCHED_NOT_ON_HEAP;
} else { } else {
@ -273,7 +273,7 @@ int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, nn_etime_t
entidx_lookup_proxy_participant_guid (gv->entity_index, &proxypp->privileged_pp_guid) != NULL) entidx_lookup_proxy_participant_guid (gv->entity_index, &proxypp->privileged_pp_guid) != NULL)
{ {
GVLOGDISC ("but postponing because privileged pp "PGUIDFMT" is still live\n", PGUID (proxypp->privileged_pp_guid)); GVLOGDISC ("but postponing because privileged pp "PGUIDFMT" is still live\n", PGUID (proxypp->privileged_pp_guid));
l->tsched = add_duration_to_etime (tnowE, 200 * T_MILLISECOND); l->tsched = ddsrt_etime_add_duration (tnowE, DDS_MSECS (200));
ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l); ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
continue; continue;
} }
@ -285,7 +285,7 @@ int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, nn_etime_t
switch (k) switch (k)
{ {
case EK_PROXY_PARTICIPANT: case EK_PROXY_PARTICIPANT:
delete_proxy_participant_by_guid (gv, &g, now(), 1); delete_proxy_participant_by_guid (gv, &g, ddsrt_time_wallclock(), 1);
break; break;
case EK_PROXY_WRITER: case EK_PROXY_WRITER:
proxy_writer_set_notalive ((struct proxy_writer *) l->entity, true); proxy_writer_set_notalive ((struct proxy_writer *) l->entity, true);
@ -302,7 +302,7 @@ int64_t check_and_handle_lease_expiration (struct ddsi_domaingv *gv, nn_etime_t
ddsrt_mutex_lock (&gv->leaseheap_lock); ddsrt_mutex_lock (&gv->leaseheap_lock);
} }
delay = (l == NULL) ? T_NEVER : (l->tsched.v - tnowE.v); delay = (l == NULL) ? DDS_INFINITY : (l->tsched.v - tnowE.v);
ddsrt_mutex_unlock (&gv->leaseheap_lock); ddsrt_mutex_unlock (&gv->leaseheap_lock);
return delay; return delay;
} }

View file

@ -1,683 +0,0 @@
/*
* 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 <ctype.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "dds/ddsrt/ifaddrs.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/md5.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/sockets.h"
#include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_nwif.h"
#include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_unused.h"
#include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_addrset.h" /* unspec locator */
#include "dds/ddsi/q_feature_check.h"
#include "dds/ddsi/ddsi_ipaddr.h"
#include "dds/ddsrt/avl.h"
static void print_sockerror (const struct ddsrt_log_cfg *logcfg, const char *msg)
{
DDS_CERROR (logcfg, "SOCKET %s\n", msg);
}
uint32_t locator_to_hopefully_unique_uint32 (const nn_locator_t *src)
{
uint32_t id = 0;
if (src->kind == NN_LOCATOR_KIND_UDPv4 || src->kind == NN_LOCATOR_KIND_TCPv4)
memcpy (&id, src->address + 12, sizeof (id));
else
{
#if DDSRT_HAVE_IPV6
ddsrt_md5_state_t st;
ddsrt_md5_byte_t digest[16];
ddsrt_md5_init (&st);
ddsrt_md5_append (&st, (const ddsrt_md5_byte_t *) ((const struct sockaddr_in6 *) src)->sin6_addr.s6_addr, 16);
ddsrt_md5_finish (&st, digest);
memcpy (&id, digest, sizeof (id));
#else
DDS_FATAL ("IPv6 unavailable\n");
#endif
}
return id;
}
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
void set_socket_diffserv (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, int diffserv)
{
if (ddsrt_setsockopt (sock, IPPROTO_IP, IP_TOS, (char*) &diffserv, sizeof (diffserv)) != DDS_RETCODE_OK)
{
print_sockerror (logcfg, "IP_TOS");
}
}
#endif
#ifdef SO_NOSIGPIPE
static void set_socket_nosigpipe (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock)
{
int val = 1;
if (ddsrt_setsockopt (sock, SOL_SOCKET, SO_NOSIGPIPE, (char*) &val, sizeof (val)) != DDS_RETCODE_OK)
{
print_sockerror (logcfg, "SO_NOSIGPIPE");
}
}
#endif
#ifdef TCP_NODELAY
static void set_socket_nodelay (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock)
{
int val = 1;
if (ddsrt_setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char*) &val, sizeof (val)) != DDS_RETCODE_OK)
{
print_sockerror (logcfg, "TCP_NODELAY");
}
}
#endif
static int set_rcvbuf (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket, const struct config_maybe_uint32 *min_size)
{
uint32_t ReceiveBufferSize;
socklen_t optlen = (socklen_t) sizeof (ReceiveBufferSize);
uint32_t socket_min_rcvbuf_size;
dds_return_t rc;
if (min_size->isdefault)
socket_min_rcvbuf_size = 1048576;
else
socket_min_rcvbuf_size = min_size->value;
rc = ddsrt_getsockopt(
socket, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, &optlen);
/* TCP/IP stack may not support SO_RCVBUF. */
if (rc == DDS_RETCODE_BAD_PARAMETER) {
DDS_CLOG (DDS_LC_CONFIG, logcfg, "cannot retrieve socket receive buffer size\n");
return 0;
} else if (rc != DDS_RETCODE_OK) {
print_sockerror (logcfg, "get SO_RCVBUF");
return -2;
}
if (ReceiveBufferSize < socket_min_rcvbuf_size)
{
/* make sure the receive buffersize is at least the minimum required */
ReceiveBufferSize = socket_min_rcvbuf_size;
(void) ddsrt_setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (const char *) &ReceiveBufferSize, sizeof (ReceiveBufferSize));
/* We don't check the return code from setsockopt, because some O/Ss tend
to silently cap the buffer size. The only way to make sure is to read
the option value back and check it is now set correctly. */
if (ddsrt_getsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, &optlen) != DDS_RETCODE_OK)
{
print_sockerror (logcfg, "get SO_RCVBUF");
return -2;
}
if (ReceiveBufferSize < socket_min_rcvbuf_size)
{
/* NN_ERROR does more than just DDS_ERROR(), hence the duplication */
DDS_CLOG (min_size->isdefault ? DDS_LC_CONFIG : DDS_LC_ERROR, logcfg,
"failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n",
socket_min_rcvbuf_size, ReceiveBufferSize);
}
else
{
DDS_CLOG (DDS_LC_CONFIG, logcfg, "socket receive buffer size set to %"PRIu32" bytes\n", ReceiveBufferSize);
}
}
return 0;
}
static int set_sndbuf (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket, uint32_t min_size)
{
unsigned SendBufferSize;
socklen_t optlen = (socklen_t) sizeof(SendBufferSize);
dds_return_t rc;
rc = ddsrt_getsockopt(
socket, SOL_SOCKET, SO_SNDBUF,(char *)&SendBufferSize, &optlen);
if (rc == DDS_RETCODE_BAD_PARAMETER) {
DDS_CLOG (DDS_LC_CONFIG, logcfg, "cannot retrieve socket send buffer size\n");
return 0;
} else if (rc != DDS_RETCODE_OK) {
print_sockerror (logcfg, "get SO_SNDBUF");
return -2;
}
if (SendBufferSize < min_size )
{
/* make sure the send buffersize is at least the minimum required */
SendBufferSize = min_size;
if (ddsrt_setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (const char *)&SendBufferSize, sizeof (SendBufferSize)) != DDS_RETCODE_OK)
{
print_sockerror (logcfg, "SO_SNDBUF");
return -2;
}
}
return 0;
}
static int maybe_set_dont_route (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket, const struct config *config)
{
if (config->dontRoute)
{
#if DDSRT_HAVE_IPV6
if (config->transport_selector == TRANS_TCP6 || config->transport_selector == TRANS_UDP6)
{
unsigned ipv6Flag = 1;
if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ipv6Flag, sizeof (ipv6Flag)) != DDS_RETCODE_OK)
{
print_sockerror (logcfg, "IPV6_UNICAST_HOPS");
return -2;
}
}
else
#endif
if (config->transport_selector == TRANS_TCP || config->transport_selector == TRANS_UDP)
{
int one = 1;
if (ddsrt_setsockopt (socket, SOL_SOCKET, SO_DONTROUTE, (char *) &one, sizeof (one)) != DDS_RETCODE_OK)
{
print_sockerror (logcfg, "SO_DONTROUTE");
return -2;
}
}
}
return 0;
}
static int set_reuse_options (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket)
{
/* Set REUSEADDR (if available on platform) for
multicast sockets, leave unicast sockets alone. */
int one = 1;
dds_return_t rc = ddsrt_setsockopt (
socket, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (one));
if (rc == DDS_RETCODE_BAD_PARAMETER) {
DDS_CLOG (DDS_LC_CONFIG, logcfg, "cannot enable address reuse on socket\n");
return 0;
} else if (rc != DDS_RETCODE_OK) {
print_sockerror (logcfg, "SO_REUSEADDR");
return -2;
}
return 0;
}
static int bind_socket (ddsrt_socket_t socket, unsigned short port, const struct ddsi_domaingv *gv)
{
dds_return_t rc = DDS_RETCODE_ERROR;
#if DDSRT_HAVE_IPV6
if (gv->config.transport_selector == TRANS_TCP6 || gv->config.transport_selector == TRANS_UDP6)
{
struct sockaddr_in6 socketname;
memset (&socketname, 0, sizeof (socketname));
socketname.sin6_family = AF_INET6;
socketname.sin6_port = htons (port);
socketname.sin6_addr = ddsrt_in6addr_any;
if (IN6_IS_ADDR_LINKLOCAL (&socketname.sin6_addr)) {
socketname.sin6_scope_id = gv->interfaceNo;
}
rc = ddsrt_bind (socket, (struct sockaddr *) &socketname, sizeof (socketname));
}
else
#endif
if (gv->config.transport_selector == TRANS_TCP || gv->config.transport_selector == TRANS_UDP)
{
struct sockaddr_in socketname;
socketname.sin_family = AF_INET;
socketname.sin_port = htons (port);
socketname.sin_addr.s_addr = htonl (INADDR_ANY);
rc = ddsrt_bind (socket, (struct sockaddr *) &socketname, sizeof (socketname));
}
if (rc != DDS_RETCODE_OK && rc != DDS_RETCODE_PRECONDITION_NOT_MET)
{
print_sockerror (&gv->logconfig, "bind");
}
return (rc == DDS_RETCODE_OK) ? 0 : -1;
}
#if DDSRT_HAVE_IPV6
static int set_mc_options_transmit_ipv6 (ddsrt_socket_t socket, const struct ddsi_domaingv *gv)
{
unsigned interfaceNo = gv->interfaceNo;
unsigned ttl = (unsigned) gv->config.multicast_ttl;
unsigned loop;
if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_IF, &interfaceNo, sizeof (interfaceNo)) != DDS_RETCODE_OK)
{
print_sockerror (&gv->logconfig, "IPV6_MULTICAST_IF");
return -2;
}
if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, sizeof (ttl)) != DDS_RETCODE_OK)
{
print_sockerror (&gv->logconfig, "IPV6_MULTICAST_HOPS");
return -2;
}
loop = (unsigned) !!gv->config.enableMulticastLoopback;
if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof (loop)) != DDS_RETCODE_OK)
{
print_sockerror (&gv->logconfig, "IPV6_MULTICAST_LOOP");
return -2;
}
return 0;
}
#endif
static int set_mc_options_transmit_ipv4 (ddsrt_socket_t socket, const struct ddsi_domaingv *gv)
{
unsigned char ttl = (unsigned char) gv->config.multicast_ttl;
unsigned char loop;
dds_return_t ret;
#if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET
if (gv->config.use_multicast_if_mreqn)
{
struct ip_mreqn mreqn;
memset (&mreqn, 0, sizeof (mreqn));
/* looks like imr_multiaddr is not relevant, not sure about imr_address */
mreqn.imr_multiaddr.s_addr = htonl (INADDR_ANY);
if (gv->config.use_multicast_if_mreqn > 1)
memcpy (&mreqn.imr_address.s_addr, gv->ownloc.address + 12, 4);
else
mreqn.imr_address.s_addr = htonl (INADDR_ANY);
mreqn.imr_ifindex = (int) gv->interfaceNo;
ret = ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof (mreqn));
}
else
#endif
{
ret = ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, gv->ownloc.address + 12, 4);
}
if (ret != DDS_RETCODE_OK)
{
print_sockerror (&gv->logconfig, "IP_MULTICAST_IF");
return -2;
}
if (ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &ttl, sizeof (ttl)) != DDS_RETCODE_OK)
{
print_sockerror (&gv->logconfig, "IP_MULICAST_TTL");
return -2;
}
loop = (unsigned char) gv->config.enableMulticastLoopback;
if (ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof (loop)) != DDS_RETCODE_OK)
{
print_sockerror (&gv->logconfig, "IP_MULTICAST_LOOP");
return -2;
}
return 0;
}
static int set_mc_options_transmit (ddsrt_socket_t socket, const struct ddsi_domaingv *gv)
{
#if DDSRT_HAVE_IPV6
if (gv->config.transport_selector == TRANS_TCP6 || gv->config.transport_selector == TRANS_UDP6)
{
return set_mc_options_transmit_ipv6 (socket, gv);
}
else
#endif
if (gv->config.transport_selector == TRANS_TCP || gv->config.transport_selector == TRANS_UDP)
{
return set_mc_options_transmit_ipv4 (socket, gv);
}
else
{
return -2;
}
}
int make_socket (ddsrt_socket_t *sock, uint16_t port, bool stream, bool reuse, const struct ddsi_domaingv *gv)
{
/* FIXME: this stuff has to move to the transports */
int rc = -2;
dds_return_t ret;
#if DDSRT_HAVE_IPV6
if (gv->config.transport_selector == TRANS_TCP6 || gv->config.transport_selector == TRANS_UDP6)
{
ret = ddsrt_socket(sock, AF_INET6, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
}
else
#endif
if (gv->config.transport_selector == TRANS_TCP || gv->config.transport_selector == TRANS_UDP)
{
ret = ddsrt_socket(sock, AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
}
else
{
return -2;
}
if (ret != DDS_RETCODE_OK)
{
print_sockerror (&gv->logconfig, "socket");
return rc;
}
if (port && reuse && ((rc = set_reuse_options (&gv->logconfig, *sock)) < 0))
{
goto fail;
}
if
(
(rc = set_rcvbuf (&gv->logconfig, *sock, &gv->config.socket_min_rcvbuf_size) < 0) ||
(rc = set_sndbuf (&gv->logconfig, *sock, gv->config.socket_min_sndbuf_size) < 0) ||
((rc = maybe_set_dont_route (&gv->logconfig, *sock, &gv->config)) < 0) ||
((rc = bind_socket (*sock, port, gv)) < 0)
)
{
goto fail;
}
if (! stream)
{
if ((rc = set_mc_options_transmit (*sock, gv)) < 0)
{
goto fail;
}
}
if (stream)
{
#ifdef SO_NOSIGPIPE
set_socket_nosigpipe (&gv->logconfig, *sock);
#endif
#ifdef TCP_NODELAY
if (gv->config.tcp_nodelay)
{
set_socket_nodelay (&gv->logconfig, *sock);
}
#endif
}
return 0;
fail:
ddsrt_close(*sock);
*sock = DDSRT_INVALID_SOCKET;
return rc;
}
static int multicast_override(const char *ifname, const struct config *config)
{
char *copy = ddsrt_strdup (config->assumeMulticastCapable), *cursor = copy, *tok;
int match = 0;
if (copy != NULL)
{
while ((tok = ddsrt_strsep (&cursor, ",")) != NULL)
{
if (ddsi2_patmatch (tok, ifname))
match = 1;
}
}
ddsrt_free (copy);
return match;
}
#ifdef __linux
/* FIMXE: HACK HACK */
#include <linux/if_packet.h>
#endif
int find_own_ip (struct ddsi_domaingv *gv, const char *requested_address)
{
const char *sep = " ";
char last_if_name[80] = "";
int quality = -1;
int i;
ddsrt_ifaddrs_t *ifa, *ifa_root = NULL;
int maxq_list[MAX_INTERFACES];
int maxq_count = 0;
size_t maxq_strlen = 0;
int selected_idx = -1;
char addrbuf[DDSI_LOCSTRLEN];
GVLOG (DDS_LC_CONFIG, "interfaces:");
{
int ret;
ret = ddsi_enumerate_interfaces(gv->m_factory, gv->config.transport_selector, &ifa_root);
if (ret < 0) {
GVERROR ("ddsi_enumerate_interfaces(%s): %d\n", gv->m_factory->m_typename, ret);
return 0;
}
}
gv->n_interfaces = 0;
last_if_name[0] = 0;
for (ifa = ifa_root; ifa != NULL; ifa = ifa->next)
{
char if_name[sizeof (last_if_name)];
int q = 0;
(void) ddsrt_strlcpy(if_name, ifa->name, sizeof(if_name));
if (strcmp (if_name, last_if_name))
GVLOG (DDS_LC_CONFIG, "%s%s", sep, if_name);
(void) ddsrt_strlcpy(last_if_name, if_name, sizeof(last_if_name));
/* interface must be up */
if ((ifa->flags & IFF_UP) == 0) {
GVLOG (DDS_LC_CONFIG, " (interface down)");
continue;
} else if (ddsrt_sockaddr_isunspecified(ifa->addr)) {
GVLOG (DDS_LC_CONFIG, " (address unspecified)");
continue;
}
switch (ifa->type)
{
case DDSRT_IFTYPE_WIFI:
GVLOG (DDS_LC_CONFIG, " wireless");
break;
case DDSRT_IFTYPE_WIRED:
GVLOG (DDS_LC_CONFIG, " wired");
break;
case DDSRT_IFTYPE_UNKNOWN:
break;
}
#if defined(__linux) && !LWIP_SOCKET
if (ifa->addr->sa_family == AF_PACKET)
{
/* FIXME: weirdo warning warranted */
nn_locator_t *l = &gv->interfaces[gv->n_interfaces].loc;
l->kind = NN_LOCATOR_KIND_RAWETH;
l->port = NN_LOCATOR_PORT_INVALID;
memset(l->address, 0, 10);
memcpy(l->address + 10, ((struct sockaddr_ll *)ifa->addr)->sll_addr, 6);
}
else
#endif
{
ddsi_ipaddr_to_loc(gv->m_factory, &gv->interfaces[gv->n_interfaces].loc, ifa->addr, gv->m_factory->m_kind);
}
ddsi_locator_to_string_no_port(addrbuf, sizeof(addrbuf), &gv->interfaces[gv->n_interfaces].loc);
GVLOG (DDS_LC_CONFIG, " %s(", addrbuf);
if (!(ifa->flags & IFF_MULTICAST) && multicast_override (if_name, &gv->config))
{
GVLOG (DDS_LC_CONFIG, "assume-mc:");
ifa->flags |= IFF_MULTICAST;
}
if (ifa->flags & IFF_LOOPBACK)
{
/* Loopback device has the lowest priority of every interface
available, because the other interfaces at least in principle
allow communicating with other machines. */
q += 0;
#if DDSRT_HAVE_IPV6
if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *)ifa->addr)->sin6_addr)))
q += 1;
#endif
}
else
{
#if DDSRT_HAVE_IPV6
/* We accept link-local IPv6 addresses, but an interface with a
link-local address will end up lower in the ordering than one
with a global address. When forced to use a link-local
address, we restrict ourselves to operating on that one
interface only and assume any advertised (incoming) link-local
address belongs to that interface. FIXME: this is wrong, and
should be changed to tag addresses with the interface over
which it was received. But that means proper multi-homing
support and has quite an impact in various places, not least of
which is the abstraction layer. */
if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *)ifa->addr)->sin6_addr)))
q += 5;
#endif
/* We strongly prefer a multicast capable interface, if that's
not available anything that's not point-to-point, or else we
hope IP routing will take care of the issues. */
if (ifa->flags & IFF_MULTICAST)
q += 4;
else if (!(ifa->flags & IFF_POINTOPOINT))
q += 3;
else
q += 2;
}
GVLOG (DDS_LC_CONFIG, "q%d)", q);
if (q == quality) {
maxq_list[maxq_count] = gv->n_interfaces;
maxq_strlen += 2 + strlen (if_name);
maxq_count++;
} else if (q > quality) {
maxq_list[0] = gv->n_interfaces;
maxq_strlen += 2 + strlen (if_name);
maxq_count = 1;
quality = q;
}
if (ifa->addr->sa_family == AF_INET && ifa->netmask)
{
ddsi_ipaddr_to_loc(gv->m_factory, &gv->interfaces[gv->n_interfaces].netmask, ifa->netmask, gv->m_factory->m_kind);
}
else
{
gv->interfaces[gv->n_interfaces].netmask.kind = gv->m_factory->m_kind;
gv->interfaces[gv->n_interfaces].netmask.port = NN_LOCATOR_PORT_INVALID;
memset(&gv->interfaces[gv->n_interfaces].netmask.address, 0, sizeof(gv->interfaces[gv->n_interfaces].netmask.address));
}
gv->interfaces[gv->n_interfaces].mc_capable = ((ifa->flags & IFF_MULTICAST) != 0);
gv->interfaces[gv->n_interfaces].mc_flaky = ((ifa->type == DDSRT_IFTYPE_WIFI) != 0);
gv->interfaces[gv->n_interfaces].point_to_point = ((ifa->flags & IFF_POINTOPOINT) != 0);
gv->interfaces[gv->n_interfaces].if_index = ifa->index;
gv->interfaces[gv->n_interfaces].name = ddsrt_strdup (if_name);
gv->n_interfaces++;
}
GVLOG (DDS_LC_CONFIG, "\n");
ddsrt_freeifaddrs (ifa_root);
if (requested_address == NULL)
{
if (maxq_count > 1)
{
const int idx = maxq_list[0];
char *names;
int p;
ddsi_locator_to_string_no_port (addrbuf, sizeof(addrbuf), &gv->interfaces[idx].loc);
names = ddsrt_malloc (maxq_strlen + 1);
p = 0;
for (i = 0; i < maxq_count && (size_t) p < maxq_strlen; i++)
p += snprintf (names + p, maxq_strlen - (size_t) p, ", %s", gv->interfaces[maxq_list[i]].name);
GVWARNING ("using network interface %s (%s) selected arbitrarily from: %s\n",
gv->interfaces[idx].name, addrbuf, names + 2);
ddsrt_free (names);
}
if (maxq_count > 0)
selected_idx = maxq_list[0];
else
GVERROR ("failed to determine default own IP address\n");
}
else
{
nn_locator_t req;
/* Presumably an interface name */
for (i = 0; i < gv->n_interfaces; i++)
{
if (strcmp (gv->interfaces[i].name, gv->config.networkAddressString) == 0)
break;
}
if (i < gv->n_interfaces)
; /* got a match */
else if (ddsi_locator_from_string(gv, &req, gv->config.networkAddressString, gv->m_factory) != AFSR_OK)
; /* not good, i = gv->n_interfaces, so error handling will kick in */
else
{
/* Try an exact match on the address */
for (i = 0; i < gv->n_interfaces; i++)
if (compare_locators(&gv->interfaces[i].loc, &req) == 0)
break;
if (i == gv->n_interfaces && req.kind == NN_LOCATOR_KIND_UDPv4)
{
/* Try matching on network portion only, where the network
portion is based on the netmask of the interface under
consideration */
for (i = 0; i < gv->n_interfaces; i++)
{
uint32_t req1, ip1, nm1;
memcpy (&req1, req.address + 12, sizeof (req1));
memcpy (&ip1, gv->interfaces[i].loc.address + 12, sizeof (ip1));
memcpy (&nm1, gv->interfaces[i].netmask.address + 12, sizeof (nm1));
/* If the host portion of the requested address is non-zero,
skip this interface */
if (req1 & ~nm1)
continue;
if ((req1 & nm1) == (ip1 & nm1))
break;
}
}
}
if (i < gv->n_interfaces)
selected_idx = i;
else
GVERROR ("%s: does not match an available interface\n", gv->config.networkAddressString);
}
if (selected_idx < 0)
return 0;
else
{
gv->ownloc = gv->interfaces[selected_idx].loc;
gv->selected_interface = selected_idx;
gv->interfaceNo = gv->interfaces[selected_idx].if_index;
#if DDSRT_HAVE_IPV6
if (gv->extloc.kind == NN_LOCATOR_KIND_TCPv6 || gv->extloc.kind == NN_LOCATOR_KIND_UDPv6)
{
struct sockaddr_in6 addr;
memcpy(&addr.sin6_addr, gv->ownloc.address, sizeof(addr.sin6_addr));
gv->ipv6_link_local = IN6_IS_ADDR_LINKLOCAL (&addr.sin6_addr) != 0;
}
else
{
gv->ipv6_link_local = 0;
}
#endif
GVLOG (DDS_LC_CONFIG, "selected interface: %s (index %u)\n",
gv->interfaces[selected_idx].name, gv->interfaceNo);
return 1;
}
}

View file

@ -14,7 +14,6 @@
#include "dds/ddsrt/endian.h" #include "dds/ddsrt/endian.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_bswap.h" #include "dds/ddsi/q_bswap.h"
@ -77,7 +76,7 @@ static const ipv4_hdr_t ipv4_hdr_template = {
#define IPV4_HDR_SIZE 20 #define IPV4_HDR_SIZE 20
#define UDP_HDR_SIZE 8 #define UDP_HDR_SIZE 8
FILE *new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name) FILE *new_pcap_file (struct ddsi_domaingv *gv, const char *name)
{ {
DDSRT_WARNING_MSVC_OFF(4996); DDSRT_WARNING_MSVC_OFF(4996);
FILE *fp; FILE *fp;
@ -85,7 +84,7 @@ FILE *new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name)
if ((fp = fopen (name, "wb")) == NULL) if ((fp = fopen (name, "wb")) == NULL)
{ {
DDS_CWARNING (logcfg, "packet capture disabled: file %s could not be opened for writing\n", name); GVWARNING ("packet capture disabled: file %s could not be opened for writing\n", name);
return NULL; return NULL;
} }
@ -127,7 +126,7 @@ static uint16_t calc_ipv4_checksum (const uint16_t *x)
return (uint16_t) ~s; return (uint16_t) ~s;
} }
void write_pcap_received (struct ddsi_domaingv *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz) void write_pcap_received (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz)
{ {
if (gv->config.transport_selector == TRANS_UDP) if (gv->config.transport_selector == TRANS_UDP)
{ {
@ -140,7 +139,7 @@ void write_pcap_received (struct ddsi_domaingv *gv, nn_wctime_t tstamp, const st
size_t sz_ud = sz + UDP_HDR_SIZE; size_t sz_ud = sz + UDP_HDR_SIZE;
size_t sz_iud = sz_ud + IPV4_HDR_SIZE; size_t sz_iud = sz_ud + IPV4_HDR_SIZE;
ddsrt_mutex_lock (&gv->pcap_lock); ddsrt_mutex_lock (&gv->pcap_lock);
wctime_to_sec_usec (&pcap_hdr.ts_sec, &pcap_hdr.ts_usec, tstamp); ddsrt_wctime_to_sec_usec (&pcap_hdr.ts_sec, &pcap_hdr.ts_usec, tstamp);
pcap_hdr.incl_len = pcap_hdr.orig_len = (uint32_t) sz_iud; pcap_hdr.incl_len = pcap_hdr.orig_len = (uint32_t) sz_iud;
(void) fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, gv->pcap_fp); (void) fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, gv->pcap_fp);
u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr = ipv4_hdr_template;
@ -160,7 +159,7 @@ void write_pcap_received (struct ddsi_domaingv *gv, nn_wctime_t tstamp, const st
} }
} }
void write_pcap_sent (struct ddsi_domaingv *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, const ddsrt_msghdr_t *hdr, size_t sz) void write_pcap_sent (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const struct sockaddr_storage *src, const ddsrt_msghdr_t *hdr, size_t sz)
{ {
if (gv->config.transport_selector == TRANS_UDP) if (gv->config.transport_selector == TRANS_UDP)
{ {
@ -173,7 +172,7 @@ void write_pcap_sent (struct ddsi_domaingv *gv, nn_wctime_t tstamp, const struct
size_t sz_ud = sz + UDP_HDR_SIZE; size_t sz_ud = sz + UDP_HDR_SIZE;
size_t sz_iud = sz_ud + IPV4_HDR_SIZE; size_t sz_iud = sz_ud + IPV4_HDR_SIZE;
ddsrt_mutex_lock (&gv->pcap_lock); ddsrt_mutex_lock (&gv->pcap_lock);
wctime_to_sec_usec (&pcap_hdr.ts_sec, &pcap_hdr.ts_usec, tstamp); ddsrt_wctime_to_sec_usec (&pcap_hdr.ts_sec, &pcap_hdr.ts_usec, tstamp);
pcap_hdr.incl_len = pcap_hdr.orig_len = (uint32_t) sz_iud; pcap_hdr.incl_len = pcap_hdr.orig_len = (uint32_t) sz_iud;
(void) fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, gv->pcap_fp); (void) fwrite (&pcap_hdr, sizeof (pcap_hdr), 1, gv->pcap_fp);
u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr = ipv4_hdr_template;

View file

@ -12,7 +12,6 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/ddsi_xqos.h" #include "dds/ddsi/ddsi_xqos.h"
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_qosmatch.h" #include "dds/ddsi/q_qosmatch.h"

View file

@ -2454,7 +2454,7 @@ static uint32_t dqueue_thread (struct nn_dqueue *q)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ts1->gv); struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ts1->gv);
nn_mtime_t next_thread_cputime = { 0 }; ddsrt_mtime_t next_thread_cputime = { 0 };
int keepgoing = 1; int keepgoing = 1;
ddsi_guid_t rdguid, *prdguid = NULL; ddsi_guid_t rdguid, *prdguid = NULL;
uint32_t rdguid_count = 0; uint32_t rdguid_count = 0;

View file

@ -209,7 +209,7 @@ static int valid_InfoTS (InfoTS_t *msg, size_t size, int byteswap)
msg->time.seconds = ddsrt_bswap4 (msg->time.seconds); msg->time.seconds = ddsrt_bswap4 (msg->time.seconds);
msg->time.fraction = ddsrt_bswap4u (msg->time.fraction); msg->time.fraction = ddsrt_bswap4u (msg->time.fraction);
} }
return valid_ddsi_timestamp (msg->time); return ddsi_is_valid_timestamp (msg->time);
} }
} }
@ -314,7 +314,7 @@ static int set_sampleinfo_bswap (struct nn_rsample_info *sampleinfo, struct CDRH
static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, Data_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp, uint32_t *payloadsz) static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, Data_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp, uint32_t *payloadsz)
{ {
/* on success: sampleinfo->{seq,rst,statusinfo,pt_wr_info_zoff,bswap,complex_qos} all set */ /* on success: sampleinfo->{seq,rst,statusinfo,bswap,complex_qos} all set */
ddsi_guid_t pwr_guid; ddsi_guid_t pwr_guid;
unsigned char *ptr; unsigned char *ptr;
@ -351,7 +351,6 @@ static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, D
*payloadp = NULL; *payloadp = NULL;
sampleinfo->size = 0; /* size is full payload size, no payload & unfragmented => size = 0 */ sampleinfo->size = 0; /* size is full payload size, no payload & unfragmented => size = 0 */
sampleinfo->statusinfo = 0; sampleinfo->statusinfo = 0;
sampleinfo->pt_wr_info_zoff = NN_OFF_TO_ZOFF (0);
sampleinfo->complex_qos = 0; sampleinfo->complex_qos = 0;
return 1; return 1;
} }
@ -380,7 +379,6 @@ static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, D
else else
{ {
sampleinfo->statusinfo = 0; sampleinfo->statusinfo = 0;
sampleinfo->pt_wr_info_zoff = NN_OFF_TO_ZOFF (0);
sampleinfo->complex_qos = 0; sampleinfo->complex_qos = 0;
} }
@ -407,7 +405,6 @@ static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, D
static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rmsg, DataFrag_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp, uint32_t *payloadsz) static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rmsg, DataFrag_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp, uint32_t *payloadsz)
{ {
/* on success: sampleinfo->{rst,statusinfo,pt_wr_info_zoff,bswap,complex_qos} all set */
ddsi_guid_t pwr_guid; ddsi_guid_t pwr_guid;
unsigned char *ptr; unsigned char *ptr;
@ -484,7 +481,6 @@ static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rms
else else
{ {
sampleinfo->statusinfo = 0; sampleinfo->statusinfo = 0;
sampleinfo->pt_wr_info_zoff = NN_OFF_TO_ZOFF (0);
sampleinfo->complex_qos = 0; sampleinfo->complex_qos = 0;
} }
@ -581,7 +577,7 @@ static int acknack_is_nack (const AckNack_t *msg)
return x != 0; return x != 0;
} }
static int accept_ack_or_hb_w_timeout (nn_count_t new_count, nn_count_t *exp_count, nn_etime_t tnow, nn_etime_t *t_last_accepted, int force_accept) static int accept_ack_or_hb_w_timeout (nn_count_t new_count, nn_count_t *exp_count, ddsrt_etime_t tnow, ddsrt_etime_t *t_last_accepted, int force_accept)
{ {
/* AckNacks and Heartbeats with a sequence number (called "count" /* AckNacks and Heartbeats with a sequence number (called "count"
for some reason) equal to or less than the highest one received for some reason) equal to or less than the highest one received
@ -599,7 +595,7 @@ static int accept_ack_or_hb_w_timeout (nn_count_t new_count, nn_count_t *exp_cou
This combined procedure should give the best of all worlds, and This combined procedure should give the best of all worlds, and
is not more expensive in the common case. */ is not more expensive in the common case. */
const int64_t timeout = 2 * T_SECOND; const int64_t timeout = DDS_SECS (2);
if (new_count < *exp_count && tnow.v - t_last_accepted->v < timeout && !force_accept) if (new_count < *exp_count && tnow.v - t_last_accepted->v < timeout && !force_accept)
return 0; return 0;
@ -685,7 +681,7 @@ struct nn_xmsg * nn_gap_info_create_gap(struct writer *wr, struct proxy_reader *
return m; return m;
} }
static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const AckNack_t *msg, nn_wctime_t timestamp, SubmessageKind_t prev_smid) static int handle_AckNack (struct receiver_state *rst, ddsrt_etime_t tnow, const AckNack_t *msg, ddsrt_wctime_t timestamp, SubmessageKind_t prev_smid)
{ {
struct proxy_reader *prd; struct proxy_reader *prd;
struct wr_prd_match *rn; struct wr_prd_match *rn;
@ -789,9 +785,9 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
moment. */ moment. */
if (rst->gv->config.meas_hb_to_ack_latency && timestamp.v) if (rst->gv->config.meas_hb_to_ack_latency && timestamp.v)
{ {
nn_wctime_t tstamp_now = now (); ddsrt_wctime_t tstamp_now = ddsrt_time_wallclock ();
nn_lat_estim_update (&rn->hb_to_ack_latency, tstamp_now.v - timestamp.v); nn_lat_estim_update (&rn->hb_to_ack_latency, tstamp_now.v - timestamp.v);
if ((rst->gv->logconfig.c.mask & DDS_LC_TRACE) && tstamp_now.v > rn->hb_to_ack_latency_tlastlog.v + 10 * T_SECOND) if ((rst->gv->logconfig.c.mask & DDS_LC_TRACE) && tstamp_now.v > rn->hb_to_ack_latency_tlastlog.v + DDS_SECS (10))
{ {
nn_lat_estim_log (DDS_LC_TRACE, &rst->gv->logconfig, NULL, &rn->hb_to_ack_latency); nn_lat_estim_log (DDS_LC_TRACE, &rst->gv->logconfig, NULL, &rn->hb_to_ack_latency);
rn->hb_to_ack_latency_tlastlog = tstamp_now; rn->hb_to_ack_latency_tlastlog = tstamp_now;
@ -938,7 +934,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
if (rst->gv->config.retransmit_merging != REXMIT_MERGE_NEVER && rn->assumed_in_sync && !prd->filter) if (rst->gv->config.retransmit_merging != REXMIT_MERGE_NEVER && rn->assumed_in_sync && !prd->filter)
{ {
/* send retransmit to all receivers, but skip if recently done */ /* send retransmit to all receivers, but skip if recently done */
nn_mtime_t tstamp = now_mt (); ddsrt_mtime_t tstamp = ddsrt_time_monotonic ();
if (tstamp.v > sample.last_rexmit_ts.v + rst->gv->config.retransmit_merging_period) if (tstamp.v > sample.last_rexmit_ts.v + rst->gv->config.retransmit_merging_period)
{ {
RSTTRACE (" RX%"PRId64, seqbase + i); RSTTRACE (" RX%"PRId64, seqbase + i);
@ -1024,7 +1020,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
gradually lowering rate. If we just got a request for a gradually lowering rate. If we just got a request for a
retransmit, and there is more to be retransmitted, surely the retransmit, and there is more to be retransmitted, surely the
rate should be kept up for now */ rate should be kept up for now */
writer_hbcontrol_note_asyncwrite (wr, now_mt ()); writer_hbcontrol_note_asyncwrite (wr, ddsrt_time_monotonic ());
} }
/* If "final" flag not set, we must respond with a heartbeat. Do it /* If "final" flag not set, we must respond with a heartbeat. Do it
now if we haven't done so already */ now if we haven't done so already */
@ -1089,9 +1085,9 @@ struct handle_Heartbeat_helper_arg {
struct receiver_state *rst; struct receiver_state *rst;
const Heartbeat_t *msg; const Heartbeat_t *msg;
struct proxy_writer *pwr; struct proxy_writer *pwr;
nn_wctime_t timestamp; ddsrt_wctime_t timestamp;
nn_etime_t tnow; ddsrt_etime_t tnow;
nn_mtime_t tnow_mt; ddsrt_mtime_t tnow_mt;
}; };
static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct handle_Heartbeat_helper_arg * const arg) static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct handle_Heartbeat_helper_arg * const arg)
@ -1128,8 +1124,7 @@ static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct hand
once, regardless of which readers care about it. */ once, regardless of which readers care about it. */
if (wn->acknack_xevent) if (wn->acknack_xevent)
{ {
nn_mtime_t tsched; ddsrt_mtime_t tsched = DDSRT_MTIME_NEVER;
tsched.v = T_NEVER;
if (wn->filtered) if (wn->filtered)
last_seq = wn->last_seq; last_seq = wn->last_seq;
@ -1158,7 +1153,7 @@ static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct hand
} }
} }
static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Heartbeat_t *msg, nn_wctime_t timestamp, SubmessageKind_t prev_smid) static int handle_Heartbeat (struct receiver_state *rst, ddsrt_etime_t tnow, struct nn_rmsg *rmsg, const Heartbeat_t *msg, ddsrt_wctime_t timestamp, SubmessageKind_t prev_smid)
{ {
/* We now cheat: and process the heartbeat for _all_ readers, /* We now cheat: and process the heartbeat for _all_ readers,
always, regardless of the destination address in the Heartbeat always, regardless of the destination address in the Heartbeat
@ -1211,7 +1206,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct
ddsrt_mutex_lock (&pwr->e.lock); ddsrt_mutex_lock (&pwr->e.lock);
if (msg->smhdr.flags & HEARTBEAT_FLAG_LIVELINESS && if (msg->smhdr.flags & HEARTBEAT_FLAG_LIVELINESS &&
pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_AUTOMATIC && pwr->c.xqos->liveliness.kind != DDS_LIVELINESS_AUTOMATIC &&
pwr->c.xqos->liveliness.lease_duration != T_NEVER) pwr->c.xqos->liveliness.lease_duration != DDS_INFINITY)
{ {
if ((lease = ddsrt_atomic_ldvoidp (&pwr->c.proxypp->minl_man)) != NULL) if ((lease = ddsrt_atomic_ldvoidp (&pwr->c.proxypp->minl_man)) != NULL)
lease_renew (lease, tnow); lease_renew (lease, tnow);
@ -1342,7 +1337,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct
arg.pwr = pwr; arg.pwr = pwr;
arg.timestamp = timestamp; arg.timestamp = timestamp;
arg.tnow = tnow; arg.tnow = tnow;
arg.tnow_mt = now_mt (); arg.tnow_mt = ddsrt_time_monotonic ();
handle_forall_destinations (&dst, pwr, (ddsrt_avl_walk_t) handle_Heartbeat_helper, &arg); handle_forall_destinations (&dst, pwr, (ddsrt_avl_walk_t) handle_Heartbeat_helper, &arg);
RSTTRACE (")"); RSTTRACE (")");
@ -1350,7 +1345,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct
return 1; return 1;
} }
static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime_t tnow), const HeartbeatFrag_t *msg, SubmessageKind_t prev_smid) static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(ddsrt_etime_t tnow), const HeartbeatFrag_t *msg, SubmessageKind_t prev_smid)
{ {
const seqno_t seq = fromSN (msg->writerSN); const seqno_t seq = fromSN (msg->writerSN);
const nn_fragment_number_t fragnum = msg->lastFragmentNum - 1; /* we do 0-based */ const nn_fragment_number_t fragnum = msg->lastFragmentNum - 1; /* we do 0-based */
@ -1459,7 +1454,7 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
samples we no longer care about) */ samples we no longer care about) */
int64_t delay = rst->gv->config.nack_delay; int64_t delay = rst->gv->config.nack_delay;
RSTTRACE ("/nackfrag"); RSTTRACE ("/nackfrag");
(void) resched_xevent_if_earlier (m->acknack_xevent, add_duration_to_mtime (now_mt(), delay)); (void) resched_xevent_if_earlier (m->acknack_xevent, ddsrt_mtime_add_duration (ddsrt_time_monotonic(), delay));
} }
} }
} }
@ -1468,7 +1463,7 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
return 1; return 1;
} }
static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const NackFrag_t *msg, SubmessageKind_t prev_smid) static int handle_NackFrag (struct receiver_state *rst, ddsrt_etime_t tnow, const NackFrag_t *msg, SubmessageKind_t prev_smid)
{ {
struct proxy_reader *prd; struct proxy_reader *prd;
struct wr_prd_match *rn; struct wr_prd_match *rn;
@ -1588,7 +1583,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
struct whc_state whcst; struct whc_state whcst;
whc_get_state(wr->whc, &whcst); whc_get_state(wr->whc, &whcst);
force_heartbeat_to_peer (wr, &whcst, prd, 1); force_heartbeat_to_peer (wr, &whcst, prd, 1);
writer_hbcontrol_note_asyncwrite (wr, now_mt ()); writer_hbcontrol_note_asyncwrite (wr, ddsrt_time_monotonic ());
} }
out: out:
@ -1628,17 +1623,17 @@ static int handle_InfoSRC (struct receiver_state *rst, const InfoSRC_t *msg)
return 1; return 1;
} }
static int handle_InfoTS (const struct receiver_state *rst, const InfoTS_t *msg, nn_wctime_t *timestamp) static int handle_InfoTS (const struct receiver_state *rst, const InfoTS_t *msg, ddsrt_wctime_t *timestamp)
{ {
RSTTRACE ("INFOTS("); RSTTRACE ("INFOTS(");
if (msg->smhdr.flags & INFOTS_INVALIDATE_FLAG) if (msg->smhdr.flags & INFOTS_INVALIDATE_FLAG)
{ {
*timestamp = NN_WCTIME_INVALID; *timestamp = DDSRT_WCTIME_INVALID;
RSTTRACE ("invalidate"); RSTTRACE ("invalidate");
} }
else else
{ {
*timestamp = nn_wctime_from_ddsi_time (msg->time); *timestamp = ddsi_wctime_from_ddsi_time (msg->time);
if (rst->gv->logconfig.c.mask & DDS_LC_TRACE) if (rst->gv->logconfig.c.mask & DDS_LC_TRACE)
RSTTRACE ("%d.%09d", (int) (timestamp->v / 1000000000), (int) (timestamp->v % 1000000000)); RSTTRACE ("%d.%09d", (int) (timestamp->v / 1000000000), (int) (timestamp->v % 1000000000));
} }
@ -1714,7 +1709,7 @@ static int handle_one_gap (struct proxy_writer *pwr, struct pwr_rd_match *wn, se
return gap_was_valuable; return gap_was_valuable;
} }
static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Gap_t *msg, SubmessageKind_t prev_smid) static int handle_Gap (struct receiver_state *rst, ddsrt_etime_t tnow, struct nn_rmsg *rmsg, const Gap_t *msg, SubmessageKind_t prev_smid)
{ {
/* Option 1: Process the Gap for the proxy writer and all /* Option 1: Process the Gap for the proxy writer and all
out-of-sync readers: what do I care which reader is being out-of-sync readers: what do I care which reader is being
@ -1854,7 +1849,7 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
return 1; return 1;
} }
static struct ddsi_serdata *get_serdata (struct ddsi_sertopic const * const topic, const struct nn_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, nn_wctime_t tstamp) static struct ddsi_serdata *get_serdata (struct ddsi_sertopic const * const topic, const struct nn_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, ddsrt_wctime_t tstamp)
{ {
struct ddsi_serdata *sd = ddsi_serdata_from_ser (topic, justkey ? SDK_KEY : SDK_DATA, fragchain, sz); struct ddsi_serdata *sd = ddsi_serdata_from_ser (topic, justkey ? SDK_KEY : SDK_DATA, fragchain, sz);
if (sd) if (sd)
@ -1871,7 +1866,7 @@ struct remote_sourceinfo {
const ddsi_plist_t *qos; const ddsi_plist_t *qos;
const struct nn_rdata *fragchain; const struct nn_rdata *fragchain;
unsigned statusinfo; unsigned statusinfo;
nn_wctime_t tstamp; ddsrt_wctime_t tstamp;
}; };
static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, struct ddsi_domaingv *gv, struct ddsi_sertopic const * const topic, void *vsourceinfo) static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, struct ddsi_domaingv *gv, struct ddsi_sertopic const * const topic, void *vsourceinfo)
@ -1883,7 +1878,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk,
const struct nn_rdata * __restrict fragchain = si->fragchain; const struct nn_rdata * __restrict fragchain = si->fragchain;
const uint32_t statusinfo = si->statusinfo; const uint32_t statusinfo = si->statusinfo;
const unsigned char data_smhdr_flags = si->data_smhdr_flags; const unsigned char data_smhdr_flags = si->data_smhdr_flags;
const nn_wctime_t tstamp = si->tstamp; const ddsrt_wctime_t tstamp = si->tstamp;
const ddsi_plist_t * __restrict qos = si->qos; const ddsi_plist_t * __restrict qos = si->qos;
const char *failmsg = NULL; const char *failmsg = NULL;
struct ddsi_serdata *sample = NULL; struct ddsi_serdata *sample = NULL;
@ -1910,7 +1905,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk,
else if (sampleinfo->size) else if (sampleinfo->size)
{ {
/* dispose or unregister with included serialized key or data /* dispose or unregister with included serialized key or data
(data is a PrismTech extension) -- i.e., dispose or unregister (data is a Adlink extension) -- i.e., dispose or unregister
as one would expect to receive */ as one would expect to receive */
if (data_smhdr_flags & DATA_FLAG_KEYFLAG) if (data_smhdr_flags & DATA_FLAG_KEYFLAG)
{ {
@ -2122,7 +2117,7 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
} }
/* FIXME: should it be 0, local wall clock time or INVALID? */ /* FIXME: should it be 0, local wall clock time or INVALID? */
const nn_wctime_t tstamp = (sampleinfo->timestamp.v != NN_WCTIME_INVALID.v) ? sampleinfo->timestamp : ((nn_wctime_t) {0}); const ddsrt_wctime_t tstamp = (sampleinfo->timestamp.v != DDSRT_WCTIME_INVALID.v) ? sampleinfo->timestamp : ((ddsrt_wctime_t) {0});
struct ddsi_writer_info wrinfo; struct ddsi_writer_info wrinfo;
ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos, statusinfo); ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos, statusinfo);
@ -2190,7 +2185,7 @@ static void clean_defrag (struct proxy_writer *pwr)
nn_defrag_notegap (pwr->defrag, 1, seq); nn_defrag_notegap (pwr->defrag, 1, seq);
} }
static void handle_regular (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Data_DataFrag_common_t *msg, const struct nn_rsample_info *sampleinfo, static void handle_regular (struct receiver_state *rst, ddsrt_etime_t tnow, struct nn_rmsg *rmsg, const Data_DataFrag_common_t *msg, const struct nn_rsample_info *sampleinfo,
uint32_t fragnum, struct nn_rdata *rdata, struct nn_dqueue **deferred_wakeup, bool renew_manbypp_lease) uint32_t fragnum, struct nn_rdata *rdata, struct nn_dqueue **deferred_wakeup, bool renew_manbypp_lease)
{ {
struct proxy_writer *pwr; struct proxy_writer *pwr;
@ -2489,7 +2484,7 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con
} }
} }
static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Data_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup, SubmessageKind_t prev_smid) static int handle_Data (struct receiver_state *rst, ddsrt_etime_t tnow, struct nn_rmsg *rmsg, const Data_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup, SubmessageKind_t prev_smid)
{ {
RSTTRACE ("DATA("PGUIDFMT" -> "PGUIDFMT" #%"PRId64, RSTTRACE ("DATA("PGUIDFMT" -> "PGUIDFMT" #%"PRId64,
PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u, PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u,
@ -2554,7 +2549,7 @@ static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_r
return 1; return 1;
} }
static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const DataFrag_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup, SubmessageKind_t prev_smid) static int handle_DataFrag (struct receiver_state *rst, ddsrt_etime_t tnow, struct nn_rmsg *rmsg, const DataFrag_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup, SubmessageKind_t prev_smid)
{ {
RSTTRACE ("DATAFRAG("PGUIDFMT" -> "PGUIDFMT" #%"PRId64"/[%u..%u]", RSTTRACE ("DATAFRAG("PGUIDFMT" -> "PGUIDFMT" #%"PRId64"/[%u..%u]",
PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u, PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u,
@ -2781,8 +2776,8 @@ static int handle_submsg_sequence
struct ddsi_domaingv *gv, struct ddsi_domaingv *gv,
ddsi_tran_conn_t conn, ddsi_tran_conn_t conn,
const nn_locator_t *srcloc, const nn_locator_t *srcloc,
nn_wctime_t tnowWC, ddsrt_wctime_t tnowWC,
nn_etime_t tnowE, ddsrt_etime_t tnowE,
const ddsi_guid_prefix_t * const src_prefix, const ddsi_guid_prefix_t * const src_prefix,
const ddsi_guid_prefix_t * const dst_prefix, const ddsi_guid_prefix_t * const dst_prefix,
unsigned char * const msg /* NOT const - we may byteswap it */, unsigned char * const msg /* NOT const - we may byteswap it */,
@ -2797,7 +2792,7 @@ static int handle_submsg_sequence
Header_t * hdr = (Header_t *) msg; Header_t * hdr = (Header_t *) msg;
struct receiver_state *rst; struct receiver_state *rst;
int rst_live, ts_for_latmeas; int rst_live, ts_for_latmeas;
nn_wctime_t timestamp; ddsrt_wctime_t timestamp;
size_t submsg_size = 0; size_t submsg_size = 0;
unsigned char * end = msg + len; unsigned char * end = msg + len;
struct nn_dqueue *deferred_wakeup = NULL; struct nn_dqueue *deferred_wakeup = NULL;
@ -2830,7 +2825,7 @@ static int handle_submsg_sequence
rst->gv = gv; rst->gv = gv;
rst_live = 0; rst_live = 0;
ts_for_latmeas = 0; ts_for_latmeas = 0;
timestamp = NN_WCTIME_INVALID; timestamp = DDSRT_WCTIME_INVALID;
assert (thread_is_asleep ()); assert (thread_is_asleep ());
thread_state_awake_fixed_domain (ts1); thread_state_awake_fixed_domain (ts1);
@ -2885,14 +2880,14 @@ static int handle_submsg_sequence
state = "parse:acknack"; state = "parse:acknack";
if (!valid_AckNack (rst, &sm->acknack, submsg_size, byteswap)) if (!valid_AckNack (rst, &sm->acknack, submsg_size, byteswap))
goto malformed; goto malformed;
handle_AckNack (rst, tnowE, &sm->acknack, ts_for_latmeas ? timestamp : NN_WCTIME_INVALID, prev_smid); handle_AckNack (rst, tnowE, &sm->acknack, ts_for_latmeas ? timestamp : DDSRT_WCTIME_INVALID, prev_smid);
ts_for_latmeas = 0; ts_for_latmeas = 0;
break; break;
case SMID_HEARTBEAT: case SMID_HEARTBEAT:
state = "parse:heartbeat"; state = "parse:heartbeat";
if (!valid_Heartbeat (&sm->heartbeat, submsg_size, byteswap)) if (!valid_Heartbeat (&sm->heartbeat, submsg_size, byteswap))
goto malformed; goto malformed;
handle_Heartbeat (rst, tnowE, rmsg, &sm->heartbeat, ts_for_latmeas ? timestamp : NN_WCTIME_INVALID, prev_smid); handle_Heartbeat (rst, tnowE, rmsg, &sm->heartbeat, ts_for_latmeas ? timestamp : DDSRT_WCTIME_INVALID, prev_smid);
ts_for_latmeas = 0; ts_for_latmeas = 0;
break; break;
case SMID_GAP: case SMID_GAP:
@ -3006,7 +3001,7 @@ static int handle_submsg_sequence
ts_for_latmeas = 0; ts_for_latmeas = 0;
} }
break; break;
case SMID_PT_MSG_LEN: case SMID_ADLINK_MSG_LEN:
{ {
#if 0 #if 0
state = "parse:msg_len"; state = "parse:msg_len";
@ -3014,7 +3009,7 @@ static int handle_submsg_sequence
GVTRACE ("MSG_LEN(%"PRIu32")", ((MsgLen_t*) sm)->length); GVTRACE ("MSG_LEN(%"PRIu32")", ((MsgLen_t*) sm)->length);
break; break;
} }
case SMID_PT_ENTITY_ID: case SMID_ADLINK_ENTITY_ID:
{ {
#if 0 #if 0
state = "parse:entity_id"; state = "parse:entity_id";
@ -3173,7 +3168,7 @@ static bool do_packet (struct thread_state1 * const ts1, struct ddsi_domaingv *g
ml->length = ddsrt_bswap4u (ml->length); ml->length = ddsrt_bswap4u (ml->length);
} }
if (ml->smhdr.submessageId != SMID_PT_MSG_LEN) if (ml->smhdr.submessageId != SMID_ADLINK_MSG_LEN)
{ {
malformed_packet_received_nosubmsg (gv, buff, sz, "header", hdr->vendorid); malformed_packet_received_nosubmsg (gv, buff, sz, "header", hdr->vendorid);
sz = -1; sz = -1;
@ -3223,30 +3218,10 @@ static bool do_packet (struct thread_state1 * const ts1, struct ddsi_domaingv *g
GVTRACE ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu from %s\n", GVTRACE ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu from %s\n",
PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, addrstr); PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, addrstr);
} }
nn_rtps_msg_state_t res = decode_rtps_message(ts1, nn_rtps_msg_state_t res = decode_rtps_message (ts1, gv, &rmsg, &hdr, &buff, &sz, rbpool, conn->m_stream);
gv,
&rmsg,
&hdr,
&buff,
&sz,
rbpool,
conn->m_stream);
if (res != NN_RTPS_MSG_STATE_ERROR) if (res != NN_RTPS_MSG_STATE_ERROR)
{ {
handle_submsg_sequence (ts1, handle_submsg_sequence (ts1, gv, conn, &srcloc, ddsrt_time_wallclock (), ddsrt_time_elapsed (), &hdr->guid_prefix, guidprefix, buff, (size_t) sz, buff + RTPS_MESSAGE_HEADER_SIZE, rmsg, res == NN_RTPS_MSG_STATE_ENCODED);
gv,
conn,
&srcloc,
now (),
now_et (),
&hdr->guid_prefix,
guidprefix,
buff,
(size_t) sz,
buff + RTPS_MESSAGE_HEADER_SIZE,
rmsg,
res == NN_RTPS_MSG_STATE_ENCODED);
} }
else else
{ {
@ -3416,97 +3391,6 @@ static int recv_thread_waitset_add_conn (os_sockWaitset ws, ddsi_tran_conn_t con
} }
} }
enum local_deaf_state_recover {
LDSR_NORMAL = 0, /* matches gv.deaf for normal operation */
LDSR_DEAF = 1, /* matches gv.deaf for "deaf" state */
LDSR_REJOIN = 2
};
struct local_deaf_state {
enum local_deaf_state_recover state;
nn_mtime_t tnext;
};
static int check_and_handle_deafness_recover (struct ddsi_domaingv *gv, struct local_deaf_state *st, unsigned num_fixed_uc)
{
int rebuildws = 0;
if (now_mt().v < st->tnext.v)
{
GVTRACE ("check_and_handle_deafness_recover: state %d too early\n", (int)st->state);
return 0;
}
switch (st->state)
{
case LDSR_NORMAL:
assert(0);
break;
case LDSR_DEAF: {
ddsi_tran_conn_t disc = gv->disc_conn_mc, data = gv->data_conn_mc;
GVTRACE ("check_and_handle_deafness_recover: state %d create new sockets\n", (int) st->state);
if (!create_multicast_sockets (gv))
goto error;
GVTRACE ("check_and_handle_deafness_recover: state %d transfer group membership admin\n", (int) st->state);
ddsi_transfer_group_membership (gv->mship, disc, gv->disc_conn_mc);
ddsi_transfer_group_membership (gv->mship, data, gv->data_conn_mc);
GVTRACE ("check_and_handle_deafness_recover: state %d drop from waitset and add new\n", (int) st->state);
/* see waitset construction code in recv_thread */
os_sockWaitsetPurge (gv->recv_threads[0].arg.u.many.ws, num_fixed_uc);
if (recv_thread_waitset_add_conn (gv->recv_threads[0].arg.u.many.ws, gv->disc_conn_mc) < 0)
DDS_FATAL("check_and_handle_deafness_recover: failed to add disc_conn_mc to waitset\n");
if (recv_thread_waitset_add_conn (gv->recv_threads[0].arg.u.many.ws, gv->data_conn_mc) < 0)
DDS_FATAL("check_and_handle_deafness_recover: failed to add data_conn_mc to waitset\n");
GVTRACE ("check_and_handle_deafness_recover: state %d close sockets\n", (int)st->state);
ddsi_conn_free(disc);
ddsi_conn_free(data);
rebuildws = 1;
st->state = LDSR_REJOIN;
}
/* FALLS THROUGH */
case LDSR_REJOIN:
GVTRACE ("check_and_handle_deafness_recover: state %d rejoin on disc socket\n", (int)st->state);
if (ddsi_rejoin_transferred_mcgroups (gv, gv->mship, gv->disc_conn_mc) < 0)
goto error;
GVTRACE ("check_and_handle_deafness_recover: state %d rejoin on data socket\n", (int)st->state);
if (ddsi_rejoin_transferred_mcgroups (gv, gv->mship, gv->data_conn_mc) < 0)
goto error;
GVTRACE ("check_and_handle_deafness_recover: state %d done\n", (int)st->state);
st->state = LDSR_NORMAL;
break;
}
GVTRACE ("check_and_handle_deafness_recover: state %d returning %d\n", (int)st->state, rebuildws);
return rebuildws;
error:
GVTRACE ("check_and_handle_deafness_recover: state %d failed, returning %d\n", (int)st->state, rebuildws);
st->state = LDSR_DEAF;
st->tnext = add_duration_to_mtime(now_mt(), T_SECOND);
return rebuildws;
}
static int check_and_handle_deafness (struct ddsi_domaingv *gv, struct local_deaf_state *st, unsigned num_fixed_uc)
{
const int gv_deaf = gv->deaf;
assert (gv_deaf == 0 || gv_deaf == 1);
if (gv_deaf == (int)st->state)
return 0;
else if (gv_deaf)
{
GVTRACE ("check_and_handle_deafness: going deaf (%d -> %d)\n", (int)st->state, (int)LDSR_DEAF);
st->state = LDSR_DEAF;
st->tnext = now_mt();
return 0;
}
else if (!gv->config.allowMulticast)
{
GVTRACE ("check_and_handle_deafness: no longer deaf (multicast disabled)\n");
st->state = LDSR_NORMAL;
return 0;
}
else
{
return check_and_handle_deafness_recover (gv, st, num_fixed_uc);
}
}
void trigger_recv_threads (const struct ddsi_domaingv *gv) void trigger_recv_threads (const struct ddsi_domaingv *gv)
{ {
for (uint32_t i = 0; i < gv->n_recv_threads; i++) for (uint32_t i = 0; i < gv->n_recv_threads; i++)
@ -3523,7 +3407,7 @@ void trigger_recv_threads (const struct ddsi_domaingv *gv)
iov.iov_base = &dummy; iov.iov_base = &dummy;
iov.iov_len = 1; iov.iov_len = 1;
GVTRACE ("trigger_recv_threads: %d single %s\n", i, ddsi_locator_to_string (buf, sizeof (buf), dst)); GVTRACE ("trigger_recv_threads: %d single %s\n", i, ddsi_locator_to_string (buf, sizeof (buf), dst));
ddsi_conn_write (gv->data_conn_uc, dst, 1, &iov, 0); ddsi_conn_write (gv->xmit_conn, dst, 1, &iov, 0);
break; break;
} }
case RTM_MANY: { case RTM_MANY: {
@ -3542,7 +3426,7 @@ uint32_t recv_thread (void *vrecv_thread_arg)
struct ddsi_domaingv * const gv = recv_thread_arg->gv; struct ddsi_domaingv * const gv = recv_thread_arg->gv;
struct nn_rbufpool *rbpool = recv_thread_arg->rbpool; struct nn_rbufpool *rbpool = recv_thread_arg->rbpool;
os_sockWaitset waitset = recv_thread_arg->mode == RTM_MANY ? recv_thread_arg->u.many.ws : NULL; os_sockWaitset waitset = recv_thread_arg->mode == RTM_MANY ? recv_thread_arg->u.many.ws : NULL;
nn_mtime_t next_thread_cputime = { 0 }; ddsrt_mtime_t next_thread_cputime = { 0 };
nn_rbufpool_setowner (rbpool, ddsrt_thread_self ()); nn_rbufpool_setowner (rbpool, ddsrt_thread_self ());
if (waitset == NULL) if (waitset == NULL)
@ -3559,9 +3443,6 @@ uint32_t recv_thread (void *vrecv_thread_arg)
struct local_participant_set lps; struct local_participant_set lps;
unsigned num_fixed = 0, num_fixed_uc = 0; unsigned num_fixed = 0, num_fixed_uc = 0;
os_sockWaitsetCtx ctx; os_sockWaitsetCtx ctx;
struct local_deaf_state lds;
lds.state = gv->deaf ? LDSR_DEAF : LDSR_NORMAL;
lds.tnext = now_mt();
local_participant_set_init (&lps, &gv->participant_set_generation); local_participant_set_init (&lps, &gv->participant_set_generation);
if (gv->m_factory->m_connless) if (gv->m_factory->m_connless)
{ {
@ -3583,9 +3464,8 @@ uint32_t recv_thread (void *vrecv_thread_arg)
while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing)) while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing))
{ {
int rebuildws; int rebuildws = 0;
LOG_THREAD_CPUTIME (&gv->logconfig, next_thread_cputime); LOG_THREAD_CPUTIME (&gv->logconfig, next_thread_cputime);
rebuildws = check_and_handle_deafness (gv, &lds, num_fixed_uc);
if (gv->config.many_sockets_mode != MSM_MANY_UNICAST) if (gv->config.many_sockets_mode != MSM_MANY_UNICAST)
{ {
/* no other sockets to check */ /* no other sockets to check */

View file

@ -47,6 +47,24 @@ extern inline void thread_state_awake_to_awake_no_nest (struct thread_state1 *ts
static struct thread_state1 *init_thread_state (const char *tname, const struct ddsi_domaingv *gv, enum thread_state state); static struct thread_state1 *init_thread_state (const char *tname, const struct ddsi_domaingv *gv, enum thread_state state);
static void reap_thread_state (struct thread_state1 *ts1); static void reap_thread_state (struct thread_state1 *ts1);
DDSRT_STATIC_ASSERT(THREAD_STATE_ZERO == 0 &&
THREAD_STATE_ZERO < THREAD_STATE_STOPPED &&
THREAD_STATE_STOPPED < THREAD_STATE_INIT &&
THREAD_STATE_INIT < THREAD_STATE_LAZILY_CREATED &&
THREAD_STATE_INIT < THREAD_STATE_ALIVE);
#if Q_THREAD_DEBUG
#include <execinfo.h>
void thread_vtime_trace (struct thread_state1 *ts1)
{
if (++ts1->stks_idx == Q_THREAD_NSTACKS)
ts1->stks_idx = 0;
const int i = ts1->stks_idx;
ts1->stks_depth[i] = backtrace (ts1->stks[i], Q_THREAD_STACKDEPTH);
}
#endif
static void *ddsrt_malloc_aligned_cacheline (size_t size) static void *ddsrt_malloc_aligned_cacheline (size_t size)
{ {
/* This wastes some space, but we use it only once and it isn't a /* This wastes some space, but we use it only once and it isn't a
@ -84,15 +102,6 @@ void thread_states_init (unsigned maxthreads)
thread_states.nthreads = maxthreads; thread_states.nthreads = maxthreads;
thread_states.ts = ddsrt_malloc_aligned_cacheline (maxthreads * sizeof (*thread_states.ts)); thread_states.ts = ddsrt_malloc_aligned_cacheline (maxthreads * sizeof (*thread_states.ts));
memset (thread_states.ts, 0, maxthreads * sizeof (*thread_states.ts)); memset (thread_states.ts, 0, maxthreads * sizeof (*thread_states.ts));
/* The compiler doesn't realize that ts is large enough. */
DDSRT_WARNING_MSVC_OFF(6386);
for (uint32_t i = 0; i < thread_states.nthreads; i++)
{
thread_states.ts[i].state = THREAD_STATE_ZERO;
ddsrt_atomic_st32 (&thread_states.ts[i].vtime, 0);
memset (thread_states.ts[i].name, 0, sizeof (thread_states.ts[i].name));
}
DDSRT_WARNING_MSVC_ON(6386);
} }
/* This thread should be at the same address as before, or never have had a slot /* This thread should be at the same address as before, or never have had a slot
@ -126,8 +135,18 @@ bool thread_states_fini (void)
ddsrt_mutex_lock (&thread_states.lock); ddsrt_mutex_lock (&thread_states.lock);
for (uint32_t i = 0; i < thread_states.nthreads; i++) for (uint32_t i = 0; i < thread_states.nthreads; i++)
{ {
assert (thread_states.ts[i].state != THREAD_STATE_ALIVE); switch (thread_states.ts[i].state)
others += (thread_states.ts[i].state == THREAD_STATE_LAZILY_CREATED); {
case THREAD_STATE_ZERO:
break;
case THREAD_STATE_LAZILY_CREATED:
others++;
break;
case THREAD_STATE_STOPPED:
case THREAD_STATE_INIT:
case THREAD_STATE_ALIVE:
assert (0);
}
} }
ddsrt_mutex_unlock (&thread_states.lock); ddsrt_mutex_unlock (&thread_states.lock);
if (others == 0) if (others == 0)
@ -143,30 +162,35 @@ bool thread_states_fini (void)
} }
} }
ddsrt_attribute_no_sanitize (("thread"))
static struct thread_state1 *find_thread_state (ddsrt_thread_t tid) static struct thread_state1 *find_thread_state (ddsrt_thread_t tid)
{ {
if (thread_states.ts) { if (thread_states.ts)
{
ddsrt_mutex_lock (&thread_states.lock);
for (uint32_t i = 0; i < thread_states.nthreads; i++) for (uint32_t i = 0; i < thread_states.nthreads; i++)
{ {
if (ddsrt_thread_equal (thread_states.ts[i].tid, tid) && thread_states.ts[i].state != THREAD_STATE_ZERO) if (thread_states.ts[i].state > THREAD_STATE_INIT && ddsrt_thread_equal (thread_states.ts[i].tid, tid))
{
ddsrt_mutex_unlock (&thread_states.lock);
return &thread_states.ts[i]; return &thread_states.ts[i];
}
} }
ddsrt_mutex_unlock (&thread_states.lock);
} }
return NULL; return NULL;
} }
static void cleanup_thread_state (void *data) static void cleanup_thread_state (void *data)
{ {
struct thread_state1 *ts = find_thread_state(ddsrt_thread_self()); struct thread_state1 *ts1 = find_thread_state (ddsrt_thread_self ());
(void)data; (void) data;
if (ts) if (ts1)
{ {
assert(ts->state == THREAD_STATE_LAZILY_CREATED); assert (ts1->state == THREAD_STATE_LAZILY_CREATED);
assert(vtime_asleep_p(ddsrt_atomic_ld32 (&ts->vtime))); assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime)));
reset_thread_state(ts); reap_thread_state (ts1);
} }
ddsrt_fini(); ddsrt_fini ();
} }
static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self) static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self)
@ -178,9 +202,9 @@ static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self)
char name[128]; char name[128];
ddsrt_thread_getname (name, sizeof (name)); ddsrt_thread_getname (name, sizeof (name));
ddsrt_mutex_lock (&thread_states.lock); ddsrt_mutex_lock (&thread_states.lock);
if ((ts1 = init_thread_state (name, NULL, THREAD_STATE_LAZILY_CREATED)) != NULL) { if ((ts1 = init_thread_state (name, NULL, THREAD_STATE_LAZILY_CREATED)) != NULL)
{
ddsrt_init (); ddsrt_init ();
ts1->extTid = self;
ts1->tid = self; ts1->tid = self;
DDS_LOG (DDS_LC_TRACE, "started application thread %s\n", name); DDS_LOG (DDS_LC_TRACE, "started application thread %s\n", name);
ddsrt_thread_cleanup_push (&cleanup_thread_state, NULL); ddsrt_thread_cleanup_push (&cleanup_thread_state, NULL);
@ -199,38 +223,29 @@ struct thread_state1 *lookup_thread_state_real (void)
ts1 = lazy_create_thread_state (self); ts1 = lazy_create_thread_state (self);
tsd_thread_state = ts1; tsd_thread_state = ts1;
} }
assert(ts1 != NULL); assert (ts1 != NULL);
return ts1; return ts1;
} }
struct thread_context {
struct thread_state1 *self;
uint32_t (*f) (void *arg);
void *arg;
};
static uint32_t create_thread_wrapper (void *ptr) static uint32_t create_thread_wrapper (void *ptr)
{ {
uint32_t ret; struct thread_state1 * const ts1 = ptr;
struct thread_context *ctx = ptr; struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ts1->gv);
struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ctx->self->gv);
if (gv) if (gv)
GVTRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ctx->self->name); GVTRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ts1->name);
ctx->self->tid = ddsrt_thread_self (); assert (ts1->state == THREAD_STATE_INIT);
ret = ctx->f (ctx->arg); tsd_thread_state = ts1;
ddsrt_free (ctx); ddsrt_mutex_lock (&thread_states.lock);
ts1->state = THREAD_STATE_ALIVE;
ddsrt_mutex_unlock (&thread_states.lock);
const uint32_t ret = ts1->f (ts1->f_arg);
ddsrt_mutex_lock (&thread_states.lock);
ts1->state = THREAD_STATE_STOPPED;
ddsrt_mutex_unlock (&thread_states.lock);
tsd_thread_state = NULL;
return ret; return ret;
} }
static int find_free_slot (const char *name)
{
for (uint32_t i = 0; i < thread_states.nthreads; i++)
if (thread_states.ts[i].state == THREAD_STATE_ZERO)
return (int) i;
DDS_FATAL ("create_thread: %s: no free slot\n", name ? name : "(anon)");
return -1;
}
const struct config_thread_properties_listelem *lookup_thread_properties (const struct config *config, const char *name) const struct config_thread_properties_listelem *lookup_thread_properties (const struct config *config, const char *name)
{ {
const struct config_thread_properties_listelem *e; const struct config_thread_properties_listelem *e;
@ -242,36 +257,37 @@ const struct config_thread_properties_listelem *lookup_thread_properties (const
static struct thread_state1 *init_thread_state (const char *tname, const struct ddsi_domaingv *gv, enum thread_state state) static struct thread_state1 *init_thread_state (const char *tname, const struct ddsi_domaingv *gv, enum thread_state state)
{ {
int cand; uint32_t i;
struct thread_state1 *ts; for (i = 0; i < thread_states.nthreads; i++)
if (thread_states.ts[i].state == THREAD_STATE_ZERO)
if ((cand = find_free_slot (tname)) < 0) break;
if (i == thread_states.nthreads)
{
DDS_FATAL ("create_thread: %s: no free slot\n", tname ? tname : "(anon)");
return NULL; return NULL;
}
ts = &thread_states.ts[cand]; struct thread_state1 * const ts1 = &thread_states.ts[i];
ddsrt_atomic_stvoidp (&ts->gv, (struct ddsi_domaingv *) gv); assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime)));
assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts->vtime))); memset (ts1, 0, sizeof (*ts1));
(void) ddsrt_strlcpy (ts->name, tname, sizeof (ts->name)); ddsrt_atomic_stvoidp (&ts1->gv, (struct ddsi_domaingv *) gv);
ts->state = state; (void) ddsrt_strlcpy (ts1->name, tname, sizeof (ts1->name));
ts1->state = state;
return ts; return ts1;
} }
static dds_return_t create_thread_int (struct thread_state1 **ts1, const struct ddsi_domaingv *gv, struct config_thread_properties_listelem const * const tprops, const char *name, uint32_t (*f) (void *arg), void *arg) static dds_return_t create_thread_int (struct thread_state1 **ts1_out, const struct ddsi_domaingv *gv, struct config_thread_properties_listelem const * const tprops, const char *name, uint32_t (*f) (void *arg), void *arg)
{ {
ddsrt_threadattr_t tattr; ddsrt_threadattr_t tattr;
ddsrt_thread_t tid; struct thread_state1 *ts1;
struct thread_context *ctxt;
ctxt = ddsrt_malloc (sizeof (*ctxt));
ddsrt_mutex_lock (&thread_states.lock); ddsrt_mutex_lock (&thread_states.lock);
*ts1 = init_thread_state (name, gv, THREAD_STATE_ALIVE); ts1 = *ts1_out = init_thread_state (name, gv, THREAD_STATE_INIT);
if (*ts1 == NULL) if (ts1 == NULL)
goto fatal; goto fatal;
ctxt->self = *ts1; ts1->f = f;
ctxt->f = f; ts1->f_arg = arg;
ctxt->arg = arg;
ddsrt_threadattr_init (&tattr); ddsrt_threadattr_init (&tattr);
if (tprops != NULL) if (tprops != NULL)
{ {
@ -286,19 +302,17 @@ static dds_return_t create_thread_int (struct thread_state1 **ts1, const struct
GVTRACE ("create_thread: %s: class %d priority %"PRId32" stack %"PRIu32"\n", name, (int) tattr.schedClass, tattr.schedPriority, tattr.stackSize); GVTRACE ("create_thread: %s: class %d priority %"PRId32" stack %"PRIu32"\n", name, (int) tattr.schedClass, tattr.schedPriority, tattr.stackSize);
} }
if (ddsrt_thread_create (&tid, name, &tattr, &create_thread_wrapper, ctxt) != DDS_RETCODE_OK) if (ddsrt_thread_create (&ts1->tid, name, &tattr, &create_thread_wrapper, ts1) != DDS_RETCODE_OK)
{ {
(*ts1)->state = THREAD_STATE_ZERO; ts1->state = THREAD_STATE_ZERO;
DDS_FATAL ("create_thread: %s: ddsrt_thread_create failed\n", name); DDS_FATAL ("create_thread: %s: ddsrt_thread_create failed\n", name);
goto fatal; goto fatal;
} }
(*ts1)->extTid = tid; /* overwrite the temporary value with the correct external one */
ddsrt_mutex_unlock (&thread_states.lock); ddsrt_mutex_unlock (&thread_states.lock);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
fatal: fatal:
ddsrt_mutex_unlock (&thread_states.lock); ddsrt_mutex_unlock (&thread_states.lock);
ddsrt_free (ctxt); *ts1_out = NULL;
*ts1 = NULL;
abort (); abort ();
return DDS_RETCODE_ERROR; return DDS_RETCODE_ERROR;
} }
@ -317,34 +331,53 @@ dds_return_t create_thread (struct thread_state1 **ts1, const struct ddsi_domain
static void reap_thread_state (struct thread_state1 *ts1) static void reap_thread_state (struct thread_state1 *ts1)
{ {
ddsrt_mutex_lock (&thread_states.lock); ddsrt_mutex_lock (&thread_states.lock);
ts1->state = THREAD_STATE_ZERO; switch (ts1->state)
{
case THREAD_STATE_INIT:
case THREAD_STATE_STOPPED:
case THREAD_STATE_LAZILY_CREATED:
ts1->state = THREAD_STATE_ZERO;
break;
case THREAD_STATE_ZERO:
case THREAD_STATE_ALIVE:
assert (0);
}
ddsrt_mutex_unlock (&thread_states.lock); ddsrt_mutex_unlock (&thread_states.lock);
} }
dds_return_t join_thread (struct thread_state1 *ts1) dds_return_t join_thread (struct thread_state1 *ts1)
{ {
dds_return_t ret; dds_return_t ret;
assert (ts1->state == THREAD_STATE_ALIVE); ddsrt_mutex_lock (&thread_states.lock);
ret = ddsrt_thread_join (ts1->extTid, NULL); switch (ts1->state)
{
case THREAD_STATE_INIT:
case THREAD_STATE_STOPPED:
case THREAD_STATE_ALIVE:
break;
case THREAD_STATE_ZERO:
case THREAD_STATE_LAZILY_CREATED:
assert (0);
}
ddsrt_mutex_unlock (&thread_states.lock);
ret = ddsrt_thread_join (ts1->tid, NULL);
assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime))); assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime)));
reap_thread_state (ts1); reap_thread_state (ts1);
return ret; return ret;
} }
void reset_thread_state (struct thread_state1 *ts1)
{
if (ts1)
reap_thread_state (ts1);
}
void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv) void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv)
{ {
for (uint32_t i = 0; i < thread_states.nthreads; i++) for (uint32_t i = 0; i < thread_states.nthreads; i++)
{ {
if (thread_states.ts[i].state != THREAD_STATE_ZERO && struct thread_state1 * const ts1 = &thread_states.ts[i];
(gv == NULL || ddsrt_atomic_ldvoidp (&thread_states.ts[i].gv) == gv)) if (ts1->state > THREAD_STATE_INIT && (gv == NULL || ddsrt_atomic_ldvoidp (&ts1->gv) == gv))
{ {
log_stacktrace (logcfg, thread_states.ts[i].name, thread_states.ts[i].tid); /* There's a race condition here that may cause us to call log_stacktrace with an invalid
thread id (or even with a thread id mapping to a newly created thread that isn't really
relevant in this context!) but this is an optional debug feature, so it's not worth the
bother to avoid it. */
log_stacktrace (logcfg, ts1->name, ts1->tid);
} }
} }
} }

View file

@ -1,185 +0,0 @@
/*
* 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 "dds/ddsrt/time.h"
#include "dds/ddsi/q_time.h"
nn_wctime_t now (void)
{
/* This function uses the wall clock.
* This clock is not affected by time spent in suspend mode.
* This clock is affected when the real time system clock jumps
* forwards/backwards */
nn_wctime_t t;
t.v = dds_time();
return t;
}
nn_mtime_t now_mt (void)
{
/* This function uses the monotonic clock.
* This clock stops while the system is in suspend mode.
* This clock is not affected by any jumps of the realtime clock. */
nn_mtime_t t;
t.v = ddsrt_time_monotonic();
return t;
}
nn_etime_t now_et (void)
{
/* This function uses the elapsed clock.
* This clock is not affected by any jumps of the realtime clock.
* This clock does NOT stop when the system is in suspend mode.
* This clock stops when the system is shut down, and starts when the system is restarted.
* When restarted, there are no assumptions about the initial value of clock. */
nn_etime_t t;
t.v = ddsrt_time_elapsed();
return t;
}
static void time_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, int64_t t)
{
*sec = (int32_t) (t / T_SECOND);
*usec = (int32_t) (t % T_SECOND) / 1000;
}
void mtime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, nn_mtime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}
void wctime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, nn_wctime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}
void etime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, nn_etime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}
nn_mtime_t mtime_round_up (nn_mtime_t t, int64_t round)
{
/* This function rounds up t to the nearest next multiple of round.
t is nanoseconds, round is milliseconds. Avoid functions from
maths libraries to keep code portable */
assert (t.v >= 0 && round >= 0);
if (round == 0 || t.v == T_NEVER)
{
return t;
}
else
{
int64_t remainder = t.v % round;
if (remainder == 0)
{
return t;
}
else
{
nn_mtime_t u;
u.v = t.v + round - remainder;
return u;
}
}
}
static int64_t add_duration_to_time (int64_t t, int64_t d)
{
uint64_t sum;
assert (t >= 0 && d >= 0);
sum = (uint64_t)t + (uint64_t)d;
return sum >= T_NEVER ? T_NEVER : (int64_t)sum;
}
nn_mtime_t add_duration_to_mtime (nn_mtime_t t, int64_t d)
{
/* assumed T_NEVER <=> MAX_INT64 */
nn_mtime_t u;
u.v = add_duration_to_time (t.v, d);
return u;
}
nn_wctime_t add_duration_to_wctime (nn_wctime_t t, int64_t d)
{
/* assumed T_NEVER <=> MAX_INT64 */
nn_wctime_t u;
u.v = add_duration_to_time (t.v, d);
return u;
}
nn_etime_t add_duration_to_etime (nn_etime_t t, int64_t d)
{
/* assumed T_NEVER <=> MAX_INT64 */
nn_etime_t u;
u.v = add_duration_to_time (t.v, d);
return u;
}
int valid_ddsi_timestamp (ddsi_time_t t)
{
return t.seconds != DDSI_TIME_INVALID.seconds && t.fraction != DDSI_TIME_INVALID.fraction;
}
static ddsi_time_t nn_to_ddsi_time (int64_t t)
{
if (t == T_NEVER)
return DDSI_TIME_INFINITE;
else
{
/* ceiling(ns * 2^32/10^9) -- can't change the ceiling to round-to-nearest
because that would break backwards compatibility, but round-to-nearest
of the inverse is correctly rounded anyway, so it shouldn't ever matter. */
ddsi_time_t x;
int ns = (int) (t % T_SECOND);
x.seconds = (int) (t / T_SECOND);
x.fraction = (unsigned) (((T_SECOND-1) + ((int64_t) ns << 32)) / T_SECOND);
return x;
}
}
ddsi_time_t nn_wctime_to_ddsi_time (nn_wctime_t t)
{
return nn_to_ddsi_time (t.v);
}
static int64_t nn_from_ddsi_time (ddsi_time_t x)
{
if (x.seconds == DDSI_TIME_INFINITE.seconds && x.fraction == DDSI_TIME_INFINITE.fraction)
return T_NEVER;
else
{
/* Round-to-nearest conversion of DDSI time fraction to nanoseconds */
int ns = (int) (((int64_t) 2147483648u + (int64_t) x.fraction * T_SECOND) >> 32);
return x.seconds * (int64_t) T_SECOND + ns;
}
}
nn_wctime_t nn_wctime_from_ddsi_time (ddsi_time_t x)
{
nn_wctime_t t;
t.v = nn_from_ddsi_time (x);
return t;
}
ddsi_duration_t nn_to_ddsi_duration (int64_t x)
{
return nn_to_ddsi_time (x);
}
int64_t nn_from_ddsi_duration (ddsi_duration_t x)
{
return nn_from_ddsi_time (x);
}

View file

@ -26,7 +26,6 @@
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
#include "dds/ddsi/q_xevent.h" #include "dds/ddsi/q_xevent.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_transmit.h" #include "dds/ddsi/q_transmit.h"
@ -61,12 +60,12 @@ void writer_hbcontrol_init (struct hbcontrol *hbc)
hbc->t_of_last_write.v = 0; hbc->t_of_last_write.v = 0;
hbc->t_of_last_hb.v = 0; hbc->t_of_last_hb.v = 0;
hbc->t_of_last_ackhb.v = 0; hbc->t_of_last_ackhb.v = 0;
hbc->tsched.v = T_NEVER; hbc->tsched = DDSRT_MTIME_NEVER;
hbc->hbs_since_last_write = 0; hbc->hbs_since_last_write = 0;
hbc->last_packetid = 0; hbc->last_packetid = 0;
} }
static void writer_hbcontrol_note_hb (struct writer *wr, nn_mtime_t tnow, int ansreq) static void writer_hbcontrol_note_hb (struct writer *wr, ddsrt_mtime_t tnow, int ansreq)
{ {
struct hbcontrol * const hbc = &wr->hbcontrol; struct hbcontrol * const hbc = &wr->hbcontrol;
@ -80,7 +79,7 @@ static void writer_hbcontrol_note_hb (struct writer *wr, nn_mtime_t tnow, int an
hbc->hbs_since_last_write++; hbc->hbs_since_last_write++;
} }
int64_t writer_hbcontrol_intv (const struct writer *wr, const struct whc_state *whcst, UNUSED_ARG (nn_mtime_t tnow)) int64_t writer_hbcontrol_intv (const struct writer *wr, const struct whc_state *whcst, UNUSED_ARG (ddsrt_mtime_t tnow))
{ {
struct ddsi_domaingv const * const gv = wr->e.gv; struct ddsi_domaingv const * const gv = wr->e.gv;
struct hbcontrol const * const hbc = &wr->hbcontrol; struct hbcontrol const * const hbc = &wr->hbcontrol;
@ -106,11 +105,11 @@ int64_t writer_hbcontrol_intv (const struct writer *wr, const struct whc_state *
return ret; return ret;
} }
void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow) void writer_hbcontrol_note_asyncwrite (struct writer *wr, ddsrt_mtime_t tnow)
{ {
struct ddsi_domaingv const * const gv = wr->e.gv; struct ddsi_domaingv const * const gv = wr->e.gv;
struct hbcontrol * const hbc = &wr->hbcontrol; struct hbcontrol * const hbc = &wr->hbcontrol;
nn_mtime_t tnext; ddsrt_mtime_t tnext;
/* Reset number of heartbeats since last write: that means the /* Reset number of heartbeats since last write: that means the
heartbeat rate will go back up to the default */ heartbeat rate will go back up to the default */
@ -129,13 +128,13 @@ void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow)
} }
} }
int writer_hbcontrol_must_send (const struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow /* monotonic */) int writer_hbcontrol_must_send (const struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow /* monotonic */)
{ {
struct hbcontrol const * const hbc = &wr->hbcontrol; struct hbcontrol const * const hbc = &wr->hbcontrol;
return (tnow.v >= hbc->t_of_last_hb.v + writer_hbcontrol_intv (wr, whcst, tnow)); return (tnow.v >= hbc->t_of_last_hb.v + writer_hbcontrol_intv (wr, whcst, tnow));
} }
struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow, int hbansreq, int issync) struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow, int hbansreq, int issync)
{ {
struct ddsi_domaingv const * const gv = wr->e.gv; struct ddsi_domaingv const * const gv = wr->e.gv;
struct nn_xmsg *msg; struct nn_xmsg *msg;
@ -234,7 +233,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
return msg; return msg;
} }
static int writer_hbcontrol_ack_required_generic (const struct writer *wr, const struct whc_state *whcst, nn_mtime_t tlast, nn_mtime_t tnow, int piggyback) static int writer_hbcontrol_ack_required_generic (const struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tlast, ddsrt_mtime_t tnow, int piggyback)
{ {
struct ddsi_domaingv const * const gv = wr->e.gv; struct ddsi_domaingv const * const gv = wr->e.gv;
struct hbcontrol const * const hbc = &wr->hbcontrol; struct hbcontrol const * const hbc = &wr->hbcontrol;
@ -270,17 +269,17 @@ static int writer_hbcontrol_ack_required_generic (const struct writer *wr, const
return 0; return 0;
} }
int writer_hbcontrol_ack_required (const struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow) int writer_hbcontrol_ack_required (const struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow)
{ {
struct hbcontrol const * const hbc = &wr->hbcontrol; struct hbcontrol const * const hbc = &wr->hbcontrol;
return writer_hbcontrol_ack_required_generic (wr, whcst, hbc->t_of_last_write, tnow, 0); return writer_hbcontrol_ack_required_generic (wr, whcst, hbc->t_of_last_write, tnow, 0);
} }
struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_state *whcst, nn_mtime_t tnow, uint32_t packetid, int *hbansreq) struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow, uint32_t packetid, int *hbansreq)
{ {
struct hbcontrol * const hbc = &wr->hbcontrol; struct hbcontrol * const hbc = &wr->hbcontrol;
uint32_t last_packetid; uint32_t last_packetid;
nn_mtime_t tlast; ddsrt_mtime_t tlast;
struct nn_xmsg *msg; struct nn_xmsg *msg;
tlast = hbc->t_of_last_write; tlast = hbc->t_of_last_write;
@ -316,7 +315,7 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_
ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n", ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n",
PGUID (wr->e.guid), PGUID (wr->e.guid),
*hbansreq ? "" : " final", *hbansreq ? "" : " final",
(hbc->tsched.v == T_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9, (hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9,
ddsrt_avl_is_empty (&wr->readers) ? -1 : root_rdmatch (wr)->min_seq, ddsrt_avl_is_empty (&wr->readers) ? -1 : root_rdmatch (wr)->min_seq,
ddsrt_avl_is_empty (&wr->readers) || root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!", ddsrt_avl_is_empty (&wr->readers) || root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!",
whcst->max_seq, writer_read_seq_xmit(wr)); whcst->max_seq, writer_read_seq_xmit(wr));
@ -383,7 +382,7 @@ void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_sta
{ {
/* If configured to measure heartbeat-to-ack latency, we must add /* If configured to measure heartbeat-to-ack latency, we must add
a timestamp. No big deal if it fails. */ a timestamp. No big deal if it fails. */
nn_xmsg_add_timestamp (msg, now ()); nn_xmsg_add_timestamp (msg, ddsrt_time_wallclock ());
} }
hb = nn_xmsg_append (msg, &sm_marker, sizeof (Heartbeat_t)); hb = nn_xmsg_append (msg, &sm_marker, sizeof (Heartbeat_t));
@ -757,9 +756,9 @@ dds_return_t write_hb_liveliness (struct ddsi_domaingv * const gv, struct ddsi_g
} }
if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT && ((lease = ddsrt_atomic_ldvoidp (&wr->c.pp->minl_man)) != NULL)) if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT && ((lease = ddsrt_atomic_ldvoidp (&wr->c.pp->minl_man)) != NULL))
lease_renew (lease, now_et()); lease_renew (lease, ddsrt_time_elapsed());
else if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC && wr->lease != NULL) else if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC && wr->lease != NULL)
lease_renew (wr->lease, now_et()); lease_renew (wr->lease, ddsrt_time_elapsed());
if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL) if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
return DDS_RETCODE_OUT_OF_RESOURCES; return DDS_RETCODE_OUT_OF_RESOURCES;
@ -990,13 +989,13 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct ddsi_pli
if ((wr->reliable && have_reliable_subs (wr)) || wr_deadline || wr->handle_as_transient_local) if ((wr->reliable && have_reliable_subs (wr)) || wr_deadline || wr->handle_as_transient_local)
{ {
nn_mtime_t exp = NN_MTIME_NEVER; ddsrt_mtime_t exp = DDSRT_MTIME_NEVER;
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
/* Don't set expiry for samples with flags unregister or dispose, because these are required /* Don't set expiry for samples with flags unregister or dispose, because these are required
* for sample lifecycle and should always be delivered to the reader so that is can clean up * for sample lifecycle and should always be delivered to the reader so that is can clean up
* its history cache. */ * its history cache. */
if (wr->xqos->lifespan.duration != DDS_INFINITY && (serdata->statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0) if (wr->xqos->lifespan.duration != DDS_INFINITY && (serdata->statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0)
exp = add_duration_to_mtime(serdata->twrite, wr->xqos->lifespan.duration); exp = ddsrt_mtime_add_duration(serdata->twrite, wr->xqos->lifespan.duration);
#endif #endif
res = ((insres = whc_insert (wr->whc, writer_max_drop_seq (wr), seq, exp, plist, serdata, tk)) < 0) ? insres : 1; res = ((insres = whc_insert (wr->whc, writer_max_drop_seq (wr), seq, exp, plist, serdata, tk)) < 0) ? insres : 1;
@ -1071,8 +1070,8 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
writer. */ writer. */
struct ddsi_domaingv const * const gv = wr->e.gv; struct ddsi_domaingv const * const gv = wr->e.gv;
dds_return_t result = DDS_RETCODE_OK; dds_return_t result = DDS_RETCODE_OK;
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
const nn_mtime_t abstimeout = add_duration_to_mtime (tnow, wr->xqos->reliability.max_blocking_time); const ddsrt_mtime_t abstimeout = ddsrt_mtime_add_duration (tnow, wr->xqos->reliability.max_blocking_time);
struct whc_state whcst; struct whc_state whcst;
whc_get_state (wr->whc, &whcst); whc_get_state (wr->whc, &whcst);
@ -1108,7 +1107,7 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing) && !writer_may_continue (wr, &whcst)) while (ddsrt_atomic_ld32 (&gv->rtps_keepgoing) && !writer_may_continue (wr, &whcst))
{ {
int64_t reltimeout; int64_t reltimeout;
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
reltimeout = abstimeout.v - tnow.v; reltimeout = abstimeout.v - tnow.v;
result = DDS_RETCODE_TIMEOUT; result = DDS_RETCODE_TIMEOUT;
if (reltimeout > 0) if (reltimeout > 0)
@ -1143,8 +1142,8 @@ static int maybe_grow_whc (struct writer *wr)
struct ddsi_domaingv const * const gv = wr->e.gv; struct ddsi_domaingv const * const gv = wr->e.gv;
if (!wr->retransmitting && gv->config.whc_adaptive && wr->whc_high < gv->config.whc_highwater_mark) if (!wr->retransmitting && gv->config.whc_adaptive && wr->whc_high < gv->config.whc_highwater_mark)
{ {
nn_etime_t tnow = now_et(); ddsrt_etime_t tnow = ddsrt_time_elapsed();
nn_etime_t tgrow = add_duration_to_etime (wr->t_whc_high_upd, 10 * T_MILLISECOND); ddsrt_etime_t tgrow = ddsrt_etime_add_duration (wr->t_whc_high_upd, DDS_MSECS (10));
if (tnow.v >= tgrow.v) if (tnow.v >= tgrow.v)
{ {
uint32_t m = (gv->config.whc_highwater_mark - wr->whc_high) / 32; uint32_t m = (gv->config.whc_highwater_mark - wr->whc_high) / 32;
@ -1160,15 +1159,15 @@ int write_sample_p2p_wrlock_held(struct writer *wr, seqno_t seq, struct ddsi_pli
{ {
struct ddsi_domaingv * const gv = wr->e.gv; struct ddsi_domaingv * const gv = wr->e.gv;
int r = 0; int r = 0;
nn_mtime_t tnow; ddsrt_mtime_t tnow;
int rexmit = 1; int rexmit = 1;
struct wr_prd_match *wprd = NULL; struct wr_prd_match *wprd = NULL;
seqno_t gseq; seqno_t gseq;
struct nn_xmsg *gap = NULL; struct nn_xmsg *gap = NULL;
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
serdata->twrite = tnow; serdata->twrite = tnow;
serdata->timestamp = now(); serdata->timestamp = ddsrt_time_wallclock ();
if (prd->filter) if (prd->filter)
@ -1225,7 +1224,7 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
struct ddsi_domaingv const * const gv = wr->e.gv; struct ddsi_domaingv const * const gv = wr->e.gv;
int r; int r;
seqno_t seq; seqno_t seq;
nn_mtime_t tnow; ddsrt_mtime_t tnow;
struct lease *lease; struct lease *lease;
/* If GC not allowed, we must be sure to never block when writing. That is only the case for (true, aggressive) KEEP_LAST writers, and also only if there is no limit to how much unacknowledged data the WHC may contain. */ /* If GC not allowed, we must be sure to never block when writing. That is only the case for (true, aggressive) KEEP_LAST writers, and also only if there is no limit to how much unacknowledged data the WHC may contain. */
@ -1249,9 +1248,9 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
} }
if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT && ((lease = ddsrt_atomic_ldvoidp (&wr->c.pp->minl_man)) != NULL)) if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT && ((lease = ddsrt_atomic_ldvoidp (&wr->c.pp->minl_man)) != NULL))
lease_renew (lease, now_et()); lease_renew (lease, ddsrt_time_elapsed());
else if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC && wr->lease != NULL) else if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC && wr->lease != NULL)
lease_renew (wr->lease, now_et()); lease_renew (wr->lease, ddsrt_time_elapsed());
ddsrt_mutex_lock (&wr->e.lock); ddsrt_mutex_lock (&wr->e.lock);
@ -1298,7 +1297,7 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
} }
/* Always use the current monotonic time */ /* Always use the current monotonic time */
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
serdata->twrite = tnow; serdata->twrite = tnow;
seq = ++wr->seq; seq = ++wr->seq;

View file

@ -10,7 +10,6 @@
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/ */
#include "dds/ddsi/q_rtps.h" #include "dds/ddsi/q_rtps.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_whc.h" #include "dds/ddsi/q_whc.h"
extern inline seqno_t whc_next_seq (const struct whc *whc, seqno_t seq); extern inline seqno_t whc_next_seq (const struct whc *whc, seqno_t seq);
@ -21,7 +20,7 @@ extern inline void whc_return_sample (struct whc *whc, struct whc_borrowed_sampl
extern inline void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *it); extern inline void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *it);
extern inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_borrowed_sample *sample); extern inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_borrowed_sample *sample);
extern inline void whc_free (struct whc *whc); extern inline void whc_free (struct whc *whc);
extern int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); extern int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, ddsrt_mtime_t exp, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
extern unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st); extern unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
extern unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); extern unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
extern void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); extern void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);

View file

@ -19,7 +19,6 @@
#include "dds/ddsrt/avl.h" #include "dds/ddsrt/avl.h"
#include "dds/ddsrt/fibheap.h" #include "dds/ddsrt/fibheap.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_addrset.h" #include "dds/ddsi/q_addrset.h"
#include "dds/ddsi/q_xmsg.h" #include "dds/ddsi/q_xmsg.h"
@ -67,7 +66,7 @@ struct xevent
{ {
ddsrt_fibheap_node_t heapnode; ddsrt_fibheap_node_t heapnode;
struct xeventq *evq; struct xeventq *evq;
nn_mtime_t tsched; ddsrt_mtime_t tsched;
enum xeventkind kind; enum xeventkind kind;
union { union {
struct { struct {
@ -93,7 +92,7 @@ struct xevent
ddsi_guid_t guid; ddsi_guid_t guid;
} delete_writer; } delete_writer;
struct { struct {
void (*cb) (struct xevent *ev, void *arg, nn_mtime_t tnow); void (*cb) (struct xevent *ev, void *arg, ddsrt_mtime_t tnow);
void *arg; void *arg;
bool executing; bool executing;
} callback; } callback;
@ -158,7 +157,7 @@ struct xeventq {
}; };
static uint32_t xevent_thread (struct xeventq *xevq); static uint32_t xevent_thread (struct xeventq *xevq);
static nn_mtime_t earliest_in_xeventq (struct xeventq *evq); static ddsrt_mtime_t earliest_in_xeventq (struct xeventq *evq);
static int msg_xevents_cmp (const void *a, const void *b); static int msg_xevents_cmp (const void *a, const void *b);
static int compare_xevent_tsched (const void *va, const void *vb); static int compare_xevent_tsched (const void *va, const void *vb);
static void handle_nontimed_xevent (struct xevent_nt *xev, struct nn_xpack *xp); static void handle_nontimed_xevent (struct xevent_nt *xev, struct nn_xpack *xp);
@ -327,7 +326,7 @@ void delete_xevent (struct xevent *ev)
/* Can delete it only once, no matter how we implement it internally */ /* Can delete it only once, no matter how we implement it internally */
assert (ev->tsched.v != TSCHED_DELETE); assert (ev->tsched.v != TSCHED_DELETE);
assert (TSCHED_DELETE < ev->tsched.v); assert (TSCHED_DELETE < ev->tsched.v);
if (ev->tsched.v != T_NEVER) if (ev->tsched.v != DDS_NEVER)
{ {
ev->tsched.v = TSCHED_DELETE; ev->tsched.v = TSCHED_DELETE;
ddsrt_fibheap_decrease_key (&evq_xevents_fhdef, &evq->xevents, ev); ddsrt_fibheap_decrease_key (&evq_xevents_fhdef, &evq->xevents, ev);
@ -349,13 +348,13 @@ void delete_xevent_callback (struct xevent *ev)
assert (ev->kind == XEVK_CALLBACK); assert (ev->kind == XEVK_CALLBACK);
ddsrt_mutex_lock (&evq->lock); ddsrt_mutex_lock (&evq->lock);
/* wait until neither scheduled nor executing; loop in case the callback reschedules the event */ /* wait until neither scheduled nor executing; loop in case the callback reschedules the event */
while (ev->tsched.v != T_NEVER || ev->u.callback.executing) while (ev->tsched.v != DDS_NEVER || ev->u.callback.executing)
{ {
if (ev->tsched.v != T_NEVER) if (ev->tsched.v != DDS_NEVER)
{ {
assert (ev->tsched.v != TSCHED_DELETE); assert (ev->tsched.v != TSCHED_DELETE);
ddsrt_fibheap_delete (&evq_xevents_fhdef, &evq->xevents, ev); ddsrt_fibheap_delete (&evq_xevents_fhdef, &evq->xevents, ev);
ev->tsched.v = T_NEVER; ev->tsched.v = DDS_NEVER;
} }
if (ev->u.callback.executing) if (ev->u.callback.executing)
{ {
@ -366,11 +365,11 @@ void delete_xevent_callback (struct xevent *ev)
free_xevent (evq, ev); free_xevent (evq, ev);
} }
int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched) int resched_xevent_if_earlier (struct xevent *ev, ddsrt_mtime_t tsched)
{ {
struct xeventq *evq = ev->evq; struct xeventq *evq = ev->evq;
int is_resched; int is_resched;
if (tsched.v == T_NEVER) if (tsched.v == DDS_NEVER)
return 0; return 0;
ddsrt_mutex_lock (&evq->lock); ddsrt_mutex_lock (&evq->lock);
/* If you want to delete it, you to say so by calling the right /* If you want to delete it, you to say so by calling the right
@ -382,8 +381,8 @@ int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched)
is_resched = 0; is_resched = 0;
else else
{ {
nn_mtime_t tbefore = earliest_in_xeventq (evq); ddsrt_mtime_t tbefore = earliest_in_xeventq (evq);
if (ev->tsched.v != T_NEVER) if (ev->tsched.v != DDS_NEVER)
{ {
ev->tsched = tsched; ev->tsched = tsched;
ddsrt_fibheap_decrease_key (&evq_xevents_fhdef, &evq->xevents, ev); ddsrt_fibheap_decrease_key (&evq_xevents_fhdef, &evq->xevents, ev);
@ -401,7 +400,25 @@ int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched)
return is_resched; return is_resched;
} }
static struct xevent *qxev_common (struct xeventq *evq, nn_mtime_t tsched, enum xeventkind kind) static ddsrt_mtime_t mtime_round_up (ddsrt_mtime_t t, int64_t round)
{
/* This function rounds up t to the nearest next multiple of round.
t is nanoseconds, round is milliseconds. Avoid functions from
maths libraries to keep code portable */
assert (t.v >= 0 && round >= 0);
if (round == 0 || t.v == DDS_INFINITY)
return t;
else
{
int64_t remainder = t.v % round;
if (remainder == 0)
return t;
else
return (ddsrt_mtime_t) { t.v + round - remainder };
}
}
static struct xevent *qxev_common (struct xeventq *evq, ddsrt_mtime_t tsched, enum xeventkind kind)
{ {
/* qxev_common is the route by which all timed xevents are /* qxev_common is the route by which all timed xevents are
created. */ created. */
@ -411,9 +428,9 @@ static struct xevent *qxev_common (struct xeventq *evq, nn_mtime_t tsched, enum
ASSERT_MUTEX_HELD (&evq->lock); ASSERT_MUTEX_HELD (&evq->lock);
/* round up the scheduled time if required */ /* round up the scheduled time if required */
if (tsched.v != T_NEVER && evq->gv->config.schedule_time_rounding != 0) if (tsched.v != DDS_NEVER && evq->gv->config.schedule_time_rounding != 0)
{ {
nn_mtime_t tsched_rounded = mtime_round_up (tsched, evq->gv->config.schedule_time_rounding); ddsrt_mtime_t tsched_rounded = mtime_round_up (tsched, evq->gv->config.schedule_time_rounding);
EVQTRACE ("rounded event scheduled for %"PRId64" to %"PRId64"\n", tsched.v, tsched_rounded.v); EVQTRACE ("rounded event scheduled for %"PRId64" to %"PRId64"\n", tsched.v, tsched_rounded.v);
tsched = tsched_rounded; tsched = tsched_rounded;
} }
@ -433,11 +450,11 @@ static struct xevent_nt *qxev_common_nt (struct xeventq *evq, enum xeventkind_nt
return ev; return ev;
} }
static nn_mtime_t earliest_in_xeventq (struct xeventq *evq) static ddsrt_mtime_t earliest_in_xeventq (struct xeventq *evq)
{ {
struct xevent *min; struct xevent *min;
ASSERT_MUTEX_HELD (&evq->lock); ASSERT_MUTEX_HELD (&evq->lock);
return ((min = ddsrt_fibheap_min (&evq_xevents_fhdef, &evq->xevents)) != NULL) ? min->tsched : NN_MTIME_NEVER; return ((min = ddsrt_fibheap_min (&evq_xevents_fhdef, &evq->xevents)) != NULL) ? min->tsched : DDSRT_MTIME_NEVER;
} }
static void qxev_insert (struct xevent *ev) static void qxev_insert (struct xevent *ev)
@ -446,9 +463,9 @@ static void qxev_insert (struct xevent *ev)
event administration. */ event administration. */
struct xeventq *evq = ev->evq; struct xeventq *evq = ev->evq;
ASSERT_MUTEX_HELD (&evq->lock); ASSERT_MUTEX_HELD (&evq->lock);
if (ev->tsched.v != T_NEVER) if (ev->tsched.v != DDS_NEVER)
{ {
nn_mtime_t tbefore = earliest_in_xeventq (evq); ddsrt_mtime_t tbefore = earliest_in_xeventq (evq);
ddsrt_fibheap_insert (&evq_xevents_fhdef, &evq->xevents, ev); ddsrt_fibheap_insert (&evq_xevents_fhdef, &evq->xevents, ev);
if (ev->tsched.v < tbefore.v) if (ev->tsched.v < tbefore.v)
ddsrt_cond_broadcast (&evq->cond); ddsrt_cond_broadcast (&evq->cond);
@ -591,10 +608,10 @@ static void handle_xevk_entityid (struct nn_xpack *xp, struct xevent_nt *ev)
} }
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
static void send_heartbeat_to_all_readers(struct nn_xpack *xp, struct xevent *ev, struct writer *wr, nn_mtime_t tnow) static void send_heartbeat_to_all_readers (struct nn_xpack *xp, struct xevent *ev, struct writer *wr, ddsrt_mtime_t tnow)
{ {
struct whc_state whcst; struct whc_state whcst;
nn_mtime_t t_next; ddsrt_mtime_t t_next;
unsigned count = 0; unsigned count = 0;
ddsrt_mutex_lock (&wr->e.lock); ddsrt_mutex_lock (&wr->e.lock);
@ -602,15 +619,15 @@ static void send_heartbeat_to_all_readers(struct nn_xpack *xp, struct xevent *ev
whc_get_state(wr->whc, &whcst); whc_get_state(wr->whc, &whcst);
if (!writer_must_have_hb_scheduled (wr, &whcst)) if (!writer_must_have_hb_scheduled (wr, &whcst))
t_next.v = T_NEVER; t_next = DDSRT_MTIME_NEVER;
else if (!writer_hbcontrol_must_send (wr, &whcst, tnow)) else if (!writer_hbcontrol_must_send (wr, &whcst, tnow))
t_next.v = tnow.v + writer_hbcontrol_intv (wr, &whcst, tnow); t_next = ddsrt_mtime_add_duration (tnow, writer_hbcontrol_intv (wr, &whcst, tnow));
else else
{ {
struct wr_prd_match *m; struct wr_prd_match *m;
struct ddsi_guid last_guid = { .prefix = {.u = {0,0,0}}, .entityid = {0} }; struct ddsi_guid last_guid = { .prefix = {.u = {0,0,0}}, .entityid = {0} };
const int hbansreq = writer_hbcontrol_ack_required (wr, &whcst, tnow); const int hbansreq = writer_hbcontrol_ack_required (wr, &whcst, tnow);
t_next.v = tnow.v + writer_hbcontrol_intv (wr, &whcst, tnow); t_next = ddsrt_mtime_add_duration (tnow, writer_hbcontrol_intv (wr, &whcst, tnow));
while ((m = ddsrt_avl_lookup_succ (&wr_readers_treedef, &wr->readers, &last_guid)) != NULL) while ((m = ddsrt_avl_lookup_succ (&wr_readers_treedef, &wr->readers, &last_guid)) != NULL)
{ {
@ -652,7 +669,7 @@ static void send_heartbeat_to_all_readers(struct nn_xpack *xp, struct xevent *ev
(void)resched_xevent_if_earlier (ev, t_next); (void)resched_xevent_if_earlier (ev, t_next);
ETRACE (wr, "heartbeat(wr "PGUIDFMT") suppressed, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n", ETRACE (wr, "heartbeat(wr "PGUIDFMT") suppressed, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n",
PGUID (wr->e.guid), PGUID (wr->e.guid),
(t_next.v == T_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
ddsrt_avl_is_empty (&wr->readers) ? (int64_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root (&wr_readers_treedef, &wr->readers))->min_seq, ddsrt_avl_is_empty (&wr->readers) ? (int64_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root (&wr_readers_treedef, &wr->readers))->min_seq,
ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!", ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!",
whcst.max_seq, whcst.max_seq,
@ -665,12 +682,12 @@ static void send_heartbeat_to_all_readers(struct nn_xpack *xp, struct xevent *ev
#endif #endif
static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mtime_t tnow /* monotonic */) static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt_mtime_t tnow)
{ {
struct ddsi_domaingv const * const gv = ev->evq->gv; struct ddsi_domaingv const * const gv = ev->evq->gv;
struct nn_xmsg *msg; struct nn_xmsg *msg;
struct writer *wr; struct writer *wr;
nn_mtime_t t_next; ddsrt_mtime_t t_next;
int hbansreq = 0; int hbansreq = 0;
struct whc_state whcst; struct whc_state whcst;
@ -695,7 +712,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt
{ {
hbansreq = 1; /* just for trace */ hbansreq = 1; /* just for trace */
msg = NULL; /* Need not send it now, and no need to schedule it for the future */ msg = NULL; /* Need not send it now, and no need to schedule it for the future */
t_next.v = T_NEVER; t_next.v = DDS_NEVER;
} }
else if (!writer_hbcontrol_must_send (wr, &whcst, tnow)) else if (!writer_hbcontrol_must_send (wr, &whcst, tnow))
{ {
@ -714,7 +731,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt
PGUID (wr->e.guid), PGUID (wr->e.guid),
hbansreq ? "" : " final", hbansreq ? "" : " final",
msg ? "sent" : "suppressed", msg ? "sent" : "suppressed",
(t_next.v == T_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
ddsrt_avl_is_empty (&wr->readers) ? (seqno_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq, ddsrt_avl_is_empty (&wr->readers) ? (seqno_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq,
ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!", ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!",
whcst.max_seq, writer_read_seq_xmit (wr)); whcst.max_seq, writer_read_seq_xmit (wr));
@ -946,7 +963,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
ETRACE (pwr, "\n"); ETRACE (pwr, "\n");
} }
static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_mtime_t tnow) static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, ddsrt_mtime_t tnow)
{ {
/* FIXME: ought to keep track of which NACKs are being generated in /* FIXME: ought to keep track of which NACKs are being generated in
response to a Heartbeat. There is no point in having multiple response to a Heartbeat. There is no point in having multiple
@ -1017,7 +1034,7 @@ static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_mtim
HEARTBEAT, I've seen too many cases of not sending an NACK HEARTBEAT, I've seen too many cases of not sending an NACK
because the writing side got confused ... Better to recover because the writing side got confused ... Better to recover
eventually. */ eventually. */
(void) resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, gv->config.auto_resched_nack_delay)); (void) resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (tnow, gv->config.auto_resched_nack_delay));
} }
GVTRACE ("send acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT")\n", GVTRACE ("send acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT")\n",
PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid)); PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid));
@ -1029,12 +1046,12 @@ static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_mtim
msg = NULL; msg = NULL;
} }
if (!pwr->have_seen_heartbeat && tnow.v - rwn->tcreate.v <= 300 * T_SECOND) if (!pwr->have_seen_heartbeat && tnow.v - rwn->tcreate.v <= DDS_SECS (300))
{ {
/* Force pre-emptive AckNacks out until we receive a heartbeat, /* Force pre-emptive AckNacks out until we receive a heartbeat,
but let the frequency drop over time and stop after a couple but let the frequency drop over time and stop after a couple
of minutes. */ of minutes. */
int intv, age = (int) ((tnow.v - rwn->tcreate.v) / T_SECOND + 1); int intv, age = (int) ((tnow.v - rwn->tcreate.v) / DDS_NSECS_IN_SEC + 1);
if (age <= 10) if (age <= 10)
intv = 1; intv = 1;
else if (age <= 60) else if (age <= 60)
@ -1043,7 +1060,7 @@ static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_mtim
intv = 5; intv = 5;
else else
intv = 10; intv = 10;
(void) resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, intv * T_SECOND)); (void) resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (tnow, intv * DDS_NSECS_IN_SEC));
} }
ddsrt_mutex_unlock (&pwr->e.lock); ddsrt_mutex_unlock (&pwr->e.lock);
@ -1056,7 +1073,7 @@ static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_mtim
outofmem: outofmem:
/* What to do if out of memory? Crash or burn? */ /* What to do if out of memory? Crash or burn? */
ddsrt_mutex_unlock (&pwr->e.lock); ddsrt_mutex_unlock (&pwr->e.lock);
(void) resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, 100 * T_MILLISECOND)); (void) resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (tnow, DDS_MSECS (100)));
} }
static bool resend_spdp_sample_by_guid_key (struct writer *wr, const ddsi_guid_t *guid, struct proxy_reader *prd) static bool resend_spdp_sample_by_guid_key (struct writer *wr, const ddsi_guid_t *guid, struct proxy_reader *prd)
@ -1097,7 +1114,7 @@ static bool resend_spdp_sample_by_guid_key (struct writer *wr, const ddsi_guid_t
return sample_found; return sample_found;
} }
static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, nn_mtime_t tnow) static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, ddsrt_mtime_t tnow)
{ {
/* Like the writer pointer in the heartbeat event, the participant pointer in the spdp event is assumed valid. */ /* Like the writer pointer in the heartbeat event, the participant pointer in the spdp event is assumed valid. */
struct ddsi_domaingv *gv = ev->evq->gv; struct ddsi_domaingv *gv = ev->evq->gv;
@ -1172,11 +1189,11 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
{ {
/* Directed events are used to send SPDP packets to newly /* Directed events are used to send SPDP packets to newly
discovered peers, and used just once. */ discovered peers, and used just once. */
if (--ev->u.spdp.directed == 0 || gv->config.spdp_interval < T_SECOND || pp->lease_duration < T_SECOND) if (--ev->u.spdp.directed == 0 || gv->config.spdp_interval < DDS_SECS (1) || pp->lease_duration < DDS_SECS (1))
delete_xevent (ev); delete_xevent (ev);
else else
{ {
nn_mtime_t tnext = add_duration_to_mtime (tnow, T_SECOND); ddsrt_mtime_t tnext = ddsrt_mtime_add_duration (tnow, DDS_SECS (1));
GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
PGUID (pp->e.guid), PGUID (pp->e.guid),
PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
@ -1189,21 +1206,21 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
/* schedule next when 80% of the interval has elapsed, or 2s /* schedule next when 80% of the interval has elapsed, or 2s
before the lease ends, whichever comes first (similar to PMD), before the lease ends, whichever comes first (similar to PMD),
but never wait longer than spdp_interval */ but never wait longer than spdp_interval */
const dds_duration_t mindelta = 10 * T_MILLISECOND; const dds_duration_t mindelta = DDS_MSECS (10);
const dds_duration_t ldur = pp->lease_duration; const dds_duration_t ldur = pp->lease_duration;
nn_mtime_t tnext; ddsrt_mtime_t tnext;
int64_t intv; int64_t intv;
if (ldur < 5 * mindelta / 4) if (ldur < 5 * mindelta / 4)
intv = mindelta; intv = mindelta;
else if (ldur < 10 * T_SECOND) else if (ldur < DDS_SECS (10))
intv = 4 * ldur / 5; intv = 4 * ldur / 5;
else else
intv = ldur - 2 * T_SECOND; intv = ldur - DDS_SECS (2);
if (intv > gv->config.spdp_interval) if (intv > gv->config.spdp_interval)
intv = gv->config.spdp_interval; intv = gv->config.spdp_interval;
tnext = add_duration_to_mtime (tnow, intv); tnext = ddsrt_mtime_add_duration (tnow, intv);
GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
PGUID (pp->e.guid), PGUID (pp->e.guid),
PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
@ -1212,12 +1229,12 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
} }
} }
static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_xpack *xp, struct xevent *ev, nn_mtime_t tnow) static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_xpack *xp, struct xevent *ev, ddsrt_mtime_t tnow)
{ {
struct ddsi_domaingv * const gv = ev->evq->gv; struct ddsi_domaingv * const gv = ev->evq->gv;
struct participant *pp; struct participant *pp;
dds_duration_t intv; dds_duration_t intv;
nn_mtime_t tnext; ddsrt_mtime_t tnext;
if ((pp = entidx_lookup_participant_guid (gv->entity_index, &ev->u.pmd_update.pp_guid)) == NULL) if ((pp = entidx_lookup_participant_guid (gv->entity_index, &ev->u.pmd_update.pp_guid)) == NULL)
{ {
@ -1227,17 +1244,17 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_
write_pmd_message (ts1, xp, pp, PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE); write_pmd_message (ts1, xp, pp, PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE);
intv = pp_get_pmd_interval (pp); intv = pp_get_pmd_interval (pp);
if (intv == T_NEVER) if (intv == DDS_INFINITY)
{ {
tnext.v = T_NEVER; tnext.v = DDS_NEVER;
GVTRACE ("resched pmd("PGUIDFMT"): never\n", PGUID (pp->e.guid)); GVTRACE ("resched pmd("PGUIDFMT"): never\n", PGUID (pp->e.guid));
} }
else else
{ {
/* schedule next when 80% of the interval has elapsed, or 2s /* schedule next when 80% of the interval has elapsed, or 2s
before the lease ends, whichever comes first */ before the lease ends, whichever comes first */
if (intv >= 10 * T_SECOND) if (intv >= DDS_SECS (10))
tnext.v = tnow.v + intv - 2 * T_SECOND; tnext.v = tnow.v + intv - DDS_SECS (2);
else else
tnext.v = tnow.v + 4 * intv / 5; tnext.v = tnow.v + 4 * intv / 5;
GVTRACE ("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9); GVTRACE ("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9);
@ -1246,7 +1263,7 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_
(void) resched_xevent_if_earlier (ev, tnext); (void) resched_xevent_if_earlier (ev, tnext);
} }
static void handle_xevk_delete_writer (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, UNUSED_ARG (nn_mtime_t tnow)) static void handle_xevk_delete_writer (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, UNUSED_ARG (ddsrt_mtime_t tnow))
{ {
/* don't worry if the writer is already gone by the time we get here. */ /* don't worry if the writer is already gone by the time we get here. */
struct ddsi_domaingv * const gv = ev->evq->gv; struct ddsi_domaingv * const gv = ev->evq->gv;
@ -1255,7 +1272,7 @@ static void handle_xevk_delete_writer (UNUSED_ARG (struct nn_xpack *xp), struct
delete_xevent (ev); delete_xevent (ev);
} }
static void handle_individual_xevent (struct thread_state1 * const ts1, struct xevent *xev, struct nn_xpack *xp, nn_mtime_t tnow) static void handle_individual_xevent (struct thread_state1 * const ts1, struct xevent *xev, struct nn_xpack *xp, ddsrt_mtime_t tnow)
{ {
struct xeventq *xevq = xev->evq; struct xeventq *xevq = xev->evq;
/* We relinquish the lock while processing the event, but require it /* We relinquish the lock while processing the event, but require it
@ -1319,7 +1336,7 @@ static void handle_individual_xevent_nt (struct xevent_nt *xev, struct nn_xpack
ddsrt_free (xev); ddsrt_free (xev);
} }
static void handle_timed_xevent (struct thread_state1 * const ts1, struct xevent *xev, struct nn_xpack *xp, nn_mtime_t tnow /* monotonic */) static void handle_timed_xevent (struct thread_state1 * const ts1, struct xevent *xev, struct nn_xpack *xp, ddsrt_mtime_t tnow /* monotonic */)
{ {
/* This function handles the individual xevent irrespective of /* This function handles the individual xevent irrespective of
whether it is a "timed" or "non-timed" xevent */ whether it is a "timed" or "non-timed" xevent */
@ -1347,7 +1364,7 @@ static void handle_nontimed_xevent (struct xevent_nt *xev, struct nn_xpack *xp)
ASSERT_MUTEX_HELD (&xevq->lock); ASSERT_MUTEX_HELD (&xevq->lock);
} }
static void handle_xevents (struct thread_state1 * const ts1, struct xeventq *xevq, struct nn_xpack *xp, nn_mtime_t tnow /* monotonic */) static void handle_xevents (struct thread_state1 * const ts1, struct xeventq *xevq, struct nn_xpack *xp, ddsrt_mtime_t tnow /* monotonic */)
{ {
int xeventsToProcess = 1; int xeventsToProcess = 1;
@ -1377,14 +1394,14 @@ static void handle_xevents (struct thread_state1 * const ts1, struct xeventq *xe
determine whether it is currently on the heap or not (i.e., determine whether it is currently on the heap or not (i.e.,
scheduled or not), so set to TSCHED_NEVER to indicate it scheduled or not), so set to TSCHED_NEVER to indicate it
currently isn't. */ currently isn't. */
xev->tsched.v = T_NEVER; xev->tsched.v = DDS_NEVER;
thread_state_awake_to_awake_no_nest (ts1); thread_state_awake_to_awake_no_nest (ts1);
handle_timed_xevent (ts1, xev, xp, tnow); handle_timed_xevent (ts1, xev, xp, tnow);
} }
/* Limited-bandwidth channels means events can take a LONG time /* Limited-bandwidth channels means events can take a LONG time
to process. So read the clock more often. */ to process. So read the clock more often. */
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
} }
if (!non_timed_xmit_list_is_empty (xevq)) if (!non_timed_xmit_list_is_empty (xevq))
@ -1392,7 +1409,7 @@ static void handle_xevents (struct thread_state1 * const ts1, struct xeventq *xe
struct xevent_nt *xev = getnext_from_non_timed_xmit_list (xevq); struct xevent_nt *xev = getnext_from_non_timed_xmit_list (xevq);
thread_state_awake_to_awake_no_nest (ts1); thread_state_awake_to_awake_no_nest (ts1);
handle_nontimed_xevent (xev, xp); handle_nontimed_xevent (xev, xp);
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
} }
else else
{ {
@ -1407,14 +1424,14 @@ static uint32_t xevent_thread (struct xeventq * xevq)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
struct nn_xpack *xp; struct nn_xpack *xp;
nn_mtime_t next_thread_cputime = { 0 }; ddsrt_mtime_t next_thread_cputime = { 0 };
xp = nn_xpack_new (xevq->tev_conn, xevq->auxiliary_bandwidth_limit, xevq->gv->config.xpack_send_async); xp = nn_xpack_new (xevq->tev_conn, xevq->auxiliary_bandwidth_limit, xevq->gv->config.xpack_send_async);
ddsrt_mutex_lock (&xevq->lock); ddsrt_mutex_lock (&xevq->lock);
while (!xevq->terminate) while (!xevq->terminate)
{ {
nn_mtime_t tnow = now_mt (); ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
LOG_THREAD_CPUTIME (&xevq->gv->logconfig, next_thread_cputime); LOG_THREAD_CPUTIME (&xevq->gv->logconfig, next_thread_cputime);
@ -1432,8 +1449,8 @@ static uint32_t xevent_thread (struct xeventq * xevq)
} }
else else
{ {
nn_mtime_t twakeup = earliest_in_xeventq (xevq); ddsrt_mtime_t twakeup = earliest_in_xeventq (xevq);
if (twakeup.v == T_NEVER) if (twakeup.v == DDS_NEVER)
{ {
/* no scheduled events nor any non-timed events */ /* no scheduled events nor any non-timed events */
ddsrt_cond_wait (&xevq->cond, &xevq->lock); ddsrt_cond_wait (&xevq->cond, &xevq->lock);
@ -1444,7 +1461,7 @@ static uint32_t xevent_thread (struct xeventq * xevq)
don't want to sleep much longer than we have to. With don't want to sleep much longer than we have to. With
os_condTimedWait requiring a relative time, we don't have os_condTimedWait requiring a relative time, we don't have
much choice but to read the clock now */ much choice but to read the clock now */
tnow = now_mt (); tnow = ddsrt_time_monotonic ();
if (twakeup.v > tnow.v) if (twakeup.v > tnow.v)
{ {
twakeup.v -= tnow.v; /* ddsrt_cond_waitfor: relative timeout */ twakeup.v -= tnow.v; /* ddsrt_cond_waitfor: relative timeout */
@ -1584,7 +1601,7 @@ int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg *msg, int f
} }
} }
struct xevent *qxev_heartbeat (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *wr_guid) struct xevent *qxev_heartbeat (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *wr_guid)
{ {
/* Event _must_ be deleted before enough of the writer is freed to /* Event _must_ be deleted before enough of the writer is freed to
cause trouble. Currently used exclusively for cause trouble. Currently used exclusively for
@ -1599,7 +1616,7 @@ struct xevent *qxev_heartbeat (struct xeventq *evq, nn_mtime_t tsched, const dds
return ev; return ev;
} }
struct xevent *qxev_acknack (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *pwr_guid, const ddsi_guid_t *rd_guid) struct xevent *qxev_acknack (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *pwr_guid, const ddsi_guid_t *rd_guid)
{ {
struct xevent *ev; struct xevent *ev;
assert(evq); assert(evq);
@ -1612,7 +1629,7 @@ struct xevent *qxev_acknack (struct xeventq *evq, nn_mtime_t tsched, const ddsi_
return ev; return ev;
} }
struct xevent *qxev_spdp (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *pp_guid, const ddsi_guid_t *dest_proxypp_guid) struct xevent *qxev_spdp (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *pp_guid, const ddsi_guid_t *dest_proxypp_guid)
{ {
struct xevent *ev; struct xevent *ev;
ddsrt_mutex_lock (&evq->lock); ddsrt_mutex_lock (&evq->lock);
@ -1630,7 +1647,7 @@ struct xevent *qxev_spdp (struct xeventq *evq, nn_mtime_t tsched, const ddsi_gui
return ev; return ev;
} }
struct xevent *qxev_pmd_update (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *pp_guid) struct xevent *qxev_pmd_update (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *pp_guid)
{ {
struct xevent *ev; struct xevent *ev;
ddsrt_mutex_lock (&evq->lock); ddsrt_mutex_lock (&evq->lock);
@ -1641,7 +1658,7 @@ struct xevent *qxev_pmd_update (struct xeventq *evq, nn_mtime_t tsched, const dd
return ev; return ev;
} }
struct xevent *qxev_delete_writer (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *guid) struct xevent *qxev_delete_writer (struct xeventq *evq, ddsrt_mtime_t tsched, const ddsi_guid_t *guid)
{ {
struct xevent *ev; struct xevent *ev;
ddsrt_mutex_lock (&evq->lock); ddsrt_mutex_lock (&evq->lock);
@ -1652,7 +1669,7 @@ struct xevent *qxev_delete_writer (struct xeventq *evq, nn_mtime_t tsched, const
return ev; return ev;
} }
struct xevent *qxev_callback (struct xeventq *evq, nn_mtime_t tsched, void (*cb) (struct xevent *ev, void *arg, nn_mtime_t tnow), void *arg) struct xevent *qxev_callback (struct xeventq *evq, ddsrt_mtime_t tsched, void (*cb) (struct xevent *ev, void *arg, ddsrt_mtime_t tnow), void *arg)
{ {
struct xevent *ev; struct xevent *ev;
ddsrt_mutex_lock (&evq->lock); ddsrt_mutex_lock (&evq->lock);

View file

@ -142,7 +142,7 @@ struct nn_xmsg_chain {
struct nn_bw_limiter { struct nn_bw_limiter {
uint32_t bandwidth; /*gv.config in bytes/s (0 = UNLIMITED)*/ uint32_t bandwidth; /*gv.config in bytes/s (0 = UNLIMITED)*/
int64_t balance; int64_t balance;
nn_mtime_t last_update; ddsrt_mtime_t last_update;
}; };
#endif #endif
@ -410,9 +410,8 @@ static int submsg_is_compatible (const struct nn_xmsg *msg, SubmessageKind_t smk
case SMID_ACKNACK: case SMID_HEARTBEAT: case SMID_ACKNACK: case SMID_HEARTBEAT:
case SMID_GAP: case SMID_NACK_FRAG: case SMID_GAP: case SMID_NACK_FRAG:
case SMID_HEARTBEAT_FRAG: case SMID_HEARTBEAT_FRAG:
case SMID_PT_INFO_CONTAINER: case SMID_ADLINK_MSG_LEN:
case SMID_PT_MSG_LEN: case SMID_ADLINK_ENTITY_ID:
case SMID_PT_ENTITY_ID:
/* normal control stuff is ok */ /* normal control stuff is ok */
return 1; return 1;
case SMID_DATA: case SMID_DATA_FRAG: case SMID_DATA: case SMID_DATA_FRAG:
@ -458,9 +457,8 @@ static int submsg_is_compatible (const struct nn_xmsg *msg, SubmessageKind_t smk
case SMID_GAP: case SMID_GAP:
case SMID_NACK_FRAG: case SMID_NACK_FRAG:
case SMID_HEARTBEAT_FRAG: case SMID_HEARTBEAT_FRAG:
case SMID_PT_INFO_CONTAINER: case SMID_ADLINK_MSG_LEN:
case SMID_PT_MSG_LEN: case SMID_ADLINK_ENTITY_ID:
case SMID_PT_ENTITY_ID:
/* anything else is strictly verboten */ /* anything else is strictly verboten */
return 0; return 0;
} }
@ -659,14 +657,14 @@ void nn_xmsg_shrink (struct nn_xmsg *m, struct nn_xmsg_marker marker, size_t sz)
m->sz = marker.offset + sz; m->sz = marker.offset + sz;
} }
void nn_xmsg_add_timestamp (struct nn_xmsg *m, nn_wctime_t t) void nn_xmsg_add_timestamp (struct nn_xmsg *m, ddsrt_wctime_t t)
{ {
InfoTimestamp_t * ts; InfoTimestamp_t * ts;
struct nn_xmsg_marker sm; struct nn_xmsg_marker sm;
ts = (InfoTimestamp_t*) nn_xmsg_append (m, &sm, sizeof (InfoTimestamp_t)); ts = (InfoTimestamp_t*) nn_xmsg_append (m, &sm, sizeof (InfoTimestamp_t));
nn_xmsg_submsg_init (m, sm, SMID_INFO_TS); nn_xmsg_submsg_init (m, sm, SMID_INFO_TS);
ts->time = nn_wctime_to_ddsi_time (t); ts->time = ddsi_wctime_to_ddsi_time (t);
nn_xmsg_submsg_setnext (m, sm); nn_xmsg_submsg_setnext (m, sm);
} }
@ -676,7 +674,7 @@ void nn_xmsg_add_entityid (struct nn_xmsg * m)
struct nn_xmsg_marker sm; struct nn_xmsg_marker sm;
eid = (EntityId_t*) nn_xmsg_append (m, &sm, sizeof (EntityId_t)); eid = (EntityId_t*) nn_xmsg_append (m, &sm, sizeof (EntityId_t));
nn_xmsg_submsg_init (m, sm, SMID_PT_ENTITY_ID); nn_xmsg_submsg_init (m, sm, SMID_ADLINK_ENTITY_ID);
eid->entityid.u = NN_ENTITYID_PARTICIPANT; eid->entityid.u = NN_ENTITYID_PARTICIPANT;
nn_xmsg_submsg_setnext (m, sm); nn_xmsg_submsg_setnext (m, sm);
} }
@ -1063,12 +1061,12 @@ static void nn_xmsg_chain_add (struct nn_xmsg_chain *chain, struct nn_xmsg *m)
* If data is send too fast, a sleep is inserted to get the used bandwidth at the configured rate. * If data is send too fast, a sleep is inserted to get the used bandwidth at the configured rate.
*/ */
#define NN_BW_LIMIT_MAX_BUFFER (-30 * T_MILLISECOND) #define NN_BW_LIMIT_MAX_BUFFER (DDS_MSECS (-30))
#define NN_BW_LIMIT_MIN_SLEEP (2 * T_MILLISECOND) #define NN_BW_LIMIT_MIN_SLEEP (DDS_MSECS (2))
static void nn_bw_limit_sleep_if_needed (struct ddsi_domaingv const * const gv, struct nn_bw_limiter *this, ssize_t size) static void nn_bw_limit_sleep_if_needed (struct ddsi_domaingv const * const gv, struct nn_bw_limiter *this, ssize_t size)
{ {
if ( this->bandwidth > 0 ) { if ( this->bandwidth > 0 ) {
nn_mtime_t tnow = now_mt(); ddsrt_mtime_t tnow = ddsrt_time_monotonic();
int64_t actual_interval; int64_t actual_interval;
int64_t target_interval; int64_t target_interval;
@ -1076,7 +1074,7 @@ static void nn_bw_limit_sleep_if_needed (struct ddsi_domaingv const * const gv,
actual_interval = tnow.v - this->last_update.v; actual_interval = tnow.v - this->last_update.v;
this->last_update = tnow; this->last_update = tnow;
target_interval = T_SECOND*size/this->bandwidth; target_interval = DDS_NSECS_IN_SEC*size/this->bandwidth;
this->balance += (target_interval - actual_interval); this->balance += (target_interval - actual_interval);
@ -1111,7 +1109,7 @@ static void nn_bw_limit_init (struct nn_bw_limiter *limiter, uint32_t bandwidth_
limiter->bandwidth = bandwidth_limit; limiter->bandwidth = bandwidth_limit;
limiter->balance = 0; limiter->balance = 0;
if (bandwidth_limit) if (bandwidth_limit)
limiter->last_update = now_mt (); limiter->last_update = ddsrt_time_monotonic();
else else
limiter->last_update.v = 0; limiter->last_update.v = 0;
} }
@ -1130,7 +1128,7 @@ static void nn_xpack_reinit (struct nn_xpack *xp)
xp->call_flags = 0; xp->call_flags = 0;
xp->msg_len.length = 0; xp->msg_len.length = 0;
xp->included_msgs.latest = NULL; xp->included_msgs.latest = NULL;
xp->maxdelay = T_NEVER; xp->maxdelay = DDS_INFINITY;
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
xp->sec_info.use_rtps_encoding = 0; xp->sec_info.use_rtps_encoding = 0;
#endif #endif
@ -1165,7 +1163,7 @@ struct nn_xpack * nn_xpack_new (ddsi_tran_conn_t conn, uint32_t bw_limit, bool a
/* MSG_LEN first sub message for stream based connections */ /* MSG_LEN first sub message for stream based connections */
xp->msg_len.smhdr.submessageId = SMID_PT_MSG_LEN; xp->msg_len.smhdr.submessageId = SMID_ADLINK_MSG_LEN;
xp->msg_len.smhdr.flags = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? SMFLAG_ENDIANNESS : 0); xp->msg_len.smhdr.flags = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? SMFLAG_ENDIANNESS : 0);
xp->msg_len.smhdr.octetsToNextHeader = 4; xp->msg_len.smhdr.octetsToNextHeader = 4;

View file

@ -108,9 +108,9 @@ static struct ddsi_serdata *mkkeysample (int32_t keyval, unsigned statusinfo)
} }
#if defined(DDSI_INCLUDE_LIFESPAN) || defined (DDSI_INCLUDE_DEADLINE_MISSED) #if defined(DDSI_INCLUDE_LIFESPAN) || defined (DDSI_INCLUDE_DEADLINE_MISSED)
static nn_mtime_t rand_texp () static ddsrt_mtime_t rand_texp ()
{ {
nn_mtime_t ret = now_mt(); ddsrt_mtime_t ret = ddsrt_time_monotonic();
ret.v -= DDS_MSECS(500) + (int64_t) (ddsrt_prng_random (&prng) % DDS_MSECS(1500)); ret.v -= DDS_MSECS(500) + (int64_t) (ddsrt_prng_random (&prng) % DDS_MSECS(1500));
return ret; return ret;
} }
@ -158,7 +158,7 @@ static uint64_t store (struct ddsi_tkmap *tkmap, struct dds_rhc *rhc, struct pro
if (lifespan_expiry && (sd->statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0) if (lifespan_expiry && (sd->statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0)
pwr_info.lifespan_exp = rand_texp(); pwr_info.lifespan_exp = rand_texp();
else else
pwr_info.lifespan_exp = NN_MTIME_NEVER; pwr_info.lifespan_exp = DDSRT_MTIME_NEVER;
#endif #endif
dds_rhc_store (rhc, &pwr_info, sd, tk); dds_rhc_store (rhc, &pwr_info, sd, tk);
ddsi_tkmap_instance_unref (tkmap, tk); ddsi_tkmap_instance_unref (tkmap, tk);
@ -831,7 +831,7 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
wr_info.iid = wr[which]->e.iid; wr_info.iid = wr[which]->e.iid;
wr_info.ownership_strength = wr[which]->c.xqos->ownership_strength.value; wr_info.ownership_strength = wr[which]->c.xqos->ownership_strength.value;
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
wr_info.lifespan_exp = NN_MTIME_NEVER; wr_info.lifespan_exp = DDSRT_MTIME_NEVER;
#endif #endif
for (size_t k = 0; k < nrd; k++) for (size_t k = 0; k < nrd; k++)
dds_rhc_unregister_wr (rhc[k], &wr_info); dds_rhc_unregister_wr (rhc[k], &wr_info);
@ -962,7 +962,7 @@ int main (int argc, char **argv)
wr0_info.iid = wr0->e.iid; wr0_info.iid = wr0->e.iid;
wr0_info.ownership_strength = wr0->c.xqos->ownership_strength.value; wr0_info.ownership_strength = wr0->c.xqos->ownership_strength.value;
#ifdef DDSI_INCLUDE_LIFESPAN #ifdef DDSI_INCLUDE_LIFESPAN
wr0_info.lifespan_exp = NN_MTIME_NEVER; wr0_info.lifespan_exp = DDSRT_MTIME_NEVER;
#endif #endif
dds_rhc_unregister_wr (rhc, &wr0_info); dds_rhc_unregister_wr (rhc, &wr0_info);
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());

View file

@ -239,7 +239,7 @@ if(NOT WITH_FREERTOS)
endif() endif()
if(WIN32) if(WIN32)
target_link_libraries(ddsrt INTERFACE wsock32 ws2_32 iphlpapi bcrypt) target_link_libraries(ddsrt INTERFACE ws2_32 iphlpapi bcrypt)
elseif(UNIX) elseif(UNIX)
check_library_exists(c clock_gettime "" HAVE_CLOCK_GETTIME) check_library_exists(c clock_gettime "" HAVE_CLOCK_GETTIME)
if(NOT HAVE_CLOCK_GETTIME) if(NOT HAVE_CLOCK_GETTIME)

View file

@ -21,6 +21,7 @@
#define DDS_TIME_H #define DDS_TIME_H
#include <stdint.h> #include <stdint.h>
#include <assert.h>
#include "dds/export.h" #include "dds/export.h"
#include "dds/ddsrt/types.h" #include "dds/ddsrt/types.h"
@ -72,6 +73,23 @@ typedef int64_t dds_duration_t;
#define DDS_USECS(n) ((n) * DDS_NSECS_IN_USEC) #define DDS_USECS(n) ((n) * DDS_NSECS_IN_USEC)
/** @}*/ /** @}*/
typedef struct {
dds_time_t v;
} ddsrt_mtime_t;
typedef struct {
dds_time_t v;
} ddsrt_wctime_t;
typedef struct {
dds_time_t v;
} ddsrt_etime_t;
#define DDSRT_MTIME_NEVER ((ddsrt_mtime_t) { DDS_NEVER })
#define DDSRT_WCTIME_NEVER ((ddsrt_wctime_t) { DDS_NEVER })
#define DDSRT_ETIME_NEVER ((ddsrt_etime_t) { DDS_NEVER })
#define DDSRT_WCTIME_INVALID ((ddsrt_wctime_t) { INT64_MIN })
/** /**
* @brief Get the current time in nanoseconds since the UNIX Epoch. * @brief Get the current time in nanoseconds since the UNIX Epoch.
* *
@ -90,14 +108,12 @@ DDS_EXPORT dds_time_t dds_time(void);
DDS_EXPORT void dds_sleepfor (dds_duration_t reltime); DDS_EXPORT void dds_sleepfor (dds_duration_t reltime);
/** /**
* @brief Suspend execution of calling thread until absolute time n elapsed. * @brief Get the current time in nanoseconds since the UNIX Epoch. Identical
* to (ddsrt_wctime_t){dds_time()}
* *
* Execution is suspended until the given absolute time elapsed. Should the * @returns Curren time.
* call be interrupted, it is re-entered with the remaining time.
*
* @param[in] abstime Absolute time in nanoseconds since UNIX Epoch.
*/ */
DDS_EXPORT void dds_sleepuntil (dds_time_t abstime); DDS_EXPORT ddsrt_wctime_t ddsrt_time_wallclock(void);
/** /**
* @brief Get high resolution, monotonic time. * @brief Get high resolution, monotonic time.
@ -112,7 +128,7 @@ DDS_EXPORT void dds_sleepuntil (dds_time_t abstime);
* *
* @returns Monotonic time if available, otherwise real time. * @returns Monotonic time if available, otherwise real time.
*/ */
DDS_EXPORT dds_time_t ddsrt_time_monotonic(void); DDS_EXPORT ddsrt_mtime_t ddsrt_time_monotonic(void);
/** /**
* @brief Get high resolution, elapsed (and thus monotonic) time since some * @brief Get high resolution, elapsed (and thus monotonic) time since some
@ -126,7 +142,7 @@ DDS_EXPORT dds_time_t ddsrt_time_monotonic(void);
* *
* @returns Elapsed time if available, otherwise return monotonic time. * @returns Elapsed time if available, otherwise return monotonic time.
*/ */
DDS_EXPORT dds_time_t ddsrt_time_elapsed(void); DDS_EXPORT ddsrt_etime_t ddsrt_time_elapsed(void);
/** /**
* @brief Convert time into a human readable string in RFC 3339 format. * @brief Convert time into a human readable string in RFC 3339 format.
@ -148,6 +164,137 @@ DDS_EXPORT dds_time_t ddsrt_time_elapsed(void);
DDS_EXPORT size_t ddsrt_ctime(dds_time_t abstime, char *str, size_t size); DDS_EXPORT size_t ddsrt_ctime(dds_time_t abstime, char *str, size_t size);
/**
* @brief Calculate a time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline dds_time_t ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime)
{
assert(abstime >= 0);
assert(reltime >= 0);
return (reltime >= DDS_NEVER - abstime ? DDS_NEVER : abstime + reltime);
}
/**
* @brief Calculate a monotonic time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline ddsrt_mtime_t ddsrt_mtime_add_duration(ddsrt_mtime_t abstime, dds_duration_t reltime) {
ddsrt_mtime_t t;
t.v = ddsrt_time_add_duration (abstime.v, reltime);
return t;
}
/**
* @brief Calculate a wall-clock time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline ddsrt_wctime_t ddsrt_wctime_add_duration(ddsrt_wctime_t abstime, dds_duration_t reltime) {
ddsrt_wctime_t t;
t.v = ddsrt_time_add_duration (abstime.v, reltime);
return t;
}
/**
* @brief Calculate an elapsed time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline ddsrt_etime_t ddsrt_etime_add_duration(ddsrt_etime_t abstime, dds_duration_t reltime) {
ddsrt_etime_t t;
t.v = ddsrt_time_add_duration (abstime.v, reltime);
return t;
}
#if _WIN32
/**
* @brief Convert a relative time to microseconds rounding up.
*
* @param[in] reltime Relative time to convert.
*
* @returns INFINITE if @reltime was @DDS_INIFINITY, relative time converted to
* microseconds otherwise.
*/
inline DWORD
ddsrt_duration_to_msecs_ceil(dds_duration_t reltime)
{
if (reltime == DDS_INFINITY) {
return INFINITE;
} else if (reltime > 0) {
assert(INFINITE < (DDS_INFINITY / DDS_NSECS_IN_MSEC));
dds_duration_t max_nsecs = (INFINITE - 1) * DDS_NSECS_IN_MSEC;
if (reltime < (max_nsecs - (DDS_NSECS_IN_MSEC - 1))) {
reltime += (DDS_NSECS_IN_MSEC - 1);
} else {
reltime = max_nsecs;
}
return (DWORD)(reltime / DDS_NSECS_IN_MSEC);
}
return 0;
}
#endif
/**
* @brief Convert monotonic time seconds & microseconds
*
* @param[in] t Monotonic time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_mtime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_mtime_t t);
/**
* @brief Convert wall-clock time seconds & microseconds
*
* @param[in] t Wall-clock time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_wctime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_wctime_t t);
/**
* @brief Convert elapsed time seconds & microseconds
*
* @param[in] t Elasped time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_etime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_etime_t t);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View file

@ -25,38 +25,41 @@ uint32_t ddsrt_mh3 (const void *key, size_t len, uint32_t seed)
const uint32_t c2 = 0x1b873593; const uint32_t c2 = 0x1b873593;
uint32_t h1 = seed; uint32_t h1 = seed;
const uint32_t *blocks = (const uint32_t *) (data + nblocks * 4);
for (intptr_t i = -nblocks; i; i++)
{
uint32_t k1 = blocks[i];
k1 *= c1; if(len){
k1 = DDSRT_MH3_ROTL32 (k1, 15); const uint32_t *blocks = (const uint32_t *) (data + nblocks * 4);
k1 *= c2; for (intptr_t i = -nblocks; i; i++)
{
uint32_t k1 = blocks[i];
h1 ^= k1;
h1 = DDSRT_MH3_ROTL32 (h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
const uint8_t *tail = data + nblocks * 4;
uint32_t k1 = 0;
switch (len & 3)
{
case 3:
k1 ^= (uint32_t) tail[2] << 16;
/* FALLS THROUGH */
case 2:
k1 ^= (uint32_t) tail[1] << 8;
/* FALLS THROUGH */
case 1:
k1 ^= (uint32_t) tail[0];
k1 *= c1; k1 *= c1;
k1 = DDSRT_MH3_ROTL32 (k1, 15); k1 = DDSRT_MH3_ROTL32 (k1, 15);
k1 *= c2; k1 *= c2;
h1 ^= k1; h1 ^= k1;
/* FALLS THROUGH */ h1 = DDSRT_MH3_ROTL32 (h1, 13);
}; h1 = h1 * 5 + 0xe6546b64;
}
const uint8_t *tail = data + nblocks * 4;
uint32_t k1 = 0;
switch (len & 3)
{
case 3:
k1 ^= (uint32_t) tail[2] << 16;
/* FALLS THROUGH */
case 2:
k1 ^= (uint32_t) tail[1] << 8;
/* FALLS THROUGH */
case 1:
k1 ^= (uint32_t) tail[0];
k1 *= c1;
k1 = DDSRT_MH3_ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
/* FALLS THROUGH */
}
}
/* finalization */ /* finalization */
h1 ^= (uint32_t) len; h1 ^= (uint32_t) len;

View file

@ -18,7 +18,6 @@
#include "dds/ddsrt/string.h" #include "dds/ddsrt/string.h"
#include "dds/ddsrt/atomics.h" #include "dds/ddsrt/atomics.h"
#include "dds/ddsrt/process.h" #include "dds/ddsrt/process.h"
#include "dds/ddsrt/timeconv.h"
ddsrt_pid_t ddsrt_pid_t

View file

@ -19,7 +19,7 @@
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h" #include "dds/ddsrt/log.h"
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h" #include "dds/ddsrt/time.h"
void ddsrt_mutex_init(ddsrt_mutex_t *mutex) void ddsrt_mutex_init(ddsrt_mutex_t *mutex)
{ {

View file

@ -18,7 +18,7 @@
#include <sys/time.h> #include <sys/time.h>
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h" #include "dds/ddsrt/time.h"
void ddsrt_mutex_init (ddsrt_mutex_t *mutex) void ddsrt_mutex_init (ddsrt_mutex_t *mutex)
{ {
@ -109,8 +109,8 @@ ddsrt_cond_waituntil(
return true; return true;
} }
if (abstime > 0) { if (abstime > 0) {
ts.tv_sec = abstime / DDS_NSECS_IN_SEC; ts.tv_sec = (time_t) (abstime / DDS_NSECS_IN_SEC);
ts.tv_nsec = abstime % DDS_NSECS_IN_SEC; ts.tv_nsec = (suseconds_t) (abstime % DDS_NSECS_IN_SEC);
} }
switch (pthread_cond_timedwait(&cond->cond, &mutex->mutex, &ts)) { switch (pthread_cond_timedwait(&cond->cond, &mutex->mutex, &ts)) {

View file

@ -18,7 +18,7 @@
#include <sys/time.h> #include <sys/time.h>
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h" #include "dds/ddsrt/time.h"
void ddsrt_mutex_init (ddsrt_mutex_t *mutex) void ddsrt_mutex_init (ddsrt_mutex_t *mutex)
{ {

View file

@ -13,7 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h" #include "dds/ddsrt/time.h"
void ddsrt_mutex_init(ddsrt_mutex_t *mutex) void ddsrt_mutex_init(ddsrt_mutex_t *mutex)
{ {

View file

@ -12,11 +12,14 @@
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
#include "dds/ddsrt/timeconv.h" #include "dds/ddsrt/time.h"
#include "dds/ddsrt/string.h" #include "dds/ddsrt/string.h"
#include "dds/ddsrt/static_assert.h"
extern inline dds_time_t extern inline dds_time_t ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime);
ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime); extern inline ddsrt_mtime_t ddsrt_mtime_add_duration(ddsrt_mtime_t abstime, dds_duration_t reltime);
extern inline ddsrt_wctime_t ddsrt_wctime_add_duration(ddsrt_wctime_t abstime, dds_duration_t reltime);
extern inline ddsrt_etime_t ddsrt_etime_add_duration(ddsrt_etime_t abstime, dds_duration_t reltime);
#if !_WIN32 && !DDSRT_WITH_FREERTOS #if !_WIN32 && !DDSRT_WITH_FREERTOS
#include <errno.h> #include <errno.h>
@ -26,8 +29,8 @@ void dds_sleepfor(dds_duration_t n)
struct timespec t, r; struct timespec t, r;
if (n >= 0) { if (n >= 0) {
t.tv_sec = n / DDS_NSECS_IN_SEC; t.tv_sec = (time_t) (n / DDS_NSECS_IN_SEC);
t.tv_nsec = n % DDS_NSECS_IN_SEC; t.tv_nsec = (long) (n % DDS_NSECS_IN_SEC);
while (nanosleep(&t, &r) == -1 && errno == EINTR) { while (nanosleep(&t, &r) == -1 && errno == EINTR) {
t = r; t = r;
} }
@ -35,14 +38,6 @@ void dds_sleepfor(dds_duration_t n)
} }
#endif #endif
void dds_sleepuntil(dds_time_t abstime)
{
dds_time_t now = dds_time();
if (abstime > now)
dds_sleepfor (abstime - now);
}
size_t size_t
ddsrt_ctime(dds_time_t n, char *str, size_t size) ddsrt_ctime(dds_time_t n, char *str, size_t size)
{ {
@ -79,3 +74,23 @@ ddsrt_ctime(dds_time_t n, char *str, size_t size)
return ddsrt_strlcpy(str, buf, size); return ddsrt_strlcpy(str, buf, size);
} }
static void time_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, int64_t t)
{
*sec = (int32_t) (t / DDS_NSECS_IN_SEC);
*usec = (int32_t) (t % DDS_NSECS_IN_SEC) / 1000;
}
void ddsrt_mtime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_mtime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}
void ddsrt_wctime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_wctime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}
void ddsrt_etime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_etime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}

View file

@ -32,10 +32,15 @@ dds_time_t dds_time(void)
#endif #endif
} }
dds_time_t ddsrt_time_monotonic(void) ddsrt_wctime_t ddsrt_time_wallclock(void)
{
return (ddsrt_wctime_t) { dds_time () };
}
ddsrt_mtime_t ddsrt_time_monotonic(void)
{ {
#if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 #if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
return (int64_t) clock_gettime_nsec_np (CLOCK_UPTIME_RAW); return (ddsrt_mtime_t) { (int64_t) clock_gettime_nsec_np (CLOCK_UPTIME_RAW) };
#else #else
static mach_timebase_info_data_t timeInfo; static mach_timebase_info_data_t timeInfo;
uint64_t mt; uint64_t mt;
@ -57,16 +62,17 @@ dds_time_t ddsrt_time_monotonic(void)
(void)mach_timebase_info(&timeInfo); (void)mach_timebase_info(&timeInfo);
} }
return (dds_time_t)(mt * timeInfo.numer / timeInfo.denom); return (ddsrt_mtime_t) { mt * timeInfo.numer / timeInfo.denom };
#endif #endif
} }
dds_time_t ddsrt_time_elapsed(void) ddsrt_etime_t ddsrt_time_elapsed(void)
{ {
#if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 #if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
return (int64_t) clock_gettime_nsec_np (CLOCK_MONOTONIC_RAW); return (ddsrt_etime_t) { (int64_t) clock_gettime_nsec_np (CLOCK_MONOTONIC_RAW) };
#else #else
/* Elapsed time clock not (yet) supported on this platform. */ /* Elapsed time clock not (yet) supported on this platform. */
return ddsrt_time_monotonic(); dds_mtime_t mt = ddsrt_time_monotonic();
return (ddsrt_etime_t) { mt.v };
#endif #endif
} }

View file

@ -33,15 +33,20 @@ dds_time_t dds_time(void)
#define NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ) #define NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ)
dds_time_t ddsrt_time_monotonic (void) ddsrt_wctime_t ddsrt_time_wallclock (void)
{ {
return (xTaskGetTickCount() * NSECS_PER_TICK); return (ddsrt_wctime_t) { dds_time() };
} }
dds_time_t ddsrt_time_elapsed (void) ddsrt_mtime_t ddsrt_time_monotonic (void)
{
return (ddsrt_mtime_t) { xTaskGetTickCount() * NSECS_PER_TICK };
}
ddsrt_etime_t ddsrt_time_elapsed (void)
{ {
/* Elapsed time clock not (yet) supported on this platform. */ /* Elapsed time clock not (yet) supported on this platform. */
return ddsrt_time_monotonic (); return (ddsrt_etime_t) { xTaskGetTickCount() * NSECS_PER_TICK };
} }
void dds_sleepfor (dds_duration_t reltime) void dds_sleepfor (dds_duration_t reltime)

Some files were not shown because too many files have changed in this diff Show more