Consistent code formatting for the core code
Code formatting was quite a mess (different indentation, completely different ideas on where opening braces should go, spacing in various places, early out versus single return or goto-based error handling, &c.). This commit cleans it up. A few doxygen comment fixes allowed turning on Clang's warnings for doxygen comments, so those are no enabled by default as least on Xcode-based builds. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
19aec98b8a
commit
13480616e0
56 changed files with 2856 additions and 4542 deletions
|
@ -130,6 +130,7 @@ if(${CMAKE_GENERATOR} STREQUAL "Xcode")
|
||||||
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER YES)
|
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER YES)
|
||||||
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES)
|
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES)
|
||||||
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES)
|
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES)
|
||||||
|
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DOCUMENTATION_COMMENTS YES)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Make it easy to enable one of Clang's/gcc's analyzers, and default to using
|
# Make it easy to enable one of Clang's/gcc's analyzers, and default to using
|
||||||
|
|
|
@ -74,6 +74,7 @@ PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||||
dds__whc.h
|
dds__whc.h
|
||||||
dds__whc_builtintopic.h
|
dds__whc_builtintopic.h
|
||||||
dds__serdata_builtintopic.h
|
dds__serdata_builtintopic.h
|
||||||
|
dds__get_status.h
|
||||||
)
|
)
|
||||||
|
|
||||||
generate_export_header(
|
generate_export_header(
|
||||||
|
|
|
@ -313,7 +313,7 @@ dds_delete(dds_entity_t entity);
|
||||||
* For instance, it will return the Publisher that was used when
|
* For instance, it will return the Publisher that was used when
|
||||||
* creating a DataWriter (when that DataWriter was provided here).
|
* creating a DataWriter (when that DataWriter was provided here).
|
||||||
*
|
*
|
||||||
* @param[in] entity Entity from which to get its publisher.
|
* @param[in] writer Entity from which to get its publisher.
|
||||||
*
|
*
|
||||||
* @returns A valid entity or an error code.
|
* @returns A valid entity or an error code.
|
||||||
*
|
*
|
||||||
|
@ -361,7 +361,7 @@ dds_get_subscriber(dds_entity_t entity);
|
||||||
* For instance, it will return the DataReader that was used when
|
* For instance, it will return the DataReader that was used when
|
||||||
* creating a ReadCondition (when that ReadCondition was provided here).
|
* creating a ReadCondition (when that ReadCondition was provided here).
|
||||||
*
|
*
|
||||||
* @param[in] entity Entity from which to get its datareader.
|
* @param[in] condition Entity from which to get its datareader.
|
||||||
*
|
*
|
||||||
* @returns A valid reader handle or an error code.
|
* @returns A valid reader handle or an error code.
|
||||||
*
|
*
|
||||||
|
@ -502,7 +502,7 @@ dds_get_status_changes(dds_entity_t entity, uint32_t *status);
|
||||||
* This operation returns the status enabled on the entity
|
* This operation returns the status enabled on the entity
|
||||||
*
|
*
|
||||||
* @param[in] entity Entity to get the status.
|
* @param[in] entity Entity to get the status.
|
||||||
* @param[out] status Status set on the entity.
|
* @param[out] mask Mask of enabled statuses set on the entity.
|
||||||
*
|
*
|
||||||
* @returns A dds_return_t indicating success or failure.
|
* @returns A dds_return_t indicating success or failure.
|
||||||
*
|
*
|
||||||
|
@ -952,6 +952,8 @@ dds_create_topic(
|
||||||
const dds_qos_t *qos,
|
const dds_qos_t *qos,
|
||||||
const dds_listener_t *listener);
|
const dds_listener_t *listener);
|
||||||
|
|
||||||
|
struct ddsi_sertopic;
|
||||||
|
struct nn_plist;
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new topic with arbitrary type handling.
|
* @brief Creates a new topic with arbitrary type handling.
|
||||||
*
|
*
|
||||||
|
@ -972,8 +974,6 @@ dds_create_topic(
|
||||||
* Either participant, descriptor, name or qos is invalid.
|
* Either participant, descriptor, name or qos is invalid.
|
||||||
*/
|
*/
|
||||||
/* TODO: Check list of retcodes is complete. */
|
/* TODO: Check list of retcodes is complete. */
|
||||||
struct ddsi_sertopic;
|
|
||||||
struct nn_plist;
|
|
||||||
DDS_EXPORT dds_entity_t
|
DDS_EXPORT dds_entity_t
|
||||||
dds_create_topic_arbitrary (
|
dds_create_topic_arbitrary (
|
||||||
dds_entity_t participant,
|
dds_entity_t participant,
|
||||||
|
@ -1650,8 +1650,7 @@ dds_write_flush(dds_entity_t writer);
|
||||||
* @brief Write a CDR serialized value of a data instance
|
* @brief Write a CDR serialized value of a data instance
|
||||||
*
|
*
|
||||||
* @param[in] writer The writer entity.
|
* @param[in] writer The writer entity.
|
||||||
* @param[in] cdr CDR serialized value to be written.
|
* @param[in] serdata CDR serialized value to be written.
|
||||||
* @param[in] size Size (in bytes) of CDR encoded data to be written.
|
|
||||||
*
|
*
|
||||||
* @returns A dds_return_t indicating success or failure.
|
* @returns A dds_return_t indicating success or failure.
|
||||||
*/
|
*/
|
||||||
|
@ -2604,7 +2603,7 @@ dds_take_mask_wl(
|
||||||
uint32_t maxs,
|
uint32_t maxs,
|
||||||
uint32_t mask);
|
uint32_t mask);
|
||||||
|
|
||||||
DDS_EXPORT int
|
DDS_EXPORT dds_return_t
|
||||||
dds_takecdr(
|
dds_takecdr(
|
||||||
dds_entity_t reader_or_condition,
|
dds_entity_t reader_or_condition,
|
||||||
struct ddsi_serdata **buf,
|
struct ddsi_serdata **buf,
|
||||||
|
@ -2898,7 +2897,7 @@ dds_read_next_wl(
|
||||||
* the memory is released so that the buffer can be reused during a successive read/take operation.
|
* the memory is released so that the buffer can be reused during a successive read/take operation.
|
||||||
* When a condition is provided, the reader to which the condition belongs is looked up.
|
* When a condition is provided, the reader to which the condition belongs is looked up.
|
||||||
*
|
*
|
||||||
* @param[in] rd_or_cnd Reader or condition that belongs to a reader.
|
* @param[in] reader_or_condition Reader or condition that belongs to a reader.
|
||||||
* @param[in] buf An array of (pointers to) samples.
|
* @param[in] buf An array of (pointers to) samples.
|
||||||
* @param[in] bufsz The number of (pointers to) samples stored in buf.
|
* @param[in] bufsz The number of (pointers to) samples stored in buf.
|
||||||
*
|
*
|
||||||
|
|
|
@ -212,8 +212,8 @@ dds_qos_merge (dds_qos_t * __restrict dst, const dds_qos_t * __restrict src);
|
||||||
*
|
*
|
||||||
* Policies are copied from src to dst, unless src already has the policy set to a non-default value.
|
* Policies are copied from src to dst, unless src already has the policy set to a non-default value.
|
||||||
*
|
*
|
||||||
* @param[in,out] dst - Pointer to the destination qos structure
|
* @param[in,out] a - Pointer to the destination qos structure
|
||||||
* @param[in] src - Pointer to the source qos structure
|
* @param[in] b - Pointer to the source qos structure
|
||||||
*/
|
*/
|
||||||
DDS_EXPORT bool
|
DDS_EXPORT bool
|
||||||
dds_qos_equal (const dds_qos_t * __restrict a, const dds_qos_t * __restrict b);
|
dds_qos_equal (const dds_qos_t * __restrict a, const dds_qos_t * __restrict b);
|
||||||
|
@ -448,7 +448,7 @@ dds_qset_destination_order (
|
||||||
* @brief Set the writer data-lifecycle policy of a qos structure
|
* @brief Set the writer data-lifecycle policy of a qos structure
|
||||||
*
|
*
|
||||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||||
* @param[in] autodispose_unregistered_instances - Automatic disposal of unregistered instances
|
* @param[in] autodispose - Automatic disposal of unregistered instances
|
||||||
*/
|
*/
|
||||||
DDS_EXPORT void
|
DDS_EXPORT void
|
||||||
dds_qset_writer_data_lifecycle (dds_qos_t * __restrict qos, bool autodispose);
|
dds_qset_writer_data_lifecycle (dds_qos_t * __restrict qos, bool autodispose);
|
||||||
|
@ -738,7 +738,7 @@ dds_qget_destination_order (
|
||||||
* @brief Get the writer data-lifecycle qos policy
|
* @brief Get the writer data-lifecycle qos policy
|
||||||
*
|
*
|
||||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||||
* @param[in,out] autodispose_unregistered_instances - Pointer that will store the autodispose unregistered instances enable value
|
* @param[in,out] autodispose - Pointer that will store the autodispose unregistered instances enable value
|
||||||
*
|
*
|
||||||
* @returns - false iff any of the arguments is invalid or the qos is not present in the qos object
|
* @returns - false iff any of the arguments is invalid or the qos is not present in the qos object
|
||||||
*/
|
*/
|
||||||
|
|
56
src/core/ddsc/src/dds__get_status.h
Normal file
56
src/core/ddsc/src/dds__get_status.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2019 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 _DDS_GET_STATUS_H_
|
||||||
|
#define _DDS_GET_STATUS_H_
|
||||||
|
|
||||||
|
#include "dds/ddsrt/countargs.h"
|
||||||
|
|
||||||
|
#define DDS_GET_STATUS_LOCKED_RESET_1(status_, reset0_) \
|
||||||
|
(ent->m_##status_##_status.reset0_ = 0);
|
||||||
|
#define DDS_GET_STATUS_LOCKED_RESET_2(status_, reset0_, reset1_) \
|
||||||
|
(ent->m_##status_##_status.reset0_ = 0); \
|
||||||
|
(ent->m_##status_##_status.reset1_ = 0);
|
||||||
|
#define DDS_GET_STATUS_LOCKED_RESET_MSVC_WORKAROUND(x) x
|
||||||
|
#define DDS_GET_STATUS_LOCKED_RESET_N1(n_, status_, ...) \
|
||||||
|
DDS_GET_STATUS_LOCKED_RESET_MSVC_WORKAROUND (DDS_GET_STATUS_LOCKED_RESET_##n_ (status_, __VA_ARGS__))
|
||||||
|
#define DDS_GET_STATUS_LOCKED_RESET_N(n_, status_, ...) DDS_GET_STATUS_LOCKED_RESET_N1 (n_, status_, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define DDS_GET_STATUS_LOCKED(ent_type_, status_, STATUS_, ...) \
|
||||||
|
static void dds_get_##status_##_status_locked (dds_##ent_type_ *ent, dds_##status_##_status_t *status) \
|
||||||
|
{ \
|
||||||
|
if (status) \
|
||||||
|
*status = ent->m_##status_##_status; \
|
||||||
|
if (ent->m_entity.m_status_enable & DDS_##STATUS_##_STATUS) { \
|
||||||
|
do { DDS_GET_STATUS_LOCKED_RESET_N (DDSRT_COUNT_ARGS (__VA_ARGS__), status_, __VA_ARGS__) } while (0); \
|
||||||
|
dds_entity_status_reset (&ent->m_entity, DDS_##STATUS_##_STATUS); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DDS_GET_STATUS_COMMON(ent_type_, status_) \
|
||||||
|
dds_return_t dds_get_##status_##_status (dds_entity_t entity, dds_##status_##_status_t *status) \
|
||||||
|
{ \
|
||||||
|
dds_##ent_type_ *ent; \
|
||||||
|
dds_return_t ret; \
|
||||||
|
if ((ret = dds_##ent_type_##_lock (entity, &ent)) != DDS_RETCODE_OK) \
|
||||||
|
return ret; \
|
||||||
|
ddsrt_mutex_lock (&ent->m_entity.m_observers_lock); \
|
||||||
|
dds_get_##status_##_status_locked (ent, status); \
|
||||||
|
ddsrt_mutex_unlock (&ent->m_entity.m_observers_lock); \
|
||||||
|
dds_##ent_type_##_unlock (ent); \
|
||||||
|
return DDS_RETCODE_OK; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DDS_GET_STATUS(ent_type_, status_, STATUS_, ...) \
|
||||||
|
DDS_GET_STATUS_LOCKED (ent_type_, status_, STATUS_, __VA_ARGS__) \
|
||||||
|
DDS_GET_STATUS_COMMON (ent_type_, status_)
|
||||||
|
|
||||||
|
#endif
|
|
@ -23,7 +23,7 @@ DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_subscriber, DDS_KIND_SUBSCRIBER)
|
||||||
|
|
||||||
dds_entity_t
|
dds_entity_t
|
||||||
dds__create_subscriber_l(
|
dds__create_subscriber_l(
|
||||||
struct dds_entity *participant, /* entity-lock must be held */
|
struct dds_participant *participant, /* entity-lock must be held */
|
||||||
const dds_qos_t *qos,
|
const dds_qos_t *qos,
|
||||||
const dds_listener_t *listener);
|
const dds_listener_t *listener);
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ extern "C" {
|
||||||
|
|
||||||
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_topic, DDS_KIND_TOPIC)
|
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_topic, DDS_KIND_TOPIC)
|
||||||
|
|
||||||
DDS_EXPORT struct ddsi_sertopic * dds_topic_lookup (dds_domain * domain, const char * name);
|
DDS_EXPORT struct ddsi_sertopic * dds_topic_lookup (dds_domain * domain, const char * name) ddsrt_nonnull_all;
|
||||||
DDS_EXPORT void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic * st);
|
DDS_EXPORT void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic * st) ddsrt_nonnull_all;
|
||||||
|
|
||||||
#ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
#ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
||||||
#define DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
#define DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
||||||
|
|
|
@ -104,12 +104,12 @@ dds_domain;
|
||||||
struct dds_entity;
|
struct dds_entity;
|
||||||
typedef struct dds_entity_deriver {
|
typedef struct dds_entity_deriver {
|
||||||
/* Close can be used to terminate (blocking) actions on a entity before actually deleting it. */
|
/* Close can be used to terminate (blocking) actions on a entity before actually deleting it. */
|
||||||
dds_return_t (*close)(struct dds_entity *e);
|
dds_return_t (*close)(struct dds_entity *e) ddsrt_nonnull_all;
|
||||||
/* Delete is used to actually free the entity. */
|
/* Delete is used to actually free the entity. */
|
||||||
dds_return_t (*delete)(struct dds_entity *e);
|
dds_return_t (*delete)(struct dds_entity *e) ddsrt_nonnull_all;
|
||||||
dds_return_t (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled);
|
dds_return_t (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
dds_return_t (*validate_status)(uint32_t mask);
|
dds_return_t (*validate_status)(uint32_t mask);
|
||||||
dds_return_t (*get_instance_hdl)(struct dds_entity *e, dds_instance_handle_t *i);
|
dds_return_t (*get_instance_hdl)(struct dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||||
}
|
}
|
||||||
dds_entity_deriver;
|
dds_entity_deriver;
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ bool dds__validate_builtin_reader_qos (dds_entity_t topic, const dds_qos_t *qos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_entity_t dds__create_builtin_subscriber (dds_entity *participant)
|
static dds_entity_t dds__create_builtin_subscriber (dds_participant *participant)
|
||||||
{
|
{
|
||||||
dds_qos_t *qos = dds__create_builtin_qos ();
|
dds_qos_t *qos = dds__create_builtin_qos ();
|
||||||
dds_entity_t sub = dds__create_subscriber_l (participant, qos, NULL);
|
dds_entity_t sub = dds__create_subscriber_l (participant, qos, NULL);
|
||||||
|
@ -153,7 +153,7 @@ dds_entity_t dds__get_builtin_subscriber (dds_entity_t e)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (p->m_builtin_subscriber <= 0) {
|
if (p->m_builtin_subscriber <= 0) {
|
||||||
p->m_builtin_subscriber = dds__create_builtin_subscriber (&p->m_entity);
|
p->m_builtin_subscriber = dds__create_builtin_subscriber (p);
|
||||||
}
|
}
|
||||||
sub = p->m_builtin_subscriber;
|
sub = p->m_builtin_subscriber;
|
||||||
dds_participant_unlock(p);
|
dds_participant_unlock(p);
|
||||||
|
|
|
@ -16,17 +16,13 @@
|
||||||
#include "dds__subscriber.h"
|
#include "dds__subscriber.h"
|
||||||
#include "dds__publisher.h"
|
#include "dds__publisher.h"
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_begin_coherent (dds_entity_t entity)
|
||||||
dds_begin_coherent(
|
|
||||||
dds_entity_t entity)
|
|
||||||
{
|
{
|
||||||
static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER };
|
static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER };
|
||||||
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_end_coherent (dds_entity_t entity)
|
||||||
dds_end_coherent(
|
|
||||||
dds_entity_t entity)
|
|
||||||
{
|
{
|
||||||
static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER };
|
static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER };
|
||||||
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
||||||
|
|
|
@ -12,27 +12,24 @@
|
||||||
#include "dds__domain.h"
|
#include "dds__domain.h"
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
|
|
||||||
static int dds_domain_compare (const int32_t * a, const int32_t * b)
|
static int dds_domain_compare (const void *va, const void *vb)
|
||||||
{
|
{
|
||||||
|
const int32_t *a = va;
|
||||||
|
const int32_t *b = vb;
|
||||||
return (*a == *b) ? 0 : (*a < *b) ? -1 : 1;
|
return (*a == *b) ? 0 : (*a < *b) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALIZER
|
const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALIZER (
|
||||||
(
|
offsetof (dds_domain, m_node), offsetof (dds_domain, m_id), dds_domain_compare, 0);
|
||||||
offsetof (dds_domain, m_node),
|
|
||||||
offsetof (dds_domain, m_id),
|
|
||||||
(int (*) (const void *, const void *)) dds_domain_compare,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
dds_domain * dds_domain_find_locked (dds_domainid_t id)
|
dds_domain *dds_domain_find_locked (dds_domainid_t id)
|
||||||
{
|
{
|
||||||
return ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &id);
|
return ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &id);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_domain * dds_domain_create (dds_domainid_t id)
|
dds_domain *dds_domain_create (dds_domainid_t id)
|
||||||
{
|
{
|
||||||
dds_domain * domain;
|
dds_domain *domain;
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
domain = dds_domain_find_locked (id);
|
domain = dds_domain_find_locked (id);
|
||||||
if (domain == NULL)
|
if (domain == NULL)
|
||||||
|
@ -47,7 +44,7 @@ dds_domain * dds_domain_create (dds_domainid_t id)
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dds_domain_free (dds_domain * domain)
|
void dds_domain_free (dds_domain *domain)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
if (--domain->m_refc == 0)
|
if (--domain->m_refc == 0)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_guardcond)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_guardcond)
|
||||||
|
|
||||||
dds_entity_t dds_create_guardcondition (dds_entity_t participant)
|
dds_entity_t dds_create_guardcondition (dds_entity_t participant)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,396 +23,307 @@
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_writedispose (dds_entity_t writer, const void *data)
|
||||||
dds_writedispose(
|
|
||||||
dds_entity_t writer,
|
|
||||||
const void *data)
|
|
||||||
{
|
{
|
||||||
return dds_writedispose_ts(writer, data, dds_time());
|
return dds_writedispose_ts (writer, data, dds_time ());
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_dispose (dds_entity_t writer, const void *data)
|
||||||
dds_dispose(
|
|
||||||
dds_entity_t writer,
|
|
||||||
const void *data)
|
|
||||||
{
|
{
|
||||||
return dds_dispose_ts(writer, data, dds_time());
|
return dds_dispose_ts (writer, data, dds_time ());
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_dispose_ih (dds_entity_t writer, dds_instance_handle_t handle)
|
||||||
dds_dispose_ih(
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_instance_handle_t handle)
|
|
||||||
{
|
{
|
||||||
return dds_dispose_ih_ts(writer, handle, dds_time());
|
return dds_dispose_ih_ts (writer, handle, dds_time ());
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ddsi_tkmap_instance*
|
static struct ddsi_tkmap_instance *dds_instance_find (const dds_topic *topic, const void *data, const bool create)
|
||||||
dds_instance_find(
|
|
||||||
const dds_topic *topic,
|
|
||||||
const void *data,
|
|
||||||
const bool create)
|
|
||||||
{
|
{
|
||||||
struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
|
struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
|
||||||
struct ddsi_tkmap_instance * inst = ddsi_tkmap_find (sd, false, create);
|
struct ddsi_tkmap_instance *inst = ddsi_tkmap_find (sd, false, create);
|
||||||
ddsi_serdata_unref (sd);
|
ddsi_serdata_unref (sd);
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dds_instance_remove (const dds_topic *topic, const void *data, dds_instance_handle_t handle)
|
||||||
dds_instance_remove(
|
|
||||||
const dds_topic *topic,
|
|
||||||
const void *data,
|
|
||||||
dds_instance_handle_t handle)
|
|
||||||
{
|
{
|
||||||
struct ddsi_tkmap_instance * inst;
|
struct ddsi_tkmap_instance *inst;
|
||||||
|
if (handle != DDS_HANDLE_NIL)
|
||||||
if (handle != DDS_HANDLE_NIL)
|
inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
|
||||||
{
|
else
|
||||||
inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
|
{
|
||||||
}
|
assert (data);
|
||||||
else
|
inst = dds_instance_find (topic, data, false);
|
||||||
{
|
}
|
||||||
assert (data);
|
if (inst)
|
||||||
inst = dds_instance_find (topic, data, false);
|
{
|
||||||
}
|
ddsi_tkmap_instance_unref (inst);
|
||||||
if (inst)
|
}
|
||||||
{
|
|
||||||
ddsi_tkmap_instance_unref (inst);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const dds_topic *dds_instance_info (dds_entity *e)
|
static const dds_topic *dds_instance_info (dds_entity *e)
|
||||||
{
|
{
|
||||||
const dds_topic *topic;
|
const dds_topic *topic;
|
||||||
switch (dds_entity_kind (e))
|
switch (dds_entity_kind (e))
|
||||||
{
|
{
|
||||||
case DDS_KIND_READER:
|
case DDS_KIND_READER:
|
||||||
topic = ((dds_reader*) e)->m_topic;
|
topic = ((dds_reader*) e)->m_topic;
|
||||||
break;
|
break;
|
||||||
case DDS_KIND_WRITER:
|
case DDS_KIND_WRITER:
|
||||||
topic = ((dds_writer*) e)->m_topic;
|
topic = ((dds_writer*) e)->m_topic;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert (0);
|
assert (0);
|
||||||
topic = NULL;
|
topic = NULL;
|
||||||
}
|
}
|
||||||
return topic;
|
return topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const dds_topic * dds_instance_info_by_hdl (dds_entity_t e)
|
static const dds_topic *dds_instance_info_by_hdl (dds_entity_t e)
|
||||||
{
|
{
|
||||||
const dds_topic * topic = NULL;
|
const dds_topic *topic;
|
||||||
dds_return_t rc;
|
dds_entity *w_or_r;
|
||||||
dds_entity *w_or_r;
|
|
||||||
|
|
||||||
rc = dds_entity_lock(e, DDS_KIND_WRITER, &w_or_r);
|
if (dds_entity_lock (e, DDS_KIND_DONTCARE, &w_or_r) != DDS_RETCODE_OK)
|
||||||
if (rc == DDS_RETCODE_ILLEGAL_OPERATION)
|
return NULL;
|
||||||
{
|
|
||||||
rc = dds_entity_lock(e, DDS_KIND_READER, &w_or_r);
|
switch (dds_entity_kind (w_or_r))
|
||||||
}
|
{
|
||||||
if (rc != DDS_RETCODE_OK)
|
case DDS_KIND_WRITER:
|
||||||
{
|
case DDS_KIND_READER:
|
||||||
return NULL;
|
topic = dds_instance_info (w_or_r);
|
||||||
}
|
break;
|
||||||
topic = dds_instance_info(w_or_r);
|
default:
|
||||||
dds_entity_unlock(w_or_r);
|
topic = NULL;
|
||||||
return topic;
|
break;
|
||||||
|
}
|
||||||
|
dds_entity_unlock (w_or_r);
|
||||||
|
return topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_register_instance (dds_entity_t writer, dds_instance_handle_t *handle, const void *data)
|
||||||
dds_register_instance(
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_instance_handle_t *handle,
|
|
||||||
const void *data)
|
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
struct ddsi_tkmap_instance * inst;
|
dds_writer *wr;
|
||||||
dds_writer *wr;
|
dds_return_t ret;
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
if(data == NULL){
|
if (data == NULL || handle == NULL)
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
}
|
|
||||||
if(handle == NULL){
|
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
inst = dds_instance_find (wr->m_topic, data, true);
|
|
||||||
if(inst != NULL){
|
|
||||||
*handle = inst->m_iid;
|
|
||||||
ret = DDS_RETCODE_OK;
|
|
||||||
} else {
|
|
||||||
ret = DDS_RETCODE_ERROR;
|
|
||||||
}
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
err:
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
thread_state_awake (ts1);
|
||||||
|
struct ddsi_tkmap_instance * const inst = dds_instance_find (wr->m_topic, data, true);
|
||||||
|
if (inst == NULL)
|
||||||
|
ret = DDS_RETCODE_ERROR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*handle = inst->m_iid;
|
||||||
|
ret = DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
thread_state_asleep (ts1);
|
||||||
|
dds_writer_unlock (wr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_unregister_instance (dds_entity_t writer, const void *data)
|
||||||
dds_unregister_instance(
|
|
||||||
dds_entity_t writer,
|
|
||||||
const void *data)
|
|
||||||
{
|
{
|
||||||
return dds_unregister_instance_ts (writer, data, dds_time());
|
return dds_unregister_instance_ts (writer, data, dds_time ());
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_unregister_instance_ih (dds_entity_t writer, dds_instance_handle_t handle)
|
||||||
dds_unregister_instance_ih(
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_instance_handle_t handle)
|
|
||||||
{
|
{
|
||||||
return dds_unregister_instance_ih_ts(writer, handle, dds_time());
|
return dds_unregister_instance_ih_ts (writer, handle, dds_time ());
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_unregister_instance_ts (dds_entity_t writer, const void *data, dds_time_t timestamp)
|
||||||
dds_unregister_instance_ts(
|
|
||||||
dds_entity_t writer,
|
|
||||||
const void *data,
|
|
||||||
dds_time_t timestamp)
|
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
dds_return_t ret;
|
||||||
bool autodispose = true;
|
bool autodispose = true;
|
||||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||||
dds_writer *wr;
|
dds_writer *wr;
|
||||||
|
|
||||||
if (data == NULL){
|
if (data == NULL || timestamp < 0)
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if(timestamp < 0){
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wr->m_entity.m_qos) {
|
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||||
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
|
|
||||||
}
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
if (autodispose) {
|
|
||||||
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
|
|
||||||
action |= DDS_WR_DISPOSE_BIT;
|
|
||||||
}
|
|
||||||
ret = dds_write_impl (wr, data, timestamp, action);
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
err:
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (wr->m_entity.m_qos)
|
||||||
|
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
|
||||||
|
|
||||||
|
thread_state_awake (ts1);
|
||||||
|
if (autodispose)
|
||||||
|
{
|
||||||
|
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
|
||||||
|
action |= DDS_WR_DISPOSE_BIT;
|
||||||
|
}
|
||||||
|
ret = dds_write_impl (wr, data, timestamp, action);
|
||||||
|
thread_state_asleep (ts1);
|
||||||
|
dds_writer_unlock (wr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_unregister_instance_ih_ts (dds_entity_t writer, dds_instance_handle_t handle, dds_time_t timestamp)
|
||||||
dds_unregister_instance_ih_ts(
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_instance_handle_t handle,
|
|
||||||
dds_time_t timestamp)
|
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
dds_return_t ret = DDS_RETCODE_OK;
|
||||||
bool autodispose = true;
|
bool autodispose = true;
|
||||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||||
dds_writer *wr;
|
dds_writer *wr;
|
||||||
struct ddsi_tkmap_instance *tk;
|
struct ddsi_tkmap_instance *tk;
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wr->m_entity.m_qos) {
|
|
||||||
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
|
|
||||||
}
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
if (autodispose) {
|
|
||||||
dds_instance_remove (wr->m_topic, NULL, handle);
|
|
||||||
action |= DDS_WR_DISPOSE_BIT;
|
|
||||||
}
|
|
||||||
tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
|
|
||||||
if (tk) {
|
|
||||||
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
|
|
||||||
void *sample = ddsi_sertopic_alloc_sample (tp);
|
|
||||||
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
|
|
||||||
ddsi_tkmap_instance_unref (tk);
|
|
||||||
ret = dds_write_impl (wr, sample, timestamp, action);
|
|
||||||
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
|
|
||||||
} else {
|
|
||||||
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
|
|
||||||
}
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
err:
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (wr->m_entity.m_qos)
|
||||||
|
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
|
||||||
|
|
||||||
|
thread_state_awake (ts1);
|
||||||
|
if (autodispose)
|
||||||
|
{
|
||||||
|
dds_instance_remove (wr->m_topic, NULL, handle);
|
||||||
|
action |= DDS_WR_DISPOSE_BIT;
|
||||||
|
}
|
||||||
|
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) == NULL)
|
||||||
|
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
|
||||||
|
void *sample = ddsi_sertopic_alloc_sample (tp);
|
||||||
|
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
|
||||||
|
ddsi_tkmap_instance_unref (tk);
|
||||||
|
ret = dds_write_impl (wr, sample, timestamp, action);
|
||||||
|
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
|
||||||
|
}
|
||||||
|
thread_state_asleep (ts1);
|
||||||
|
dds_writer_unlock (wr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_writedispose_ts (dds_entity_t writer, const void *data, dds_time_t timestamp)
|
||||||
dds_writedispose_ts(
|
|
||||||
dds_entity_t writer,
|
|
||||||
const void *data,
|
|
||||||
dds_time_t timestamp)
|
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
dds_return_t ret;
|
dds_return_t ret;
|
||||||
dds_writer *wr;
|
dds_writer *wr;
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_WRITE_DISPOSE);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
|
|
||||||
}
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
thread_state_awake (ts1);
|
||||||
|
if ((ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_WRITE_DISPOSE)) == DDS_RETCODE_OK)
|
||||||
|
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
|
||||||
|
thread_state_asleep (ts1);
|
||||||
|
dds_writer_unlock (wr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_dispose_impl (dds_writer *wr, const void *data, dds_instance_handle_t handle, dds_time_t timestamp) ddsrt_nonnull_all;
|
||||||
dds_dispose_impl(
|
|
||||||
dds_writer *wr,
|
static dds_return_t dds_dispose_impl (dds_writer *wr, const void *data, dds_instance_handle_t handle, dds_time_t timestamp)
|
||||||
const void *data,
|
|
||||||
dds_instance_handle_t handle,
|
|
||||||
dds_time_t timestamp)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret;
|
dds_return_t ret;
|
||||||
assert(thread_is_awake ());
|
assert (thread_is_awake ());
|
||||||
assert(wr);
|
if ((ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_DISPOSE)) == DDS_RETCODE_OK)
|
||||||
ret = dds_write_impl(wr, data, timestamp, DDS_WR_ACTION_DISPOSE);
|
dds_instance_remove (wr->m_topic, data, handle);
|
||||||
if (ret == DDS_RETCODE_OK) {
|
return ret;
|
||||||
dds_instance_remove (wr->m_topic, data, handle);
|
}
|
||||||
}
|
|
||||||
|
dds_return_t dds_dispose_ts (dds_entity_t writer, const void *data, dds_time_t timestamp)
|
||||||
|
{
|
||||||
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
|
dds_return_t ret;
|
||||||
|
dds_writer *wr;
|
||||||
|
|
||||||
|
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
thread_state_awake (ts1);
|
||||||
|
ret = dds_dispose_impl (wr, data, DDS_HANDLE_NIL, timestamp);
|
||||||
|
thread_state_asleep (ts1);
|
||||||
|
dds_writer_unlock(wr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_dispose_ih_ts (dds_entity_t writer, dds_instance_handle_t handle, dds_time_t timestamp)
|
||||||
dds_dispose_ts(
|
|
||||||
dds_entity_t writer,
|
|
||||||
const void *data,
|
|
||||||
dds_time_t timestamp)
|
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
dds_return_t ret;
|
dds_return_t ret;
|
||||||
dds_writer *wr;
|
dds_writer *wr;
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
ret = dds_dispose_impl(wr, data, DDS_HANDLE_NIL, timestamp);
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
struct ddsi_tkmap_instance *tk;
|
||||||
|
thread_state_awake (ts1);
|
||||||
|
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) == NULL)
|
||||||
|
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
|
||||||
|
void *sample = ddsi_sertopic_alloc_sample (tp);
|
||||||
|
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
|
||||||
|
ddsi_tkmap_instance_unref (tk);
|
||||||
|
ret = dds_dispose_impl (wr, sample, handle, timestamp);
|
||||||
|
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
|
||||||
|
}
|
||||||
|
thread_state_asleep (ts1);
|
||||||
|
dds_writer_unlock (wr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_instance_handle_t dds_lookup_instance (dds_entity_t entity, const void *data)
|
||||||
dds_dispose_ih_ts(
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_instance_handle_t handle,
|
|
||||||
dds_time_t timestamp)
|
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
dds_return_t ret;
|
dds_instance_handle_t ih = DDS_HANDLE_NIL;
|
||||||
dds_writer *wr;
|
const dds_topic *topic;
|
||||||
|
struct ddsi_serdata *sd;
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
if (data == NULL)
|
||||||
if (ret == DDS_RETCODE_OK) {
|
return DDS_HANDLE_NIL;
|
||||||
struct ddsi_tkmap_instance *tk;
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) != NULL) {
|
|
||||||
struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
|
|
||||||
void *sample = ddsi_sertopic_alloc_sample (tp);
|
|
||||||
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
|
|
||||||
ddsi_tkmap_instance_unref (tk);
|
|
||||||
ret = dds_dispose_impl (wr, sample, handle, timestamp);
|
|
||||||
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
|
|
||||||
} else {
|
|
||||||
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
|
|
||||||
}
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
if ((topic = dds_instance_info_by_hdl (entity)) == NULL)
|
||||||
|
return DDS_HANDLE_NIL;
|
||||||
|
|
||||||
|
thread_state_awake (ts1);
|
||||||
|
sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
|
||||||
|
ih = ddsi_tkmap_lookup (gv.m_tkmap, sd);
|
||||||
|
ddsi_serdata_unref (sd);
|
||||||
|
thread_state_asleep (ts1);
|
||||||
|
return ih;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_instance_handle_t
|
dds_instance_handle_t dds_instance_lookup (dds_entity_t entity, const void *data)
|
||||||
dds_lookup_instance(
|
|
||||||
dds_entity_t entity,
|
|
||||||
const void *data)
|
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
return dds_lookup_instance (entity, data);
|
||||||
dds_instance_handle_t ih = DDS_HANDLE_NIL;
|
|
||||||
const dds_topic * topic;
|
|
||||||
struct ddsi_tkmap * map = gv.m_tkmap;
|
|
||||||
struct ddsi_serdata *sd;
|
|
||||||
|
|
||||||
if(data == NULL){
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
topic = dds_instance_info_by_hdl (entity);
|
|
||||||
if (topic) {
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
|
|
||||||
ih = ddsi_tkmap_lookup (map, sd);
|
|
||||||
ddsi_serdata_unref (sd);
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
}
|
|
||||||
err:
|
|
||||||
return ih;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_instance_handle_t
|
dds_return_t dds_instance_get_key (dds_entity_t entity, dds_instance_handle_t ih, void *data)
|
||||||
dds_instance_lookup (
|
|
||||||
dds_entity_t entity,
|
|
||||||
const void *data)
|
|
||||||
{
|
{
|
||||||
return dds_lookup_instance(entity, data);
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
}
|
dds_return_t ret;
|
||||||
|
const dds_topic *topic;
|
||||||
dds_return_t
|
struct ddsi_tkmap_instance *tk;
|
||||||
dds_instance_get_key(
|
|
||||||
dds_entity_t entity,
|
if (data == NULL)
|
||||||
dds_instance_handle_t ih,
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
void *data)
|
|
||||||
{
|
if ((topic = dds_instance_info_by_hdl (entity)) == NULL)
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
dds_return_t ret;
|
|
||||||
const dds_topic * topic;
|
thread_state_awake (ts1);
|
||||||
struct ddsi_tkmap_instance * tk;
|
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, ih)) == NULL)
|
||||||
|
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||||
if(data == NULL){
|
else
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
{
|
||||||
goto err;
|
ddsi_sertopic_zero_sample (topic->m_stopic, data);
|
||||||
}
|
ddsi_serdata_topicless_to_sample (topic->m_stopic, tk->m_sample, data, NULL, NULL);
|
||||||
|
ddsi_tkmap_instance_unref (tk);
|
||||||
topic = dds_instance_info_by_hdl (entity);
|
ret = DDS_RETCODE_OK;
|
||||||
if(topic == NULL){
|
}
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
thread_state_asleep (ts1);
|
||||||
goto err;
|
return ret;
|
||||||
}
|
|
||||||
thread_state_awake (ts1);
|
|
||||||
if ((tk = ddsi_tkmap_find_by_id(gv.m_tkmap, ih)) != NULL) {
|
|
||||||
ddsi_sertopic_zero_sample (topic->m_stopic, data);
|
|
||||||
ddsi_serdata_topicless_to_sample (topic->m_stopic, tk->m_sample, data, NULL, NULL);
|
|
||||||
ddsi_tkmap_instance_unref (tk);
|
|
||||||
ret = DDS_RETCODE_OK;
|
|
||||||
} else {
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
thread_state_asleep (ts1);
|
|
||||||
err:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,324 +207,169 @@ void dds_merge_listener (dds_listener_t * __restrict dst, const dds_listener_t *
|
||||||
|
|
||||||
void dds_listener_merge (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
|
void dds_listener_merge (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
|
||||||
{
|
{
|
||||||
dds_merge_listener(dst, src);
|
dds_merge_listener (dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************
|
/************************************************************************************************
|
||||||
* Setters
|
* Setters
|
||||||
************************************************************************************************/
|
************************************************************************************************/
|
||||||
|
|
||||||
void
|
void dds_lset_data_available (dds_listener_t * __restrict listener, dds_on_data_available_fn callback)
|
||||||
dds_lset_data_available (dds_listener_t * __restrict listener, dds_on_data_available_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_data_available = callback;
|
listener->on_data_available = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_data_on_readers (dds_listener_t * __restrict listener, dds_on_data_on_readers_fn callback)
|
||||||
dds_lset_data_on_readers (dds_listener_t * __restrict listener, dds_on_data_on_readers_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_data_on_readers = callback;
|
listener->on_data_on_readers = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_inconsistent_topic (dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn callback)
|
||||||
dds_lset_inconsistent_topic (dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_inconsistent_topic = callback;
|
listener->on_inconsistent_topic = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_liveliness_changed (dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn callback)
|
||||||
dds_lset_liveliness_changed (dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_liveliness_changed = callback;
|
listener->on_liveliness_changed = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_liveliness_lost (dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn callback)
|
||||||
dds_lset_liveliness_lost (dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_liveliness_lost = callback;
|
listener->on_liveliness_lost = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_offered_deadline_missed (dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn callback)
|
||||||
dds_lset_offered_deadline_missed (dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_offered_deadline_missed = callback;
|
listener->on_offered_deadline_missed = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_offered_incompatible_qos (dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn callback)
|
||||||
dds_lset_offered_incompatible_qos (dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_offered_incompatible_qos = callback;
|
listener->on_offered_incompatible_qos = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_publication_matched (dds_listener_t * __restrict listener, dds_on_publication_matched_fn callback)
|
||||||
dds_lset_publication_matched (dds_listener_t * __restrict listener, dds_on_publication_matched_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_publication_matched = callback;
|
listener->on_publication_matched = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_requested_deadline_missed (dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn callback)
|
||||||
dds_lset_requested_deadline_missed (dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_requested_deadline_missed = callback;
|
listener->on_requested_deadline_missed = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_requested_incompatible_qos (dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn callback)
|
||||||
dds_lset_requested_incompatible_qos (dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_requested_incompatible_qos = callback;
|
listener->on_requested_incompatible_qos = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_sample_lost (dds_listener_t * __restrict listener, dds_on_sample_lost_fn callback)
|
||||||
dds_lset_sample_lost (dds_listener_t * __restrict listener, dds_on_sample_lost_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_sample_lost = callback;
|
listener->on_sample_lost = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_sample_rejected (dds_listener_t * __restrict listener, dds_on_sample_rejected_fn callback)
|
||||||
dds_lset_sample_rejected (dds_listener_t * __restrict listener, dds_on_sample_rejected_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_sample_rejected = callback;
|
listener->on_sample_rejected = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lset_subscription_matched (dds_listener_t * __restrict listener, dds_on_subscription_matched_fn callback)
|
||||||
dds_lset_subscription_matched (dds_listener_t * __restrict listener, dds_on_subscription_matched_fn callback)
|
|
||||||
{
|
{
|
||||||
if (listener) {
|
if (listener)
|
||||||
listener->on_subscription_matched = callback;
|
listener->on_subscription_matched = callback;
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************
|
/************************************************************************************************
|
||||||
* Getters
|
* Getters
|
||||||
************************************************************************************************/
|
************************************************************************************************/
|
||||||
|
|
||||||
void
|
void dds_lget_data_available (const dds_listener_t * __restrict listener, dds_on_data_available_fn *callback)
|
||||||
dds_lget_data_available (const dds_listener_t * __restrict listener, dds_on_data_available_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_data_available;
|
*callback = listener->on_data_available;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_data_on_readers (const dds_listener_t * __restrict listener, dds_on_data_on_readers_fn *callback)
|
||||||
dds_lget_data_on_readers (const dds_listener_t * __restrict listener, dds_on_data_on_readers_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_data_on_readers;
|
*callback = listener->on_data_on_readers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dds_lget_inconsistent_topic (const dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn *callback)
|
void dds_lget_inconsistent_topic (const dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn *callback)
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_inconsistent_topic;
|
*callback = listener->on_inconsistent_topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_liveliness_changed (const dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn *callback)
|
||||||
dds_lget_liveliness_changed (const dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_liveliness_changed;
|
*callback = listener->on_liveliness_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_liveliness_lost (const dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn *callback)
|
||||||
dds_lget_liveliness_lost (const dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_liveliness_lost;
|
*callback = listener->on_liveliness_lost;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_offered_deadline_missed (const dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn *callback)
|
||||||
dds_lget_offered_deadline_missed (const dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_offered_deadline_missed;
|
*callback = listener->on_offered_deadline_missed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_offered_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn *callback)
|
||||||
dds_lget_offered_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_offered_incompatible_qos;
|
*callback = listener->on_offered_incompatible_qos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_publication_matched (const dds_listener_t * __restrict listener, dds_on_publication_matched_fn *callback)
|
||||||
dds_lget_publication_matched (const dds_listener_t * __restrict listener, dds_on_publication_matched_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback){
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_publication_matched;
|
*callback = listener->on_publication_matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_requested_deadline_missed (const dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn *callback)
|
||||||
dds_lget_requested_deadline_missed (const dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback) {
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_requested_deadline_missed;
|
*callback = listener->on_requested_deadline_missed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_requested_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn *callback)
|
||||||
dds_lget_requested_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback) {
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_requested_incompatible_qos;
|
*callback = listener->on_requested_incompatible_qos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_sample_lost (const dds_listener_t *__restrict listener, dds_on_sample_lost_fn *callback)
|
||||||
dds_lget_sample_lost (const dds_listener_t *__restrict listener, dds_on_sample_lost_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback) {
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_sample_lost;
|
*callback = listener->on_sample_lost;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_sample_rejected (const dds_listener_t *__restrict listener, dds_on_sample_rejected_fn *callback)
|
||||||
dds_lget_sample_rejected (const dds_listener_t *__restrict listener, dds_on_sample_rejected_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback) {
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_sample_rejected;
|
*callback = listener->on_sample_rejected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_lget_subscription_matched (const dds_listener_t * __restrict listener, dds_on_subscription_matched_fn *callback)
|
||||||
dds_lget_subscription_matched (const dds_listener_t * __restrict listener, dds_on_subscription_matched_fn *callback)
|
|
||||||
{
|
{
|
||||||
if(!callback) {
|
if (callback && listener)
|
||||||
DDS_ERROR("Argument callback is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (!listener) {
|
|
||||||
DDS_ERROR("Argument listener is NULL\n");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
*callback = listener->on_subscription_matched;
|
*callback = listener->on_subscription_matched;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,260 +21,183 @@
|
||||||
#include "dds__participant.h"
|
#include "dds__participant.h"
|
||||||
#include "dds__builtin.h"
|
#include "dds__builtin.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_participant)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_participant)
|
||||||
|
|
||||||
#define DDS_PARTICIPANT_STATUS_MASK 0u
|
#define DDS_PARTICIPANT_STATUS_MASK (0u)
|
||||||
|
|
||||||
/* List of created participants */
|
/* List of created participants */
|
||||||
|
static dds_entity *dds_pp_head = NULL;
|
||||||
|
|
||||||
static dds_entity * dds_pp_head = NULL;
|
static dds_return_t dds_participant_status_validate (uint32_t mask)
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_participant_status_validate(
|
|
||||||
uint32_t mask)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
return (mask & ~DDS_PARTICIPANT_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||||
|
|
||||||
if (mask & ~(DDS_PARTICIPANT_STATUS_MASK)) {
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_participant_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||||
dds_participant_delete(
|
|
||||||
dds_entity *e)
|
static dds_return_t dds_participant_delete (dds_entity *e)
|
||||||
{
|
{
|
||||||
dds_entity *prev = NULL;
|
assert (dds_entity_kind (e) == DDS_KIND_PARTICIPANT);
|
||||||
dds_entity *iter;
|
|
||||||
|
|
||||||
assert(e);
|
thread_state_awake (lookup_thread_state ());
|
||||||
assert(dds_entity_kind(e) == DDS_KIND_PARTICIPANT);
|
dds_domain_free (e->m_domain);
|
||||||
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
|
dds_entity *prev, *iter;
|
||||||
|
for (iter = dds_pp_head, prev = NULL; iter; prev = iter, iter = iter->m_next)
|
||||||
|
{
|
||||||
|
if (iter == e)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert (iter);
|
||||||
|
if (prev)
|
||||||
|
prev->m_next = iter->m_next;
|
||||||
|
else
|
||||||
|
dds_pp_head = iter->m_next;
|
||||||
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
/* Every dds_init needs a dds_fini. */
|
||||||
|
dds_fini ();
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
dds_domain_free (e->m_domain);
|
static dds_return_t dds_participant_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_participant_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||||
|
{
|
||||||
|
*i = participant_instance_id (&e->m_guid);
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_participant_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_participant_qos_validate (const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
(void)enabled;
|
||||||
|
|
||||||
|
if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_participant_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_participant_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
dds_return_t ret;
|
||||||
|
(void)e;
|
||||||
|
if ((ret = dds_participant_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
|
||||||
|
return ret;
|
||||||
|
if (enabled) /* FIXME: changing QoS */
|
||||||
|
return DDS_RETCODE_UNSUPPORTED;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||||
|
{
|
||||||
|
dds_entity_t ret;
|
||||||
|
nn_guid_t guid;
|
||||||
|
dds_participant * pp;
|
||||||
|
nn_plist_t plist;
|
||||||
|
dds_qos_t *new_qos = NULL;
|
||||||
|
|
||||||
|
/* Make sure DDS instance is initialized. */
|
||||||
|
if ((ret = dds_init (domain)) != DDS_RETCODE_OK)
|
||||||
|
goto err_dds_init;
|
||||||
|
|
||||||
|
/* Check domain id */
|
||||||
|
if ((ret = dds__check_domain (domain)) != DDS_RETCODE_OK)
|
||||||
|
goto err_domain_check;
|
||||||
|
|
||||||
|
/* Validate qos or use default if NULL */
|
||||||
|
if (qos && (ret = dds_participant_qos_validate (qos, false)) != DDS_RETCODE_OK)
|
||||||
|
goto err_qos_validation;
|
||||||
|
|
||||||
|
new_qos = dds_create_qos ();
|
||||||
|
if (qos != NULL)
|
||||||
|
(void) dds_copy_qos (new_qos, qos);
|
||||||
|
|
||||||
|
/* Translate qos */
|
||||||
|
nn_plist_init_empty (&plist);
|
||||||
|
dds_merge_qos (&plist.qos, new_qos);
|
||||||
|
|
||||||
|
thread_state_awake (lookup_thread_state ());
|
||||||
|
ret = new_participant (&guid, 0, &plist);
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
nn_plist_fini (&plist);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ret = DDS_RETCODE_ERROR;
|
||||||
|
goto err_new_participant;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp = dds_alloc (sizeof (*pp));
|
||||||
|
if ((ret = dds_entity_init (&pp->m_entity, NULL, DDS_KIND_PARTICIPANT, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK)) < 0)
|
||||||
|
goto err_entity_init;
|
||||||
|
|
||||||
|
pp->m_entity.m_guid = guid;
|
||||||
|
pp->m_entity.m_domain = dds_domain_create (dds_domain_default ());
|
||||||
|
pp->m_entity.m_domainid = dds_domain_default ();
|
||||||
|
pp->m_entity.m_deriver.delete = dds_participant_delete;
|
||||||
|
pp->m_entity.m_deriver.set_qos = dds_participant_qos_set;
|
||||||
|
pp->m_entity.m_deriver.get_instance_hdl = dds_participant_instance_hdl;
|
||||||
|
pp->m_entity.m_deriver.validate_status = dds_participant_status_validate;
|
||||||
|
pp->m_builtin_subscriber = 0;
|
||||||
|
|
||||||
|
/* Add participant to extent */
|
||||||
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
|
pp->m_entity.m_next = dds_pp_head;
|
||||||
|
dds_pp_head = &pp->m_entity;
|
||||||
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
err_entity_init:
|
||||||
|
dds_free (pp);
|
||||||
|
err_new_participant:
|
||||||
|
dds_delete_qos (new_qos);
|
||||||
|
err_qos_validation:
|
||||||
|
err_domain_check:
|
||||||
|
dds_fini ();
|
||||||
|
err_dds_init:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dds_entity_t dds_lookup_participant (dds_domainid_t domain_id, dds_entity_t *participants, size_t size)
|
||||||
|
{
|
||||||
|
ddsrt_mutex_t *init_mutex;
|
||||||
|
|
||||||
|
ddsrt_init ();
|
||||||
|
init_mutex = ddsrt_get_singleton_mutex ();
|
||||||
|
|
||||||
|
if ((participants != NULL && (size <= 0 || size >= INT32_MAX)) || (participants == NULL && size != 0))
|
||||||
|
{
|
||||||
|
ddsrt_fini ();
|
||||||
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (participants)
|
||||||
|
participants[0] = 0;
|
||||||
|
|
||||||
|
dds_return_t ret = 0;
|
||||||
|
ddsrt_mutex_lock (init_mutex);
|
||||||
|
if (dds_global.m_init_count > 0)
|
||||||
|
{
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
iter = dds_pp_head;
|
for (dds_entity *iter = dds_pp_head; iter; iter = iter->m_next)
|
||||||
while (iter) {
|
{
|
||||||
if (iter == e) {
|
if (iter->m_domainid == domain_id)
|
||||||
if (prev) {
|
{
|
||||||
prev->m_next = iter->m_next;
|
if ((size_t) ret < size)
|
||||||
} else {
|
participants[ret] = iter->m_hdllink.hdl;
|
||||||
dds_pp_head = iter->m_next;
|
ret++;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
prev = iter;
|
|
||||||
iter = iter->m_next;
|
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
|
}
|
||||||
assert (iter);
|
ddsrt_mutex_unlock (init_mutex);
|
||||||
|
ddsrt_fini ();
|
||||||
thread_state_asleep (lookup_thread_state ());
|
return ret;
|
||||||
|
|
||||||
/* Every dds_init needs a dds_fini. */
|
|
||||||
dds_fini();
|
|
||||||
|
|
||||||
return DDS_RETCODE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_participant_instance_hdl(
|
|
||||||
dds_entity *e,
|
|
||||||
dds_instance_handle_t *i)
|
|
||||||
{
|
|
||||||
assert(e);
|
|
||||||
assert(i);
|
|
||||||
*i = (dds_instance_handle_t)participant_instance_id(&e->m_guid);
|
|
||||||
return DDS_RETCODE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_participant_qos_validate(
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
|
||||||
assert(qos);
|
|
||||||
(void)enabled;
|
|
||||||
|
|
||||||
/* Check consistency. */
|
|
||||||
if ((qos->present & QP_USER_DATA) && !validate_octetseq(&qos->user_data)) {
|
|
||||||
DDS_ERROR("User data QoS policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)) {
|
|
||||||
DDS_ERROR("Prismtech entity factory QoS policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_participant_qos_set(
|
|
||||||
dds_entity *e,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = dds_participant_qos_validate(qos, enabled);
|
|
||||||
(void)e;
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
if (enabled) {
|
|
||||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
|
||||||
DDS_ERROR("Changing the participant QoS is not supported\n");
|
|
||||||
ret = DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_entity_t
|
|
||||||
dds_create_participant(
|
|
||||||
const dds_domainid_t domain,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
const dds_listener_t *listener)
|
|
||||||
{
|
|
||||||
int q_rc;
|
|
||||||
dds_return_t ret;
|
|
||||||
dds_entity_t e;
|
|
||||||
nn_guid_t guid;
|
|
||||||
dds_participant * pp;
|
|
||||||
nn_plist_t plist;
|
|
||||||
dds_qos_t * new_qos = NULL;
|
|
||||||
|
|
||||||
/* Make sure DDS instance is initialized. */
|
|
||||||
ret = dds_init(domain);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
e = (dds_entity_t)ret;
|
|
||||||
goto fail_dds_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check domain id */
|
|
||||||
ret = dds__check_domain (domain);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
e = (dds_entity_t)ret;
|
|
||||||
goto fail_domain_check;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Validate qos */
|
|
||||||
if (qos) {
|
|
||||||
ret = dds_participant_qos_validate (qos, false);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
e = (dds_entity_t)ret;
|
|
||||||
goto fail_qos_validation;
|
|
||||||
}
|
|
||||||
new_qos = dds_create_qos ();
|
|
||||||
/* Only returns failure when one of the qos args is NULL, which
|
|
||||||
* is not the case here. */
|
|
||||||
(void)dds_copy_qos(new_qos, qos);
|
|
||||||
} else {
|
|
||||||
/* Use default qos. */
|
|
||||||
new_qos = dds_create_qos ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Translate qos */
|
|
||||||
nn_plist_init_empty(&plist);
|
|
||||||
dds_merge_qos (&plist.qos, new_qos);
|
|
||||||
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
|
||||||
q_rc = new_participant (&guid, 0, &plist);
|
|
||||||
thread_state_asleep (lookup_thread_state ());
|
|
||||||
nn_plist_fini (&plist);
|
|
||||||
if (q_rc != 0) {
|
|
||||||
DDS_ERROR("Internal error");
|
|
||||||
e = DDS_RETCODE_ERROR;
|
|
||||||
goto fail_new_participant;
|
|
||||||
}
|
|
||||||
|
|
||||||
pp = dds_alloc (sizeof (*pp));
|
|
||||||
e = dds_entity_init (&pp->m_entity, NULL, DDS_KIND_PARTICIPANT, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK);
|
|
||||||
if (e < 0) {
|
|
||||||
goto fail_entity_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
pp->m_entity.m_guid = guid;
|
|
||||||
pp->m_entity.m_domain = dds_domain_create (dds_domain_default());
|
|
||||||
pp->m_entity.m_domainid = dds_domain_default();
|
|
||||||
pp->m_entity.m_deriver.delete = dds_participant_delete;
|
|
||||||
pp->m_entity.m_deriver.set_qos = dds_participant_qos_set;
|
|
||||||
pp->m_entity.m_deriver.get_instance_hdl = dds_participant_instance_hdl;
|
|
||||||
pp->m_entity.m_deriver.validate_status = dds_participant_status_validate;
|
|
||||||
pp->m_builtin_subscriber = 0;
|
|
||||||
|
|
||||||
/* Add participant to extent */
|
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
|
||||||
pp->m_entity.m_next = dds_pp_head;
|
|
||||||
dds_pp_head = &pp->m_entity;
|
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
|
||||||
|
|
||||||
return e;
|
|
||||||
|
|
||||||
fail_entity_init:
|
|
||||||
dds_free(pp);
|
|
||||||
fail_new_participant:
|
|
||||||
dds_delete_qos(new_qos);
|
|
||||||
fail_qos_validation:
|
|
||||||
fail_domain_check:
|
|
||||||
dds_fini();
|
|
||||||
fail_dds_init:
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_entity_t
|
|
||||||
dds_lookup_participant(
|
|
||||||
dds_domainid_t domain_id,
|
|
||||||
dds_entity_t *participants,
|
|
||||||
size_t size)
|
|
||||||
{
|
|
||||||
dds_return_t ret = 0;
|
|
||||||
ddsrt_mutex_t *init_mutex;
|
|
||||||
|
|
||||||
/* Be sure the DDS lifecycle resources are initialized. */
|
|
||||||
ddsrt_init();
|
|
||||||
init_mutex = ddsrt_get_singleton_mutex();
|
|
||||||
|
|
||||||
if ((participants != NULL) && ((size <= 0) || (size >= INT32_MAX))) {
|
|
||||||
DDS_ERROR("Array is given, but with invalid size\n");
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if ((participants == NULL) && (size != 0)) {
|
|
||||||
DDS_ERROR("Size is given, but no array\n");
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(participants){
|
|
||||||
participants[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ddsrt_mutex_lock (init_mutex);
|
|
||||||
|
|
||||||
/* Check if dds is intialized. */
|
|
||||||
if (dds_global.m_init_count > 0) {
|
|
||||||
dds_entity* iter;
|
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
|
||||||
iter = dds_pp_head;
|
|
||||||
while (iter) {
|
|
||||||
if (iter->m_domainid == domain_id) {
|
|
||||||
if ((size_t)ret < size) {
|
|
||||||
participants[ret] = iter->m_hdllink.hdl;
|
|
||||||
}
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
iter = iter->m_next;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
ddsrt_mutex_unlock (init_mutex);
|
|
||||||
|
|
||||||
err:
|
|
||||||
ddsrt_fini();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,153 +13,102 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "dds/ddsrt/misc.h"
|
#include "dds/ddsrt/misc.h"
|
||||||
#include "dds__listener.h"
|
#include "dds__listener.h"
|
||||||
|
#include "dds__participant.h"
|
||||||
#include "dds__publisher.h"
|
#include "dds__publisher.h"
|
||||||
#include "dds__qos.h"
|
#include "dds__qos.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/version.h"
|
#include "dds/version.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_publisher)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_publisher)
|
||||||
|
|
||||||
#define DDS_PUBLISHER_STATUS_MASK 0u
|
#define DDS_PUBLISHER_STATUS_MASK (0u)
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_publisher_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||||
dds_publisher_instance_hdl(
|
|
||||||
dds_entity *e,
|
static dds_return_t dds_publisher_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||||
dds_instance_handle_t *i)
|
|
||||||
{
|
{
|
||||||
(void)e;
|
/* FIXME: Get/generate proper handle. */
|
||||||
(void)i;
|
(void) e;
|
||||||
/* TODO: Get/generate proper handle. */
|
(void) i;
|
||||||
DDS_ERROR("Getting publisher instance handle is not supported\n");
|
return DDS_RETCODE_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_publisher_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_publisher_qos_validate (const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy (&qos->presentation) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PARTITION) && !validate_stringseq (&qos->partition))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
/* FIXME: Improve/check immutable check. */
|
||||||
|
if (enabled && (qos->present & QP_PRESENTATION))
|
||||||
|
return DDS_RETCODE_IMMUTABLE_POLICY;
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_publisher_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_publisher_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
dds_return_t ret;
|
||||||
|
(void)e;
|
||||||
|
if ((ret = dds_publisher_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
|
||||||
|
return ret;
|
||||||
|
if (enabled) /* FIXME: QoS changes. */
|
||||||
return DDS_RETCODE_UNSUPPORTED;
|
return DDS_RETCODE_UNSUPPORTED;
|
||||||
}
|
return DDS_RETCODE_OK;
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_publisher_qos_validate(
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
|
||||||
assert(qos);
|
|
||||||
|
|
||||||
/* Check consistency. */
|
|
||||||
if((qos->present & QP_GROUP_DATA) && !validate_octetseq(&qos->group_data)){
|
|
||||||
DDS_ERROR("Group data policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_PRESENTATION) && (validate_presentation_qospolicy(&qos->presentation) != 0)){
|
|
||||||
DDS_ERROR("Presentation policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_PARTITION) && !validate_stringseq(&qos->partition)){
|
|
||||||
DDS_ERROR("Partition policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)){
|
|
||||||
DDS_ERROR("Prismtech entity factory policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if(ret == DDS_RETCODE_OK && enabled && (qos->present & QP_PRESENTATION)){
|
|
||||||
/* TODO: Improve/check immutable check. */
|
|
||||||
DDS_ERROR("Presentation policy is immutable\n");
|
|
||||||
ret = DDS_RETCODE_IMMUTABLE_POLICY;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_publisher_qos_set(
|
|
||||||
dds_entity *e,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = dds_publisher_qos_validate(qos, enabled);
|
|
||||||
(void)e;
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
if (enabled) {
|
|
||||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
|
||||||
DDS_ERROR(DDS_PROJECT_NAME" does not support changing QoS policies yet\n");
|
|
||||||
ret = DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t dds_publisher_status_validate (uint32_t mask)
|
static dds_return_t dds_publisher_status_validate (uint32_t mask)
|
||||||
{
|
{
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
return (mask & ~DDS_PUBLISHER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (mask & ~(DDS_PUBLISHER_STATUS_MASK)) {
|
dds_entity_t dds_create_publisher (dds_entity_t participant, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||||
DDS_ERROR("Invalid status mask\n");
|
{
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
dds_participant *par;
|
||||||
}
|
dds_publisher *pub;
|
||||||
|
dds_entity_t hdl;
|
||||||
|
dds_qos_t *new_qos = NULL;
|
||||||
|
dds_return_t ret;
|
||||||
|
|
||||||
|
if (qos && (ret = dds_publisher_qos_validate (qos, false)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (qos)
|
||||||
|
{
|
||||||
|
new_qos = dds_create_qos ();
|
||||||
|
(void) dds_copy_qos (new_qos, qos);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub = dds_alloc (sizeof (*pub));
|
||||||
|
hdl = dds_entity_init (&pub->m_entity, &par->m_entity, DDS_KIND_PUBLISHER, new_qos, listener, DDS_PUBLISHER_STATUS_MASK);
|
||||||
|
pub->m_entity.m_deriver.set_qos = dds_publisher_qos_set;
|
||||||
|
pub->m_entity.m_deriver.get_instance_hdl = dds_publisher_instance_hdl;
|
||||||
|
pub->m_entity.m_deriver.validate_status = dds_publisher_status_validate;
|
||||||
|
dds_participant_unlock (par);
|
||||||
|
return hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_t
|
dds_return_t dds_suspend (dds_entity_t publisher)
|
||||||
dds_create_publisher(
|
|
||||||
dds_entity_t participant,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
const dds_listener_t *listener)
|
|
||||||
{
|
|
||||||
dds_entity * par;
|
|
||||||
dds_publisher * pub;
|
|
||||||
dds_entity_t hdl;
|
|
||||||
dds_qos_t * new_qos = NULL;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking participant\n");
|
|
||||||
hdl = ret;
|
|
||||||
goto lock_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Validate qos */
|
|
||||||
if (qos) {
|
|
||||||
ret = dds_publisher_qos_validate(qos, false);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
hdl = ret;
|
|
||||||
goto qos_err;
|
|
||||||
}
|
|
||||||
new_qos = dds_create_qos ();
|
|
||||||
/* Only returns failure when one of the qos args is NULL, which
|
|
||||||
* is not the case here. */
|
|
||||||
(void)dds_copy_qos(new_qos, qos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create publisher */
|
|
||||||
pub = dds_alloc (sizeof (*pub));
|
|
||||||
hdl = dds_entity_init (&pub->m_entity, par, DDS_KIND_PUBLISHER, new_qos, listener, DDS_PUBLISHER_STATUS_MASK);
|
|
||||||
pub->m_entity.m_deriver.set_qos = dds_publisher_qos_set;
|
|
||||||
pub->m_entity.m_deriver.get_instance_hdl = dds_publisher_instance_hdl;
|
|
||||||
pub->m_entity.m_deriver.validate_status = dds_publisher_status_validate;
|
|
||||||
|
|
||||||
qos_err:
|
|
||||||
dds_entity_unlock(par);
|
|
||||||
lock_err:
|
|
||||||
return hdl;
|
|
||||||
}
|
|
||||||
|
|
||||||
DDS_EXPORT dds_return_t
|
|
||||||
dds_suspend(
|
|
||||||
dds_entity_t publisher)
|
|
||||||
{
|
{
|
||||||
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_resume (dds_entity_t publisher)
|
||||||
dds_resume(
|
|
||||||
dds_entity_t publisher)
|
|
||||||
{
|
{
|
||||||
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_wait_for_acks (dds_entity_t publisher_or_writer, dds_duration_t timeout)
|
||||||
dds_wait_for_acks(
|
|
||||||
dds_entity_t publisher_or_writer,
|
|
||||||
dds_duration_t timeout)
|
|
||||||
{
|
{
|
||||||
if (timeout < 0)
|
if (timeout < 0)
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
@ -167,23 +116,12 @@ dds_wait_for_acks(
|
||||||
return dds_generic_unimplemented_operation_manykinds (publisher_or_writer, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
return dds_generic_unimplemented_operation_manykinds (publisher_or_writer, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_publisher_begin_coherent (dds_entity_t publisher)
|
||||||
dds_publisher_begin_coherent(
|
|
||||||
dds_entity_t e)
|
|
||||||
{
|
{
|
||||||
/* TODO: CHAM-124 Currently unsupported. */
|
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||||
(void)e;
|
|
||||||
DDS_ERROR("Using coherency to get a coherent data set is not being supported yet\n");
|
|
||||||
return DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_publisher_end_coherent (dds_entity_t publisher)
|
||||||
dds_publisher_end_coherent(
|
|
||||||
dds_entity_t e)
|
|
||||||
{
|
{
|
||||||
/* TODO: CHAM-124 Currently unsupported. */
|
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||||
(void)e;
|
|
||||||
DDS_ERROR("Using coherency to get a coherent data set is not being supported yet\n");
|
|
||||||
return DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,32 +21,27 @@
|
||||||
#include "dds/ddsi/ddsi_serdata.h"
|
#include "dds/ddsi/ddsi_serdata.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
|
|
||||||
DDS_EXPORT dds_entity_t
|
dds_entity_t dds_create_querycondition (dds_entity_t reader, uint32_t mask, dds_querycondition_filter_fn filter)
|
||||||
dds_create_querycondition(
|
|
||||||
dds_entity_t reader,
|
|
||||||
uint32_t mask,
|
|
||||||
dds_querycondition_filter_fn filter)
|
|
||||||
{
|
{
|
||||||
|
dds_return_t rc;
|
||||||
|
dds_reader *r;
|
||||||
|
|
||||||
|
if ((rc = dds_reader_lock (reader, &r)) != DDS_RETCODE_OK)
|
||||||
|
return rc;
|
||||||
|
else
|
||||||
|
{
|
||||||
dds_entity_t hdl;
|
dds_entity_t hdl;
|
||||||
dds_return_t rc;
|
dds_readcond *cond = dds_create_readcond (r, DDS_KIND_COND_QUERY, mask, filter);
|
||||||
dds_reader *r;
|
assert (cond);
|
||||||
|
const bool success = (cond->m_entity.m_deriver.delete != 0);
|
||||||
rc = dds_reader_lock(reader, &r);
|
dds_reader_unlock (r);
|
||||||
if (rc == DDS_RETCODE_OK) {
|
if (success)
|
||||||
dds_readcond *cond = dds_create_readcond(r, DDS_KIND_COND_QUERY, mask, filter);
|
hdl = cond->m_entity.m_hdllink.hdl;
|
||||||
assert(cond);
|
else
|
||||||
const bool success = (cond->m_entity.m_deriver.delete != 0);
|
{
|
||||||
dds_reader_unlock(r);
|
dds_delete (cond->m_entity.m_hdllink.hdl);
|
||||||
if (success) {
|
hdl = DDS_RETCODE_OUT_OF_RESOURCES;
|
||||||
hdl = cond->m_entity.m_hdllink.hdl;
|
|
||||||
} else {
|
|
||||||
dds_delete (cond->m_entity.m_hdllink.hdl);
|
|
||||||
hdl = DDS_RETCODE_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
|
||||||
hdl = rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hdl;
|
return hdl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,65 +18,56 @@
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_readcond_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||||
dds_readcond_delete(
|
|
||||||
dds_entity *e)
|
static dds_return_t dds_readcond_delete (dds_entity *e)
|
||||||
{
|
{
|
||||||
dds_rhc_remove_readcondition((dds_readcond*)e);
|
dds_rhc_remove_readcondition ((dds_readcond *) e);
|
||||||
return DDS_RETCODE_OK;
|
return DDS_RETCODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_readcond*
|
dds_readcond *dds_create_readcond (dds_reader *rd, dds_entity_kind_t kind, uint32_t mask, dds_querycondition_filter_fn filter)
|
||||||
dds_create_readcond(
|
|
||||||
dds_reader *rd,
|
|
||||||
dds_entity_kind_t kind,
|
|
||||||
uint32_t mask,
|
|
||||||
dds_querycondition_filter_fn filter)
|
|
||||||
{
|
{
|
||||||
dds_readcond * cond = dds_alloc(sizeof(*cond));
|
dds_readcond *cond = dds_alloc (sizeof (*cond));
|
||||||
assert((kind == DDS_KIND_COND_READ && filter == 0) || (kind == DDS_KIND_COND_QUERY && filter != 0));
|
assert ((kind == DDS_KIND_COND_READ && filter == 0) || (kind == DDS_KIND_COND_QUERY && filter != 0));
|
||||||
(void) dds_entity_init(&cond->m_entity, (dds_entity*)rd, kind, NULL, NULL, 0);
|
(void) dds_entity_init (&cond->m_entity, &rd->m_entity, kind, NULL, NULL, 0);
|
||||||
cond->m_entity.m_deriver.delete = dds_readcond_delete;
|
cond->m_entity.m_deriver.delete = dds_readcond_delete;
|
||||||
cond->m_rhc = rd->m_rd->rhc;
|
cond->m_rhc = rd->m_rd->rhc;
|
||||||
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
|
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
|
||||||
cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
|
cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
|
||||||
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
|
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
|
||||||
cond->m_rd_guid = rd->m_entity.m_guid;
|
cond->m_rd_guid = rd->m_entity.m_guid;
|
||||||
if (kind == DDS_KIND_COND_QUERY) {
|
if (kind == DDS_KIND_COND_QUERY)
|
||||||
cond->m_query.m_filter = filter;
|
{
|
||||||
cond->m_query.m_qcmask = 0;
|
cond->m_query.m_filter = filter;
|
||||||
}
|
cond->m_query.m_qcmask = 0;
|
||||||
if (!dds_rhc_add_readcondition (cond)) {
|
}
|
||||||
/* FIXME: current entity management code can't deal with an error late in the creation of the
|
if (!dds_rhc_add_readcondition (cond))
|
||||||
entity because it doesn't allow deleting it again ... instead use a hack to signal a problem
|
{
|
||||||
to the caller and let that one handle it. */
|
/* FIXME: current entity management code can't deal with an error late in the creation of the
|
||||||
cond->m_entity.m_deriver.delete = 0;
|
entity because it doesn't allow deleting it again ... instead use a hack to signal a problem
|
||||||
}
|
to the caller and let that one handle it. */
|
||||||
return cond;
|
cond->m_entity.m_deriver.delete = 0;
|
||||||
|
}
|
||||||
|
return cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_t
|
dds_entity_t dds_create_readcondition (dds_entity_t reader, uint32_t mask)
|
||||||
dds_create_readcondition(
|
|
||||||
dds_entity_t reader,
|
|
||||||
uint32_t mask)
|
|
||||||
{
|
{
|
||||||
|
dds_reader *rd;
|
||||||
|
dds_return_t rc;
|
||||||
|
if ((rc = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK)
|
||||||
|
return rc;
|
||||||
|
else
|
||||||
|
{
|
||||||
dds_entity_t hdl;
|
dds_entity_t hdl;
|
||||||
dds_reader * rd;
|
dds_readcond *cond = dds_create_readcond(rd, DDS_KIND_COND_READ, mask, 0);
|
||||||
dds_return_t rc;
|
assert (cond);
|
||||||
|
assert (cond->m_entity.m_deriver.delete);
|
||||||
rc = dds_reader_lock(reader, &rd);
|
hdl = cond->m_entity.m_hdllink.hdl;
|
||||||
if (rc == DDS_RETCODE_OK) {
|
dds_reader_unlock (rd);
|
||||||
dds_readcond *cond = dds_create_readcond(rd, DDS_KIND_COND_READ, mask, 0);
|
|
||||||
assert(cond);
|
|
||||||
assert(cond->m_entity.m_deriver.delete);
|
|
||||||
hdl = cond->m_entity.m_hdllink.hdl;
|
|
||||||
dds_reader_unlock(rd);
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
|
||||||
hdl = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hdl;
|
return hdl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_t dds_get_datareader (dds_entity_t condition)
|
dds_entity_t dds_get_datareader (dds_entity_t condition)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "dds/dds.h"
|
#include "dds/dds.h"
|
||||||
#include "dds/version.h"
|
#include "dds/version.h"
|
||||||
|
#include "dds/ddsrt/static_assert.h"
|
||||||
#include "dds__subscriber.h"
|
#include "dds__subscriber.h"
|
||||||
#include "dds__reader.h"
|
#include "dds__reader.h"
|
||||||
#include "dds__listener.h"
|
#include "dds__listener.h"
|
||||||
|
@ -20,135 +21,96 @@
|
||||||
#include "dds__init.h"
|
#include "dds__init.h"
|
||||||
#include "dds__rhc.h"
|
#include "dds__rhc.h"
|
||||||
#include "dds__topic.h"
|
#include "dds__topic.h"
|
||||||
|
#include "dds__get_status.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds__builtin.h"
|
#include "dds__builtin.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_reader)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_reader)
|
||||||
|
|
||||||
#define DDS_READER_STATUS_MASK \
|
#define DDS_READER_STATUS_MASK \
|
||||||
DDS_SAMPLE_REJECTED_STATUS |\
|
(DDS_SAMPLE_REJECTED_STATUS |\
|
||||||
DDS_LIVELINESS_CHANGED_STATUS |\
|
DDS_LIVELINESS_CHANGED_STATUS |\
|
||||||
DDS_REQUESTED_DEADLINE_MISSED_STATUS |\
|
DDS_REQUESTED_DEADLINE_MISSED_STATUS |\
|
||||||
DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS |\
|
DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS |\
|
||||||
DDS_DATA_AVAILABLE_STATUS |\
|
DDS_DATA_AVAILABLE_STATUS |\
|
||||||
DDS_SAMPLE_LOST_STATUS |\
|
DDS_SAMPLE_LOST_STATUS |\
|
||||||
DDS_SUBSCRIPTION_MATCHED_STATUS
|
DDS_SUBSCRIPTION_MATCHED_STATUS)
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_reader_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||||
dds_reader_instance_hdl(
|
|
||||||
dds_entity *e,
|
static dds_return_t dds_reader_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||||
dds_instance_handle_t *i)
|
|
||||||
{
|
{
|
||||||
assert(e);
|
*i = reader_instance_id (&e->m_guid);
|
||||||
assert(i);
|
return DDS_RETCODE_OK;
|
||||||
*i = (dds_instance_handle_t)reader_instance_id(&e->m_guid);
|
|
||||||
return DDS_RETCODE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_reader_close (dds_entity *e) ddsrt_nonnull_all;
|
||||||
dds_reader_close(
|
|
||||||
dds_entity *e)
|
static dds_return_t dds_reader_close (dds_entity *e)
|
||||||
{
|
{
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
dds_return_t ret = DDS_RETCODE_OK;
|
||||||
|
thread_state_awake (lookup_thread_state ());
|
||||||
|
if (delete_reader (&e->m_guid) != 0)
|
||||||
|
ret = DDS_RETCODE_ERROR;
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
assert(e);
|
static dds_return_t dds_reader_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||||
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
static dds_return_t dds_reader_delete (dds_entity *e)
|
||||||
if (delete_reader(&e->m_guid) != 0) {
|
{
|
||||||
DDS_ERROR("Internal error");
|
dds_reader * const rd = (dds_reader *) e;
|
||||||
ret = DDS_RETCODE_ERROR;
|
dds_return_t ret;
|
||||||
}
|
if ((ret = dds_delete (rd->m_topic->m_entity.m_hdllink.hdl)) == DDS_RETCODE_OK)
|
||||||
thread_state_asleep (lookup_thread_state ());
|
{
|
||||||
|
/* Delete an implicitly created parent; for normal ones, this is expected
|
||||||
|
to fail with BAD_PARAMETER - FIXME: there must be a cleaner way */
|
||||||
|
ret = dds_delete_impl (e->m_parent->m_hdllink.hdl, true);
|
||||||
|
if (ret == DDS_RETCODE_BAD_PARAMETER)
|
||||||
|
ret = DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
dds_free (rd->m_loan);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_reader_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_reader_qos_validate (const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
if (!dds_qos_validate_common (qos))
|
||||||
|
return DDS_RETCODE_ERROR;
|
||||||
|
if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PRISMTECH_READER_DATA_LIFECYCLE) && validate_reader_data_lifecycle (&qos->reader_data_lifecycle) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_TIME_BASED_FILTER) && validate_duration (&qos->time_based_filter.minimum_separation) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && validate_history_and_resource_limits (&qos->history, &qos->resource_limits) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_TIME_BASED_FILTER) && (qos->present & QP_DEADLINE) && !validate_deadline_and_timebased_filter (qos->deadline.deadline, qos->time_based_filter.minimum_separation))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
return (enabled ? dds_qos_validate_mutable_common (qos) : DDS_RETCODE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_reader_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_reader_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
dds_return_t ret;
|
||||||
|
(void) e;
|
||||||
|
if ((ret = dds_reader_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
/* FIXME: QoS changes. */
|
||||||
|
return (enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_reader_status_validate (uint32_t mask)
|
||||||
dds_reader_delete(
|
|
||||||
dds_entity *e)
|
|
||||||
{
|
{
|
||||||
dds_reader *rd = (dds_reader*)e;
|
return (mask & ~DDS_READER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||||
dds_return_t ret;
|
|
||||||
assert(e);
|
|
||||||
ret = dds_delete(rd->m_topic->m_entity.m_hdllink.hdl);
|
|
||||||
if(ret == DDS_RETCODE_OK){
|
|
||||||
ret = dds_delete_impl(e->m_parent->m_hdllink.hdl, true);
|
|
||||||
if(ret == DDS_RETCODE_BAD_PARAMETER){
|
|
||||||
ret = DDS_RETCODE_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dds_free(rd->m_loan);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_reader_qos_validate(
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
|
||||||
|
|
||||||
assert(qos);
|
|
||||||
|
|
||||||
/* Check consistency. */
|
|
||||||
if(!dds_qos_validate_common(qos)) {
|
|
||||||
DDS_ERROR("Argument Qos is not valid\n");
|
|
||||||
ret = DDS_RETCODE_ERROR;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_USER_DATA) && !(validate_octetseq (&qos->user_data))) {
|
|
||||||
DDS_ERROR("User data policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_PRISMTECH_READER_DATA_LIFECYCLE) && (validate_reader_data_lifecycle (&qos->reader_data_lifecycle) != 0)) {
|
|
||||||
DDS_ERROR("Prismtech reader data lifecycle policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_TIME_BASED_FILTER) && (validate_duration (&qos->time_based_filter.minimum_separation) != 0)) {
|
|
||||||
DDS_ERROR("Time based filter policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && (validate_history_and_resource_limits (&qos->history, &qos->resource_limits) != 0)) {
|
|
||||||
DDS_ERROR("History and resource limits policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_TIME_BASED_FILTER) && (qos->present & QP_DEADLINE) && !(validate_deadline_and_timebased_filter (qos->deadline.deadline, qos->time_based_filter.minimum_separation))) {
|
|
||||||
DDS_ERROR("Time based filter and deadline policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if(ret == DDS_RETCODE_OK && enabled) {
|
|
||||||
ret = dds_qos_validate_mutable_common(qos);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_reader_qos_set(
|
|
||||||
dds_entity *e,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = dds_reader_qos_validate(qos, enabled);
|
|
||||||
(void)e;
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
if (enabled) {
|
|
||||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
|
||||||
DDS_ERROR(DDS_PROJECT_NAME" does not support changing QoS policies\n");
|
|
||||||
ret = DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_reader_status_validate(
|
|
||||||
uint32_t mask)
|
|
||||||
{
|
|
||||||
return (mask & ~(DDS_READER_STATUS_MASK)) ?
|
|
||||||
DDS_RETCODE_BAD_PARAMETER :
|
|
||||||
DDS_RETCODE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dds_reader_data_available_cb (struct dds_reader *rd)
|
void dds_reader_data_available_cb (struct dds_reader *rd)
|
||||||
|
@ -349,170 +311,157 @@ void dds_reader_status_cb (void *ventity, const status_cb_data_t *data)
|
||||||
ddsrt_mutex_unlock (&entity->m_observers_lock);
|
ddsrt_mutex_unlock (&entity->m_observers_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_t
|
dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||||
dds_create_reader(
|
|
||||||
dds_entity_t participant_or_subscriber,
|
|
||||||
dds_entity_t topic,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
const dds_listener_t *listener)
|
|
||||||
{
|
{
|
||||||
dds_qos_t * rqos;
|
dds_qos_t *rqos;
|
||||||
dds_subscriber * sub = NULL;
|
dds_subscriber *sub = NULL;
|
||||||
dds_entity_t subscriber;
|
dds_entity_t subscriber;
|
||||||
dds_reader * rd;
|
dds_reader *rd;
|
||||||
struct rhc * rhc;
|
struct rhc *rhc;
|
||||||
dds_topic * tp;
|
dds_topic *tp;
|
||||||
dds_entity_t reader;
|
dds_entity_t reader;
|
||||||
dds_entity_t t;
|
dds_entity_t t;
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
dds_return_t ret = DDS_RETCODE_OK;
|
||||||
bool internal_topic;
|
bool internal_topic;
|
||||||
|
|
||||||
switch (topic) {
|
switch (topic)
|
||||||
case DDS_BUILTIN_TOPIC_DCPSPARTICIPANT:
|
{
|
||||||
case DDS_BUILTIN_TOPIC_DCPSTOPIC:
|
case DDS_BUILTIN_TOPIC_DCPSPARTICIPANT:
|
||||||
case DDS_BUILTIN_TOPIC_DCPSPUBLICATION:
|
case DDS_BUILTIN_TOPIC_DCPSTOPIC:
|
||||||
case DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION:
|
case DDS_BUILTIN_TOPIC_DCPSPUBLICATION:
|
||||||
internal_topic = true;
|
case DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION:
|
||||||
subscriber = dds__get_builtin_subscriber(participant_or_subscriber);
|
internal_topic = true;
|
||||||
t = dds__get_builtin_topic (subscriber, topic);
|
subscriber = dds__get_builtin_subscriber (participant_or_subscriber);
|
||||||
break;
|
t = dds__get_builtin_topic (subscriber, topic);
|
||||||
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
dds_entity *p_or_s;
|
dds_entity *p_or_s;
|
||||||
if ((ret = dds_entity_claim (participant_or_subscriber, &p_or_s)) != DDS_RETCODE_OK) {
|
if ((ret = dds_entity_claim (participant_or_subscriber, &p_or_s)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
if (dds_entity_kind (p_or_s) == DDS_KIND_PARTICIPANT)
|
||||||
if (dds_entity_kind (p_or_s) == DDS_KIND_PARTICIPANT) {
|
subscriber = dds_create_subscriber (participant_or_subscriber, qos, NULL);
|
||||||
subscriber = dds_create_subscriber(participant_or_subscriber, qos, NULL);
|
else
|
||||||
} else {
|
subscriber = participant_or_subscriber;
|
||||||
subscriber = participant_or_subscriber;
|
dds_entity_release (p_or_s);
|
||||||
}
|
internal_topic = false;
|
||||||
dds_entity_release (p_or_s);
|
t = topic;
|
||||||
internal_topic = false;
|
break;
|
||||||
t = topic;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK) {
|
if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK)
|
||||||
reader = ret;
|
{
|
||||||
goto err_sub_lock;
|
reader = ret;
|
||||||
}
|
goto err_sub_lock;
|
||||||
|
}
|
||||||
|
|
||||||
if ((subscriber != participant_or_subscriber) && !internal_topic) {
|
if (subscriber != participant_or_subscriber && !internal_topic)
|
||||||
/* Delete implicit subscriber if reader creation fails */
|
{
|
||||||
sub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
/* Delete implicit subscriber if reader creation fails */
|
||||||
}
|
sub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
||||||
|
}
|
||||||
|
|
||||||
ret = dds_topic_lock(t, &tp);
|
if ((ret = dds_topic_lock (t, &tp)) != DDS_RETCODE_OK)
|
||||||
if (ret != DDS_RETCODE_OK) {
|
{
|
||||||
DDS_ERROR("Error occurred on locking topic\n");
|
reader = ret;
|
||||||
reader = ret;
|
goto err_tp_lock;
|
||||||
goto err_tp_lock;
|
}
|
||||||
}
|
assert (tp->m_stopic);
|
||||||
assert (tp->m_stopic);
|
assert (sub->m_entity.m_domain == tp->m_entity.m_domain);
|
||||||
assert (sub->m_entity.m_domain == tp->m_entity.m_domain);
|
|
||||||
|
|
||||||
/* Merge qos from topic and subscriber */
|
/* Merge qos from topic and subscriber, dds_copy_qos only fails when it is passed a null
|
||||||
rqos = dds_create_qos ();
|
argument, but that isn't the case here */
|
||||||
if (qos) {
|
rqos = dds_create_qos ();
|
||||||
/* Only returns failure when one of the qos args is NULL, which
|
if (qos)
|
||||||
* is not the case here. */
|
(void) dds_copy_qos (rqos, qos);
|
||||||
(void)dds_copy_qos(rqos, qos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sub->m_entity.m_qos){
|
if (sub->m_entity.m_qos)
|
||||||
dds_merge_qos (rqos, sub->m_entity.m_qos);
|
dds_merge_qos (rqos, sub->m_entity.m_qos);
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->m_entity.m_qos) {
|
if (tp->m_entity.m_qos)
|
||||||
dds_merge_qos (rqos, tp->m_entity.m_qos);
|
{
|
||||||
|
dds_merge_qos (rqos, tp->m_entity.m_qos);
|
||||||
|
/* reset the following qos policies if set during topic qos merge as they aren't applicable for reader */
|
||||||
|
rqos->present &= ~(QP_DURABILITY_SERVICE | QP_TRANSPORT_PRIORITY | QP_LIFESPAN);
|
||||||
|
}
|
||||||
|
nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd);
|
||||||
|
|
||||||
/* reset the following qos policies if set during topic qos merge as they aren't applicable for reader */
|
if ((ret = dds_reader_qos_validate (rqos, false)) != DDS_RETCODE_OK)
|
||||||
rqos->present &= ~(QP_DURABILITY_SERVICE | QP_TRANSPORT_PRIORITY | QP_LIFESPAN);
|
{
|
||||||
}
|
dds_delete_qos (rqos);
|
||||||
nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd);
|
reader = ret;
|
||||||
|
goto err_bad_qos;
|
||||||
|
}
|
||||||
|
|
||||||
ret = dds_reader_qos_validate (rqos, false);
|
/* Additional checks required for built-in topics: we don't want to
|
||||||
if (ret != 0) {
|
run into a resource limit on a built-in topic, it is a needless
|
||||||
dds_delete_qos(rqos);
|
complication */
|
||||||
reader = ret;
|
if (internal_topic && !dds__validate_builtin_reader_qos (topic, qos))
|
||||||
goto err_bad_qos;
|
{
|
||||||
}
|
dds_delete_qos (rqos);
|
||||||
|
reader = DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
goto err_bad_qos;
|
||||||
|
}
|
||||||
|
|
||||||
/* Additional checks required for built-in topics */
|
/* Create reader and associated read cache */
|
||||||
if (internal_topic && !dds__validate_builtin_reader_qos(topic, qos)) {
|
rd = dds_alloc (sizeof (*rd));
|
||||||
dds_delete_qos(rqos);
|
reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK);
|
||||||
DDS_ERROR("Invalid QoS specified for built-in topic reader");
|
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
|
||||||
reader = DDS_RETCODE_INCONSISTENT_POLICY;
|
rd->m_topic = tp;
|
||||||
goto err_bad_qos;
|
rhc = dds_rhc_new (rd, tp->m_stopic);
|
||||||
}
|
dds_entity_add_ref_nolock (&tp->m_entity);
|
||||||
|
rd->m_entity.m_deriver.close = dds_reader_close;
|
||||||
|
rd->m_entity.m_deriver.delete = dds_reader_delete;
|
||||||
|
rd->m_entity.m_deriver.set_qos = dds_reader_qos_set;
|
||||||
|
rd->m_entity.m_deriver.validate_status = dds_reader_status_validate;
|
||||||
|
rd->m_entity.m_deriver.get_instance_hdl = dds_reader_instance_hdl;
|
||||||
|
|
||||||
/* Create reader and associated read cache */
|
/* Extra claim of this reader to make sure that the delete waits until DDSI
|
||||||
rd = dds_alloc (sizeof (*rd));
|
has deleted its reader as well. This can be known through the callback. */
|
||||||
reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK);
|
dds_handle_claim_inc (&rd->m_entity.m_hdllink);
|
||||||
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
|
|
||||||
rd->m_topic = tp;
|
|
||||||
rhc = dds_rhc_new (rd, tp->m_stopic);
|
|
||||||
dds_entity_add_ref_nolock (&tp->m_entity);
|
|
||||||
rd->m_entity.m_deriver.close = dds_reader_close;
|
|
||||||
rd->m_entity.m_deriver.delete = dds_reader_delete;
|
|
||||||
rd->m_entity.m_deriver.set_qos = dds_reader_qos_set;
|
|
||||||
rd->m_entity.m_deriver.validate_status = dds_reader_status_validate;
|
|
||||||
rd->m_entity.m_deriver.get_instance_hdl = dds_reader_instance_hdl;
|
|
||||||
|
|
||||||
/* Extra claim of this reader to make sure that the delete waits until DDSI
|
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
|
||||||
* has deleted its reader as well. This can be known through the callback. */
|
ddsrt_mutex_unlock (&sub->m_entity.m_mutex);
|
||||||
dds_handle_claim_inc (&rd->m_entity.m_hdllink);
|
|
||||||
|
|
||||||
ddsrt_mutex_unlock(&tp->m_entity.m_mutex);
|
thread_state_awake (lookup_thread_state ());
|
||||||
ddsrt_mutex_unlock(&sub->m_entity.m_mutex);
|
ret = new_reader (&rd->m_rd, &rd->m_entity.m_guid, NULL, &sub->m_entity.m_participant->m_guid, tp->m_stopic, rqos, rhc, dds_reader_status_cb, rd);
|
||||||
|
ddsrt_mutex_lock (&sub->m_entity.m_mutex);
|
||||||
|
ddsrt_mutex_lock (&tp->m_entity.m_mutex);
|
||||||
|
assert (ret == DDS_RETCODE_OK); /* FIXME: can be out-of-resources at the very least */
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
/* For persistent data register reader with durability */
|
||||||
ret = new_reader(&rd->m_rd, &rd->m_entity.m_guid, NULL, &sub->m_entity.m_participant->m_guid, tp->m_stopic,
|
if (dds_global.m_dur_reader && (rd->m_entity.m_qos->durability.kind > NN_TRANSIENT_LOCAL_DURABILITY_QOS)) {
|
||||||
rqos, rhc, dds_reader_status_cb, rd);
|
(dds_global.m_dur_reader) (rd, rhc);
|
||||||
ddsrt_mutex_lock(&sub->m_entity.m_mutex);
|
}
|
||||||
ddsrt_mutex_lock(&tp->m_entity.m_mutex);
|
dds_topic_unlock (tp);
|
||||||
assert (ret == DDS_RETCODE_OK);
|
dds_subscriber_unlock (sub);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
|
||||||
|
|
||||||
/* For persistent data register reader with durability */
|
if (internal_topic)
|
||||||
if (dds_global.m_dur_reader && (rd->m_entity.m_qos->durability.kind > NN_TRANSIENT_LOCAL_DURABILITY_QOS)) {
|
{
|
||||||
(dds_global.m_dur_reader) (rd, rhc);
|
/* If topic is builtin, then the topic entity is local and should be deleted because the application won't. */
|
||||||
}
|
dds_delete (t);
|
||||||
dds_topic_unlock(tp);
|
}
|
||||||
dds_subscriber_unlock(sub);
|
return reader;
|
||||||
|
|
||||||
if (internal_topic) {
|
|
||||||
/* If topic is builtin, then the topic entity is local and should
|
|
||||||
* be deleted because the application won't. */
|
|
||||||
dds_delete(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
return reader;
|
|
||||||
|
|
||||||
err_bad_qos:
|
err_bad_qos:
|
||||||
dds_topic_unlock(tp);
|
dds_topic_unlock (tp);
|
||||||
err_tp_lock:
|
err_tp_lock:
|
||||||
dds_subscriber_unlock(sub);
|
dds_subscriber_unlock (sub);
|
||||||
if((sub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
if ((sub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0)
|
||||||
(void)dds_delete(subscriber);
|
(void) dds_delete (subscriber);
|
||||||
}
|
|
||||||
err_sub_lock:
|
err_sub_lock:
|
||||||
if (internal_topic) {
|
if (internal_topic)
|
||||||
/* If topic is builtin, then the topic entity is local and should
|
dds_delete (t);
|
||||||
* be deleted because the application won't. */
|
return reader;
|
||||||
dds_delete(t);
|
|
||||||
}
|
|
||||||
return reader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb, void *cbarg)
|
void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb, void *cbarg)
|
||||||
{
|
{
|
||||||
dds_entity *dds_entity;
|
dds_entity *dds_entity;
|
||||||
if (dds_entity_claim(entity, &dds_entity) != DDS_RETCODE_OK)
|
if (dds_entity_claim (entity, &dds_entity) != DDS_RETCODE_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dds_entity_kind (dds_entity) != DDS_KIND_READER)
|
if (dds_entity_kind (dds_entity) != DDS_KIND_READER)
|
||||||
{
|
{
|
||||||
dds_entity_release (dds_entity);
|
dds_entity_release (dds_entity);
|
||||||
|
@ -532,7 +481,7 @@ void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb
|
||||||
while ((m = ddsrt_avl_lookup_succ_eq (&rd_writers_treedef, &rd->writers, &pwrguid)) != NULL)
|
while ((m = ddsrt_avl_lookup_succ_eq (&rd_writers_treedef, &rd->writers, &pwrguid)) != NULL)
|
||||||
{
|
{
|
||||||
/* have to be careful walking the tree -- pretty is different, but
|
/* have to be careful walking the tree -- pretty is different, but
|
||||||
I want to check this before I write a lookup_succ function. */
|
I want to check this before I write a lookup_succ function. */
|
||||||
struct rd_pwr_match *m_next;
|
struct rd_pwr_match *m_next;
|
||||||
nn_guid_t pwrguid_next;
|
nn_guid_t pwrguid_next;
|
||||||
pwrguid = m->pwr_guid;
|
pwrguid = m->pwr_guid;
|
||||||
|
@ -621,169 +570,12 @@ dds_entity_t dds_get_subscriber (dds_entity_t entity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
/* Reset sets everything (type) 0, including the reason field, verify that 0 is correct */
|
||||||
dds_get_subscription_matched_status (
|
DDSRT_STATIC_ASSERT ((int) DDS_NOT_REJECTED == 0);
|
||||||
dds_entity_t reader,
|
|
||||||
dds_subscription_matched_status_t * status)
|
|
||||||
{
|
|
||||||
dds_reader *rd;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_reader_lock(reader, &rd);
|
DDS_GET_STATUS (reader, subscription_matched, SUBSCRIPTION_MATCHED, total_count_change, current_count_change)
|
||||||
if (ret != DDS_RETCODE_OK) {
|
DDS_GET_STATUS (reader, liveliness_changed, LIVELINESS_CHANGED, alive_count_change, not_alive_count_change)
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
DDS_GET_STATUS (reader, sample_rejected, SAMPLE_REJECTED, total_count_change, last_reason)
|
||||||
goto fail;
|
DDS_GET_STATUS (reader, sample_lost, SAMPLE_LOST, total_count_change)
|
||||||
}
|
DDS_GET_STATUS (reader, requested_deadline_missed, REQUESTED_DEADLINE_MISSED, total_count_change)
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
DDS_GET_STATUS (reader, requested_incompatible_qos, REQUESTED_INCOMPATIBLE_QOS, total_count_change)
|
||||||
if (status) {
|
|
||||||
*status = rd->m_subscription_matched_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
|
|
||||||
if (rd->m_entity.m_status_enable & DDS_SUBSCRIPTION_MATCHED_STATUS) {
|
|
||||||
rd->m_subscription_matched_status.total_count_change = 0;
|
|
||||||
rd->m_subscription_matched_status.current_count_change = 0;
|
|
||||||
dds_entity_status_reset(&rd->m_entity, DDS_SUBSCRIPTION_MATCHED_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
|
|
||||||
dds_reader_unlock(rd);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t
|
|
||||||
dds_get_liveliness_changed_status (
|
|
||||||
dds_entity_t reader,
|
|
||||||
dds_liveliness_changed_status_t * status)
|
|
||||||
{
|
|
||||||
dds_reader *rd;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_reader_lock(reader, &rd);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = rd->m_liveliness_changed_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
|
|
||||||
if (rd->m_entity.m_status_enable & DDS_LIVELINESS_CHANGED_STATUS) {
|
|
||||||
rd->m_liveliness_changed_status.alive_count_change = 0;
|
|
||||||
rd->m_liveliness_changed_status.not_alive_count_change = 0;
|
|
||||||
dds_entity_status_reset(&rd->m_entity, DDS_LIVELINESS_CHANGED_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
|
|
||||||
dds_reader_unlock(rd);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t dds_get_sample_rejected_status (
|
|
||||||
dds_entity_t reader,
|
|
||||||
dds_sample_rejected_status_t * status)
|
|
||||||
{
|
|
||||||
dds_reader *rd;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_reader_lock(reader, &rd);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = rd->m_sample_rejected_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
|
|
||||||
if (rd->m_entity.m_status_enable & DDS_SAMPLE_REJECTED_STATUS) {
|
|
||||||
rd->m_sample_rejected_status.total_count_change = 0;
|
|
||||||
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
|
|
||||||
dds_entity_status_reset(&rd->m_entity, DDS_SAMPLE_REJECTED_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
|
|
||||||
dds_reader_unlock(rd);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t dds_get_sample_lost_status (
|
|
||||||
dds_entity_t reader,
|
|
||||||
dds_sample_lost_status_t * status)
|
|
||||||
{
|
|
||||||
dds_reader *rd;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_reader_lock(reader, &rd);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = rd->m_sample_lost_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
|
|
||||||
if (rd->m_entity.m_status_enable & DDS_SAMPLE_LOST_STATUS) {
|
|
||||||
rd->m_sample_lost_status.total_count_change = 0;
|
|
||||||
dds_entity_status_reset(&rd->m_entity, DDS_SAMPLE_LOST_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
|
|
||||||
dds_reader_unlock(rd);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t dds_get_requested_deadline_missed_status (
|
|
||||||
dds_entity_t reader,
|
|
||||||
dds_requested_deadline_missed_status_t * status)
|
|
||||||
{
|
|
||||||
dds_reader *rd;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_reader_lock(reader, &rd);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = rd->m_requested_deadline_missed_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
|
|
||||||
if (rd->m_entity.m_status_enable & DDS_REQUESTED_DEADLINE_MISSED_STATUS) {
|
|
||||||
rd->m_requested_deadline_missed_status.total_count_change = 0;
|
|
||||||
dds_entity_status_reset(&rd->m_entity, DDS_REQUESTED_DEADLINE_MISSED_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
|
|
||||||
dds_reader_unlock(rd);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t dds_get_requested_incompatible_qos_status (
|
|
||||||
dds_entity_t reader,
|
|
||||||
dds_requested_incompatible_qos_status_t * status)
|
|
||||||
{
|
|
||||||
dds_reader *rd;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_reader_lock(reader, &rd);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking reader\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = rd->m_requested_incompatible_qos_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
|
|
||||||
if (rd->m_entity.m_status_enable & DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS) {
|
|
||||||
rd->m_requested_incompatible_qos_status.total_count_change = 0;
|
|
||||||
dds_entity_status_reset(&rd->m_entity, DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
|
|
||||||
dds_reader_unlock(rd);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
@ -204,9 +204,7 @@ static void dds_os_put_bytes_aligned (dds_ostream_t * __restrict s, const void *
|
||||||
|
|
||||||
static uint32_t get_type_size (enum dds_stream_typecode type)
|
static uint32_t get_type_size (enum dds_stream_typecode type)
|
||||||
{
|
{
|
||||||
struct check {
|
DDSRT_STATIC_ASSERT (DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4);
|
||||||
char x[(DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4) ? 1 : -1];
|
|
||||||
};
|
|
||||||
assert (type == DDS_OP_VAL_1BY || type == DDS_OP_VAL_2BY || type == DDS_OP_VAL_4BY || type == DDS_OP_VAL_8BY);
|
assert (type == DDS_OP_VAL_1BY || type == DDS_OP_VAL_2BY || type == DDS_OP_VAL_4BY || type == DDS_OP_VAL_8BY);
|
||||||
return (uint32_t)1 << ((uint32_t) type - 1);
|
return (uint32_t)1 << ((uint32_t) type - 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,199 +11,126 @@
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "dds__listener.h"
|
#include "dds__listener.h"
|
||||||
|
#include "dds__participant.h"
|
||||||
#include "dds__qos.h"
|
#include "dds__qos.h"
|
||||||
#include "dds__subscriber.h"
|
#include "dds__subscriber.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/version.h"
|
#include "dds/version.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_subscriber)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_subscriber)
|
||||||
|
|
||||||
#define DDS_SUBSCRIBER_STATUS_MASK \
|
#define DDS_SUBSCRIBER_STATUS_MASK \
|
||||||
DDS_DATA_ON_READERS_STATUS
|
(DDS_DATA_ON_READERS_STATUS)
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_subscriber_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||||
dds_subscriber_instance_hdl(
|
|
||||||
dds_entity *e,
|
static dds_return_t dds_subscriber_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||||
dds_instance_handle_t *i)
|
|
||||||
{
|
{
|
||||||
(void)e;
|
(void) e;
|
||||||
(void)i;
|
(void) i;
|
||||||
/* TODO: Get/generate proper handle. */
|
/* FIXME: Get/generate proper handle. */
|
||||||
DDS_ERROR("Generating subscriber instance handle is not supported");
|
return DDS_RETCODE_UNSUPPORTED;
|
||||||
return DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
dds__subscriber_qos_validate(
|
|
||||||
const dds_qos_t *qos,
|
static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, bool enabled)
|
||||||
bool enabled)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PARTITION) && !validate_stringseq (&qos->partition))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy (&qos->presentation) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
/* FIXME: Improve/check immutable check. */
|
||||||
|
return (enabled && (qos->present & QP_PRESENTATION)) ? DDS_RETCODE_IMMUTABLE_POLICY : DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
assert(qos);
|
static dds_return_t dds_subscriber_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
|
|
||||||
if((qos->present & QP_GROUP_DATA) && !validate_octetseq(&qos->group_data)) {
|
|
||||||
DDS_ERROR("Group data policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_PARTITION) && !validate_stringseq(&qos->partition)) {
|
|
||||||
DDS_ERROR("Partition policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy(&qos->presentation)) {
|
|
||||||
DDS_ERROR("Presentation policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)) {
|
|
||||||
DDS_ERROR("Prismtech entity factory policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if(ret == DDS_RETCODE_OK && enabled && (qos->present & QP_PRESENTATION)) {
|
|
||||||
/* TODO: Improve/check immutable check. */
|
|
||||||
DDS_ERROR("Presentation QoS policy is immutable\n");
|
|
||||||
ret = DDS_RETCODE_IMMUTABLE_POLICY;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static dds_return_t dds_subscriber_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
/* FIXME: QoS changes. */
|
||||||
|
dds_return_t ret;
|
||||||
|
(void) e;
|
||||||
|
if ((ret = dds__subscriber_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
return (enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_subscriber_status_validate (uint32_t mask)
|
||||||
dds_subscriber_qos_set(
|
|
||||||
dds_entity *e,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret = dds__subscriber_qos_validate(qos, enabled);
|
return (mask & ~DDS_SUBSCRIBER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||||
(void)e;
|
}
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
if (enabled) {
|
dds_entity_t dds__create_subscriber_l (dds_participant *participant, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
{
|
||||||
DDS_ERROR(DDS_PROJECT_NAME" does not support changing QoS policies yet\n");
|
/* participant entity lock must be held */
|
||||||
ret = DDS_RETCODE_UNSUPPORTED;
|
dds_subscriber *sub;
|
||||||
}
|
dds_entity_t subscriber;
|
||||||
}
|
dds_return_t ret;
|
||||||
|
dds_qos_t *new_qos;
|
||||||
|
|
||||||
|
/* Validate qos */
|
||||||
|
if (qos && (ret = dds__subscriber_qos_validate (qos, false)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (qos == NULL)
|
||||||
|
new_qos = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_qos = dds_create_qos ();
|
||||||
|
(void) dds_copy_qos (new_qos, qos);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub = dds_alloc (sizeof (*sub));
|
||||||
|
subscriber = dds_entity_init (&sub->m_entity, &participant->m_entity, DDS_KIND_SUBSCRIBER, new_qos, listener, DDS_SUBSCRIBER_STATUS_MASK);
|
||||||
|
sub->m_entity.m_deriver.set_qos = dds_subscriber_qos_set;
|
||||||
|
sub->m_entity.m_deriver.validate_status = dds_subscriber_status_validate;
|
||||||
|
sub->m_entity.m_deriver.get_instance_hdl = dds_subscriber_instance_hdl;
|
||||||
|
return subscriber;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
dds_entity_t dds_create_subscriber (dds_entity_t participant, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||||
dds_subscriber_status_validate(
|
|
||||||
uint32_t mask)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
dds_participant *par;
|
||||||
|
dds_entity_t hdl;
|
||||||
if (mask & ~(DDS_SUBSCRIBER_STATUS_MASK)) {
|
dds_return_t ret;
|
||||||
DDS_ERROR("Invalid status mask\n");
|
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
hdl = dds__create_subscriber_l (par, qos, listener);
|
||||||
|
dds_participant_unlock (par);
|
||||||
|
return hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_t
|
dds_return_t dds_notify_readers (dds_entity_t subscriber)
|
||||||
dds__create_subscriber_l(
|
|
||||||
dds_entity *participant, /* entity-lock must be held */
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
const dds_listener_t *listener)
|
|
||||||
{
|
{
|
||||||
dds_subscriber * sub;
|
dds_subscriber *sub;
|
||||||
dds_entity_t subscriber;
|
dds_return_t ret;
|
||||||
dds_return_t ret;
|
|
||||||
dds_qos_t * new_qos;
|
|
||||||
|
|
||||||
/* Validate qos */
|
if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK)
|
||||||
if (qos) {
|
|
||||||
if ((ret = dds__subscriber_qos_validate(qos, false)) != DDS_RETCODE_OK) {
|
|
||||||
goto err_param;
|
|
||||||
}
|
|
||||||
new_qos = dds_create_qos();
|
|
||||||
/* Only returns failure when one of the qos args is NULL, which
|
|
||||||
* is not the case here. */
|
|
||||||
(void)dds_copy_qos(new_qos, qos);
|
|
||||||
} else {
|
|
||||||
new_qos = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create subscriber */
|
|
||||||
sub = dds_alloc(sizeof(*sub));
|
|
||||||
subscriber = dds_entity_init(&sub->m_entity, participant, DDS_KIND_SUBSCRIBER, new_qos, listener, DDS_SUBSCRIBER_STATUS_MASK);
|
|
||||||
sub->m_entity.m_deriver.set_qos = dds_subscriber_qos_set;
|
|
||||||
sub->m_entity.m_deriver.validate_status = dds_subscriber_status_validate;
|
|
||||||
sub->m_entity.m_deriver.get_instance_hdl = dds_subscriber_instance_hdl;
|
|
||||||
|
|
||||||
return subscriber;
|
|
||||||
|
|
||||||
/* Error handling */
|
|
||||||
err_param:
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = DDS_RETCODE_UNSUPPORTED;
|
||||||
|
for (dds_entity *iter = sub->m_entity.m_children; iter; iter = iter->m_next)
|
||||||
|
{
|
||||||
|
ddsrt_mutex_lock (&iter->m_mutex);
|
||||||
|
// FIXME: check if reader has data available, call listener
|
||||||
|
ddsrt_mutex_unlock(&iter->m_mutex);
|
||||||
|
}
|
||||||
|
dds_subscriber_unlock (sub);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_t
|
dds_return_t dds_subscriber_begin_coherent (dds_entity_t e)
|
||||||
dds_create_subscriber(
|
|
||||||
dds_entity_t participant,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
const dds_listener_t *listener)
|
|
||||||
{
|
{
|
||||||
dds_entity * par;
|
return dds_generic_unimplemented_operation (e, DDS_KIND_SUBSCRIBER);
|
||||||
dds_entity_t hdl;
|
|
||||||
dds_return_t errnr;
|
|
||||||
|
|
||||||
errnr = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
|
||||||
if (errnr != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking participant\n");
|
|
||||||
hdl = errnr;
|
|
||||||
return hdl;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdl = dds__create_subscriber_l(par, qos, listener);
|
|
||||||
dds_entity_unlock(par);
|
|
||||||
|
|
||||||
return hdl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_subscriber_end_coherent (dds_entity_t e)
|
||||||
dds_notify_readers(
|
|
||||||
dds_entity_t subscriber)
|
|
||||||
{
|
{
|
||||||
dds_entity *iter;
|
return dds_generic_unimplemented_operation (e, DDS_KIND_SUBSCRIBER);
|
||||||
dds_entity *sub;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_entity_lock(subscriber, DDS_KIND_SUBSCRIBER, &sub);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
ret = DDS_RETCODE_UNSUPPORTED;
|
|
||||||
DDS_ERROR("Unsupported operation\n");
|
|
||||||
iter = sub->m_children;
|
|
||||||
while (iter) {
|
|
||||||
ddsrt_mutex_lock(&iter->m_mutex);
|
|
||||||
// TODO: check if reader has data available, call listener
|
|
||||||
ddsrt_mutex_unlock(&iter->m_mutex);
|
|
||||||
iter = iter->m_next;
|
|
||||||
}
|
|
||||||
dds_entity_unlock(sub);
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Error occurred on locking subscriber\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t
|
|
||||||
dds_subscriber_begin_coherent(
|
|
||||||
dds_entity_t e)
|
|
||||||
{
|
|
||||||
/* TODO: CHAM-124 Currently unsupported. */
|
|
||||||
(void)e;
|
|
||||||
DDS_ERROR("Using coherency to get a coherent data set is not currently being supported\n");
|
|
||||||
return DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t
|
|
||||||
dds_subscriber_end_coherent(
|
|
||||||
dds_entity_t e)
|
|
||||||
{
|
|
||||||
/* TODO: CHAM-124 Currently unsupported. */
|
|
||||||
(void)e;
|
|
||||||
DDS_ERROR("Using coherency to get a coherent data set is not currently being supported\n");
|
|
||||||
return DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,68 +17,53 @@
|
||||||
#include "dds__topic.h"
|
#include "dds__topic.h"
|
||||||
#include "dds__listener.h"
|
#include "dds__listener.h"
|
||||||
#include "dds__qos.h"
|
#include "dds__qos.h"
|
||||||
|
#include "dds__participant.h"
|
||||||
#include "dds__stream.h"
|
#include "dds__stream.h"
|
||||||
#include "dds__init.h"
|
#include "dds__init.h"
|
||||||
#include "dds__domain.h"
|
#include "dds__domain.h"
|
||||||
|
#include "dds__get_status.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
#include "dds/ddsi/q_ddsi_discovery.h"
|
#include "dds/ddsi/q_ddsi_discovery.h"
|
||||||
#include "dds/ddsi/ddsi_iid.h"
|
#include "dds/ddsi/ddsi_iid.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_topic)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_topic)
|
||||||
|
|
||||||
#define DDS_TOPIC_STATUS_MASK \
|
#define DDS_TOPIC_STATUS_MASK \
|
||||||
DDS_INCONSISTENT_TOPIC_STATUS
|
(DDS_INCONSISTENT_TOPIC_STATUS)
|
||||||
|
|
||||||
const ddsrt_avl_treedef_t dds_topictree_def = DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY
|
static int strcmp_wrapper (const void *va, const void *vb)
|
||||||
(
|
|
||||||
offsetof (struct ddsi_sertopic, avlnode),
|
|
||||||
offsetof (struct ddsi_sertopic, name_type_name),
|
|
||||||
(int (*) (const void *, const void *)) strcmp,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
is_valid_name(
|
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
bool valid = false;
|
return strcmp (va, vb);
|
||||||
/* DDS Spec:
|
|
||||||
* | TOPICNAME - A topic name is an identifier for a topic, and is defined as any series of characters
|
|
||||||
* | 'a', ..., 'z',
|
|
||||||
* | 'A', ..., 'Z',
|
|
||||||
* | '0', ..., '9',
|
|
||||||
* | '-' but may not start with a digit.
|
|
||||||
* It is considered that '-' is an error in the spec and should say '_'. So, that's what we'll check for.
|
|
||||||
* | '/' got added for ROS2
|
|
||||||
*/
|
|
||||||
assert(name);
|
|
||||||
if ((name[0] != '\0') && (!isdigit((unsigned char)name[0]))) {
|
|
||||||
while (isalnum((unsigned char)*name) || (*name == '_') || (*name == '/')) {
|
|
||||||
name++;
|
|
||||||
}
|
|
||||||
if (*name == '\0') {
|
|
||||||
valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ddsrt_avl_treedef_t dds_topictree_def = DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY (offsetof (struct ddsi_sertopic, avlnode), offsetof (struct ddsi_sertopic, name_type_name), strcmp_wrapper, 0);
|
||||||
|
|
||||||
static dds_return_t
|
static bool is_valid_name (const char *name) ddsrt_nonnull_all;
|
||||||
dds_topic_status_validate(
|
|
||||||
uint32_t mask)
|
static bool is_valid_name (const char *name)
|
||||||
{
|
{
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
/* DDS Spec:
|
||||||
|
* | TOPICNAME - A topic name is an identifier for a topic, and is defined as any series of characters
|
||||||
|
* | 'a', ..., 'z',
|
||||||
|
* | 'A', ..., 'Z',
|
||||||
|
* | '0', ..., '9',
|
||||||
|
* | '-' but may not start with a digit.
|
||||||
|
* It is considered that '-' is an error in the spec and should say '_'. So, that's what we'll check for.
|
||||||
|
* | '/' got added for ROS2
|
||||||
|
*/
|
||||||
|
if (name[0] == '\0' || isdigit ((unsigned char) name[0]))
|
||||||
|
return false;
|
||||||
|
for (size_t i = 0; name[i]; i++)
|
||||||
|
if (!(isalnum ((unsigned char) name[i]) || name[i] == '_' || name[i] == '/'))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (mask & ~(DDS_TOPIC_STATUS_MASK)) {
|
static dds_return_t dds_topic_status_validate (uint32_t mask)
|
||||||
DDS_ERROR("Argument mask is invalid\n");
|
{
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
return (mask & ~DDS_TOPIC_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -100,191 +85,135 @@ static void dds_topic_status_cb (struct dds_topic *tp)
|
||||||
if (lst->on_inconsistent_topic)
|
if (lst->on_inconsistent_topic)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock);
|
ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock);
|
||||||
dds_entity_invoke_listener(&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS_ID, &tp->m_inconsistent_topic_status);
|
dds_entity_invoke_listener (&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS_ID, &tp->m_inconsistent_topic_status);
|
||||||
ddsrt_mutex_lock (&tp->m_entity.m_observers_lock);
|
ddsrt_mutex_lock (&tp->m_entity.m_observers_lock);
|
||||||
tp->m_inconsistent_topic_status.total_count_change = 0;
|
tp->m_inconsistent_topic_status.total_count_change = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_status_set(&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
|
dds_entity_status_set (&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
|
||||||
tp->m_entity.m_cb_count--;
|
tp->m_entity.m_cb_count--;
|
||||||
ddsrt_cond_broadcast (&tp->m_entity.m_observers_cond);
|
ddsrt_cond_broadcast (&tp->m_entity.m_observers_cond);
|
||||||
ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock);
|
ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ddsi_sertopic *
|
struct ddsi_sertopic *dds_topic_lookup_locked (dds_domain *domain, const char *name) ddsrt_nonnull_all;
|
||||||
dds_topic_lookup_locked(
|
|
||||||
dds_domain *domain,
|
struct ddsi_sertopic *dds_topic_lookup_locked (dds_domain *domain, const char *name)
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
struct ddsi_sertopic *st = NULL;
|
ddsrt_avl_iter_t iter;
|
||||||
ddsrt_avl_iter_t iter;
|
for (struct ddsi_sertopic *st = ddsrt_avl_iter_first (&dds_topictree_def, &domain->m_topics, &iter); st; st = ddsrt_avl_iter_next (&iter))
|
||||||
|
if (strcmp (st->name, name) == 0)
|
||||||
assert (domain);
|
return st;
|
||||||
assert (name);
|
return NULL;
|
||||||
|
|
||||||
st = ddsrt_avl_iter_first (&dds_topictree_def, &domain->m_topics, &iter);
|
|
||||||
while (st) {
|
|
||||||
if (strcmp (st->name, name) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
st = ddsrt_avl_iter_next (&iter);
|
|
||||||
}
|
|
||||||
return st;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ddsi_sertopic *
|
struct ddsi_sertopic *dds_topic_lookup (dds_domain *domain, const char *name)
|
||||||
dds_topic_lookup(
|
|
||||||
dds_domain *domain,
|
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
struct ddsi_sertopic *st;
|
struct ddsi_sertopic *st;
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
st = dds_topic_lookup_locked(domain, name);
|
st = dds_topic_lookup_locked (domain, name);
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic *st)
|
||||||
dds_topic_free(
|
|
||||||
dds_domainid_t domainid,
|
|
||||||
struct ddsi_sertopic *st)
|
|
||||||
{
|
{
|
||||||
dds_domain *domain;
|
dds_domain *domain;
|
||||||
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
assert (st);
|
domain = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
|
||||||
|
if (domain != NULL)
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
{
|
||||||
domain = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
|
assert (ddsrt_avl_lookup (&dds_topictree_def, &domain->m_topics, st->name_type_name) != NULL);
|
||||||
if (domain != NULL) {
|
ddsrt_avl_delete (&dds_topictree_def, &domain->m_topics, st);
|
||||||
ddsrt_avl_delete (&dds_topictree_def, &domain->m_topics, st);
|
}
|
||||||
}
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
st->status_cb_entity = NULL;
|
||||||
st->status_cb_entity = NULL;
|
ddsi_sertopic_unref (st);
|
||||||
ddsi_sertopic_unref (st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dds_topic_add_locked (dds_domainid_t id, struct ddsi_sertopic *st)
|
||||||
dds_topic_add_locked(
|
|
||||||
dds_domainid_t id,
|
|
||||||
struct ddsi_sertopic *st)
|
|
||||||
{
|
{
|
||||||
dds_domain * dom;
|
dds_domain *dom = dds_domain_find_locked (id);
|
||||||
dom = dds_domain_find_locked (id);
|
assert (dom);
|
||||||
assert (dom);
|
assert (ddsrt_avl_lookup (&dds_topictree_def, &dom->m_topics, st->name_type_name) == NULL);
|
||||||
ddsrt_avl_insert (&dds_topictree_def, &dom->m_topics, st);
|
ddsrt_avl_insert (&dds_topictree_def, &dom->m_topics, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_EXPORT dds_entity_t
|
dds_entity_t dds_find_topic (dds_entity_t participant, const char *name)
|
||||||
dds_find_topic(
|
|
||||||
dds_entity_t participant,
|
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
dds_entity_t tp;
|
dds_entity_t tp;
|
||||||
dds_entity *p = NULL;
|
dds_participant *p;
|
||||||
struct ddsi_sertopic *st;
|
struct ddsi_sertopic *st;
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
|
|
||||||
if (name) {
|
if (name == NULL)
|
||||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &p);
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
if (rc == DDS_RETCODE_OK) {
|
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
|
||||||
st = dds_topic_lookup_locked (p->m_domain, name);
|
|
||||||
if (st) {
|
|
||||||
/* FIXME: calling addref is wrong because the Cyclone library has no
|
|
||||||
knowledge of the reference and hence simply deleting the participant
|
|
||||||
won't make the ref count drop to 0. On the other hand, the DDS spec
|
|
||||||
says find_topic (and a second call to create_topic) return a new
|
|
||||||
proxy that must separately be deleted. */
|
|
||||||
dds_entity_add_ref (&st->status_cb_entity->m_entity);
|
|
||||||
tp = st->status_cb_entity->m_entity.m_hdllink.hdl;
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Topic is not being created yet\n");
|
|
||||||
tp = DDS_RETCODE_PRECONDITION_NOT_MET;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
|
||||||
dds_entity_unlock(p);
|
|
||||||
} else {
|
|
||||||
tp = rc;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Argument name is not valid\n");
|
|
||||||
tp = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tp;
|
if ((rc = dds_participant_lock (participant, &p)) != DDS_RETCODE_OK)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
|
if ((st = dds_topic_lookup_locked (p->m_entity.m_domain, name)) == NULL)
|
||||||
|
tp = DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: calling addref is wrong because the Cyclone library has no
|
||||||
|
knowledge of the reference and hence simply deleting the participant
|
||||||
|
won't make the ref count drop to 0. On the other hand, the DDS spec
|
||||||
|
says find_topic (and a second call to create_topic) return a new
|
||||||
|
proxy that must separately be deleted. */
|
||||||
|
dds_entity_add_ref (&st->status_cb_entity->m_entity);
|
||||||
|
tp = st->status_cb_entity->m_entity.m_hdllink.hdl;
|
||||||
|
}
|
||||||
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
|
dds_participant_unlock (p);
|
||||||
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_topic_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||||
dds_topic_delete(
|
|
||||||
dds_entity *e)
|
static dds_return_t dds_topic_delete (dds_entity *e)
|
||||||
{
|
{
|
||||||
dds_topic_free(e->m_domainid, ((dds_topic*) e)->m_stopic);
|
dds_topic_free (e->m_domainid, ((dds_topic *) e)->m_stopic);
|
||||||
return DDS_RETCODE_OK;
|
return DDS_RETCODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||||
dds_topic_qos_validate(
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
|
||||||
assert(qos);
|
|
||||||
|
|
||||||
/* Check consistency. */
|
static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled)
|
||||||
if (!dds_qos_validate_common(qos)) {
|
{
|
||||||
DDS_ERROR("Argument QoS is not valid\n");
|
if (!dds_qos_validate_common (qos))
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
}
|
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
|
||||||
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data)) {
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
DDS_ERROR("Group data QoS policy is inconsistent and caused an error\n");
|
if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy(&qos->durability_service) < 0)
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
}
|
if ((qos->present & QP_LIFESPAN) && validate_duration(&qos->lifespan.duration) < 0)
|
||||||
if ((qos->present & QP_DURABILITY_SERVICE) && (validate_durability_service_qospolicy(&qos->durability_service) != 0)) {
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
DDS_ERROR("Durability service QoS policy is inconsistent and caused an error\n");
|
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && validate_history_and_resource_limits(&qos->history, &qos->resource_limits) < 0)
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
}
|
return enabled ? dds_qos_validate_mutable_common(qos) : DDS_RETCODE_OK;
|
||||||
if ((qos->present & QP_LIFESPAN) && (validate_duration(&qos->lifespan.duration) != 0)) {
|
}
|
||||||
DDS_ERROR("Lifespan QoS policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
static dds_return_t dds_topic_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||||
if (qos->present & QP_HISTORY && (qos->present & QP_RESOURCE_LIMITS) && (validate_history_and_resource_limits(&qos->history, &qos->resource_limits) != 0)) {
|
{
|
||||||
DDS_ERROR("Lifespan QoS policy is inconsistent and caused an error\n");
|
/* FIXME: QoS changes */
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
dds_return_t ret;
|
||||||
}
|
(void) e;
|
||||||
if(ret == DDS_RETCODE_OK && enabled){
|
if ((ret = dds_topic_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
|
||||||
ret = dds_qos_validate_mutable_common(qos);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
|
return enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool dupdef_qos_ok (const dds_qos_t *qos, const struct ddsi_sertopic *st)
|
||||||
static dds_return_t
|
|
||||||
dds_topic_qos_set(
|
|
||||||
dds_entity *e,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret = dds_topic_qos_validate(qos, enabled);
|
if ((qos == NULL) != (st->status_cb_entity->m_entity.m_qos == NULL))
|
||||||
(void)e;
|
return false;
|
||||||
if (ret == DDS_RETCODE_OK) {
|
else if (qos == NULL)
|
||||||
if (enabled) {
|
return true;
|
||||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
else
|
||||||
DDS_ERROR("Changing the topic QoS is not supported\n");
|
return dds_qos_equal (st->status_cb_entity->m_entity.m_qos, qos);
|
||||||
ret = DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dupdef_qos_ok(const dds_qos_t *qos, const struct ddsi_sertopic *st)
|
|
||||||
{
|
|
||||||
if ((qos == NULL) != (st->status_cb_entity->m_entity.m_qos == NULL)) {
|
|
||||||
return false;
|
|
||||||
} else if (qos == NULL) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return dds_qos_equal(st->status_cb_entity->m_entity.m_qos, qos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct ddsi_sertopic *b)
|
static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct ddsi_sertopic *b)
|
||||||
|
@ -300,276 +229,213 @@ static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct dds
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_EXPORT dds_entity_t
|
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 nn_plist_t *sedp_plist)
|
||||||
dds_create_topic_arbitrary (
|
|
||||||
dds_entity_t participant,
|
|
||||||
struct ddsi_sertopic *sertopic,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
const dds_listener_t *listener,
|
|
||||||
const nn_plist_t *sedp_plist)
|
|
||||||
{
|
{
|
||||||
struct ddsi_sertopic *stgeneric;
|
struct ddsi_sertopic *stgeneric;
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
dds_entity *par;
|
dds_participant *par;
|
||||||
dds_topic *top;
|
dds_topic *top;
|
||||||
dds_qos_t *new_qos = NULL;
|
dds_qos_t *new_qos = NULL;
|
||||||
dds_entity_t hdl;
|
dds_entity_t hdl;
|
||||||
struct participant *ddsi_pp;
|
struct participant *ddsi_pp;
|
||||||
|
|
||||||
if (sertopic == NULL){
|
if (sertopic == NULL)
|
||||||
DDS_ERROR("Topic description is NULL\n");
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto bad_param_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
if (qos && (rc = dds_topic_qos_validate (qos, false)) != DDS_RETCODE_OK)
|
||||||
if (rc != DDS_RETCODE_OK) {
|
return rc;
|
||||||
hdl = rc;
|
|
||||||
goto lock_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Validate qos */
|
if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||||
if (qos) {
|
return rc;
|
||||||
hdl = dds_topic_qos_validate (qos, false);
|
|
||||||
if (hdl != DDS_RETCODE_OK) {
|
|
||||||
goto qos_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: I find it weird that qos may be NULL in the entity */
|
/* FIXME: I find it weird that qos may be NULL in the entity */
|
||||||
|
|
||||||
/* Check if topic already exists with same name */
|
/* Check if topic already exists with same name */
|
||||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||||
if ((stgeneric = dds_topic_lookup_locked (par->m_domain, sertopic->name)) != NULL) {
|
if ((stgeneric = dds_topic_lookup_locked (par->m_entity.m_domain, sertopic->name)) != NULL) {
|
||||||
if (!sertopic_equivalent (stgeneric, sertopic)) {
|
if (!sertopic_equivalent (stgeneric, sertopic)) {
|
||||||
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
||||||
DDS_ERROR("Create topic with mismatching type\n");
|
rc = DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||||
hdl = DDS_RETCODE_PRECONDITION_NOT_MET;
|
goto err_mismatch;
|
||||||
} else if (!dupdef_qos_ok(qos, stgeneric)) {
|
} else if (!dupdef_qos_ok(qos, stgeneric)) {
|
||||||
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
||||||
DDS_ERROR("Create topic with mismatching qos\n");
|
rc = DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
hdl = DDS_RETCODE_INCONSISTENT_POLICY;
|
goto err_mismatch;
|
||||||
} else {
|
|
||||||
/* FIXME: calling addref is wrong because the Cyclone library has no
|
|
||||||
knowledge of the reference and hence simply deleting the participant
|
|
||||||
won't make the ref count drop to 0. On the other hand, the DDS spec
|
|
||||||
says find_topic (and a second call to create_topic) return a new
|
|
||||||
proxy that must separately be deleted. */
|
|
||||||
dds_entity_add_ref (&stgeneric->status_cb_entity->m_entity);
|
|
||||||
hdl = stgeneric->status_cb_entity->m_entity.m_hdllink.hdl;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
|
||||||
} else {
|
} else {
|
||||||
if (qos) {
|
/* FIXME: calling addref is wrong because the Cyclone library has no
|
||||||
new_qos = dds_create_qos();
|
knowledge of the reference and hence simply deleting the participant
|
||||||
/* Only returns failure when one of the qos args is NULL, which
|
won't make the ref count drop to 0. On the other hand, the DDS spec
|
||||||
* is not the case here. */
|
says find_topic (and a second call to create_topic) return a new
|
||||||
(void)dds_copy_qos(new_qos, qos);
|
proxy that must separately be deleted. */
|
||||||
}
|
dds_entity_add_ref (&stgeneric->status_cb_entity->m_entity);
|
||||||
|
hdl = stgeneric->status_cb_entity->m_entity.m_hdllink.hdl;
|
||||||
/* Create topic */
|
}
|
||||||
top = dds_alloc (sizeof (*top));
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
hdl = dds_entity_init (&top->m_entity, par, DDS_KIND_TOPIC, new_qos, listener, DDS_TOPIC_STATUS_MASK);
|
} else {
|
||||||
top->m_entity.m_deriver.delete = dds_topic_delete;
|
if (qos)
|
||||||
top->m_entity.m_deriver.set_qos = dds_topic_qos_set;
|
{
|
||||||
top->m_entity.m_deriver.validate_status = dds_topic_status_validate;
|
new_qos = dds_create_qos ();
|
||||||
top->m_stopic = ddsi_sertopic_ref (sertopic);
|
(void)dds_copy_qos (new_qos, qos);
|
||||||
sertopic->status_cb_entity = top;
|
|
||||||
|
|
||||||
/* Add topic to extent */
|
|
||||||
dds_topic_add_locked (par->m_domainid, sertopic);
|
|
||||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
|
||||||
|
|
||||||
/* Publish Topic */
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
|
||||||
ddsi_pp = ephash_lookup_participant_guid (&par->m_guid);
|
|
||||||
assert (ddsi_pp);
|
|
||||||
if (sedp_plist) {
|
|
||||||
sedp_write_topic (ddsi_pp, sedp_plist);
|
|
||||||
}
|
|
||||||
thread_state_asleep (lookup_thread_state ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qos_err:
|
/* Create topic */
|
||||||
dds_entity_unlock(par);
|
top = dds_alloc (sizeof (*top));
|
||||||
lock_err:
|
hdl = dds_entity_init (&top->m_entity, &par->m_entity, DDS_KIND_TOPIC, new_qos, listener, DDS_TOPIC_STATUS_MASK);
|
||||||
bad_param_err:
|
top->m_entity.m_deriver.delete = dds_topic_delete;
|
||||||
return hdl;
|
top->m_entity.m_deriver.set_qos = dds_topic_qos_set;
|
||||||
|
top->m_entity.m_deriver.validate_status = dds_topic_status_validate;
|
||||||
|
top->m_stopic = ddsi_sertopic_ref (sertopic);
|
||||||
|
sertopic->status_cb_entity = top;
|
||||||
|
|
||||||
|
/* Add topic to extent */
|
||||||
|
dds_topic_add_locked (par->m_entity.m_domainid, sertopic);
|
||||||
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
|
|
||||||
|
/* Publish Topic */
|
||||||
|
thread_state_awake (lookup_thread_state ());
|
||||||
|
ddsi_pp = ephash_lookup_participant_guid (&par->m_entity.m_guid);
|
||||||
|
assert (ddsi_pp);
|
||||||
|
if (sedp_plist)
|
||||||
|
sedp_write_topic (ddsi_pp, sedp_plist);
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
}
|
||||||
|
dds_participant_unlock (par);
|
||||||
|
return hdl;
|
||||||
|
|
||||||
|
err_mismatch:
|
||||||
|
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||||
|
dds_participant_unlock (par);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_EXPORT dds_entity_t
|
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_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)
|
|
||||||
{
|
{
|
||||||
char *key = NULL;
|
char *key = NULL;
|
||||||
struct ddsi_sertopic_default *st;
|
struct ddsi_sertopic_default *st;
|
||||||
const char *typename;
|
const char *typename;
|
||||||
dds_qos_t *new_qos = NULL;
|
dds_qos_t *new_qos = NULL;
|
||||||
nn_plist_t plist;
|
nn_plist_t plist;
|
||||||
dds_entity_t hdl;
|
dds_entity_t hdl;
|
||||||
uint32_t index;
|
size_t keysz;
|
||||||
size_t keysz;
|
|
||||||
|
|
||||||
if (desc == NULL){
|
if (desc == NULL || name == NULL || !is_valid_name (name))
|
||||||
DDS_ERROR("Topic description is NULL");
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto bad_param_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == NULL) {
|
typename = desc->m_typename;
|
||||||
DDS_ERROR("Topic name is NULL");
|
keysz = strlen (name) + strlen (typename) + 2;
|
||||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
key = dds_alloc (keysz);
|
||||||
goto bad_param_err;
|
(void) snprintf (key, keysz, "%s/%s", name, typename);
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_valid_name(name)) {
|
st = dds_alloc (sizeof (*st));
|
||||||
DDS_ERROR("Topic name contains characters that are not allowed.");
|
|
||||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto bad_param_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
typename = desc->m_typename;
|
ddsrt_atomic_st32 (&st->c.refc, 1);
|
||||||
keysz = strlen (name) + strlen (typename) + 2;
|
st->c.iid = ddsi_iid_gen ();
|
||||||
key = (char*) dds_alloc (keysz);
|
st->c.status_cb = dds_topic_status_cb;
|
||||||
(void) snprintf(key, keysz, "%s/%s", name, typename);
|
st->c.status_cb_entity = NULL; /* set by dds_create_topic_arbitrary */
|
||||||
|
st->c.name_type_name = key;
|
||||||
|
st->c.name = dds_string_dup (name);
|
||||||
|
st->c.type_name = dds_string_dup (typename);
|
||||||
|
st->c.ops = &ddsi_sertopic_ops_default;
|
||||||
|
st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey;
|
||||||
|
st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops);
|
||||||
|
st->native_encoding_identifier = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? CDR_LE : CDR_BE);
|
||||||
|
|
||||||
st = dds_alloc (sizeof (*st));
|
st->type = (void*) desc;
|
||||||
|
st->nkeys = desc->m_nkeys;
|
||||||
|
st->keys = desc->m_keys;
|
||||||
|
|
||||||
ddsrt_atomic_st32 (&st->c.refc, 1);
|
/* Check if topic cannot be optimised (memcpy marshal) */
|
||||||
st->c.iid = ddsi_iid_gen ();
|
if (!(desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE)) {
|
||||||
st->c.status_cb = dds_topic_status_cb;
|
st->opt_size = dds_stream_check_optimize (desc);
|
||||||
st->c.status_cb_entity = NULL; /* set by dds_create_topic_arbitrary */
|
}
|
||||||
st->c.name_type_name = key;
|
|
||||||
st->c.name = dds_string_dup (name);
|
|
||||||
st->c.type_name = dds_string_dup (typename);
|
|
||||||
st->c.ops = &ddsi_sertopic_ops_default;
|
|
||||||
st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey;
|
|
||||||
st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops);
|
|
||||||
st->native_encoding_identifier = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? CDR_LE : CDR_BE);
|
|
||||||
|
|
||||||
st->type = (void*) desc;
|
nn_plist_init_empty (&plist);
|
||||||
st->nkeys = desc->m_nkeys;
|
if (new_qos)
|
||||||
st->keys = desc->m_keys;
|
dds_merge_qos (&plist.qos, new_qos);
|
||||||
|
|
||||||
/* Check if topic cannot be optimised (memcpy marshal) */
|
/* Set Topic meta data (for SEDP publication) */
|
||||||
if ((desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) == 0) {
|
plist.qos.topic_name = dds_string_dup (st->c.name);
|
||||||
st->opt_size = dds_stream_check_optimize (desc);
|
plist.qos.type_name = dds_string_dup (st->c.type_name);
|
||||||
}
|
plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME);
|
||||||
|
if (desc->m_meta)
|
||||||
|
{
|
||||||
|
plist.type_description = dds_string_dup (desc->m_meta);
|
||||||
|
plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION;
|
||||||
|
}
|
||||||
|
if (desc->m_nkeys)
|
||||||
|
{
|
||||||
|
plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS;
|
||||||
|
plist.qos.subscription_keys.use_key_list = 1;
|
||||||
|
plist.qos.subscription_keys.key_list.n = desc->m_nkeys;
|
||||||
|
plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*));
|
||||||
|
for (uint32_t index = 0; index < desc->m_nkeys; index++)
|
||||||
|
plist.qos.subscription_keys.key_list.strs[index] = dds_string_dup (desc->m_keys[index].m_name);
|
||||||
|
}
|
||||||
|
|
||||||
nn_plist_init_empty (&plist);
|
hdl = dds_create_topic_arbitrary (participant, &st->c, qos, listener, &plist);
|
||||||
if (new_qos) {
|
ddsi_sertopic_unref (&st->c);
|
||||||
dds_merge_qos (&plist.qos, new_qos);
|
nn_plist_fini (&plist);
|
||||||
}
|
return hdl;
|
||||||
|
|
||||||
/* Set Topic meta data (for SEDP publication) */
|
|
||||||
plist.qos.topic_name = dds_string_dup (st->c.name);
|
|
||||||
plist.qos.type_name = dds_string_dup (st->c.type_name);
|
|
||||||
plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME);
|
|
||||||
if (desc->m_meta) {
|
|
||||||
plist.type_description = dds_string_dup (desc->m_meta);
|
|
||||||
plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION;
|
|
||||||
}
|
|
||||||
if (desc->m_nkeys) {
|
|
||||||
plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS;
|
|
||||||
plist.qos.subscription_keys.use_key_list = 1;
|
|
||||||
plist.qos.subscription_keys.key_list.n = desc->m_nkeys;
|
|
||||||
plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*));
|
|
||||||
for (index = 0; index < desc->m_nkeys; index++) {
|
|
||||||
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);
|
|
||||||
ddsi_sertopic_unref (&st->c);
|
|
||||||
nn_plist_fini (&plist);
|
|
||||||
|
|
||||||
bad_param_err:
|
|
||||||
return hdl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool dds_topic_chaining_filter (const void *sample, void *ctx)
|
||||||
dds_topic_chaining_filter(
|
|
||||||
const void *sample,
|
|
||||||
void *ctx)
|
|
||||||
{
|
{
|
||||||
dds_topic_filter_fn realf = (dds_topic_filter_fn)ctx;
|
dds_topic_filter_fn realf = (dds_topic_filter_fn) ctx;
|
||||||
return realf (sample);
|
return realf (sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dds_topic_mod_filter (dds_entity_t topic, dds_topic_intern_filter_fn *filter, void **ctx, bool set)
|
||||||
dds_topic_mod_filter(
|
|
||||||
dds_entity_t topic,
|
|
||||||
dds_topic_intern_filter_fn *filter,
|
|
||||||
void **ctx,
|
|
||||||
bool set)
|
|
||||||
{
|
{
|
||||||
dds_topic *t;
|
dds_topic *t;
|
||||||
if (dds_topic_lock(topic, &t) == DDS_RETCODE_OK) {
|
if (dds_topic_lock (topic, &t) == DDS_RETCODE_OK)
|
||||||
if (set) {
|
{
|
||||||
t->filter_fn = *filter;
|
if (set) {
|
||||||
t->filter_ctx = *ctx;
|
t->filter_fn = *filter;
|
||||||
} else {
|
t->filter_ctx = *ctx;
|
||||||
*filter = t->filter_fn;
|
|
||||||
*ctx = t->filter_ctx;
|
|
||||||
}
|
|
||||||
dds_topic_unlock(t);
|
|
||||||
} else {
|
} else {
|
||||||
*filter = 0;
|
*filter = t->filter_fn;
|
||||||
*ctx = NULL;
|
*ctx = t->filter_ctx;
|
||||||
}
|
}
|
||||||
|
dds_topic_unlock (t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*filter = 0;
|
||||||
|
*ctx = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_set_topic_filter (dds_entity_t topic, dds_topic_filter_fn filter)
|
||||||
dds_set_topic_filter(
|
|
||||||
dds_entity_t topic,
|
|
||||||
dds_topic_filter_fn filter)
|
|
||||||
{
|
{
|
||||||
dds_topic_intern_filter_fn chaining = dds_topic_chaining_filter;
|
dds_topic_intern_filter_fn chaining = dds_topic_chaining_filter;
|
||||||
void *realf = (void *)filter;
|
void *realf = (void *) filter;
|
||||||
dds_topic_mod_filter (topic, &chaining, &realf, true);
|
dds_topic_mod_filter (topic, &chaining, &realf, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_topic_set_filter (dds_entity_t topic, dds_topic_filter_fn filter)
|
||||||
dds_topic_set_filter(
|
|
||||||
dds_entity_t topic,
|
|
||||||
dds_topic_filter_fn filter)
|
|
||||||
{
|
{
|
||||||
dds_set_topic_filter(topic, filter);
|
dds_set_topic_filter (topic, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_topic_filter_fn
|
dds_topic_filter_fn dds_get_topic_filter (dds_entity_t topic)
|
||||||
dds_get_topic_filter(
|
|
||||||
dds_entity_t topic)
|
|
||||||
{
|
{
|
||||||
dds_topic_intern_filter_fn filter;
|
dds_topic_intern_filter_fn filter;
|
||||||
void *ctx;
|
void *ctx;
|
||||||
dds_topic_mod_filter (topic, &filter, &ctx, false);
|
dds_topic_mod_filter (topic, &filter, &ctx, false);
|
||||||
return (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn)ctx : 0;
|
return (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn) ctx : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_topic_filter_fn
|
dds_topic_filter_fn dds_topic_get_filter (dds_entity_t topic)
|
||||||
dds_topic_get_filter(
|
|
||||||
dds_entity_t topic)
|
|
||||||
{
|
{
|
||||||
return dds_get_topic_filter(topic);
|
return dds_get_topic_filter (topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void dds_topic_set_filter_with_ctx (dds_entity_t topic, dds_topic_intern_filter_fn filter, void *ctx)
|
||||||
dds_topic_set_filter_with_ctx(
|
|
||||||
dds_entity_t topic,
|
|
||||||
dds_topic_intern_filter_fn filter,
|
|
||||||
void *ctx)
|
|
||||||
{
|
{
|
||||||
dds_topic_mod_filter (topic, &filter, &ctx, true);
|
dds_topic_mod_filter (topic, &filter, &ctx, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_topic_intern_filter_fn
|
dds_topic_intern_filter_fn dds_topic_get_filter_with_ctx (dds_entity_t topic)
|
||||||
dds_topic_get_filter_with_ctx(
|
|
||||||
dds_entity_t topic)
|
|
||||||
{
|
{
|
||||||
dds_topic_intern_filter_fn filter;
|
dds_topic_intern_filter_fn filter;
|
||||||
void *ctx;
|
void *ctx;
|
||||||
|
@ -577,93 +443,32 @@ dds_topic_get_filter_with_ctx(
|
||||||
return (filter == dds_topic_chaining_filter) ? 0 : filter;
|
return (filter == dds_topic_chaining_filter) ? 0 : filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_EXPORT dds_return_t
|
dds_return_t dds_get_name (dds_entity_t topic, char *name, size_t size)
|
||||||
dds_get_name(
|
|
||||||
dds_entity_t topic,
|
|
||||||
char *name,
|
|
||||||
size_t size)
|
|
||||||
{
|
{
|
||||||
dds_topic *t;
|
dds_topic *t;
|
||||||
dds_return_t ret;
|
dds_return_t ret;
|
||||||
|
if (size <= 0 || name == NULL)
|
||||||
if(size <= 0){
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
DDS_ERROR("Argument size is smaller than 0\n");
|
name[0] = '\0';
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
if ((ret = dds_topic_lock (topic, &t)) != DDS_RETCODE_OK)
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if(name == NULL){
|
|
||||||
DDS_ERROR("Argument name is NULL\n");
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
name[0] = '\0';
|
|
||||||
ret = dds_topic_lock(topic, &t);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
(void)snprintf(name, size, "%s", t->m_stopic->name);
|
|
||||||
dds_topic_unlock(t);
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Error occurred on locking topic\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
fail:
|
|
||||||
return ret;
|
return ret;
|
||||||
|
(void) snprintf (name, size, "%s", t->m_stopic->name);
|
||||||
|
dds_topic_unlock (t);
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_EXPORT dds_return_t
|
dds_return_t dds_get_type_name (dds_entity_t topic, char *name, size_t size)
|
||||||
dds_get_type_name(
|
|
||||||
dds_entity_t topic,
|
|
||||||
char *name,
|
|
||||||
size_t size)
|
|
||||||
{
|
{
|
||||||
dds_topic *t;
|
dds_topic *t;
|
||||||
dds_return_t ret;
|
dds_return_t ret;
|
||||||
|
if (size <= 0 || name == NULL)
|
||||||
if(size <= 0){
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
DDS_ERROR("Argument size is smaller than 0\n");
|
name[0] = '\0';
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
if ((ret = dds_topic_lock (topic, &t)) != DDS_RETCODE_OK)
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if(name == NULL){
|
|
||||||
DDS_ERROR("Argument name is NULL\n");
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
name[0] = '\0';
|
|
||||||
ret = dds_topic_lock(topic, &t);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking topic\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
(void)snprintf(name, size, "%s", t->m_stopic->type_name);
|
|
||||||
dds_topic_unlock(t);
|
|
||||||
fail:
|
|
||||||
return ret;
|
return ret;
|
||||||
|
(void) snprintf (name, size, "%s", t->m_stopic->type_name);
|
||||||
|
dds_topic_unlock (t);
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
DDS_GET_STATUS(topic, inconsistent_topic, INCONSISTENT_TOPIC, total_count_change)
|
||||||
dds_get_inconsistent_topic_status(
|
|
||||||
dds_entity_t topic,
|
|
||||||
dds_inconsistent_topic_status_t *status)
|
|
||||||
{
|
|
||||||
dds_topic *t;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_topic_lock(topic, &t);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking topic\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = t->m_inconsistent_topic_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&t->m_entity.m_observers_lock);
|
|
||||||
if (t->m_entity.m_status_enable & DDS_INCONSISTENT_TOPIC_STATUS) {
|
|
||||||
t->m_inconsistent_topic_status.total_count_change = 0;
|
|
||||||
dds_entity_status_reset(&t->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&t->m_entity.m_observers_lock);
|
|
||||||
dds_topic_unlock(t);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,424 +14,296 @@
|
||||||
#include "dds/ddsrt/heap.h"
|
#include "dds/ddsrt/heap.h"
|
||||||
#include "dds/ddsrt/log.h"
|
#include "dds/ddsrt/log.h"
|
||||||
#include "dds__entity.h"
|
#include "dds__entity.h"
|
||||||
|
#include "dds__participant.h"
|
||||||
#include "dds__querycond.h"
|
#include "dds__querycond.h"
|
||||||
#include "dds__readcond.h"
|
#include "dds__readcond.h"
|
||||||
#include "dds__rhc.h"
|
#include "dds__rhc.h"
|
||||||
|
|
||||||
DEFINE_ENTITY_LOCK_UNLOCK(static, dds_waitset, DDS_KIND_WAITSET)
|
DEFINE_ENTITY_LOCK_UNLOCK (static, dds_waitset, DDS_KIND_WAITSET)
|
||||||
|
|
||||||
static void
|
static void dds_waitset_swap (dds_attachment **dst, dds_attachment **src, dds_attachment *prev, dds_attachment *idx)
|
||||||
dds_waitset_swap(
|
|
||||||
dds_attachment **dst,
|
|
||||||
dds_attachment **src,
|
|
||||||
dds_attachment *prev,
|
|
||||||
dds_attachment *idx)
|
|
||||||
{
|
{
|
||||||
/* Remove from source. */
|
/* Remove from source. */
|
||||||
if (prev == NULL) {
|
if (prev == NULL)
|
||||||
*src = idx->next;
|
*src = idx->next;
|
||||||
} else {
|
else
|
||||||
prev->next = idx->next;
|
prev->next = idx->next;
|
||||||
}
|
|
||||||
|
|
||||||
/* Add to destination. */
|
/* Add to destination. */
|
||||||
idx->next = *dst;
|
idx->next = *dst;
|
||||||
*dst = idx;
|
*dst = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_waitset_wait_impl (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_time_t abstimeout)
|
||||||
dds_waitset_wait_impl(
|
|
||||||
dds_entity_t waitset,
|
|
||||||
dds_attach_t *xs,
|
|
||||||
size_t nxs,
|
|
||||||
dds_time_t abstimeout,
|
|
||||||
dds_time_t tnow)
|
|
||||||
{
|
{
|
||||||
dds_waitset *ws;
|
dds_waitset *ws;
|
||||||
dds_return_t ret;
|
dds_return_t ret;
|
||||||
dds_attachment *idx;
|
dds_attachment *idx;
|
||||||
dds_attachment *next;
|
dds_attachment *prev;
|
||||||
dds_attachment *prev;
|
|
||||||
|
|
||||||
if ((xs == NULL) && (nxs != 0)){
|
if (xs == NULL && nxs != 0)
|
||||||
DDS_ERROR("A size was given, but no array\n");
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
if (xs != NULL && nxs == 0)
|
||||||
}
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
if ((xs != NULL) && (nxs == 0)){
|
|
||||||
DDS_ERROR("Array is given with an invalid size\n");
|
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Locking the waitset here will delay a possible deletion until it is
|
|
||||||
* unlocked. Even when the related mutex is unlocked by a conditioned wait. */
|
|
||||||
ret = dds_waitset_lock(waitset, &ws);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
/* Check if any of any previous triggered entities has changed there status
|
|
||||||
* and thus it trigger value could be false now. */
|
|
||||||
idx = ws->triggered;
|
|
||||||
prev = NULL;
|
|
||||||
while (idx != NULL) {
|
|
||||||
next = idx->next;
|
|
||||||
if (idx->entity->m_trigger == 0) {
|
|
||||||
/* Move observed entity to triggered list. */
|
|
||||||
dds_waitset_swap(&(ws->observed), &(ws->triggered), prev, idx);
|
|
||||||
} else {
|
|
||||||
prev = idx;
|
|
||||||
}
|
|
||||||
idx = next;
|
|
||||||
}
|
|
||||||
/* Check if any of the entities have been triggered. */
|
|
||||||
idx = ws->observed;
|
|
||||||
prev = NULL;
|
|
||||||
while (idx != NULL) {
|
|
||||||
next = idx->next;
|
|
||||||
if (idx->entity->m_trigger > 0) {
|
|
||||||
/* Move observed entity to triggered list. */
|
|
||||||
dds_waitset_swap(&(ws->triggered), &(ws->observed), prev, idx);
|
|
||||||
} else {
|
|
||||||
prev = idx;
|
|
||||||
}
|
|
||||||
idx = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only wait/keep waiting when whe have something to observer and there aren't any triggers yet. */
|
|
||||||
while ((ws->observed != NULL) && (ws->triggered == NULL) && (ret == DDS_RETCODE_OK)) {
|
|
||||||
if (abstimeout == DDS_NEVER) {
|
|
||||||
ddsrt_cond_wait(&ws->m_entity.m_cond, &ws->m_entity.m_mutex);
|
|
||||||
} else if (abstimeout <= tnow) {
|
|
||||||
ret = DDS_RETCODE_TIMEOUT;
|
|
||||||
} else {
|
|
||||||
dds_duration_t dt = abstimeout - tnow;
|
|
||||||
(void)ddsrt_cond_waitfor(&ws->m_entity.m_cond, &ws->m_entity.m_mutex, dt);
|
|
||||||
tnow = dds_time();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get number of triggered entities
|
|
||||||
* - set attach array when needed
|
|
||||||
* - swap them back to observed */
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
ret = 0;
|
|
||||||
idx = ws->triggered;
|
|
||||||
while (idx != NULL) {
|
|
||||||
if ((uint32_t)ret < (uint32_t)nxs) {
|
|
||||||
xs[ret] = idx->arg;
|
|
||||||
}
|
|
||||||
ret++;
|
|
||||||
|
|
||||||
next = idx->next;
|
|
||||||
/* The idx is always the first in triggered, so no prev. */
|
|
||||||
dds_waitset_swap(&(ws->observed), &(ws->triggered), NULL, idx);
|
|
||||||
idx = next;
|
|
||||||
}
|
|
||||||
} else if (ret == DDS_RETCODE_TIMEOUT) {
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Internal error");
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_waitset_unlock(ws);
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Error occurred on locking waitset\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Locking the waitset here will delay a possible deletion until it is
|
||||||
|
* unlocked. Even when the related mutex is unlocked by a conditioned wait. */
|
||||||
|
if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* Move any previously but no longer triggering entities back to the observed list */
|
||||||
|
idx = ws->triggered;
|
||||||
|
prev = NULL;
|
||||||
|
while (idx != NULL)
|
||||||
|
{
|
||||||
|
dds_attachment *next = idx->next;
|
||||||
|
if (idx->entity->m_trigger == 0)
|
||||||
|
dds_waitset_swap (&ws->observed, &ws->triggered, prev, idx);
|
||||||
|
else
|
||||||
|
prev = idx;
|
||||||
|
idx = next;
|
||||||
|
}
|
||||||
|
/* Check if any of the observed entities are currently triggered, moving them
|
||||||
|
to the triggered list */
|
||||||
|
idx = ws->observed;
|
||||||
|
prev = NULL;
|
||||||
|
while (idx != NULL)
|
||||||
|
{
|
||||||
|
dds_attachment *next = idx->next;
|
||||||
|
if (idx->entity->m_trigger > 0)
|
||||||
|
dds_waitset_swap (&ws->triggered, &ws->observed, prev, idx);
|
||||||
|
else
|
||||||
|
prev = idx;
|
||||||
|
idx = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only wait/keep waiting when we have something to observe and there aren't any triggers yet. */
|
||||||
|
while (ws->observed != NULL && ws->triggered == NULL)
|
||||||
|
if (!ddsrt_cond_waituntil (&ws->m_entity.m_cond, &ws->m_entity.m_mutex, abstimeout))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Get number of triggered entities
|
||||||
|
* - set attach array when needed
|
||||||
|
* - swap them back to observed */
|
||||||
|
ret = 0;
|
||||||
|
idx = ws->triggered;
|
||||||
|
while (idx != NULL)
|
||||||
|
{
|
||||||
|
if ((uint32_t) ret < (uint32_t) nxs)
|
||||||
|
xs[ret] = idx->arg;
|
||||||
|
ret++;
|
||||||
|
|
||||||
|
/* The idx is always the first in triggered, so no prev. */
|
||||||
|
dds_attachment *next = idx->next;
|
||||||
|
dds_waitset_swap (&ws->observed, &ws->triggered, NULL, idx);
|
||||||
|
idx = next;
|
||||||
|
}
|
||||||
|
dds_waitset_unlock (ws);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dds_waitset_close_list (dds_attachment **list, dds_entity_t waitset)
|
||||||
dds_waitset_close_list(
|
|
||||||
dds_attachment **list,
|
|
||||||
dds_entity_t waitset)
|
|
||||||
{
|
{
|
||||||
dds_attachment *idx = *list;
|
dds_attachment *idx = *list;
|
||||||
dds_attachment *next;
|
dds_attachment *next;
|
||||||
while (idx != NULL) {
|
while (idx != NULL)
|
||||||
next = idx->next;
|
{
|
||||||
(void)dds_entity_observer_unregister(idx->entity->m_hdllink.hdl, waitset);
|
next = idx->next;
|
||||||
ddsrt_free(idx);
|
(void) dds_entity_observer_unregister (idx->entity->m_hdllink.hdl, waitset);
|
||||||
idx = next;
|
ddsrt_free (idx);
|
||||||
}
|
idx = next;
|
||||||
*list = NULL;
|
}
|
||||||
|
*list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool dds_waitset_remove_from_list (dds_attachment **list, dds_entity_t observed)
|
||||||
dds_waitset_remove_from_list(
|
|
||||||
dds_attachment **list,
|
|
||||||
dds_entity_t observed)
|
|
||||||
{
|
{
|
||||||
dds_attachment *idx = *list;
|
dds_attachment *idx, *prev;
|
||||||
dds_attachment *prev = NULL;
|
for (idx = *list, prev = NULL; idx != NULL; prev = idx, idx = idx->next)
|
||||||
|
if (idx->entity->m_hdllink.hdl == observed)
|
||||||
while (idx != NULL) {
|
break;
|
||||||
if (idx->entity->m_hdllink.hdl == observed) {
|
if (idx == NULL)
|
||||||
if (prev == NULL) {
|
|
||||||
*list = idx->next;
|
|
||||||
} else {
|
|
||||||
prev->next = idx->next;
|
|
||||||
}
|
|
||||||
ddsrt_free(idx);
|
|
||||||
|
|
||||||
/* We're done. */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
prev = idx;
|
|
||||||
idx = idx->next;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (prev == NULL)
|
||||||
|
*list = idx->next;
|
||||||
|
else
|
||||||
|
prev->next = idx->next;
|
||||||
|
ddsrt_free (idx);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_waitset_close (struct dds_entity *e)
|
||||||
dds_waitset_close(
|
|
||||||
struct dds_entity *e)
|
|
||||||
{
|
{
|
||||||
dds_waitset *ws = (dds_waitset*)e;
|
dds_waitset *ws = (dds_waitset *) e;
|
||||||
|
dds_waitset_close_list (&ws->observed, e->m_hdllink.hdl);
|
||||||
dds_waitset_close_list(&ws->observed, e->m_hdllink.hdl);
|
dds_waitset_close_list (&ws->triggered, e->m_hdllink.hdl);
|
||||||
dds_waitset_close_list(&ws->triggered, e->m_hdllink.hdl);
|
ddsrt_cond_broadcast (&e->m_cond);
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
/* Trigger waitset to wake up. */
|
|
||||||
ddsrt_cond_broadcast(&e->m_cond);
|
|
||||||
|
|
||||||
return DDS_RETCODE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_EXPORT dds_entity_t
|
dds_entity_t dds_create_waitset (dds_entity_t participant)
|
||||||
dds_create_waitset(
|
|
||||||
dds_entity_t participant)
|
|
||||||
{
|
{
|
||||||
dds_entity_t hdl;
|
dds_entity_t hdl;
|
||||||
dds_entity *par;
|
dds_participant *par;
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
|
|
||||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||||
if (rc == DDS_RETCODE_OK) {
|
return rc;
|
||||||
dds_waitset *waitset = dds_alloc(sizeof(*waitset));
|
|
||||||
hdl = dds_entity_init(&waitset->m_entity, par, DDS_KIND_WAITSET, NULL, NULL, 0);
|
|
||||||
waitset->m_entity.m_deriver.close = dds_waitset_close;
|
|
||||||
waitset->observed = NULL;
|
|
||||||
waitset->triggered = NULL;
|
|
||||||
dds_entity_unlock(par);
|
|
||||||
} else {
|
|
||||||
hdl = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hdl;
|
dds_waitset *waitset = dds_alloc (sizeof (*waitset));
|
||||||
|
hdl = dds_entity_init (&waitset->m_entity, &par->m_entity, DDS_KIND_WAITSET, NULL, NULL, 0);
|
||||||
|
waitset->m_entity.m_deriver.close = dds_waitset_close;
|
||||||
|
waitset->observed = NULL;
|
||||||
|
waitset->triggered = NULL;
|
||||||
|
dds_participant_unlock (par);
|
||||||
|
return hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DDS_EXPORT dds_return_t
|
dds_return_t dds_waitset_get_entities (dds_entity_t waitset, dds_entity_t *entities, size_t size)
|
||||||
dds_waitset_get_entities(
|
|
||||||
dds_entity_t waitset,
|
|
||||||
dds_entity_t *entities,
|
|
||||||
size_t size)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret;
|
dds_return_t ret;
|
||||||
dds_waitset *ws;
|
dds_waitset *ws;
|
||||||
|
|
||||||
ret = dds_waitset_lock(waitset, &ws);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
dds_attachment* iter;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
iter = ws->observed;
|
|
||||||
while (iter) {
|
|
||||||
if (((size_t)ret < size) && (entities != NULL)) {
|
|
||||||
entities[ret] = iter->entity->m_hdllink.hdl;
|
|
||||||
}
|
|
||||||
ret++;
|
|
||||||
iter = iter->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
iter = ws->triggered;
|
|
||||||
while (iter) {
|
|
||||||
if (((size_t)ret < size) && (entities != NULL)) {
|
|
||||||
entities[ret] = iter->entity->m_hdllink.hdl;
|
|
||||||
}
|
|
||||||
ret++;
|
|
||||||
iter = iter->next;
|
|
||||||
}
|
|
||||||
dds_waitset_unlock(ws);
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Error occurred on locking waitset\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
for (dds_attachment *iter = ws->observed; iter != NULL; iter = iter->next)
|
||||||
|
{
|
||||||
|
if ((size_t) ret < size && entities != NULL)
|
||||||
|
entities[ret] = iter->entity->m_hdllink.hdl;
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
for (dds_attachment *iter = ws->triggered; iter != NULL; iter = iter->next)
|
||||||
|
{
|
||||||
|
if ((size_t) ret < size && entities != NULL)
|
||||||
|
entities[ret] = iter->entity->m_hdllink.hdl;
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
dds_waitset_unlock(ws);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dds_waitset_move (dds_attachment **src, dds_attachment **dst, dds_entity_t entity)
|
||||||
static void
|
|
||||||
dds_waitset_move(
|
|
||||||
dds_attachment **src,
|
|
||||||
dds_attachment **dst,
|
|
||||||
dds_entity_t entity)
|
|
||||||
{
|
{
|
||||||
dds_attachment *idx = *src;
|
dds_attachment *idx, *prev;
|
||||||
dds_attachment *prev = NULL;
|
for (idx = *src, prev = NULL; idx != NULL; prev = idx, idx = idx->next)
|
||||||
while (idx != NULL) {
|
if (idx->entity->m_hdllink.hdl == entity)
|
||||||
if (idx->entity->m_hdllink.hdl == entity) {
|
break;
|
||||||
/* Swap idx from src to dst. */
|
if (idx != NULL)
|
||||||
dds_waitset_swap(dst, src, prev, idx);
|
{
|
||||||
|
/* Swap idx from src to dst. */
|
||||||
/* We're done. */
|
dds_waitset_swap (dst, src, prev, idx);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
prev = idx;
|
|
||||||
idx = idx->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dds_waitset_remove (dds_waitset *ws, dds_entity_t observed)
|
||||||
dds_waitset_remove(
|
|
||||||
dds_waitset *ws,
|
|
||||||
dds_entity_t observed)
|
|
||||||
{
|
{
|
||||||
if (!dds_waitset_remove_from_list(&(ws->observed), observed)) {
|
if (!dds_waitset_remove_from_list (&ws->observed, observed))
|
||||||
(void)dds_waitset_remove_from_list(&(ws->triggered), observed);
|
(void) dds_waitset_remove_from_list (&ws->triggered, observed);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called when the observed entity signals a status change. */
|
/* This is called when the observed entity signals a status change. */
|
||||||
void
|
void dds_waitset_observer (dds_entity_t observer, dds_entity_t observed, uint32_t status)
|
||||||
dds_waitset_observer(
|
|
||||||
dds_entity_t observer,
|
|
||||||
dds_entity_t observed,
|
|
||||||
uint32_t status)
|
|
||||||
{
|
{
|
||||||
dds_waitset *ws;
|
dds_waitset *ws;
|
||||||
if (dds_waitset_lock(observer, &ws) == DDS_RETCODE_OK) {
|
if (dds_waitset_lock (observer, &ws) == DDS_RETCODE_OK) {
|
||||||
if (status & DDS_DELETING_STATUS) {
|
if (status & DDS_DELETING_STATUS) {
|
||||||
/* Remove this observed entity, which is being deleted, from the waitset. */
|
/* Remove this observed entity, which is being deleted, from the waitset. */
|
||||||
dds_waitset_remove(ws, observed);
|
dds_waitset_remove (ws, observed);
|
||||||
/* Our registration to this observed entity will be removed automatically. */
|
/* Our registration to this observed entity will be removed automatically. */
|
||||||
} else if (status != 0) {
|
} else if (status != 0) {
|
||||||
/* Move observed entity to triggered list. */
|
/* Move observed entity to triggered list. */
|
||||||
dds_waitset_move(&(ws->observed), &(ws->triggered), observed);
|
dds_waitset_move (&ws->observed, &ws->triggered, observed);
|
||||||
} else {
|
|
||||||
/* Remove observed entity from triggered list (which it possibly resides in). */
|
|
||||||
dds_waitset_move(&(ws->triggered), &(ws->observed), observed);
|
|
||||||
}
|
|
||||||
/* Trigger waitset to wake up. */
|
|
||||||
ddsrt_cond_broadcast(&ws->m_entity.m_cond);
|
|
||||||
dds_waitset_unlock(ws);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DDS_EXPORT dds_return_t
|
|
||||||
dds_waitset_attach(
|
|
||||||
dds_entity_t waitset,
|
|
||||||
dds_entity_t entity,
|
|
||||||
dds_attach_t x)
|
|
||||||
{
|
|
||||||
dds_entity *e = NULL;
|
|
||||||
dds_waitset *ws;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_waitset_lock(waitset, &ws);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
if (waitset != entity) {
|
|
||||||
ret = dds_entity_lock(entity, DDS_KIND_DONTCARE, &e);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
e = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e = &ws->m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This will fail if given entity is already attached (or deleted). */
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
ret = dds_entity_observer_register_nl(e, waitset, dds_waitset_observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
dds_attachment *a = ddsrt_malloc(sizeof(dds_attachment));
|
|
||||||
a->arg = x;
|
|
||||||
a->entity = e;
|
|
||||||
if (e->m_trigger > 0) {
|
|
||||||
a->next = ws->triggered;
|
|
||||||
ws->triggered = a;
|
|
||||||
} else {
|
|
||||||
a->next = ws->observed;
|
|
||||||
ws->observed = a;
|
|
||||||
}
|
|
||||||
ret = DDS_RETCODE_OK;
|
|
||||||
} else if (ret != DDS_RETCODE_PRECONDITION_NOT_MET) {
|
|
||||||
DDS_ERROR("Entity is not valid\n");
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Entity is already attached\n");
|
|
||||||
}
|
|
||||||
if ((e != NULL) && (waitset != entity)) {
|
|
||||||
dds_entity_unlock(e);
|
|
||||||
}
|
|
||||||
dds_waitset_unlock(ws);
|
|
||||||
} else {
|
} else {
|
||||||
DDS_ERROR("Error occurred on locking waitset\n");
|
/* Remove observed entity from triggered list (which it possibly resides in). */
|
||||||
|
dds_waitset_move (&ws->triggered, &ws->observed, observed);
|
||||||
}
|
}
|
||||||
|
/* Trigger waitset to wake up. */
|
||||||
return ret;
|
ddsrt_cond_broadcast (&ws->m_entity.m_cond);
|
||||||
|
dds_waitset_unlock (ws);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_EXPORT dds_return_t
|
dds_return_t dds_waitset_attach (dds_entity_t waitset, dds_entity_t entity, dds_attach_t x)
|
||||||
dds_waitset_detach(
|
|
||||||
dds_entity_t waitset,
|
|
||||||
dds_entity_t entity)
|
|
||||||
{
|
{
|
||||||
dds_waitset *ws;
|
dds_entity *e;
|
||||||
dds_return_t ret;
|
dds_waitset *ws;
|
||||||
|
dds_return_t ret;
|
||||||
ret = dds_waitset_lock(waitset, &ws);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
/* Possibly fails when entity was not attached. */
|
|
||||||
if (waitset == entity) {
|
|
||||||
ret = dds_entity_observer_unregister_nl(&ws->m_entity, waitset);
|
|
||||||
} else {
|
|
||||||
ret = dds_entity_observer_unregister(entity, waitset);
|
|
||||||
}
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
dds_waitset_remove(ws, entity);
|
|
||||||
} else if (ret != DDS_RETCODE_PRECONDITION_NOT_MET) {
|
|
||||||
DDS_ERROR("The given entity to detach is invalid\n");
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("The given entity to detach was not attached previously\n");
|
|
||||||
}
|
|
||||||
dds_waitset_unlock(ws);
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Error occurred on locking waitset\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (waitset == entity)
|
||||||
|
e = &ws->m_entity;
|
||||||
|
else if ((ret = dds_entity_lock (entity, DDS_KIND_DONTCARE, &e)) != DDS_RETCODE_OK)
|
||||||
|
{
|
||||||
|
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
goto err_waitset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This will fail if given entity is already attached (or deleted). */
|
||||||
|
if ((ret = dds_entity_observer_register_nl (e, waitset, dds_waitset_observer)) != DDS_RETCODE_OK)
|
||||||
|
goto err_entity;
|
||||||
|
|
||||||
|
dds_attachment *a = ddsrt_malloc (sizeof (*a));
|
||||||
|
a->arg = x;
|
||||||
|
a->entity = e;
|
||||||
|
if (e->m_trigger > 0) {
|
||||||
|
a->next = ws->triggered;
|
||||||
|
ws->triggered = a;
|
||||||
|
} else {
|
||||||
|
a->next = ws->observed;
|
||||||
|
ws->observed = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_entity:
|
||||||
|
if (e != &ws->m_entity)
|
||||||
|
dds_entity_unlock (e);
|
||||||
|
err_waitset:
|
||||||
|
dds_waitset_unlock (ws);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_waitset_detach (dds_entity_t waitset, dds_entity_t entity)
|
||||||
dds_waitset_wait_until(
|
|
||||||
dds_entity_t waitset,
|
|
||||||
dds_attach_t *xs,
|
|
||||||
size_t nxs,
|
|
||||||
dds_time_t abstimeout)
|
|
||||||
{
|
{
|
||||||
return dds_waitset_wait_impl(waitset, xs, nxs, abstimeout, dds_time());
|
dds_waitset *ws;
|
||||||
|
dds_return_t ret;
|
||||||
|
|
||||||
|
if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Possibly fails when entity was not attached. */
|
||||||
|
if (waitset == entity)
|
||||||
|
ret = dds_entity_observer_unregister_nl (&ws->m_entity, waitset);
|
||||||
|
else
|
||||||
|
ret = dds_entity_observer_unregister (entity, waitset);
|
||||||
|
|
||||||
|
if (ret == DDS_RETCODE_OK)
|
||||||
|
dds_waitset_remove (ws, entity);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ret != DDS_RETCODE_PRECONDITION_NOT_MET)
|
||||||
|
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
dds_waitset_unlock (ws);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
dds_return_t dds_waitset_wait_until (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_time_t abstimeout)
|
||||||
dds_waitset_wait(
|
|
||||||
dds_entity_t waitset,
|
|
||||||
dds_attach_t *xs,
|
|
||||||
size_t nxs,
|
|
||||||
dds_duration_t reltimeout)
|
|
||||||
{
|
{
|
||||||
dds_entity_t ret;
|
return dds_waitset_wait_impl(waitset, xs, nxs, abstimeout);
|
||||||
|
}
|
||||||
|
|
||||||
if (reltimeout >= 0) {
|
dds_return_t dds_waitset_wait (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_duration_t reltimeout)
|
||||||
dds_time_t tnow = dds_time();
|
{
|
||||||
dds_time_t abstimeout = (DDS_INFINITY - reltimeout <= tnow) ? DDS_NEVER : (tnow + reltimeout);
|
if (reltimeout < 0)
|
||||||
ret = dds_waitset_wait_impl(waitset, xs, nxs, abstimeout, tnow);
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
} else{
|
const dds_time_t tnow = dds_time ();
|
||||||
DDS_ERROR("Negative timeout\n");
|
const dds_time_t abstimeout = (DDS_INFINITY - reltimeout <= tnow) ? DDS_NEVER : (tnow + reltimeout);
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
return dds_waitset_wait_impl (waitset, xs, nxs, abstimeout);
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t dds_waitset_set_trigger (dds_entity_t waitset, bool trigger)
|
dds_return_t dds_waitset_set_trigger (dds_entity_t waitset, bool trigger)
|
||||||
|
@ -455,4 +327,3 @@ dds_return_t dds_waitset_set_trigger (dds_entity_t waitset, bool trigger)
|
||||||
dds_waitset_unlock (ws);
|
dds_waitset_unlock (ws);
|
||||||
return DDS_RETCODE_OK;
|
return DDS_RETCODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct whc_node {
|
||||||
struct whc_node *next_seq; /* next in this interval */
|
struct whc_node *next_seq; /* next in this interval */
|
||||||
struct whc_node *prev_seq; /* prev in this interval */
|
struct whc_node *prev_seq; /* prev in this interval */
|
||||||
struct whc_idxnode *idxnode; /* NULL if not in index */
|
struct whc_idxnode *idxnode; /* NULL if not in index */
|
||||||
unsigned idxnode_pos; /* index in idxnode.hist */
|
uint32_t idxnode_pos; /* index in idxnode.hist */
|
||||||
seqno_t seq;
|
seqno_t seq;
|
||||||
uint64_t total_bytes; /* cumulative number of bytes up to and including this node */
|
uint64_t total_bytes; /* cumulative number of bytes up to and including this node */
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -43,7 +43,7 @@ struct whc_node {
|
||||||
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;
|
nn_mtime_t last_rexmit_ts;
|
||||||
unsigned rexmit_count;
|
uint32_t rexmit_count;
|
||||||
struct ddsi_serdata *serdata;
|
struct ddsi_serdata *serdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ struct whc_idxnode {
|
||||||
uint64_t iid;
|
uint64_t iid;
|
||||||
seqno_t prune_seq;
|
seqno_t prune_seq;
|
||||||
struct ddsi_tkmap_instance *tk;
|
struct ddsi_tkmap_instance *tk;
|
||||||
unsigned headidx;
|
uint32_t headidx;
|
||||||
#if __STDC_VERSION__ >= 199901L
|
#if __STDC_VERSION__ >= 199901L
|
||||||
struct whc_node *hist[];
|
struct whc_node *hist[];
|
||||||
#else
|
#else
|
||||||
|
@ -77,14 +77,14 @@ struct whc_seq_entry {
|
||||||
struct whc_impl {
|
struct whc_impl {
|
||||||
struct whc common;
|
struct whc common;
|
||||||
ddsrt_mutex_t lock;
|
ddsrt_mutex_t lock;
|
||||||
unsigned seq_size;
|
uint32_t seq_size;
|
||||||
size_t unacked_bytes;
|
size_t unacked_bytes;
|
||||||
size_t sample_overhead;
|
size_t sample_overhead;
|
||||||
uint64_t total_bytes; /* total number of bytes pushed in */
|
uint64_t total_bytes; /* total number of bytes pushed in */
|
||||||
unsigned is_transient_local: 1;
|
unsigned is_transient_local: 1;
|
||||||
unsigned hdepth; /* 0 = unlimited */
|
uint32_t hdepth; /* 0 = unlimited */
|
||||||
unsigned tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
|
uint32_t tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
|
||||||
unsigned idxdepth; /* = max(hdepth, tldepth) */
|
uint32_t idxdepth; /* = max (hdepth, tldepth) */
|
||||||
seqno_t max_drop_seq; /* samples in whc with seq <= max_drop_seq => transient-local */
|
seqno_t max_drop_seq; /* samples in whc with seq <= max_drop_seq => transient-local */
|
||||||
struct whc_intvnode *open_intv; /* interval where next sample will go (usually) */
|
struct whc_intvnode *open_intv; /* interval where next sample will go (usually) */
|
||||||
struct whc_node *maxseq_node; /* NULL if empty; if not in open_intv, open_intv is empty */
|
struct whc_node *maxseq_node; /* NULL if empty; if not in open_intv, open_intv is empty */
|
||||||
|
@ -103,14 +103,12 @@ struct whc_sample_iter_impl {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* check that our definition of whc_sample_iter fits in the type that callers allocate */
|
/* check that our definition of whc_sample_iter fits in the type that callers allocate */
|
||||||
struct whc_sample_iter_sizecheck {
|
DDSRT_STATIC_ASSERT (sizeof (struct whc_sample_iter_impl) <= sizeof (struct whc_sample_iter));
|
||||||
char fits_in_generic_type[sizeof(struct whc_sample_iter_impl) <= sizeof(struct whc_sample_iter) ? 1 : -1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Hash + interval tree adminitration of samples-by-sequence number
|
/* Hash + interval tree adminitration of samples-by-sequence number
|
||||||
* - by definition contains all samples in WHC (unchanged from older versions)
|
* - by definition contains all samples in WHC (unchanged from older versions)
|
||||||
* Circular array of samples per instance, inited to all 0
|
* Circular array of samples per instance, inited to all 0
|
||||||
* - length is max(durability_service.history_depth, history.depth), KEEP_ALL => as-if 0
|
* - length is max (durability_service.history_depth, history.depth), KEEP_ALL => as-if 0
|
||||||
* - no instance index if above length 0
|
* - no instance index if above length 0
|
||||||
* - each sample (i.e., whc_node): backpointer into index
|
* - each sample (i.e., whc_node): backpointer into index
|
||||||
* - maintain index of latest sample, end of history then trivially follows from index arithmetic
|
* - maintain index of latest sample, end of history then trivially follows from index arithmetic
|
||||||
|
@ -124,24 +122,24 @@ static void insert_whcn_in_hash (struct whc_impl *whc, struct whc_node *whcn);
|
||||||
static void whc_delete_one (struct whc_impl *whc, struct whc_node *whcn);
|
static void whc_delete_one (struct whc_impl *whc, struct whc_node *whcn);
|
||||||
static int compare_seq (const void *va, const void *vb);
|
static int compare_seq (const void *va, const void *vb);
|
||||||
static void free_deferred_free_list (struct whc_node *deferred_free_list);
|
static void free_deferred_free_list (struct whc_node *deferred_free_list);
|
||||||
static void get_state_locked(const struct whc_impl *whc, struct whc_state *st);
|
static void get_state_locked (const struct whc_impl *whc, struct whc_state *st);
|
||||||
|
|
||||||
static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list);
|
static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list);
|
||||||
static unsigned 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, struct nn_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, struct nn_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);
|
||||||
static void whc_default_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info);
|
static void whc_default_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info);
|
||||||
static unsigned whc_default_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
|
static uint32_t whc_default_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
|
||||||
static void whc_default_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it);
|
static void whc_default_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it);
|
||||||
static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample);
|
static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample);
|
||||||
static void whc_default_free (struct whc *whc);
|
static void whc_default_free (struct whc *whc);
|
||||||
|
|
||||||
static const ddsrt_avl_treedef_t whc_seq_treedef =
|
static const ddsrt_avl_treedef_t whc_seq_treedef =
|
||||||
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct whc_intvnode, avlnode), offsetof (struct whc_intvnode, min), compare_seq, 0);
|
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct whc_intvnode, avlnode), offsetof (struct whc_intvnode, min), compare_seq, 0);
|
||||||
|
|
||||||
static const struct whc_ops whc_ops = {
|
static const struct whc_ops whc_ops = {
|
||||||
.insert = whc_default_insert,
|
.insert = whc_default_insert,
|
||||||
|
@ -159,12 +157,12 @@ static const struct whc_ops whc_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Number of instantiated WHCs and a global freelist for WHC nodes that gets
|
/* Number of instantiated WHCs and a global freelist for WHC nodes that gets
|
||||||
initialized lazily and cleaned up automatically when the last WHC is freed.
|
initialized lazily and cleaned up automatically when the last WHC is freed.
|
||||||
Protected by dds_global.m_mutex.
|
Protected by dds_global.m_mutex.
|
||||||
|
|
||||||
sizeof (whc_node) on 64-bit machines ~ 100 bytes, so this is ~1MB
|
sizeof (whc_node) on 64-bit machines ~ 100 bytes, so this is ~1MB
|
||||||
8k entries seems to be roughly the amount needed for minimum samples,
|
8k entries seems to be roughly the amount needed for minimum samples,
|
||||||
maximum message size and a short round-trip time */
|
maximum message size and a short round-trip time */
|
||||||
#define MAX_FREELIST_SIZE 8192
|
#define MAX_FREELIST_SIZE 8192
|
||||||
static uint32_t whc_count;
|
static uint32_t whc_count;
|
||||||
static struct nn_freelist whc_node_freelist;
|
static struct nn_freelist whc_node_freelist;
|
||||||
|
@ -175,9 +173,9 @@ static uint32_t whc_seq_entry_hash (const void *vn)
|
||||||
const struct whc_seq_entry *n = vn;
|
const struct whc_seq_entry *n = vn;
|
||||||
/* we hash the lower 32 bits, on the assumption that with 4 billion
|
/* we hash the lower 32 bits, on the assumption that with 4 billion
|
||||||
samples in between there won't be significant correlation */
|
samples in between there won't be significant correlation */
|
||||||
const uint64_t c = UINT64_C(16292676669999574021);
|
const uint64_t c = UINT64_C (16292676669999574021);
|
||||||
const uint32_t x = (uint32_t) n->seq;
|
const uint32_t x = (uint32_t) n->seq;
|
||||||
return (unsigned) ((x * c) >> 32);
|
return (uint32_t) ((x * c) >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int whc_seq_entry_eq (const void *va, const void *vb)
|
static int whc_seq_entry_eq (const void *va, const void *vb)
|
||||||
|
@ -192,9 +190,9 @@ static uint32_t whc_node_hash (const void *vn)
|
||||||
const struct whc_node *n = vn;
|
const struct whc_node *n = vn;
|
||||||
/* we hash the lower 32 bits, on the assumption that with 4 billion
|
/* we hash the lower 32 bits, on the assumption that with 4 billion
|
||||||
samples in between there won't be significant correlation */
|
samples in between there won't be significant correlation */
|
||||||
const uint64_t c = UINT64_C(16292676669999574021);
|
const uint64_t c = UINT64_C (16292676669999574021);
|
||||||
const uint32_t x = (uint32_t) n->seq;
|
const uint32_t x = (uint32_t) n->seq;
|
||||||
return (unsigned) ((x * c) >> 32);
|
return (uint32_t) ((x * c) >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int whc_node_eq (const void *va, const void *vb)
|
static int whc_node_eq (const void *va, const void *vb)
|
||||||
|
@ -245,10 +243,10 @@ static struct whc_node *whc_findmax_procedurally (const struct whc_impl *whc)
|
||||||
static void check_whc (const struct whc_impl *whc)
|
static void check_whc (const struct whc_impl *whc)
|
||||||
{
|
{
|
||||||
/* there's much more we can check, but it gets expensive quite
|
/* there's much more we can check, but it gets expensive quite
|
||||||
quickly: all nodes but open_intv non-empty, non-overlapping and
|
quickly: all nodes but open_intv non-empty, non-overlapping and
|
||||||
non-contiguous; min & maxp1 of intervals correct; each interval
|
non-contiguous; min & maxp1 of intervals correct; each interval
|
||||||
contiguous; all samples in seq & in seqhash; tlidx \subseteq seq;
|
contiguous; all samples in seq & in seqhash; tlidx \subseteq seq;
|
||||||
seq-number ordered list correct; &c. */
|
seq-number ordered list correct; &c. */
|
||||||
assert (whc->open_intv != NULL);
|
assert (whc->open_intv != NULL);
|
||||||
assert (whc->open_intv == ddsrt_avl_find_max (&whc_seq_treedef, &whc->seq));
|
assert (whc->open_intv == ddsrt_avl_find_max (&whc_seq_treedef, &whc->seq));
|
||||||
assert (ddsrt_avl_find_succ (&whc_seq_treedef, &whc->seq, whc->open_intv) == NULL);
|
assert (ddsrt_avl_find_succ (&whc_seq_treedef, &whc->seq, whc->open_intv) == NULL);
|
||||||
|
@ -269,7 +267,7 @@ static void check_whc (const struct whc_impl *whc)
|
||||||
}
|
}
|
||||||
assert (whc->maxseq_node == whc_findmax_procedurally (whc));
|
assert (whc->maxseq_node == whc_findmax_procedurally (whc));
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined (NDEBUG)
|
||||||
if (config.enabled_xchecks & DDS_XCHECK_WHC)
|
if (config.enabled_xchecks & DDS_XCHECK_WHC)
|
||||||
{
|
{
|
||||||
struct whc_intvnode *firstintv;
|
struct whc_intvnode *firstintv;
|
||||||
|
@ -295,10 +293,10 @@ static void insert_whcn_in_hash (struct whc_impl *whc, struct whc_node *whcn)
|
||||||
#if USE_EHH
|
#if USE_EHH
|
||||||
struct whc_seq_entry e = { .seq = whcn->seq, .whcn = whcn };
|
struct whc_seq_entry e = { .seq = whcn->seq, .whcn = whcn };
|
||||||
if (!ddsrt_ehh_add (whc->seq_hash, &e))
|
if (!ddsrt_ehh_add (whc->seq_hash, &e))
|
||||||
assert(0);
|
assert (0);
|
||||||
#else
|
#else
|
||||||
if (!ddsrt_hh_add (whc->seq_hash, whcn))
|
if (!ddsrt_hh_add (whc->seq_hash, whcn))
|
||||||
assert(0);
|
assert (0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,11 +305,11 @@ static void remove_whcn_from_hash (struct whc_impl *whc, struct whc_node *whcn)
|
||||||
/* precondition: whcn is in hash */
|
/* precondition: whcn is in hash */
|
||||||
#if USE_EHH
|
#if USE_EHH
|
||||||
struct whc_seq_entry e = { .seq = whcn->seq };
|
struct whc_seq_entry e = { .seq = whcn->seq };
|
||||||
if (!ddsrt_ehh_remove(whc->seq_hash, &e))
|
if (!ddsrt_ehh_remove (whc->seq_hash, &e))
|
||||||
assert(0);
|
assert (0);
|
||||||
#else
|
#else
|
||||||
if (!ddsrt_hh_remove(whc->seq_hash, whcn))
|
if (!ddsrt_hh_remove (whc->seq_hash, whcn))
|
||||||
assert(0);
|
assert (0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,14 +317,14 @@ static struct whc_node *whc_findseq (const struct whc_impl *whc, seqno_t seq)
|
||||||
{
|
{
|
||||||
#if USE_EHH
|
#if USE_EHH
|
||||||
struct whc_seq_entry e = { .seq = seq }, *r;
|
struct whc_seq_entry e = { .seq = seq }, *r;
|
||||||
if ((r = ddsrt_ehh_lookup(whc->seq_hash, &e)) != NULL)
|
if ((r = ddsrt_ehh_lookup (whc->seq_hash, &e)) != NULL)
|
||||||
return r->whcn;
|
return r->whcn;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
#else
|
#else
|
||||||
struct whc_node template;
|
struct whc_node template;
|
||||||
template.seq = seq;
|
template.seq = seq;
|
||||||
return ddsrt_hh_lookup(whc->seq_hash, &template);
|
return ddsrt_hh_lookup (whc->seq_hash, &template);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,11 +332,11 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
struct whc_idxnode idxn;
|
struct whc_idxnode idxn;
|
||||||
char pad[sizeof(struct whc_idxnode) + sizeof(struct whc_node *)];
|
char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
|
||||||
} template;
|
} template;
|
||||||
struct whc_idxnode *n;
|
struct whc_idxnode *n;
|
||||||
check_whc (whc);
|
check_whc (whc);
|
||||||
template.idxn.iid = ddsi_tkmap_lookup(gv.m_tkmap, serdata_key);
|
template.idxn.iid = ddsi_tkmap_lookup (gv.m_tkmap, serdata_key);
|
||||||
n = ddsrt_hh_lookup (whc->idx_hash, &template.idxn);
|
n = ddsrt_hh_lookup (whc->idx_hash, &template.idxn);
|
||||||
if (n == NULL)
|
if (n == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -349,13 +347,13 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct whc *whc_new (int is_transient_local, unsigned hdepth, unsigned tldepth)
|
struct whc *whc_new (int is_transient_local, uint32_t hdepth, uint32_t tldepth)
|
||||||
{
|
{
|
||||||
size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */
|
size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */
|
||||||
struct whc_impl *whc;
|
struct whc_impl *whc;
|
||||||
struct whc_intvnode *intv;
|
struct whc_intvnode *intv;
|
||||||
|
|
||||||
assert((hdepth == 0 || tldepth <= hdepth) || is_transient_local);
|
assert ((hdepth == 0 || tldepth <= hdepth) || is_transient_local);
|
||||||
|
|
||||||
whc = ddsrt_malloc (sizeof (*whc));
|
whc = ddsrt_malloc (sizeof (*whc));
|
||||||
whc->common.ops = &whc_ops;
|
whc->common.ops = &whc_ops;
|
||||||
|
@ -372,11 +370,11 @@ struct whc *whc_new (int is_transient_local, unsigned hdepth, unsigned tldepth)
|
||||||
#if USE_EHH
|
#if USE_EHH
|
||||||
whc->seq_hash = ddsrt_ehh_new (sizeof (struct whc_seq_entry), 32, whc_seq_entry_hash, whc_seq_entry_eq);
|
whc->seq_hash = ddsrt_ehh_new (sizeof (struct whc_seq_entry), 32, whc_seq_entry_hash, whc_seq_entry_eq);
|
||||||
#else
|
#else
|
||||||
whc->seq_hash = ddsrt_hh_new(32, whc_node_hash, whc_node_eq);
|
whc->seq_hash = ddsrt_hh_new (32, whc_node_hash, whc_node_eq);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (whc->idxdepth > 0)
|
if (whc->idxdepth > 0)
|
||||||
whc->idx_hash = ddsrt_hh_new(32, whc_idxnode_hash_key, whc_idxnode_eq_key);
|
whc->idx_hash = ddsrt_hh_new (32, whc_idxnode_hash_key, whc_idxnode_eq_key);
|
||||||
else
|
else
|
||||||
whc->idx_hash = NULL;
|
whc->idx_hash = NULL;
|
||||||
|
|
||||||
|
@ -417,9 +415,9 @@ void whc_default_free (struct whc *whc_generic)
|
||||||
{
|
{
|
||||||
struct ddsrt_hh_iter it;
|
struct ddsrt_hh_iter it;
|
||||||
struct whc_idxnode *n;
|
struct whc_idxnode *n;
|
||||||
for (n = ddsrt_hh_iter_first(whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next(&it))
|
for (n = ddsrt_hh_iter_first (whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next (&it))
|
||||||
ddsrt_free(n);
|
ddsrt_free (n);
|
||||||
ddsrt_hh_free(whc->idx_hash);
|
ddsrt_hh_free (whc->idx_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -427,10 +425,10 @@ void whc_default_free (struct whc *whc_generic)
|
||||||
while (whcn)
|
while (whcn)
|
||||||
{
|
{
|
||||||
struct whc_node *tmp = whcn;
|
struct whc_node *tmp = whcn;
|
||||||
/* The compiler doesn't realize that whcn->prev_seq is always initialized. */
|
/* The compiler doesn't realize that whcn->prev_seq is always initialized. */
|
||||||
DDSRT_WARNING_MSVC_OFF(6001);
|
DDSRT_WARNING_MSVC_OFF (6001);
|
||||||
whcn = whcn->prev_seq;
|
whcn = whcn->prev_seq;
|
||||||
DDSRT_WARNING_MSVC_ON(6001);
|
DDSRT_WARNING_MSVC_ON (6001);
|
||||||
free_whc_node_contents (tmp);
|
free_whc_node_contents (tmp);
|
||||||
ddsrt_free (tmp);
|
ddsrt_free (tmp);
|
||||||
}
|
}
|
||||||
|
@ -452,7 +450,7 @@ DDSRT_WARNING_MSVC_ON(6001);
|
||||||
ddsrt_free (whc);
|
ddsrt_free (whc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_state_locked(const struct whc_impl *whc, struct whc_state *st)
|
static void get_state_locked (const struct whc_impl *whc, struct whc_state *st)
|
||||||
{
|
{
|
||||||
if (whc->seq_size == 0)
|
if (whc->seq_size == 0)
|
||||||
{
|
{
|
||||||
|
@ -473,12 +471,12 @@ static void get_state_locked(const struct whc_impl *whc, struct whc_state *st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void whc_default_get_state(const struct whc *whc_generic, struct whc_state *st)
|
static void whc_default_get_state (const struct whc *whc_generic, struct whc_state *st)
|
||||||
{
|
{
|
||||||
const struct whc_impl * const whc = (const struct whc_impl *)whc_generic;
|
const struct whc_impl * const whc = (const struct whc_impl *)whc_generic;
|
||||||
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
||||||
check_whc (whc);
|
check_whc (whc);
|
||||||
get_state_locked(whc, st);
|
get_state_locked (whc, st);
|
||||||
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
|
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,8 +487,8 @@ static struct whc_node *find_nextseq_intv (struct whc_intvnode **p_intv, const s
|
||||||
if ((n = whc_findseq (whc, seq)) == NULL)
|
if ((n = whc_findseq (whc, seq)) == NULL)
|
||||||
{
|
{
|
||||||
/* don't know seq => lookup interval with min > seq (intervals are
|
/* don't know seq => lookup interval with min > seq (intervals are
|
||||||
contiguous, so if we don't know seq, an interval [X,Y) with X <
|
contiguous, so if we don't know seq, an interval [X,Y) with X <
|
||||||
SEQ < Y can't exist */
|
SEQ < Y can't exist */
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
{
|
{
|
||||||
struct whc_intvnode *predintv = ddsrt_avl_lookup_pred_eq (&whc_seq_treedef, &whc->seq, &seq);
|
struct whc_intvnode *predintv = ddsrt_avl_lookup_pred_eq (&whc_seq_treedef, &whc->seq, &seq);
|
||||||
|
@ -551,13 +549,12 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
unsigned i;
|
for (uint32_t i = 0; i < whc->idxdepth; i++)
|
||||||
for (i = 0; i < whc->idxdepth; i++)
|
|
||||||
assert (i == idxn->headidx || idxn->hist[i] == NULL);
|
assert (i == idxn->headidx || idxn->hist[i] == NULL);
|
||||||
#endif
|
#endif
|
||||||
if (!ddsrt_hh_remove (whc->idx_hash, idxn))
|
if (!ddsrt_hh_remove (whc->idx_hash, idxn))
|
||||||
assert (0);
|
assert (0);
|
||||||
ddsi_tkmap_instance_unref(idxn->tk);
|
ddsi_tkmap_instance_unref (idxn->tk);
|
||||||
ddsrt_free (idxn);
|
ddsrt_free (idxn);
|
||||||
}
|
}
|
||||||
whcn->idxnode = NULL;
|
whcn->idxnode = NULL;
|
||||||
|
@ -565,8 +562,7 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w
|
||||||
|
|
||||||
static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn)
|
static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn)
|
||||||
{
|
{
|
||||||
unsigned i;
|
for (uint32_t i = 0; i < whc->idxdepth; i++)
|
||||||
for (i = 0; i < whc->idxdepth; i++)
|
|
||||||
{
|
{
|
||||||
if (idxn->hist[i])
|
if (idxn->hist[i])
|
||||||
{
|
{
|
||||||
|
@ -574,13 +570,13 @@ static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_s
|
||||||
oldn->idxnode = NULL;
|
oldn->idxnode = NULL;
|
||||||
if (oldn->seq <= max_drop_seq)
|
if (oldn->seq <= max_drop_seq)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " prune tl whcn %p\n", (void *)oldn);
|
DDS_LOG (DDS_LC_WHC, " prune tl whcn %p\n", (void *)oldn);
|
||||||
assert(oldn != whc->maxseq_node);
|
assert (oldn != whc->maxseq_node);
|
||||||
whc_delete_one (whc, oldn);
|
whc_delete_one (whc, oldn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ddsrt_free(idxn);
|
ddsrt_free (idxn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void delete_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn)
|
static void delete_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn)
|
||||||
|
@ -590,34 +586,34 @@ static void delete_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop
|
||||||
free_one_instance_from_idx (whc, max_drop_seq, idxn);
|
free_one_instance_from_idx (whc, max_drop_seq, idxn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int whcn_in_tlidx (const struct whc_impl *whc, const struct whc_idxnode *idxn, unsigned pos)
|
static int whcn_in_tlidx (const struct whc_impl *whc, const struct whc_idxnode *idxn, uint32_t pos)
|
||||||
{
|
{
|
||||||
if (idxn == NULL)
|
if (idxn == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned d = (idxn->headidx + (pos > idxn->headidx ? whc->idxdepth : 0)) - pos;
|
uint32_t d = (idxn->headidx + (pos > idxn->headidx ? whc->idxdepth : 0)) - pos;
|
||||||
assert (d < whc->idxdepth);
|
assert (d < whc->idxdepth);
|
||||||
return d < whc->tldepth;
|
return d < whc->tldepth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st)
|
static uint32_t whc_default_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st)
|
||||||
{
|
{
|
||||||
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
||||||
seqno_t old_max_drop_seq;
|
seqno_t old_max_drop_seq;
|
||||||
struct whc_node *deferred_free_list;
|
struct whc_node *deferred_free_list;
|
||||||
unsigned cnt;
|
uint32_t cnt;
|
||||||
|
|
||||||
/* We only remove them from whc->tlidx: we don't remove them from
|
/* We only remove them from whc->tlidx: we don't remove them from
|
||||||
whc->seq yet. That'll happen eventually. */
|
whc->seq yet. That'll happen eventually. */
|
||||||
ddsrt_mutex_lock (&whc->lock);
|
ddsrt_mutex_lock (&whc->lock);
|
||||||
check_whc (whc);
|
check_whc (whc);
|
||||||
|
|
||||||
if (whc->idxdepth == 0)
|
if (whc->idxdepth == 0)
|
||||||
{
|
{
|
||||||
/* if not maintaining an index at all, this is nonsense */
|
/* if not maintaining an index at all, this is nonsense */
|
||||||
get_state_locked(whc, st);
|
get_state_locked (whc, st);
|
||||||
ddsrt_mutex_unlock (&whc->lock);
|
ddsrt_mutex_unlock (&whc->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -625,29 +621,29 @@ static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, stru
|
||||||
assert (!whc->is_transient_local);
|
assert (!whc->is_transient_local);
|
||||||
if (whc->tldepth > 0)
|
if (whc->tldepth > 0)
|
||||||
{
|
{
|
||||||
assert(whc->hdepth == 0 || whc->tldepth <= whc->hdepth);
|
assert (whc->hdepth == 0 || whc->tldepth <= whc->hdepth);
|
||||||
whc->tldepth = 0;
|
whc->tldepth = 0;
|
||||||
if (whc->hdepth == 0)
|
if (whc->hdepth == 0)
|
||||||
{
|
{
|
||||||
struct ddsrt_hh_iter it;
|
struct ddsrt_hh_iter it;
|
||||||
struct whc_idxnode *n;
|
struct whc_idxnode *n;
|
||||||
for (n = ddsrt_hh_iter_first(whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next(&it))
|
for (n = ddsrt_hh_iter_first (whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next (&it))
|
||||||
free_one_instance_from_idx (whc, 0, n);
|
free_one_instance_from_idx (whc, 0, n);
|
||||||
ddsrt_hh_free(whc->idx_hash);
|
ddsrt_hh_free (whc->idx_hash);
|
||||||
whc->idxdepth = 0;
|
whc->idxdepth = 0;
|
||||||
whc->idx_hash = NULL;
|
whc->idx_hash = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Immediately drop them from the WHC (used to delay it until the
|
/* Immediately drop them from the WHC (used to delay it until the
|
||||||
next ack); but need to make sure remove_acked_messages processes
|
next ack); but need to make sure remove_acked_messages processes
|
||||||
them all. */
|
them all. */
|
||||||
old_max_drop_seq = whc->max_drop_seq;
|
old_max_drop_seq = whc->max_drop_seq;
|
||||||
whc->max_drop_seq = 0;
|
whc->max_drop_seq = 0;
|
||||||
cnt = whc_default_remove_acked_messages_full (whc, old_max_drop_seq, &deferred_free_list);
|
cnt = whc_default_remove_acked_messages_full (whc, old_max_drop_seq, &deferred_free_list);
|
||||||
whc_default_free_deferred_free_list (whc_generic, deferred_free_list);
|
whc_default_free_deferred_free_list (whc_generic, deferred_free_list);
|
||||||
assert (whc->max_drop_seq == old_max_drop_seq);
|
assert (whc->max_drop_seq == old_max_drop_seq);
|
||||||
get_state_locked(whc, st);
|
get_state_locked (whc, st);
|
||||||
ddsrt_mutex_unlock (&whc->lock);
|
ddsrt_mutex_unlock (&whc->lock);
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
@ -661,14 +657,14 @@ static size_t whcn_size (const struct whc_impl *whc, const struct whc_node *whcn
|
||||||
static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_intv, struct whc_node **p_whcn)
|
static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_intv, struct whc_node **p_whcn)
|
||||||
{
|
{
|
||||||
/* Removes *p_whcn, possibly deleting or splitting *p_intv, as the
|
/* Removes *p_whcn, possibly deleting or splitting *p_intv, as the
|
||||||
case may be. Does *NOT* update whc->seq_size. *p_intv must be
|
case may be. Does *NOT* update whc->seq_size. *p_intv must be
|
||||||
the interval containing *p_whcn (&& both must actually exist).
|
the interval containing *p_whcn (&& both must actually exist).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
- 0 if delete failed (only possible cause is memory exhaustion),
|
- 0 if delete failed (only possible cause is memory exhaustion),
|
||||||
in which case *p_intv & *p_whcn are undefined;
|
in which case *p_intv & *p_whcn are undefined;
|
||||||
- 1 if successful, in which case *p_intv & *p_whcn are set
|
- 1 if successful, in which case *p_intv & *p_whcn are set
|
||||||
correctly for the next sample in sequence number order */
|
correctly for the next sample in sequence number order */
|
||||||
struct whc_intvnode *intv = *p_intv;
|
struct whc_intvnode *intv = *p_intv;
|
||||||
struct whc_node *whcn = *p_whcn;
|
struct whc_node *whcn = *p_whcn;
|
||||||
assert (whcn->seq >= intv->min && whcn->seq < intv->maxp1);
|
assert (whcn->seq >= intv->min && whcn->seq < intv->maxp1);
|
||||||
|
@ -685,13 +681,13 @@ static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_i
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take it out of seqhash; deleting it from the list ordered on
|
/* Take it out of seqhash; deleting it from the list ordered on
|
||||||
sequence numbers is left to the caller (it has to be done unconditionally,
|
sequence numbers is left to the caller (it has to be done unconditionally,
|
||||||
but remove_acked_messages defers it until the end or a skipped node). */
|
but remove_acked_messages defers it until the end or a skipped node). */
|
||||||
remove_whcn_from_hash (whc, whcn);
|
remove_whcn_from_hash (whc, whcn);
|
||||||
|
|
||||||
/* We may have introduced a hole & have to split the interval
|
/* We may have introduced a hole & have to split the interval
|
||||||
node, or we may have nibbled of the first one, or even the
|
node, or we may have nibbled of the first one, or even the
|
||||||
last one. */
|
last one. */
|
||||||
if (whcn == intv->first)
|
if (whcn == intv->first)
|
||||||
{
|
{
|
||||||
if (whcn == intv->last && intv != whc->open_intv)
|
if (whcn == intv->last && intv != whc->open_intv)
|
||||||
|
@ -714,7 +710,7 @@ static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_i
|
||||||
else if (whcn == intv->last)
|
else if (whcn == intv->last)
|
||||||
{
|
{
|
||||||
/* well, at least it isn't the first one & so the interval is
|
/* well, at least it isn't the first one & so the interval is
|
||||||
still non-empty and we don't have to drop the interval */
|
still non-empty and we don't have to drop the interval */
|
||||||
assert (intv->min < whcn->seq);
|
assert (intv->min < whcn->seq);
|
||||||
assert (whcn->prev_seq);
|
assert (whcn->prev_seq);
|
||||||
assert (whcn->prev_seq->seq + 1 == whcn->seq);
|
assert (whcn->prev_seq->seq + 1 == whcn->seq);
|
||||||
|
@ -725,9 +721,9 @@ static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_i
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* somewhere in the middle => split the interval (ideally,
|
/* somewhere in the middle => split the interval (ideally,
|
||||||
would split it lazily, but it really is a transient-local
|
would split it lazily, but it really is a transient-local
|
||||||
issue only, and so we can (for now) get away with splitting
|
issue only, and so we can (for now) get away with splitting
|
||||||
it greedily */
|
it greedily */
|
||||||
struct whc_intvnode *new_intv;
|
struct whc_intvnode *new_intv;
|
||||||
ddsrt_avl_ipath_t path;
|
ddsrt_avl_ipath_t path;
|
||||||
|
|
||||||
|
@ -746,7 +742,7 @@ static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_i
|
||||||
assert (new_intv->min < new_intv->maxp1);
|
assert (new_intv->min < new_intv->maxp1);
|
||||||
|
|
||||||
/* insert new node & continue the loop with intv set to the
|
/* insert new node & continue the loop with intv set to the
|
||||||
new interval */
|
new interval */
|
||||||
if (ddsrt_avl_lookup_ipath (&whc_seq_treedef, &whc->seq, &new_intv->min, &path) != NULL)
|
if (ddsrt_avl_lookup_ipath (&whc_seq_treedef, &whc->seq, &new_intv->min, &path) != NULL)
|
||||||
assert (0);
|
assert (0);
|
||||||
ddsrt_avl_insert_ipath (&whc_seq_treedef, &whc->seq, new_intv, &path);
|
ddsrt_avl_insert_ipath (&whc_seq_treedef, &whc->seq, new_intv, &path);
|
||||||
|
@ -801,11 +797,11 @@ static void whc_default_free_deferred_free_list (struct whc *whc_generic, struct
|
||||||
free_deferred_free_list (deferred_free_list);
|
free_deferred_free_list (deferred_free_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
|
static uint32_t whc_default_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
|
||||||
{
|
{
|
||||||
struct whc_intvnode *intv;
|
struct whc_intvnode *intv;
|
||||||
struct whc_node *whcn;
|
struct whc_node *whcn;
|
||||||
unsigned ndropped = 0;
|
uint32_t ndropped = 0;
|
||||||
|
|
||||||
/* In the trivial case of an empty WHC, get out quickly */
|
/* In the trivial case of an empty WHC, get out quickly */
|
||||||
if (max_drop_seq <= whc->max_drop_seq || whc->maxseq_node == NULL)
|
if (max_drop_seq <= whc->max_drop_seq || whc->maxseq_node == NULL)
|
||||||
|
@ -817,7 +813,7 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If simple, we have always dropped everything up to whc->max_drop_seq,
|
/* If simple, we have always dropped everything up to whc->max_drop_seq,
|
||||||
and there can only be a single interval */
|
and there can only be a single interval */
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
whcn = find_nextseq_intv (&intv, whc, whc->max_drop_seq);
|
whcn = find_nextseq_intv (&intv, whc, whc->max_drop_seq);
|
||||||
assert (whcn == NULL || whcn->prev_seq == NULL);
|
assert (whcn == NULL || whcn->prev_seq == NULL);
|
||||||
|
@ -826,14 +822,14 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
|
||||||
intv = whc->open_intv;
|
intv = whc->open_intv;
|
||||||
|
|
||||||
/* Drop everything up to and including max_drop_seq, or absent that one,
|
/* Drop everything up to and including max_drop_seq, or absent that one,
|
||||||
the highest available sequence number (which then must be less) */
|
the highest available sequence number (which then must be less) */
|
||||||
if ((whcn = whc_findseq (whc, max_drop_seq)) == NULL)
|
if ((whcn = whc_findseq (whc, max_drop_seq)) == NULL)
|
||||||
{
|
{
|
||||||
if (max_drop_seq < intv->min)
|
if (max_drop_seq < intv->min)
|
||||||
{
|
{
|
||||||
/* at startup, whc->max_drop_seq = 0 and reader states have max ack'd seq taken from wr->seq;
|
/* at startup, whc->max_drop_seq = 0 and reader states have max ack'd seq taken from wr->seq;
|
||||||
so if multiple readers are matched and the writer runs ahead of the readers, for the first
|
so if multiple readers are matched and the writer runs ahead of the readers, for the first
|
||||||
ack, whc->max_drop_seq < max_drop_seq = MIN(readers max ack) < intv->min */
|
ack, whc->max_drop_seq < max_drop_seq = MIN (readers max ack) < intv->min */
|
||||||
if (max_drop_seq > whc->max_drop_seq)
|
if (max_drop_seq > whc->max_drop_seq)
|
||||||
whc->max_drop_seq = max_drop_seq;
|
whc->max_drop_seq = max_drop_seq;
|
||||||
*deferred_free_list = NULL;
|
*deferred_free_list = NULL;
|
||||||
|
@ -847,7 +843,7 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
|
||||||
}
|
}
|
||||||
|
|
||||||
*deferred_free_list = intv->first;
|
*deferred_free_list = intv->first;
|
||||||
ndropped = (unsigned) (whcn->seq - intv->min + 1);
|
ndropped = (uint32_t) (whcn->seq - intv->min + 1);
|
||||||
|
|
||||||
intv->first = whcn->next_seq;
|
intv->first = whcn->next_seq;
|
||||||
intv->min = max_drop_seq + 1;
|
intv->min = max_drop_seq + 1;
|
||||||
|
@ -877,18 +873,18 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
|
||||||
return ndropped;
|
return ndropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
|
static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
|
||||||
{
|
{
|
||||||
struct whc_intvnode *intv;
|
struct whc_intvnode *intv;
|
||||||
struct whc_node *whcn;
|
struct whc_node *whcn;
|
||||||
struct whc_node *prev_seq;
|
struct whc_node *prev_seq;
|
||||||
struct whc_node deferred_list_head, *last_to_free = &deferred_list_head;
|
struct whc_node deferred_list_head, *last_to_free = &deferred_list_head;
|
||||||
unsigned ndropped = 0;
|
uint32_t ndropped = 0;
|
||||||
|
|
||||||
if (whc->is_transient_local && whc->tldepth == 0)
|
if (whc->is_transient_local && whc->tldepth == 0)
|
||||||
{
|
{
|
||||||
/* KEEP_ALL on transient local, so we can never ever delete anything */
|
/* KEEP_ALL on transient local, so we can never ever delete anything */
|
||||||
DDS_LOG(DDS_LC_WHC, " KEEP_ALL transient-local: do nothing\n");
|
DDS_LOG (DDS_LC_WHC, " KEEP_ALL transient-local: do nothing\n");
|
||||||
*deferred_free_list = NULL;
|
*deferred_free_list = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -898,11 +894,11 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
||||||
prev_seq = whcn ? whcn->prev_seq : NULL;
|
prev_seq = whcn ? whcn->prev_seq : NULL;
|
||||||
while (whcn && whcn->seq <= max_drop_seq)
|
while (whcn && whcn->seq <= max_drop_seq)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " whcn %p %"PRId64, (void *) whcn, whcn->seq);
|
DDS_LOG (DDS_LC_WHC, " whcn %p %"PRId64, (void *) whcn, whcn->seq);
|
||||||
if (whcn_in_tlidx(whc, whcn->idxnode, whcn->idxnode_pos))
|
if (whcn_in_tlidx (whc, whcn->idxnode, whcn->idxnode_pos))
|
||||||
{
|
{
|
||||||
/* quickly skip over samples in tlidx */
|
/* quickly skip over samples in tlidx */
|
||||||
DDS_LOG(DDS_LC_WHC, " tl:keep");
|
DDS_LOG (DDS_LC_WHC, " tl:keep");
|
||||||
if (whcn->unacked)
|
if (whcn->unacked)
|
||||||
{
|
{
|
||||||
assert (whc->unacked_bytes >= whcn->size);
|
assert (whc->unacked_bytes >= whcn->size);
|
||||||
|
@ -920,13 +916,13 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " delete");
|
DDS_LOG (DDS_LC_WHC, " delete");
|
||||||
last_to_free->next_seq = whcn;
|
last_to_free->next_seq = whcn;
|
||||||
last_to_free = last_to_free->next_seq;
|
last_to_free = last_to_free->next_seq;
|
||||||
whc_delete_one_intv (whc, &intv, &whcn);
|
whc_delete_one_intv (whc, &intv, &whcn);
|
||||||
ndropped++;
|
ndropped++;
|
||||||
}
|
}
|
||||||
DDS_LOG(DDS_LC_WHC, "\n");
|
DDS_LOG (DDS_LC_WHC, "\n");
|
||||||
}
|
}
|
||||||
if (prev_seq)
|
if (prev_seq)
|
||||||
prev_seq->next_seq = whcn;
|
prev_seq->next_seq = whcn;
|
||||||
|
@ -936,32 +932,32 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
||||||
*deferred_free_list = deferred_list_head.next_seq;
|
*deferred_free_list = deferred_list_head.next_seq;
|
||||||
|
|
||||||
/* If the history is deeper than durability_service.history (but not KEEP_ALL), then there
|
/* If the history is deeper than durability_service.history (but not KEEP_ALL), then there
|
||||||
may be old samples in this instance, samples that were retained because they were within
|
may be old samples in this instance, samples that were retained because they were within
|
||||||
the T-L history but that are not anymore. Writing new samples will eventually push these
|
the T-L history but that are not anymore. Writing new samples will eventually push these
|
||||||
out, but if the difference is large and the update rate low, it may take a long time.
|
out, but if the difference is large and the update rate low, it may take a long time.
|
||||||
Thus, we had better prune them. */
|
Thus, we had better prune them. */
|
||||||
if (whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
|
if (whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
|
||||||
{
|
{
|
||||||
assert(whc->hdepth == whc->idxdepth);
|
assert (whc->hdepth == whc->idxdepth);
|
||||||
DDS_LOG(DDS_LC_WHC, " idxdepth %u > tldepth %u > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
|
DDS_LOG (DDS_LC_WHC, " idxdepth %"PRIu32" > tldepth %"PRIu32" > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
|
||||||
|
|
||||||
/* Do a second pass over the sequence number range we just processed: this time we only
|
/* Do a second pass over the sequence number range we just processed: this time we only
|
||||||
encounter samples that were retained because of the transient-local durability setting
|
encounter samples that were retained because of the transient-local durability setting
|
||||||
(the rest has been dropped already) and we prune old samples in the instance */
|
(the rest has been dropped already) and we prune old samples in the instance */
|
||||||
whcn = find_nextseq_intv (&intv, whc, whc->max_drop_seq);
|
whcn = find_nextseq_intv (&intv, whc, whc->max_drop_seq);
|
||||||
while (whcn && whcn->seq <= max_drop_seq)
|
while (whcn && whcn->seq <= max_drop_seq)
|
||||||
{
|
{
|
||||||
struct whc_idxnode * const idxn = whcn->idxnode;
|
struct whc_idxnode * const idxn = whcn->idxnode;
|
||||||
unsigned cnt, idx;
|
uint32_t cnt, idx;
|
||||||
|
|
||||||
DDS_LOG(DDS_LC_WHC, " whcn %p %"PRId64" idxn %p prune_seq %"PRId64":", (void *)whcn, whcn->seq, (void *)idxn, idxn->prune_seq);
|
DDS_LOG (DDS_LC_WHC, " whcn %p %"PRId64" idxn %p prune_seq %"PRId64":", (void *) whcn, whcn->seq, (void *) idxn, idxn->prune_seq);
|
||||||
|
|
||||||
assert(whcn_in_tlidx(whc, idxn, whcn->idxnode_pos));
|
assert (whcn_in_tlidx (whc, idxn, whcn->idxnode_pos));
|
||||||
assert (idxn->prune_seq <= max_drop_seq);
|
assert (idxn->prune_seq <= max_drop_seq);
|
||||||
|
|
||||||
if (idxn->prune_seq == max_drop_seq)
|
if (idxn->prune_seq == max_drop_seq)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " already pruned\n");
|
DDS_LOG (DDS_LC_WHC, " already pruned\n");
|
||||||
whcn = whcn->next_seq;
|
whcn = whcn->next_seq;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -977,27 +973,27 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
||||||
if ((oldn = idxn->hist[idx]) != NULL)
|
if ((oldn = idxn->hist[idx]) != NULL)
|
||||||
{
|
{
|
||||||
/* Delete it - but this may not result in deleting the index node as
|
/* Delete it - but this may not result in deleting the index node as
|
||||||
there must still be a more recent one available */
|
there must still be a more recent one available */
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
struct whc_node whcn_template;
|
struct whc_node whcn_template;
|
||||||
union {
|
union {
|
||||||
struct whc_idxnode idxn;
|
struct whc_idxnode idxn;
|
||||||
char pad[sizeof(struct whc_idxnode) + sizeof(struct whc_node *)];
|
char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
|
||||||
} template;
|
} template;
|
||||||
template.idxn.headidx = 0;
|
template.idxn.headidx = 0;
|
||||||
template.idxn.hist[0] = &whcn_template;
|
template.idxn.hist[0] = &whcn_template;
|
||||||
whcn_template.serdata = ddsi_serdata_ref(oldn->serdata);
|
whcn_template.serdata = ddsi_serdata_ref (oldn->serdata);
|
||||||
assert(oldn->seq < whcn->seq);
|
assert (oldn->seq < whcn->seq);
|
||||||
#endif
|
#endif
|
||||||
DDS_LOG(DDS_LC_WHC, " del %p %"PRId64, (void *) oldn, oldn->seq);
|
DDS_LOG (DDS_LC_WHC, " del %p %"PRId64, (void *) oldn, oldn->seq);
|
||||||
whc_delete_one (whc, oldn);
|
whc_delete_one (whc, oldn);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert(ddsrt_hh_lookup(whc->idx_hash, &template) == idxn);
|
assert (ddsrt_hh_lookup (whc->idx_hash, &template) == idxn);
|
||||||
ddsi_serdata_unref(whcn_template.serdata);
|
ddsi_serdata_unref (whcn_template.serdata);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DDS_LOG(DDS_LC_WHC, "\n");
|
DDS_LOG (DDS_LC_WHC, "\n");
|
||||||
whcn = whcn->next_seq;
|
whcn = whcn->next_seq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1011,22 +1007,22 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
||||||
return ndropped;
|
return ndropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned whc_default_remove_acked_messages (struct whc *whc_generic, 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_generic, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list)
|
||||||
{
|
{
|
||||||
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
||||||
unsigned cnt;
|
uint32_t cnt;
|
||||||
|
|
||||||
ddsrt_mutex_lock (&whc->lock);
|
ddsrt_mutex_lock (&whc->lock);
|
||||||
assert (max_drop_seq < MAX_SEQ_NUMBER);
|
assert (max_drop_seq < MAX_SEQ_NUMBER);
|
||||||
assert (max_drop_seq >= whc->max_drop_seq);
|
assert (max_drop_seq >= whc->max_drop_seq);
|
||||||
|
|
||||||
if (dds_get_log_mask() & DDS_LC_WHC)
|
if (dds_get_log_mask () & DDS_LC_WHC)
|
||||||
{
|
{
|
||||||
struct whc_state tmp;
|
struct whc_state tmp;
|
||||||
get_state_locked(whc, &tmp);
|
get_state_locked (whc, &tmp);
|
||||||
DDS_LOG(DDS_LC_WHC, "whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq);
|
DDS_LOG (DDS_LC_WHC, "whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq);
|
||||||
DDS_LOG(DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n",
|
DDS_LOG (DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
|
||||||
tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
check_whc (whc);
|
check_whc (whc);
|
||||||
|
@ -1035,7 +1031,7 @@ static unsigned whc_default_remove_acked_messages (struct whc *whc_generic, seqn
|
||||||
cnt = whc_default_remove_acked_messages_noidx (whc, max_drop_seq, deferred_free_list);
|
cnt = whc_default_remove_acked_messages_noidx (whc, max_drop_seq, deferred_free_list);
|
||||||
else
|
else
|
||||||
cnt = whc_default_remove_acked_messages_full (whc, max_drop_seq, deferred_free_list);
|
cnt = whc_default_remove_acked_messages_full (whc, max_drop_seq, deferred_free_list);
|
||||||
get_state_locked(whc, whcst);
|
get_state_locked (whc, whcst);
|
||||||
ddsrt_mutex_unlock (&whc->lock);
|
ddsrt_mutex_unlock (&whc->lock);
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
@ -1108,38 +1104,39 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
struct whc_idxnode *idxn;
|
struct whc_idxnode *idxn;
|
||||||
union {
|
union {
|
||||||
struct whc_idxnode idxn;
|
struct whc_idxnode idxn;
|
||||||
char pad[sizeof(struct whc_idxnode) + sizeof(struct whc_node *)];
|
char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
|
||||||
} template;
|
} template;
|
||||||
|
|
||||||
ddsrt_mutex_lock (&whc->lock);
|
ddsrt_mutex_lock (&whc->lock);
|
||||||
check_whc (whc);
|
check_whc (whc);
|
||||||
|
|
||||||
if (dds_get_log_mask() & DDS_LC_WHC)
|
if (dds_get_log_mask () & DDS_LC_WHC)
|
||||||
{
|
{
|
||||||
struct whc_state whcst;
|
struct whc_state whcst;
|
||||||
get_state_locked(whc, &whcst);
|
get_state_locked (whc, &whcst);
|
||||||
DDS_LOG(DDS_LC_WHC, "whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash);
|
DDS_LOG (DDS_LC_WHC, "whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n",
|
||||||
DDS_LOG(DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n",
|
(void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash);
|
||||||
whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
DDS_LOG (DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
|
||||||
|
whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (max_drop_seq < MAX_SEQ_NUMBER);
|
assert (max_drop_seq < MAX_SEQ_NUMBER);
|
||||||
assert (max_drop_seq >= whc->max_drop_seq);
|
assert (max_drop_seq >= whc->max_drop_seq);
|
||||||
|
|
||||||
/* Seq must be greater than what is currently stored. Usually it'll
|
/* Seq must be greater than what is currently stored. Usually it'll
|
||||||
be the next sequence number, but if there are no readers
|
be the next sequence number, but if there are no readers
|
||||||
temporarily, a gap may be among the possibilities */
|
temporarily, a gap may be among the possibilities */
|
||||||
assert (whc->seq_size == 0 || seq > whc->maxseq_node->seq);
|
assert (whc->seq_size == 0 || seq > whc->maxseq_node->seq);
|
||||||
|
|
||||||
/* Always insert in seq admin */
|
/* Always insert in seq admin */
|
||||||
newn = whc_default_insert_seq (whc, max_drop_seq, seq, plist, serdata);
|
newn = whc_default_insert_seq (whc, max_drop_seq, seq, plist, serdata);
|
||||||
|
|
||||||
DDS_LOG(DDS_LC_WHC, " whcn %p:", (void*)newn);
|
DDS_LOG (DDS_LC_WHC, " whcn %p:", (void*)newn);
|
||||||
|
|
||||||
/* Special case of empty data (such as commit messages) can't go into index, and if we're not maintaining an index, we're done, too */
|
/* Special case of empty data (such as commit messages) can't go into index, and if we're not maintaining an index, we're done, too */
|
||||||
if (serdata->kind == SDK_EMPTY || whc->idxdepth == 0)
|
if (serdata->kind == SDK_EMPTY || whc->idxdepth == 0)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " empty or no hist\n");
|
DDS_LOG (DDS_LC_WHC, " empty or no hist\n");
|
||||||
ddsrt_mutex_unlock (&whc->lock);
|
ddsrt_mutex_unlock (&whc->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1148,15 +1145,15 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
if ((idxn = ddsrt_hh_lookup (whc->idx_hash, &template)) != NULL)
|
if ((idxn = ddsrt_hh_lookup (whc->idx_hash, &template)) != NULL)
|
||||||
{
|
{
|
||||||
/* Unregisters cause deleting of index entry, non-unregister of adding/overwriting in history */
|
/* Unregisters cause deleting of index entry, non-unregister of adding/overwriting in history */
|
||||||
DDS_LOG(DDS_LC_WHC, " idxn %p", (void *)idxn);
|
DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
|
||||||
if (serdata->statusinfo & NN_STATUSINFO_UNREGISTER)
|
if (serdata->statusinfo & NN_STATUSINFO_UNREGISTER)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " unreg:delete\n");
|
DDS_LOG (DDS_LC_WHC, " unreg:delete\n");
|
||||||
delete_one_instance_from_idx (whc, max_drop_seq, idxn);
|
delete_one_instance_from_idx (whc, max_drop_seq, idxn);
|
||||||
if (newn->seq <= max_drop_seq)
|
if (newn->seq <= max_drop_seq)
|
||||||
{
|
{
|
||||||
struct whc_node *prev_seq = newn->prev_seq;
|
struct whc_node *prev_seq = newn->prev_seq;
|
||||||
DDS_LOG(DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
|
DDS_LOG (DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
|
||||||
whc_delete_one (whc, newn);
|
whc_delete_one (whc, newn);
|
||||||
whc->maxseq_node = prev_seq;
|
whc->maxseq_node = prev_seq;
|
||||||
}
|
}
|
||||||
|
@ -1168,7 +1165,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
idxn->headidx = 0;
|
idxn->headidx = 0;
|
||||||
if ((oldn = idxn->hist[idxn->headidx]) != NULL)
|
if ((oldn = idxn->hist[idxn->headidx]) != NULL)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " overwrite whcn %p", (void *)oldn);
|
DDS_LOG (DDS_LC_WHC, " overwrite whcn %p", (void *)oldn);
|
||||||
oldn->idxnode = NULL;
|
oldn->idxnode = NULL;
|
||||||
}
|
}
|
||||||
idxn->hist[idxn->headidx] = newn;
|
idxn->hist[idxn->headidx] = newn;
|
||||||
|
@ -1177,46 +1174,45 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
|
|
||||||
if (oldn && (whc->hdepth > 0 || oldn->seq <= max_drop_seq))
|
if (oldn && (whc->hdepth > 0 || oldn->seq <= max_drop_seq))
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " prune whcn %p", (void *)oldn);
|
DDS_LOG (DDS_LC_WHC, " prune whcn %p", (void *)oldn);
|
||||||
assert(oldn != whc->maxseq_node);
|
assert (oldn != whc->maxseq_node);
|
||||||
whc_delete_one (whc, oldn);
|
whc_delete_one (whc, oldn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special case for dropping everything beyond T-L history when the new sample is being
|
/* Special case for dropping everything beyond T-L history when the new sample is being
|
||||||
auto-acknowledged (for lack of reliable readers), and the keep-last T-L history is
|
auto-acknowledged (for lack of reliable readers), and the keep-last T-L history is
|
||||||
shallower than the keep-last regular history (normal path handles this via pruning in
|
shallower than the keep-last regular history (normal path handles this via pruning in
|
||||||
whc_default_remove_acked_messages, but that never happens when there are no readers). */
|
whc_default_remove_acked_messages, but that never happens when there are no readers). */
|
||||||
if (seq <= max_drop_seq && whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
|
if (seq <= max_drop_seq && whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
|
||||||
{
|
{
|
||||||
unsigned pos = idxn->headidx + whc->idxdepth - whc->tldepth;
|
uint32_t pos = idxn->headidx + whc->idxdepth - whc->tldepth;
|
||||||
if (pos >= whc->idxdepth)
|
if (pos >= whc->idxdepth)
|
||||||
pos -= whc->idxdepth;
|
pos -= whc->idxdepth;
|
||||||
if ((oldn = idxn->hist[pos]) != NULL)
|
if ((oldn = idxn->hist[pos]) != NULL)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " prune tl whcn %p", (void *)oldn);
|
DDS_LOG (DDS_LC_WHC, " prune tl whcn %p", (void *)oldn);
|
||||||
assert(oldn != whc->maxseq_node);
|
assert (oldn != whc->maxseq_node);
|
||||||
whc_delete_one (whc, oldn);
|
whc_delete_one (whc, oldn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DDS_LOG(DDS_LC_WHC, "\n");
|
DDS_LOG (DDS_LC_WHC, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " newkey");
|
DDS_LOG (DDS_LC_WHC, " newkey");
|
||||||
/* Ignore unregisters, but insert everything else */
|
/* Ignore unregisters, but insert everything else */
|
||||||
if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER))
|
if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER))
|
||||||
{
|
{
|
||||||
unsigned i;
|
|
||||||
idxn = ddsrt_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0]));
|
idxn = ddsrt_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0]));
|
||||||
DDS_LOG(DDS_LC_WHC, " idxn %p", (void *)idxn);
|
DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
|
||||||
ddsi_tkmap_instance_ref(tk);
|
ddsi_tkmap_instance_ref (tk);
|
||||||
idxn->iid = tk->m_iid;
|
idxn->iid = tk->m_iid;
|
||||||
idxn->tk = tk;
|
idxn->tk = tk;
|
||||||
idxn->prune_seq = 0;
|
idxn->prune_seq = 0;
|
||||||
idxn->headidx = 0;
|
idxn->headidx = 0;
|
||||||
idxn->hist[0] = newn;
|
idxn->hist[0] = newn;
|
||||||
for (i = 1; i < whc->idxdepth; i++)
|
for (uint32_t i = 1; i < whc->idxdepth; i++)
|
||||||
idxn->hist[i] = NULL;
|
idxn->hist[i] = NULL;
|
||||||
newn->idxnode = idxn;
|
newn->idxnode = idxn;
|
||||||
newn->idxnode_pos = 0;
|
newn->idxnode_pos = 0;
|
||||||
|
@ -1225,24 +1221,24 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_WHC, " unreg:skip");
|
DDS_LOG (DDS_LC_WHC, " unreg:skip");
|
||||||
if (newn->seq <= max_drop_seq)
|
if (newn->seq <= max_drop_seq)
|
||||||
{
|
{
|
||||||
struct whc_node *prev_seq = newn->prev_seq;
|
struct whc_node *prev_seq = newn->prev_seq;
|
||||||
DDS_LOG(DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
|
DDS_LOG (DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
|
||||||
whc_delete_one (whc, newn);
|
whc_delete_one (whc, newn);
|
||||||
whc->maxseq_node = prev_seq;
|
whc->maxseq_node = prev_seq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DDS_LOG(DDS_LC_WHC, "\n");
|
DDS_LOG (DDS_LC_WHC, "\n");
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&whc->lock);
|
ddsrt_mutex_unlock (&whc->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_borrowed_sample(struct whc_borrowed_sample *sample, struct whc_node *whcn)
|
static void make_borrowed_sample (struct whc_borrowed_sample *sample, struct whc_node *whcn)
|
||||||
{
|
{
|
||||||
assert(!whcn->borrowed);
|
assert (!whcn->borrowed);
|
||||||
whcn->borrowed = 1;
|
whcn->borrowed = 1;
|
||||||
sample->seq = whcn->seq;
|
sample->seq = whcn->seq;
|
||||||
sample->plist = whcn->plist;
|
sample->plist = whcn->plist;
|
||||||
|
@ -1258,11 +1254,11 @@ static bool whc_default_borrow_sample (const struct whc *whc_generic, seqno_t se
|
||||||
struct whc_node *whcn;
|
struct whc_node *whcn;
|
||||||
bool found;
|
bool found;
|
||||||
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
||||||
if ((whcn = whc_findseq(whc, seq)) == NULL)
|
if ((whcn = whc_findseq (whc, seq)) == NULL)
|
||||||
found = false;
|
found = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
make_borrowed_sample(sample, whcn);
|
make_borrowed_sample (sample, whcn);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
|
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
|
||||||
|
@ -1275,11 +1271,11 @@ static bool whc_default_borrow_sample_key (const struct whc *whc_generic, const
|
||||||
struct whc_node *whcn;
|
struct whc_node *whcn;
|
||||||
bool found;
|
bool found;
|
||||||
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
||||||
if ((whcn = whc_findkey(whc, serdata_key)) == NULL)
|
if ((whcn = whc_findkey (whc, serdata_key)) == NULL)
|
||||||
found = false;
|
found = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
make_borrowed_sample(sample, whcn);
|
make_borrowed_sample (sample, whcn);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
|
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
|
||||||
|
@ -1293,14 +1289,15 @@ static void return_sample_locked (struct whc_impl *whc, struct whc_borrowed_samp
|
||||||
{
|
{
|
||||||
/* data no longer present in WHC - that means ownership for serdata, plist shifted to the borrowed copy and "returning" it really becomes "destroying" it */
|
/* data no longer present in WHC - that means ownership for serdata, plist shifted to the borrowed copy and "returning" it really becomes "destroying" it */
|
||||||
ddsi_serdata_unref (sample->serdata);
|
ddsi_serdata_unref (sample->serdata);
|
||||||
if (sample->plist) {
|
if (sample->plist)
|
||||||
|
{
|
||||||
nn_plist_fini (sample->plist);
|
nn_plist_fini (sample->plist);
|
||||||
ddsrt_free (sample->plist);
|
ddsrt_free (sample->plist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(whcn->borrowed);
|
assert (whcn->borrowed);
|
||||||
whcn->borrowed = 0;
|
whcn->borrowed = 0;
|
||||||
if (update_retransmit_info)
|
if (update_retransmit_info)
|
||||||
{
|
{
|
||||||
|
@ -1338,7 +1335,7 @@ static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_
|
||||||
if (!it->first)
|
if (!it->first)
|
||||||
{
|
{
|
||||||
seq = sample->seq;
|
seq = sample->seq;
|
||||||
return_sample_locked(whc, sample, false);
|
return_sample_locked (whc, sample, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1349,7 +1346,7 @@ static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_
|
||||||
valid = false;
|
valid = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
make_borrowed_sample(sample, whcn);
|
make_borrowed_sample (sample, whcn);
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&whc->lock);
|
ddsrt_mutex_unlock (&whc->lock);
|
||||||
|
|
|
@ -44,9 +44,7 @@ struct bwhc_iter {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* check that our definition of whc_sample_iter fits in the type that callers allocate */
|
/* check that our definition of whc_sample_iter fits in the type that callers allocate */
|
||||||
struct bwhc_sample_iter_sizecheck {
|
DDSRT_STATIC_ASSERT (sizeof (struct bwhc_iter) <= sizeof (struct whc_sample_iter));
|
||||||
char fits_in_generic_type[sizeof(struct bwhc_iter) <= sizeof(struct whc_sample_iter) ? 1 : -1];
|
|
||||||
};
|
|
||||||
|
|
||||||
static void bwhc_free (struct whc *whc_generic)
|
static void bwhc_free (struct whc *whc_generic)
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,13 +111,13 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* When deleting, pwr is no longer accessible via the hash
|
/* When deleting, pwr is no longer accessible via the hash
|
||||||
tables, and consequently, a reader may be deleted without
|
tables, and consequently, a reader may be deleted without
|
||||||
it being possible to remove it from rdary. The primary
|
it being possible to remove it from rdary. The primary
|
||||||
reason rdary exists is to avoid locking the proxy writer
|
reason rdary exists is to avoid locking the proxy writer
|
||||||
but this is less of an issue when we are deleting it, so
|
but this is less of an issue when we are deleting it, so
|
||||||
we fall back to using the GUIDs so that we can deliver all
|
we fall back to using the GUIDs so that we can deliver all
|
||||||
samples we received from it. As writer being deleted any
|
samples we received from it. As writer being deleted any
|
||||||
reliable samples that are rejected are simply discarded. */
|
reliable samples that are rejected are simply discarded. */
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
struct pwr_rd_match *m;
|
struct pwr_rd_match *m;
|
||||||
struct proxy_writer_info pwr_info;
|
struct proxy_writer_info pwr_info;
|
||||||
|
@ -130,8 +130,8 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL)
|
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
DDS_TRACE("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
|
DDS_TRACE ("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
|
||||||
/* Copied the return value ignore from DDSI deliver_user_data() function. */
|
/* Copied the return value ignore from DDSI deliver_user_data () function. */
|
||||||
if ((ret = try_store (rd->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK)
|
if ((ret = try_store (rd->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -152,40 +152,34 @@ dds_return_t dds_write_impl (dds_writer *wr, const void * data, dds_time_t tstam
|
||||||
int w_rc;
|
int w_rc;
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
{
|
|
||||||
DDS_ERROR("No data buffer provided\n");
|
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for topic filter */
|
/* Check for topic filter */
|
||||||
if (wr->m_topic->filter_fn && !writekey)
|
if (wr->m_topic->filter_fn && !writekey)
|
||||||
if (!(wr->m_topic->filter_fn) (data, wr->m_topic->filter_ctx))
|
if (! wr->m_topic->filter_fn (data, wr->m_topic->filter_ctx))
|
||||||
return DDS_RETCODE_OK;
|
return DDS_RETCODE_OK;
|
||||||
|
|
||||||
thread_state_awake (ts1);
|
thread_state_awake (ts1);
|
||||||
|
|
||||||
/* Serialize and write data or key */
|
/* Serialize and write data or key */
|
||||||
d = ddsi_serdata_from_sample (ddsi_wr->topic, writekey ? SDK_KEY : SDK_DATA, data);
|
d = ddsi_serdata_from_sample (ddsi_wr->topic, writekey ? SDK_KEY : SDK_DATA, data);
|
||||||
d->statusinfo = ((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) | ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0);
|
d->statusinfo = (((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) |
|
||||||
|
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0));
|
||||||
d->timestamp.v = tstamp;
|
d->timestamp.v = tstamp;
|
||||||
ddsi_serdata_ref (d);
|
ddsi_serdata_ref (d);
|
||||||
tk = ddsi_tkmap_lookup_instance_ref (d);
|
tk = ddsi_tkmap_lookup_instance_ref (d);
|
||||||
w_rc = write_sample_gc (ts1, wr->m_xp, ddsi_wr, d, tk);
|
w_rc = write_sample_gc (ts1, wr->m_xp, ddsi_wr, d, tk);
|
||||||
|
|
||||||
if (w_rc >= 0)
|
if (w_rc >= 0) {
|
||||||
{
|
|
||||||
/* Flush out write unless configured to batch */
|
/* Flush out write unless configured to batch */
|
||||||
if (!config.whc_batch)
|
if (!config.whc_batch)
|
||||||
nn_xpack_send (wr->m_xp, false);
|
nn_xpack_send (wr->m_xp, false);
|
||||||
ret = DDS_RETCODE_OK;
|
ret = DDS_RETCODE_OK;
|
||||||
} else if (w_rc == DDS_RETCODE_TIMEOUT) {
|
} else if (w_rc == DDS_RETCODE_TIMEOUT) {
|
||||||
DDS_ERROR ("The writer could not deliver data on time, probably due to a reader resources being full\n");
|
|
||||||
ret = DDS_RETCODE_TIMEOUT;
|
ret = DDS_RETCODE_TIMEOUT;
|
||||||
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
|
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
|
||||||
DDS_ERROR ("Invalid data provided\n");
|
|
||||||
ret = DDS_RETCODE_ERROR;
|
ret = DDS_RETCODE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
DDS_ERROR ("Internal error\n");
|
|
||||||
ret = DDS_RETCODE_ERROR;
|
ret = DDS_RETCODE_ERROR;
|
||||||
}
|
}
|
||||||
if (ret == DDS_RETCODE_OK)
|
if (ret == DDS_RETCODE_OK)
|
||||||
|
@ -213,13 +207,10 @@ dds_return_t dds_writecdr_impl_lowlevel (struct writer *ddsi_wr, struct nn_xpack
|
||||||
nn_xpack_send (xp, false);
|
nn_xpack_send (xp, false);
|
||||||
ret = DDS_RETCODE_OK;
|
ret = DDS_RETCODE_OK;
|
||||||
} else if (w_rc == DDS_RETCODE_TIMEOUT) {
|
} else if (w_rc == DDS_RETCODE_TIMEOUT) {
|
||||||
DDS_ERROR ("The writer could not deliver data on time, probably due to a reader resources being full\n");
|
|
||||||
ret = DDS_RETCODE_TIMEOUT;
|
ret = DDS_RETCODE_TIMEOUT;
|
||||||
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
|
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
|
||||||
DDS_ERROR ("Invalid data provided\n");
|
|
||||||
ret = DDS_RETCODE_ERROR;
|
ret = DDS_RETCODE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
DDS_ERROR ("Internal error\n");
|
|
||||||
ret = DDS_RETCODE_ERROR;
|
ret = DDS_RETCODE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +227,8 @@ dds_return_t dds_writecdr_impl (dds_writer *wr, struct ddsi_serdata *d, dds_time
|
||||||
if (wr->m_topic->filter_fn)
|
if (wr->m_topic->filter_fn)
|
||||||
abort ();
|
abort ();
|
||||||
/* Set if disposing or unregistering */
|
/* Set if disposing or unregistering */
|
||||||
d->statusinfo = ((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) | ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0);
|
d->statusinfo = (((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) |
|
||||||
|
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0));
|
||||||
d->timestamp.v = tstamp;
|
d->timestamp.v = tstamp;
|
||||||
return dds_writecdr_impl_lowlevel (wr->m_wr, wr->m_xp, d);
|
return dds_writecdr_impl_lowlevel (wr->m_wr, wr->m_xp, d);
|
||||||
}
|
}
|
||||||
|
@ -252,9 +244,7 @@ void dds_write_flush (dds_entity_t writer)
|
||||||
dds_writer *wr;
|
dds_writer *wr;
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
thread_state_awake (ts1);
|
thread_state_awake (ts1);
|
||||||
if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
if ((rc = dds_writer_lock (writer, &wr)) == DDS_RETCODE_OK)
|
||||||
DDS_ERROR ("Error occurred on locking writer\n");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
nn_xpack_send (wr->m_xp, true);
|
nn_xpack_send (wr->m_xp, true);
|
||||||
dds_writer_unlock (wr);
|
dds_writer_unlock (wr);
|
||||||
|
|
|
@ -24,40 +24,29 @@
|
||||||
#include "dds__init.h"
|
#include "dds__init.h"
|
||||||
#include "dds__publisher.h"
|
#include "dds__publisher.h"
|
||||||
#include "dds__topic.h"
|
#include "dds__topic.h"
|
||||||
|
#include "dds__get_status.h"
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
#include "dds__whc.h"
|
#include "dds__whc.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_writer)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_writer)
|
||||||
|
|
||||||
#define DDS_WRITER_STATUS_MASK \
|
#define DDS_WRITER_STATUS_MASK \
|
||||||
DDS_LIVELINESS_LOST_STATUS |\
|
(DDS_LIVELINESS_LOST_STATUS |\
|
||||||
DDS_OFFERED_DEADLINE_MISSED_STATUS |\
|
DDS_OFFERED_DEADLINE_MISSED_STATUS |\
|
||||||
DDS_OFFERED_INCOMPATIBLE_QOS_STATUS |\
|
DDS_OFFERED_INCOMPATIBLE_QOS_STATUS |\
|
||||||
DDS_PUBLICATION_MATCHED_STATUS
|
DDS_PUBLICATION_MATCHED_STATUS)
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_writer_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||||
dds_writer_instance_hdl(
|
|
||||||
dds_entity *e,
|
static dds_return_t dds_writer_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||||
dds_instance_handle_t *i)
|
|
||||||
{
|
{
|
||||||
assert(e);
|
*i = writer_instance_id(&e->m_guid);
|
||||||
assert(i);
|
return DDS_RETCODE_OK;
|
||||||
*i = (dds_instance_handle_t)writer_instance_id(&e->m_guid);
|
|
||||||
return DDS_RETCODE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_writer_status_validate (uint32_t mask)
|
||||||
dds_writer_status_validate(
|
|
||||||
uint32_t mask)
|
|
||||||
{
|
{
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
return (mask & ~DDS_WRITER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||||
|
|
||||||
if (mask & ~(DDS_WRITER_STATUS_MASK)) {
|
|
||||||
DDS_ERROR("Invalid status mask\n");
|
|
||||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -173,285 +162,217 @@ static void dds_writer_status_cb (void *ventity, const status_cb_data_t *data)
|
||||||
ddsrt_mutex_unlock (&entity->m_observers_lock);
|
ddsrt_mutex_unlock (&entity->m_observers_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t get_bandwidth_limit (nn_transport_priority_qospolicy_t transport_priority)
|
||||||
get_bandwidth_limit(
|
|
||||||
nn_transport_priority_qospolicy_t transport_priority)
|
|
||||||
{
|
{
|
||||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
||||||
struct config_channel_listelem *channel = find_channel (transport_priority);
|
struct config_channel_listelem *channel = find_channel (transport_priority);
|
||||||
return channel->data_bandwidth_limit;
|
return channel->data_bandwidth_limit;
|
||||||
#else
|
#else
|
||||||
(void)transport_priority;
|
(void) transport_priority;
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static dds_return_t dds_writer_close (dds_entity *e) ddsrt_nonnull_all;
|
||||||
dds_writer_close(
|
|
||||||
dds_entity *e)
|
|
||||||
{
|
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
|
||||||
dds_writer *wr = (dds_writer*)e;
|
|
||||||
|
|
||||||
assert(e);
|
static dds_return_t dds_writer_close (dds_entity *e)
|
||||||
|
{
|
||||||
|
dds_writer * const wr = (dds_writer *) e;
|
||||||
|
dds_return_t ret;
|
||||||
|
thread_state_awake (lookup_thread_state ());
|
||||||
|
nn_xpack_send (wr->m_xp, false);
|
||||||
|
if ((ret = delete_writer (&e->m_guid)) < 0)
|
||||||
|
ret = DDS_RETCODE_ERROR;
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_writer_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
static dds_return_t dds_writer_delete (dds_entity *e)
|
||||||
|
{
|
||||||
|
dds_writer * const wr = (dds_writer *) e;
|
||||||
|
dds_return_t ret;
|
||||||
|
/* FIXME: not freeing WHC here because it is owned by the DDSI entity */
|
||||||
|
thread_state_awake (lookup_thread_state ());
|
||||||
|
nn_xpack_free (wr->m_xp);
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
if ((ret = dds_delete (wr->m_topic->m_entity.m_hdllink.hdl)) == DDS_RETCODE_OK)
|
||||||
|
{
|
||||||
|
ret = dds_delete_impl (e->m_parent->m_hdllink.hdl, true);
|
||||||
|
if (ret == DDS_RETCODE_BAD_PARAMETER)
|
||||||
|
ret = DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_writer_qos_validate (const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
if (!dds_qos_validate_common(qos))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy (&qos->durability_service) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_LIFESPAN) && validate_duration (&qos->lifespan.duration) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && validate_history_and_resource_limits(&qos->history, &qos->resource_limits) < 0)
|
||||||
|
return DDS_RETCODE_INCONSISTENT_POLICY;
|
||||||
|
return enabled ? dds_qos_validate_mutable_common (qos) : DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dds_return_t dds_writer_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||||
|
{
|
||||||
|
/* FIXME: QoS changes */
|
||||||
|
dds_return_t ret;
|
||||||
|
|
||||||
|
if ((ret = dds_writer_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Sort-of support updating ownership strength */
|
||||||
|
if ((qos->present & QP_OWNERSHIP_STRENGTH) && (qos->present & ~QP_OWNERSHIP_STRENGTH) == 0)
|
||||||
|
{
|
||||||
|
dds_ownership_kind_t kind;
|
||||||
|
dds_qget_ownership (e->m_qos, &kind);
|
||||||
|
|
||||||
|
if (kind != DDS_OWNERSHIP_EXCLUSIVE)
|
||||||
|
return DDS_RETCODE_ERROR;
|
||||||
|
|
||||||
|
struct writer *ddsi_wr = ((dds_writer *) e)->m_wr;
|
||||||
|
dds_qset_ownership_strength (e->m_qos, qos->ownership_strength.value);
|
||||||
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
thread_state_awake (lookup_thread_state ());
|
||||||
nn_xpack_send (wr->m_xp, false);
|
|
||||||
if (delete_writer (&e->m_guid) != 0) {
|
/* FIXME: with QoS changes being unsupported by the underlying stack I wonder what will happen; locking the underlying DDSI writer is of doubtful value as well */
|
||||||
DDS_ERROR("Internal error");
|
ddsrt_mutex_lock (&ddsi_wr->e.lock);
|
||||||
ret = DDS_RETCODE_ERROR;
|
ddsi_wr->xqos->ownership_strength.value = qos->ownership_strength.value;
|
||||||
}
|
ddsrt_mutex_unlock (&ddsi_wr->e.lock);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
thread_state_asleep (lookup_thread_state ());
|
||||||
return ret;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
ret = DDS_RETCODE_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dds_return_t
|
static struct whc *make_whc (const dds_qos_t *qos)
|
||||||
dds_writer_delete(
|
|
||||||
dds_entity *e)
|
|
||||||
{
|
|
||||||
dds_writer *wr = (dds_writer*)e;
|
|
||||||
dds_return_t ret;
|
|
||||||
/* FIXME: not freeing WHC here because it is owned by the DDSI entity */
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
|
||||||
nn_xpack_free(wr->m_xp);
|
|
||||||
thread_state_asleep (lookup_thread_state ());
|
|
||||||
ret = dds_delete(wr->m_topic->m_entity.m_hdllink.hdl);
|
|
||||||
if(ret == DDS_RETCODE_OK){
|
|
||||||
ret = dds_delete_impl(e->m_parent->m_hdllink.hdl, true);
|
|
||||||
if(ret == DDS_RETCODE_BAD_PARAMETER){
|
|
||||||
ret = DDS_RETCODE_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_writer_qos_validate(
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = DDS_RETCODE_OK;
|
|
||||||
|
|
||||||
assert(qos);
|
|
||||||
|
|
||||||
/* Check consistency. */
|
|
||||||
if(dds_qos_validate_common(qos) != true){
|
|
||||||
DDS_ERROR("Provided inconsistent QoS policy\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if((qos->present & QP_USER_DATA) && validate_octetseq(&qos->user_data) != true){
|
|
||||||
DDS_ERROR("User Data QoS policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy(&qos->durability_service) != 0){
|
|
||||||
DDS_ERROR("Durability service QoS policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if ((qos->present & QP_LIFESPAN) && validate_duration(&qos->lifespan.duration) != 0){
|
|
||||||
DDS_ERROR("Lifespan QoS policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && (validate_history_and_resource_limits(&qos->history, &qos->resource_limits) != 0)){
|
|
||||||
DDS_ERROR("Resource limits QoS policy is inconsistent and caused an error\n");
|
|
||||||
ret = DDS_RETCODE_INCONSISTENT_POLICY;
|
|
||||||
}
|
|
||||||
if(ret == DDS_RETCODE_OK && enabled) {
|
|
||||||
ret = dds_qos_validate_mutable_common(qos);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dds_return_t
|
|
||||||
dds_writer_qos_set(
|
|
||||||
dds_entity *e,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
bool enabled)
|
|
||||||
{
|
|
||||||
dds_return_t ret = dds_writer_qos_validate(qos, enabled);
|
|
||||||
if (ret == DDS_RETCODE_OK) {
|
|
||||||
/*
|
|
||||||
* TODO: CHAM-95: DDSI does not support changing QoS policies.
|
|
||||||
*
|
|
||||||
* Only Ownership is required for the minimum viable product. This seems
|
|
||||||
* to be the only QoS policy that DDSI supports changes on.
|
|
||||||
*/
|
|
||||||
if (qos->present & QP_OWNERSHIP_STRENGTH) {
|
|
||||||
dds_ownership_kind_t kind;
|
|
||||||
/* check for ownership before updating, ownership strength is applicable only if
|
|
||||||
* writer is exclusive */
|
|
||||||
dds_qget_ownership (e->m_qos, &kind);
|
|
||||||
|
|
||||||
if (kind == DDS_OWNERSHIP_EXCLUSIVE) {
|
|
||||||
struct writer * ddsi_wr = ((dds_writer*)e)->m_wr;
|
|
||||||
|
|
||||||
dds_qset_ownership_strength (e->m_qos, qos->ownership_strength.value);
|
|
||||||
|
|
||||||
thread_state_awake (lookup_thread_state ());
|
|
||||||
|
|
||||||
/* FIXME: with QoS changes being unsupported by the underlying stack I wonder what will happen; locking the underlying DDSI writer is of doubtful value as well */
|
|
||||||
ddsrt_mutex_lock (&ddsi_wr->e.lock);
|
|
||||||
if (qos->ownership_strength.value != ddsi_wr->xqos->ownership_strength.value) {
|
|
||||||
ddsi_wr->xqos->ownership_strength.value = qos->ownership_strength.value;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&ddsi_wr->e.lock);
|
|
||||||
thread_state_asleep (lookup_thread_state ());
|
|
||||||
} else {
|
|
||||||
DDS_ERROR("Setting ownership strength doesn't make sense when the ownership is shared\n");
|
|
||||||
ret = DDS_RETCODE_ERROR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (enabled) {
|
|
||||||
DDS_ERROR(DDS_PROJECT_NAME" does not support changing QoS policies yet\n");
|
|
||||||
ret = DDS_RETCODE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct whc *make_whc(const dds_qos_t *qos)
|
|
||||||
{
|
{
|
||||||
bool handle_as_transient_local;
|
bool handle_as_transient_local;
|
||||||
unsigned hdepth, tldepth;
|
uint32_t hdepth, tldepth;
|
||||||
/* Construct WHC -- if aggressive_keep_last1 is set, the WHC will
|
/* Construct WHC -- if aggressive_keep_last1 is set, the WHC will
|
||||||
drop all samples for which a later update is available. This
|
drop all samples for which a later update is available. This
|
||||||
forces it to maintain a tlidx. */
|
forces it to maintain a tlidx. */
|
||||||
handle_as_transient_local = (qos->durability.kind == NN_TRANSIENT_LOCAL_DURABILITY_QOS);
|
handle_as_transient_local = (qos->durability.kind == NN_TRANSIENT_LOCAL_DURABILITY_QOS);
|
||||||
if (qos->history.kind == NN_KEEP_ALL_HISTORY_QOS)
|
if (qos->history.kind == NN_KEEP_ALL_HISTORY_QOS)
|
||||||
hdepth = 0;
|
hdepth = 0;
|
||||||
else
|
else
|
||||||
hdepth = (unsigned)qos->history.depth;
|
hdepth = (unsigned) qos->history.depth;
|
||||||
if (handle_as_transient_local) {
|
if (!handle_as_transient_local)
|
||||||
|
tldepth = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
if (qos->durability_service.history.kind == NN_KEEP_ALL_HISTORY_QOS)
|
if (qos->durability_service.history.kind == NN_KEEP_ALL_HISTORY_QOS)
|
||||||
tldepth = 0;
|
tldepth = 0;
|
||||||
else
|
else
|
||||||
tldepth = (unsigned)qos->durability_service.history.depth;
|
tldepth = (unsigned) qos->durability_service.history.depth;
|
||||||
} else {
|
|
||||||
tldepth = 0;
|
|
||||||
}
|
}
|
||||||
return whc_new (handle_as_transient_local, hdepth, tldepth);
|
return whc_new (handle_as_transient_local, hdepth, tldepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||||
dds_entity_t
|
|
||||||
dds_create_writer(
|
|
||||||
dds_entity_t participant_or_publisher,
|
|
||||||
dds_entity_t topic,
|
|
||||||
const dds_qos_t *qos,
|
|
||||||
const dds_listener_t *listener)
|
|
||||||
{
|
{
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
dds_qos_t * wqos;
|
dds_qos_t *wqos;
|
||||||
dds_writer * wr;
|
dds_writer *wr;
|
||||||
dds_entity_t writer;
|
dds_entity_t writer;
|
||||||
dds_publisher * pub = NULL;
|
dds_publisher *pub = NULL;
|
||||||
dds_topic * tp;
|
dds_topic *tp;
|
||||||
dds_entity_t publisher;
|
dds_entity_t publisher;
|
||||||
ddsi_tran_conn_t conn = gv.data_conn_uc;
|
ddsi_tran_conn_t conn = gv.data_conn_uc;
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
dds_entity *p_or_p;
|
dds_entity *p_or_p;
|
||||||
if ((rc = dds_entity_claim (participant_or_publisher, &p_or_p)) != DDS_RETCODE_OK) {
|
if ((rc = dds_entity_claim (participant_or_publisher, &p_or_p)) != DDS_RETCODE_OK)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
if (dds_entity_kind (p_or_p) == DDS_KIND_PARTICIPANT)
|
||||||
if (dds_entity_kind (p_or_p) == DDS_KIND_PARTICIPANT) {
|
publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
|
||||||
publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
|
else
|
||||||
} else {
|
publisher = participant_or_publisher;
|
||||||
publisher = participant_or_publisher;
|
dds_entity_release (p_or_p);
|
||||||
}
|
}
|
||||||
dds_entity_release (p_or_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rc = dds_publisher_lock(publisher, &pub)) != DDS_RETCODE_OK) {
|
if ((rc = dds_publisher_lock (publisher, &pub)) != DDS_RETCODE_OK)
|
||||||
writer = rc;
|
return rc;
|
||||||
goto err_pub_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (publisher != participant_or_publisher) {
|
if (publisher != participant_or_publisher)
|
||||||
pub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
pub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
||||||
}
|
|
||||||
|
|
||||||
rc = dds_topic_lock(topic, &tp);
|
if ((rc = dds_topic_lock (topic, &tp)) != DDS_RETCODE_OK)
|
||||||
if (rc != DDS_RETCODE_OK) {
|
goto err_tp_lock;
|
||||||
DDS_ERROR("Error occurred on locking topic\n");
|
|
||||||
writer = rc;
|
|
||||||
goto err_tp_lock;
|
|
||||||
}
|
|
||||||
assert(tp->m_stopic);
|
|
||||||
assert(pub->m_entity.m_domain == tp->m_entity.m_domain);
|
|
||||||
|
|
||||||
/* Merge Topic & Publisher qos */
|
assert (tp->m_stopic);
|
||||||
wqos = dds_create_qos();
|
assert (pub->m_entity.m_domain == tp->m_entity.m_domain);
|
||||||
if (qos) {
|
|
||||||
/* Only returns failure when one of the qos args is NULL, which
|
|
||||||
* is not the case here. */
|
|
||||||
(void)dds_copy_qos(wqos, qos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pub->m_entity.m_qos) {
|
/* Merge Topic & Publisher qos */
|
||||||
dds_merge_qos(wqos, pub->m_entity.m_qos);
|
wqos = dds_create_qos ();
|
||||||
}
|
if (qos)
|
||||||
|
(void) dds_copy_qos (wqos, qos);
|
||||||
|
if (pub->m_entity.m_qos)
|
||||||
|
dds_merge_qos (wqos, pub->m_entity.m_qos);
|
||||||
|
if (tp->m_entity.m_qos)
|
||||||
|
dds_merge_qos (wqos, tp->m_entity.m_qos);
|
||||||
|
nn_xqos_mergein_missing (wqos, &gv.default_xqos_wr);
|
||||||
|
|
||||||
if (tp->m_entity.m_qos) {
|
if ((rc = dds_writer_qos_validate (wqos, false)) != DDS_RETCODE_OK)
|
||||||
/* merge topic qos data to writer qos */
|
{
|
||||||
dds_merge_qos(wqos, tp->m_entity.m_qos);
|
dds_delete_qos(wqos);
|
||||||
}
|
goto err_bad_qos;
|
||||||
nn_xqos_mergein_missing(wqos, &gv.default_xqos_wr);
|
}
|
||||||
|
|
||||||
ret = dds_writer_qos_validate(wqos, false);
|
/* Create writer */
|
||||||
if (ret != 0) {
|
wr = dds_alloc (sizeof (*wr));
|
||||||
dds_delete_qos(wqos);
|
writer = dds_entity_init (&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
|
||||||
writer = ret;
|
|
||||||
goto err_bad_qos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create writer */
|
wr->m_topic = tp;
|
||||||
wr = dds_alloc(sizeof (*wr));
|
dds_entity_add_ref_nolock (&tp->m_entity);
|
||||||
writer = dds_entity_init(&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
|
wr->m_xp = nn_xpack_new (conn, get_bandwidth_limit (wqos->transport_priority), config.xpack_send_async);
|
||||||
|
wr->m_entity.m_deriver.close = dds_writer_close;
|
||||||
|
wr->m_entity.m_deriver.delete = dds_writer_delete;
|
||||||
|
wr->m_entity.m_deriver.set_qos = dds_writer_qos_set;
|
||||||
|
wr->m_entity.m_deriver.validate_status = dds_writer_status_validate;
|
||||||
|
wr->m_entity.m_deriver.get_instance_hdl = dds_writer_instance_hdl;
|
||||||
|
wr->m_whc = make_whc (wqos);
|
||||||
|
|
||||||
wr->m_topic = tp;
|
/* Extra claim of this writer to make sure that the delete waits until DDSI
|
||||||
dds_entity_add_ref_nolock(&tp->m_entity);
|
* has deleted its writer as well. This can be known through the callback. */
|
||||||
wr->m_xp = nn_xpack_new(conn, get_bandwidth_limit(wqos->transport_priority), config.xpack_send_async);
|
dds_handle_claim_inc (&wr->m_entity.m_hdllink);
|
||||||
wr->m_entity.m_deriver.close = dds_writer_close;
|
|
||||||
wr->m_entity.m_deriver.delete = dds_writer_delete;
|
|
||||||
wr->m_entity.m_deriver.set_qos = dds_writer_qos_set;
|
|
||||||
wr->m_entity.m_deriver.validate_status = dds_writer_status_validate;
|
|
||||||
wr->m_entity.m_deriver.get_instance_hdl = dds_writer_instance_hdl;
|
|
||||||
wr->m_whc = make_whc (wqos);
|
|
||||||
|
|
||||||
/* Extra claim of this writer to make sure that the delete waits until DDSI
|
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
|
||||||
* has deleted its writer as well. This can be known through the callback. */
|
ddsrt_mutex_unlock (&pub->m_entity.m_mutex);
|
||||||
dds_handle_claim_inc (&wr->m_entity.m_hdllink);
|
|
||||||
|
|
||||||
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
|
thread_state_awake (lookup_thread_state ());
|
||||||
ddsrt_mutex_unlock (&pub->m_entity.m_mutex);
|
rc = new_writer (&wr->m_wr, &wr->m_entity.m_guid, NULL, &pub->m_entity.m_participant->m_guid, tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
|
||||||
|
ddsrt_mutex_lock (&pub->m_entity.m_mutex);
|
||||||
thread_state_awake (lookup_thread_state ());
|
ddsrt_mutex_lock (&tp->m_entity.m_mutex);
|
||||||
ret = new_writer(&wr->m_wr, &wr->m_entity.m_guid, NULL, &pub->m_entity.m_participant->m_guid, tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
|
assert(rc == DDS_RETCODE_OK);
|
||||||
ddsrt_mutex_lock (&pub->m_entity.m_mutex);
|
thread_state_asleep (lookup_thread_state ());
|
||||||
ddsrt_mutex_lock (&tp->m_entity.m_mutex);
|
dds_topic_unlock (tp);
|
||||||
assert(ret == DDS_RETCODE_OK);
|
dds_publisher_unlock (pub);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
return writer;
|
||||||
dds_topic_unlock(tp);
|
|
||||||
dds_publisher_unlock(pub);
|
|
||||||
return writer;
|
|
||||||
|
|
||||||
err_bad_qos:
|
err_bad_qos:
|
||||||
dds_topic_unlock(tp);
|
dds_topic_unlock (tp);
|
||||||
err_tp_lock:
|
err_tp_lock:
|
||||||
dds_publisher_unlock(pub);
|
dds_publisher_unlock (pub);
|
||||||
if((pub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
if ((pub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
||||||
(void)dds_delete(publisher);
|
(void )dds_delete (publisher);
|
||||||
}
|
}
|
||||||
err_pub_lock:
|
return rc;
|
||||||
return writer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_entity_t
|
dds_entity_t dds_get_publisher (dds_entity_t writer)
|
||||||
dds_get_publisher(
|
|
||||||
dds_entity_t writer)
|
|
||||||
{
|
{
|
||||||
dds_entity *e;
|
dds_entity *e;
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
|
@ -472,115 +393,7 @@ dds_get_publisher(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_return_t
|
DDS_GET_STATUS(writer, publication_matched, PUBLICATION_MATCHED, total_count_change, current_count_change)
|
||||||
dds_get_publication_matched_status (
|
DDS_GET_STATUS(writer, liveliness_lost, LIVELINESS_LOST, total_count_change)
|
||||||
dds_entity_t writer,
|
DDS_GET_STATUS(writer, offered_deadline_missed, OFFERED_DEADLINE_MISSED, total_count_change)
|
||||||
dds_publication_matched_status_t * status)
|
DDS_GET_STATUS(writer, offered_incompatible_qos, OFFERED_INCOMPATIBLE_QOS, total_count_change)
|
||||||
{
|
|
||||||
dds_writer *wr;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking writer\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = wr->m_publication_matched_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
|
|
||||||
if (wr->m_entity.m_status_enable & DDS_PUBLICATION_MATCHED_STATUS) {
|
|
||||||
wr->m_publication_matched_status.total_count_change = 0;
|
|
||||||
wr->m_publication_matched_status.current_count_change = 0;
|
|
||||||
dds_entity_status_reset(&wr->m_entity, DDS_PUBLICATION_MATCHED_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t
|
|
||||||
dds_get_liveliness_lost_status (
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_liveliness_lost_status_t * status)
|
|
||||||
{
|
|
||||||
dds_writer *wr;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking writer\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = wr->m_liveliness_lost_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
|
|
||||||
if (wr->m_entity.m_status_enable & DDS_LIVELINESS_LOST_STATUS) {
|
|
||||||
wr->m_liveliness_lost_status.total_count_change = 0;
|
|
||||||
dds_entity_status_reset(&wr->m_entity, DDS_LIVELINESS_LOST_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t
|
|
||||||
dds_get_offered_deadline_missed_status(
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_offered_deadline_missed_status_t *status)
|
|
||||||
{
|
|
||||||
dds_writer *wr;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking writer\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = wr->m_offered_deadline_missed_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
|
|
||||||
if (wr->m_entity.m_status_enable & DDS_OFFERED_DEADLINE_MISSED_STATUS) {
|
|
||||||
wr->m_offered_deadline_missed_status.total_count_change = 0;
|
|
||||||
dds_entity_status_reset(&wr->m_entity, DDS_OFFERED_DEADLINE_MISSED_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dds_return_t
|
|
||||||
dds_get_offered_incompatible_qos_status (
|
|
||||||
dds_entity_t writer,
|
|
||||||
dds_offered_incompatible_qos_status_t * status)
|
|
||||||
{
|
|
||||||
dds_writer *wr;
|
|
||||||
dds_return_t ret;
|
|
||||||
|
|
||||||
ret = dds_writer_lock(writer, &wr);
|
|
||||||
if (ret != DDS_RETCODE_OK) {
|
|
||||||
DDS_ERROR("Error occurred on locking writer\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
|
||||||
if (status) {
|
|
||||||
*status = wr->m_offered_incompatible_qos_status;
|
|
||||||
}
|
|
||||||
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
|
|
||||||
if (wr->m_entity.m_status_enable & DDS_OFFERED_INCOMPATIBLE_QOS_STATUS) {
|
|
||||||
wr->m_offered_incompatible_qos_status.total_count_change = 0;
|
|
||||||
dds_entity_status_reset(&wr->m_entity, DDS_OFFERED_INCOMPATIBLE_QOS_STATUS);
|
|
||||||
}
|
|
||||||
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
|
|
||||||
dds_writer_unlock(wr);
|
|
||||||
fail:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
@ -105,7 +105,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
||||||
q_rtps.h
|
q_rtps.h
|
||||||
q_security.h
|
q_security.h
|
||||||
q_sockwaitset.h
|
q_sockwaitset.h
|
||||||
q_static_assert.h
|
|
||||||
q_thread.h
|
q_thread.h
|
||||||
q_time.h
|
q_time.h
|
||||||
q_transmit.h
|
q_transmit.h
|
||||||
|
|
|
@ -467,17 +467,6 @@ nn_vendorid_t get_entity_vendorid (const struct entity_common *e);
|
||||||
* - RTPS_PF_ONLY_LOCAL FIXME: not used, it seems
|
* - RTPS_PF_ONLY_LOCAL FIXME: not used, it seems
|
||||||
* @param[in] plist
|
* @param[in] plist
|
||||||
* Parameters/QoS for this participant
|
* Parameters/QoS for this participant
|
||||||
* @param[out] dest
|
|
||||||
* Filled with the recognized parameters in the input if successful, otherwise
|
|
||||||
* initialized to an empty parameter list. Where possible, pointers alias the
|
|
||||||
* input (indicated by the "aliased" bits in the plist/xqos structures), but
|
|
||||||
* some things cannot be aliased (e.g., the array of pointers to strings for a
|
|
||||||
* sequence of strings).
|
|
||||||
* Generally, nn_plist_fini should be called when done with the parameter list,
|
|
||||||
* even when nn_plist_unlias or nn_xqos_unlias hasn't been called.
|
|
||||||
* @param[out] nextafterplist
|
|
||||||
* If non-NULL, *nextafterplist is set to the first byte following the parameter
|
|
||||||
* list sentinel on successful parse, or to NULL on failure
|
|
||||||
*
|
*
|
||||||
* @returns A dds_return_t indicating success or failure.
|
* @returns A dds_return_t indicating success or failure.
|
||||||
*
|
*
|
||||||
|
@ -562,11 +551,11 @@ int writer_must_have_hb_scheduled (const struct writer *wr, const struct whc_sta
|
||||||
void writer_set_retransmitting (struct writer *wr);
|
void writer_set_retransmitting (struct writer *wr);
|
||||||
void writer_clear_retransmitting (struct writer *wr);
|
void writer_clear_retransmitting (struct writer *wr);
|
||||||
|
|
||||||
int delete_writer (const struct nn_guid *guid);
|
dds_return_t delete_writer (const struct nn_guid *guid);
|
||||||
int delete_writer_nolinger (const struct nn_guid *guid);
|
dds_return_t delete_writer_nolinger (const struct nn_guid *guid);
|
||||||
int delete_writer_nolinger_locked (struct writer *wr);
|
dds_return_t delete_writer_nolinger_locked (struct writer *wr);
|
||||||
|
|
||||||
int delete_reader (const struct nn_guid *guid);
|
dds_return_t delete_reader (const struct nn_guid *guid);
|
||||||
uint64_t reader_instance_id (const struct nn_guid *guid);
|
uint64_t reader_instance_id (const struct nn_guid *guid);
|
||||||
|
|
||||||
struct local_orphan_writer {
|
struct local_orphan_writer {
|
||||||
|
|
|
@ -18,9 +18,7 @@ extern "C" {
|
||||||
|
|
||||||
struct nn_xqos;
|
struct nn_xqos;
|
||||||
|
|
||||||
int partition_match_based_on_wildcard_in_left_operand (const struct nn_xqos *a, const struct nn_xqos *b, const char **realname);
|
|
||||||
int partitions_match_p (const struct nn_xqos *a, const struct nn_xqos *b);
|
int partitions_match_p (const struct nn_xqos *a, const struct nn_xqos *b);
|
||||||
int is_wildcard_partition (const char *str);
|
|
||||||
|
|
||||||
/* Returns -1 on success, or QoS id of first mismatch (>=0) */
|
/* Returns -1 on success, or QoS id of first mismatch (>=0) */
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "dds/ddsrt/atomics.h"
|
#include "dds/ddsrt/atomics.h"
|
||||||
#include "dds/ddsrt/sync.h"
|
#include "dds/ddsrt/sync.h"
|
||||||
#include "dds/ddsrt/threads.h"
|
#include "dds/ddsrt/threads.h"
|
||||||
#include "dds/ddsi/q_static_assert.h"
|
#include "dds/ddsrt/static_assert.h"
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -125,7 +125,7 @@ DDS_EXPORT inline bool vtime_asleep_p (vtime_t vtime)
|
||||||
|
|
||||||
DDS_EXPORT inline bool vtime_gt (vtime_t vtime1, vtime_t vtime0)
|
DDS_EXPORT inline bool vtime_gt (vtime_t vtime1, vtime_t vtime0)
|
||||||
{
|
{
|
||||||
Q_STATIC_ASSERT_CODE (sizeof (vtime_t) == sizeof (svtime_t));
|
DDSRT_STATIC_ASSERT_CODE (sizeof (vtime_t) == sizeof (svtime_t));
|
||||||
return (svtime_t) ((vtime1 & VTIME_TIME_MASK) - (vtime0 & VTIME_TIME_MASK)) > 0;
|
return (svtime_t) ((vtime1 & VTIME_TIME_MASK) - (vtime0 & VTIME_TIME_MASK)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -332,8 +332,9 @@ static enum ddsi_locator_from_string_result ddsi_raweth_address_from_string (dds
|
||||||
memset (loc->address, 0, sizeof (loc->address));
|
memset (loc->address, 0, sizeof (loc->address));
|
||||||
while (i < 6 && *str != 0)
|
while (i < 6 && *str != 0)
|
||||||
{
|
{
|
||||||
int o, p;
|
unsigned o;
|
||||||
if (sscanf (str, "%x%n", &o, &p) != 1 || o < 0 || o > 255)
|
int p;
|
||||||
|
if (sscanf (str, "%x%n", &o, &p) != 1 || o > 255)
|
||||||
return AFSR_INVALID;
|
return AFSR_INVALID;
|
||||||
loc->address[10 + i++] = (unsigned char) o;
|
loc->address[10 + i++] = (unsigned char) o;
|
||||||
str += p;
|
str += p;
|
||||||
|
|
|
@ -127,12 +127,12 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
|
||||||
int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc)
|
int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc)
|
||||||
{
|
{
|
||||||
/* port_mode: -1 => take from string, if 0 & unicast, add for a range of participant indices;
|
/* port_mode: -1 => take from string, if 0 & unicast, add for a range of participant indices;
|
||||||
port_mode >= 0 => always set port to port_mode
|
port_mode >= 0 => always set port to port_mode
|
||||||
*/
|
*/
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
char *addrs_copy, *ip, *cursor, *a;
|
char *addrs_copy, *ip, *cursor, *a;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
addrs_copy = ddsrt_strdup (addrs);
|
addrs_copy = ddsrt_strdup (addrs);
|
||||||
|
@ -179,8 +179,8 @@ int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mo
|
||||||
ddsrt_free (ip);
|
ddsrt_free (ip);
|
||||||
ddsrt_free (addrs_copy);
|
ddsrt_free (addrs_copy);
|
||||||
return retval;
|
return retval;
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
|
||||||
|
|
||||||
int compare_locators (const nn_locator_t *a, const nn_locator_t *b)
|
int compare_locators (const nn_locator_t *a, const nn_locator_t *b)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1335,9 +1335,9 @@ static void do_print_uint32_bitset (struct cfgst *cfgst, uint32_t mask, size_t n
|
||||||
cfg_logelem (cfgst, sources, "%s%s", res, suffix);
|
cfg_logelem (cfgst, sources, "%s%s", res, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
|
||||||
static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *value, const struct unit *unittab, int64_t def_mult, int64_t min, int64_t max)
|
static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *value, const struct unit *unittab, int64_t def_mult, int64_t min, int64_t max)
|
||||||
{
|
{
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
int pos;
|
int pos;
|
||||||
double v_dbl;
|
double v_dbl;
|
||||||
int64_t v_int;
|
int64_t v_int;
|
||||||
|
@ -1364,8 +1364,8 @@ static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *valu
|
||||||
*elem = 0; /* some static analyzers don't "get it" */
|
*elem = 0; /* some static analyzers don't "get it" */
|
||||||
return cfg_error (cfgst, "%s: invalid value", value);
|
return cfg_error (cfgst, "%s: invalid value", value);
|
||||||
}
|
}
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
|
||||||
|
|
||||||
static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources, const struct unit *unittab, const char *zero_unit)
|
static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources, const struct unit *unittab, const char *zero_unit)
|
||||||
{
|
{
|
||||||
|
@ -1393,10 +1393,8 @@ static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources,
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GENERIC_ENUM_CTYPE_UF(type_, c_type_) \
|
#define GENERIC_ENUM_CTYPE_UF(type_, c_type_) \
|
||||||
struct en_##type_##_vs_ms_check { \
|
DDSRT_STATIC_ASSERT (sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
|
||||||
char length_eq[(sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
|
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)); \
|
||||||
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)) ? 1 : -1]; \
|
|
||||||
}; \
|
|
||||||
\
|
\
|
||||||
static int uf_##type_ (struct cfgst *cfgst, void *parent, UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) \
|
static int uf_##type_ (struct cfgst *cfgst, void *parent, UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -1773,9 +1771,9 @@ static void pf_allow_multicast(struct cfgst *cfgst, void *parent, struct cfgelem
|
||||||
do_print_uint32_bitset (cfgst, *p, sizeof (allow_multicast_codes) / sizeof (*allow_multicast_codes), allow_multicast_names, allow_multicast_codes, sources, "");
|
do_print_uint32_bitset (cfgst, *p, sizeof (allow_multicast_codes) / sizeof (*allow_multicast_codes), allow_multicast_names, allow_multicast_codes, sources, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
|
||||||
static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
|
static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
|
||||||
{
|
{
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
|
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
|
||||||
int pos;
|
int pos;
|
||||||
if (ddsrt_strcasecmp (value, "default") == 0) {
|
if (ddsrt_strcasecmp (value, "default") == 0) {
|
||||||
|
@ -1788,8 +1786,8 @@ static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem con
|
||||||
} else {
|
} else {
|
||||||
return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value);
|
return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value);
|
||||||
}
|
}
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
|
||||||
|
|
||||||
static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
|
static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
|
||||||
{
|
{
|
||||||
|
@ -1940,9 +1938,9 @@ static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const
|
||||||
pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s");
|
pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s");
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
|
||||||
static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
|
static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
|
||||||
{
|
{
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
|
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
|
||||||
int pos;
|
int pos;
|
||||||
if (ddsrt_strcasecmp (value, "any") == 0) {
|
if (ddsrt_strcasecmp (value, "any") == 0) {
|
||||||
|
@ -1955,8 +1953,8 @@ static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const
|
||||||
} else {
|
} else {
|
||||||
return cfg_error (cfgst, "'%s': neither 'any' nor a decimal integer in 0 .. 230\n", value);
|
return cfg_error (cfgst, "'%s': neither 'any' nor a decimal integer in 0 .. 230\n", value);
|
||||||
}
|
}
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
|
||||||
|
|
||||||
static void pf_domainId(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
|
static void pf_domainId(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1099,10 +1099,10 @@ static void rebuild_make_locs_nrds(int **locs_nrds, int nreaders, int nlocs, con
|
||||||
if (covered[j * nlocs + i] >= 0)
|
if (covered[j * nlocs + i] >= 0)
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
/* The compiler doesn't realize that ln is large enough. */
|
/* The compiler doesn't realize that ln is large enough. */
|
||||||
DDSRT_WARNING_MSVC_OFF(6386);
|
DDSRT_WARNING_MSVC_OFF(6386);
|
||||||
ln[i] = n;
|
ln[i] = n;
|
||||||
DDSRT_WARNING_MSVC_ON(6386);
|
DDSRT_WARNING_MSVC_ON(6386);
|
||||||
}
|
}
|
||||||
*locs_nrds = ln;
|
*locs_nrds = ln;
|
||||||
}
|
}
|
||||||
|
@ -3002,7 +3002,7 @@ static void writer_set_state (struct writer *wr, enum writer_state newstate)
|
||||||
wr->state = newstate;
|
wr->state = newstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_writer_nolinger_locked (struct writer *wr)
|
dds_return_t delete_writer_nolinger_locked (struct writer *wr)
|
||||||
{
|
{
|
||||||
DDS_LOG(DDS_LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid));
|
DDS_LOG(DDS_LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid));
|
||||||
ASSERT_MUTEX_HELD (&wr->e.lock);
|
ASSERT_MUTEX_HELD (&wr->e.lock);
|
||||||
|
@ -3014,7 +3014,7 @@ int delete_writer_nolinger_locked (struct writer *wr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_writer_nolinger (const struct nn_guid *guid)
|
dds_return_t delete_writer_nolinger (const struct nn_guid *guid)
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
/* We take no care to ensure application writers are not deleted
|
/* We take no care to ensure application writers are not deleted
|
||||||
|
@ -3043,7 +3043,7 @@ void delete_local_orphan_writer (struct local_orphan_writer *lowr)
|
||||||
ddsrt_mutex_unlock (&lowr->wr.e.lock);
|
ddsrt_mutex_unlock (&lowr->wr.e.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_writer (const struct nn_guid *guid)
|
dds_return_t delete_writer (const struct nn_guid *guid)
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
struct whc_state whcst;
|
struct whc_state whcst;
|
||||||
|
@ -3409,7 +3409,7 @@ static void gc_delete_reader (struct gcreq *gcreq)
|
||||||
ddsrt_free (rd);
|
ddsrt_free (rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_reader (const struct nn_guid *guid)
|
dds_return_t delete_reader (const struct nn_guid *guid)
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
assert (!is_writer_entityid (guid->entityid));
|
assert (!is_writer_entityid (guid->entityid));
|
||||||
|
|
|
@ -140,9 +140,9 @@ void nn_freelist_fini (struct nn_freelist *fl, void (*xfree) (void *))
|
||||||
xfree (fl->inner[i].m->x[j]);
|
xfree (fl->inner[i].m->x[j]);
|
||||||
ddsrt_free(fl->inner[i].m);
|
ddsrt_free(fl->inner[i].m);
|
||||||
}
|
}
|
||||||
/* The compiler can't make sense of all these linked lists and doesn't
|
/* The compiler can't make sense of all these linked lists and doesn't
|
||||||
* realize that the next pointers are always initialized here. */
|
* realize that the next pointers are always initialized here. */
|
||||||
DDSRT_WARNING_MSVC_OFF(6001);
|
DDSRT_WARNING_MSVC_OFF(6001);
|
||||||
while ((m = fl->mlist) != NULL)
|
while ((m = fl->mlist) != NULL)
|
||||||
{
|
{
|
||||||
fl->mlist = m->next;
|
fl->mlist = m->next;
|
||||||
|
@ -155,7 +155,7 @@ DDSRT_WARNING_MSVC_OFF(6001);
|
||||||
fl->emlist = m->next;
|
fl->emlist = m->next;
|
||||||
ddsrt_free (m);
|
ddsrt_free (m);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(6001);
|
DDSRT_WARNING_MSVC_ON(6001);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0);
|
static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0);
|
||||||
|
|
|
@ -415,43 +415,43 @@ static int check_thread_properties (void)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
|
||||||
int rtps_config_open (void)
|
int rtps_config_open (void)
|
||||||
{
|
{
|
||||||
int status;
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
|
int status;
|
||||||
|
|
||||||
if (config.tracingOutputFileName == NULL || *config.tracingOutputFileName == 0 || config.enabled_logcats == 0)
|
if (config.tracingOutputFileName == NULL || *config.tracingOutputFileName == 0 || config.enabled_logcats == 0)
|
||||||
{
|
{
|
||||||
config.enabled_logcats = 0;
|
config.enabled_logcats = 0;
|
||||||
config.tracingOutputFile = NULL;
|
config.tracingOutputFile = NULL;
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stdout") == 0)
|
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stdout") == 0)
|
||||||
{
|
{
|
||||||
config.tracingOutputFile = stdout;
|
config.tracingOutputFile = stdout;
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stderr") == 0)
|
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stderr") == 0)
|
||||||
{
|
{
|
||||||
config.tracingOutputFile = stderr;
|
config.tracingOutputFile = stderr;
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
else if ((config.tracingOutputFile = fopen (config.tracingOutputFileName, config.tracingAppendToFile ? "a" : "w")) == NULL)
|
else if ((config.tracingOutputFile = fopen (config.tracingOutputFileName, config.tracingAppendToFile ? "a" : "w")) == NULL)
|
||||||
{
|
{
|
||||||
DDS_ERROR("%s: cannot open for writing\n", config.tracingOutputFileName);
|
DDS_ERROR("%s: cannot open for writing\n", config.tracingOutputFileName);
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_set_log_mask(config.enabled_logcats);
|
dds_set_log_mask(config.enabled_logcats);
|
||||||
dds_set_trace_file(config.tracingOutputFile);
|
dds_set_trace_file(config.tracingOutputFile);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
|
||||||
|
|
||||||
int rtps_config_prep (struct cfgst *cfgst)
|
int rtps_config_prep (struct cfgst *cfgst)
|
||||||
{
|
{
|
||||||
|
@ -1654,10 +1654,10 @@ void rtps_fini (void)
|
||||||
while (gv.recvips)
|
while (gv.recvips)
|
||||||
{
|
{
|
||||||
struct config_in_addr_node *n = gv.recvips;
|
struct config_in_addr_node *n = gv.recvips;
|
||||||
/* The compiler doesn't realize that n->next is always initialized. */
|
/* The compiler doesn't realize that n->next is always initialized. */
|
||||||
DDSRT_WARNING_MSVC_OFF(6001);
|
DDSRT_WARNING_MSVC_OFF(6001);
|
||||||
gv.recvips = n->next;
|
gv.recvips = n->next;
|
||||||
DDSRT_WARNING_MSVC_ON(6001);
|
DDSRT_WARNING_MSVC_ON(6001);
|
||||||
ddsrt_free (n);
|
ddsrt_free (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,9 +77,9 @@ 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
|
||||||
|
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
|
||||||
FILE *new_pcap_file (const char *name)
|
FILE *new_pcap_file (const char *name)
|
||||||
{
|
{
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
pcap_hdr_t hdr;
|
pcap_hdr_t hdr;
|
||||||
|
|
||||||
|
@ -99,8 +99,8 @@ FILE *new_pcap_file (const char *name)
|
||||||
fwrite (&hdr, sizeof (hdr), 1, fp);
|
fwrite (&hdr, sizeof (hdr), 1, fp);
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
|
||||||
|
|
||||||
static void write_data (FILE *fp, const ddsrt_msghdr_t *msghdr, size_t sz)
|
static void write_data (FILE *fp, const ddsrt_msghdr_t *msghdr, size_t sz)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "dds/ddsrt/log.h"
|
#include "dds/ddsrt/log.h"
|
||||||
#include "dds/ddsrt/heap.h"
|
#include "dds/ddsrt/heap.h"
|
||||||
|
#include "dds/ddsrt/static_assert.h"
|
||||||
|
|
||||||
#include "dds/ddsi/q_log.h"
|
#include "dds/ddsi/q_log.h"
|
||||||
|
|
||||||
|
@ -30,7 +31,6 @@
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_protocol.h" /* for NN_STATUSINFO_... */
|
#include "dds/ddsi/q_protocol.h" /* for NN_STATUSINFO_... */
|
||||||
#include "dds/ddsi/q_radmin.h" /* for nn_plist_quickscan */
|
#include "dds/ddsi/q_radmin.h" /* for nn_plist_quickscan */
|
||||||
#include "dds/ddsi/q_static_assert.h"
|
|
||||||
|
|
||||||
#include "dds/ddsrt/avl.h"
|
#include "dds/ddsrt/avl.h"
|
||||||
#include "dds/ddsi/q_misc.h" /* for vendor_is_... */
|
#include "dds/ddsi/q_misc.h" /* for vendor_is_... */
|
||||||
|
@ -407,8 +407,8 @@ void nn_plist_fini (nn_plist_t *ps)
|
||||||
int i;
|
int i;
|
||||||
nn_xqos_fini (&ps->qos);
|
nn_xqos_fini (&ps->qos);
|
||||||
|
|
||||||
/* The compiler doesn't understand how offsetof is used in the arrays. */
|
/* The compiler doesn't understand how offsetof is used in the arrays. */
|
||||||
DDSRT_WARNING_MSVC_OFF(6001);
|
DDSRT_WARNING_MSVC_OFF(6001);
|
||||||
for (i = 0; i < (int) (sizeof (simple) / sizeof (*simple)); i++)
|
for (i = 0; i < (int) (sizeof (simple) / sizeof (*simple)); i++)
|
||||||
{
|
{
|
||||||
if ((ps->present & simple[i].fl) && !(ps->aliased & simple[i].fl))
|
if ((ps->present & simple[i].fl) && !(ps->aliased & simple[i].fl))
|
||||||
|
@ -422,7 +422,7 @@ DDSRT_WARNING_MSVC_OFF(6001);
|
||||||
if ((ps->present & locs[i].fl) && !(ps->aliased & locs[i].fl))
|
if ((ps->present & locs[i].fl) && !(ps->aliased & locs[i].fl))
|
||||||
free_locators ((nn_locators_t *) ((char *) ps + locs[i].off));
|
free_locators ((nn_locators_t *) ((char *) ps + locs[i].off));
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(6001);
|
DDSRT_WARNING_MSVC_ON(6001);
|
||||||
|
|
||||||
ps->present = 0;
|
ps->present = 0;
|
||||||
}
|
}
|
||||||
|
@ -1943,7 +1943,7 @@ static dds_return_t init_one_parameter
|
||||||
if (dd->bufsz >= 2 * sizeof (dest->statusinfo) && vendor_is_eclipse_or_opensplice(dd->vendorid))
|
if (dd->bufsz >= 2 * sizeof (dest->statusinfo) && vendor_is_eclipse_or_opensplice(dd->vendorid))
|
||||||
{
|
{
|
||||||
uint32_t statusinfox;
|
uint32_t statusinfox;
|
||||||
Q_STATIC_ASSERT_CODE (sizeof(statusinfox) == sizeof(dest->statusinfo));
|
DDSRT_STATIC_ASSERT_CODE (sizeof(statusinfox) == sizeof(dest->statusinfo));
|
||||||
memcpy (&statusinfox, dd->buf + sizeof (dest->statusinfo), sizeof (statusinfox));
|
memcpy (&statusinfox, dd->buf + sizeof (dest->statusinfo), sizeof (statusinfox));
|
||||||
statusinfox = fromBE4u (statusinfox);
|
statusinfox = fromBE4u (statusinfox);
|
||||||
if (statusinfox & NN_STATUSINFOX_OSPL_AUTO)
|
if (statusinfox & NN_STATUSINFOX_OSPL_AUTO)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "dds/ddsi/q_misc.h"
|
#include "dds/ddsi/q_misc.h"
|
||||||
#include "dds/ddsi/q_qosmatch.h"
|
#include "dds/ddsi/q_qosmatch.h"
|
||||||
|
|
||||||
int is_wildcard_partition (const char *str)
|
static int is_wildcard_partition (const char *str)
|
||||||
{
|
{
|
||||||
return strchr (str, '*') || strchr (str, '?');
|
return strchr (str, '*') || strchr (str, '?');
|
||||||
}
|
}
|
||||||
|
@ -66,46 +66,6 @@ int partitions_match_p (const nn_xqos_t *a, const nn_xqos_t *b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int partition_match_based_on_wildcard_in_left_operand (const nn_xqos_t *a, const nn_xqos_t *b, const char **realname)
|
|
||||||
{
|
|
||||||
assert (partitions_match_p (a, b));
|
|
||||||
if (!(a->present & QP_PARTITION) || a->partition.n == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (!(b->present & QP_PARTITION) || b->partition.n == 0)
|
|
||||||
{
|
|
||||||
/* Either A explicitly includes the default partition, or it is a
|
|
||||||
wildcard that matches it */
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < a->partition.n; i++)
|
|
||||||
if (strcmp (a->partition.strs[i], "") == 0)
|
|
||||||
return 0;
|
|
||||||
*realname = "";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned i, j;
|
|
||||||
int maybe_yes = 0;
|
|
||||||
for (i = 0; i < a->partition.n; i++)
|
|
||||||
for (j = 0; j < b->partition.n; j++)
|
|
||||||
{
|
|
||||||
if (partition_patmatch_p (a->partition.strs[i], b->partition.strs[j]))
|
|
||||||
{
|
|
||||||
if (!is_wildcard_partition (a->partition.strs[i]))
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*realname = b->partition.strs[j];
|
|
||||||
maybe_yes = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return maybe_yes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ddsi_duration_is_lt (nn_duration_t a0, nn_duration_t b0)
|
static int ddsi_duration_is_lt (nn_duration_t a0, nn_duration_t b0)
|
||||||
{
|
{
|
||||||
/* inf counts as <= inf */
|
/* inf counts as <= inf */
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "dds/ddsrt/md5.h"
|
#include "dds/ddsrt/md5.h"
|
||||||
#include "dds/ddsrt/sync.h"
|
#include "dds/ddsrt/sync.h"
|
||||||
#include "dds/ddsrt/string.h"
|
#include "dds/ddsrt/string.h"
|
||||||
|
#include "dds/ddsrt/static_assert.h"
|
||||||
|
|
||||||
#include "dds/ddsrt/avl.h"
|
#include "dds/ddsrt/avl.h"
|
||||||
#include "dds__stream.h"
|
#include "dds__stream.h"
|
||||||
|
@ -46,7 +47,6 @@
|
||||||
|
|
||||||
#include "dds/ddsi/q_transmit.h"
|
#include "dds/ddsi/q_transmit.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_static_assert.h"
|
|
||||||
#include "dds/ddsi/q_init.h"
|
#include "dds/ddsi/q_init.h"
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
#include "dds/ddsi/ddsi_mcgroup.h"
|
#include "dds/ddsi/ddsi_mcgroup.h"
|
||||||
|
@ -1613,7 +1613,7 @@ static int handle_one_gap (struct proxy_writer *pwr, struct pwr_rd_match *wn, se
|
||||||
anything useful, or there was insufficient memory to store it.
|
anything useful, or there was insufficient memory to store it.
|
||||||
When the result is either ACCEPT or a sample chain, it clearly
|
When the result is either ACCEPT or a sample chain, it clearly
|
||||||
meant something. */
|
meant something. */
|
||||||
Q_STATIC_ASSERT_CODE (NN_REORDER_ACCEPT == 0);
|
DDSRT_STATIC_ASSERT_CODE (NN_REORDER_ACCEPT == 0);
|
||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
gap_was_valuable = 1;
|
gap_was_valuable = 1;
|
||||||
|
|
||||||
|
@ -1877,7 +1877,7 @@ unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr)
|
||||||
case SMID_DATA_FRAG:
|
case SMID_DATA_FRAG:
|
||||||
{
|
{
|
||||||
unsigned char common = smhdr->flags & DATA_FLAG_INLINE_QOS;
|
unsigned char common = smhdr->flags & DATA_FLAG_INLINE_QOS;
|
||||||
Q_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS);
|
DDSRT_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS);
|
||||||
if (smhdr->flags & DATAFRAG_FLAG_KEYFLAG)
|
if (smhdr->flags & DATAFRAG_FLAG_KEYFLAG)
|
||||||
return common | DATA_FLAG_KEYFLAG;
|
return common | DATA_FLAG_KEYFLAG;
|
||||||
else
|
else
|
||||||
|
|
|
@ -89,15 +89,15 @@ void thread_states_init (unsigned maxthreads)
|
||||||
thread_states.ts =
|
thread_states.ts =
|
||||||
ddsrt_malloc_aligned_cacheline (maxthreads * sizeof (*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. */
|
/* The compiler doesn't realize that ts is large enough. */
|
||||||
DDSRT_WARNING_MSVC_OFF(6386);
|
DDSRT_WARNING_MSVC_OFF(6386);
|
||||||
for (i = 0; i < thread_states.nthreads; i++)
|
for (i = 0; i < thread_states.nthreads; i++)
|
||||||
{
|
{
|
||||||
thread_states.ts[i].state = THREAD_STATE_ZERO;
|
thread_states.ts[i].state = THREAD_STATE_ZERO;
|
||||||
thread_states.ts[i].vtime = 0u;
|
thread_states.ts[i].vtime = 0u;
|
||||||
thread_states.ts[i].name = NULL;
|
thread_states.ts[i].name = NULL;
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(6386);
|
DDSRT_WARNING_MSVC_ON(6386);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_states_fini (void)
|
void thread_states_fini (void)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "dds/ddsrt/heap.h"
|
#include "dds/ddsrt/heap.h"
|
||||||
#include "dds/ddsrt/sync.h"
|
#include "dds/ddsrt/sync.h"
|
||||||
|
#include "dds/ddsrt/static_assert.h"
|
||||||
|
|
||||||
#include "dds/ddsrt/avl.h"
|
#include "dds/ddsrt/avl.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
@ -30,7 +31,6 @@
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_unused.h"
|
#include "dds/ddsi/q_unused.h"
|
||||||
#include "dds/ddsi/q_hbcontrol.h"
|
#include "dds/ddsi/q_hbcontrol.h"
|
||||||
#include "dds/ddsi/q_static_assert.h"
|
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
#include "dds/ddsi/ddsi_serdata.h"
|
#include "dds/ddsi/ddsi_serdata.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
|
@ -598,7 +598,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
|
||||||
if (xmsg_kind == NN_XMSG_KIND_DATA_REXMIT)
|
if (xmsg_kind == NN_XMSG_KIND_DATA_REXMIT)
|
||||||
nn_xmsg_set_data_readerId (*pmsg, &ddcmn->readerId);
|
nn_xmsg_set_data_readerId (*pmsg, &ddcmn->readerId);
|
||||||
|
|
||||||
Q_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS);
|
DDSRT_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS);
|
||||||
assert (!(ddcmn->smhdr.flags & DATAFRAG_FLAG_INLINE_QOS));
|
assert (!(ddcmn->smhdr.flags & DATAFRAG_FLAG_INLINE_QOS));
|
||||||
|
|
||||||
if (fragnum == 0)
|
if (fragnum == 0)
|
||||||
|
|
|
@ -111,7 +111,9 @@ list(APPEND headers
|
||||||
"${include_path}/dds/ddsrt/process.h"
|
"${include_path}/dds/ddsrt/process.h"
|
||||||
"${include_path}/dds/ddsrt/strtod.h"
|
"${include_path}/dds/ddsrt/strtod.h"
|
||||||
"${include_path}/dds/ddsrt/strtol.h"
|
"${include_path}/dds/ddsrt/strtol.h"
|
||||||
"${include_path}/dds/ddsrt/types.h")
|
"${include_path}/dds/ddsrt/types.h"
|
||||||
|
"${include_path}/dds/ddsrt/countargs.h"
|
||||||
|
"${include_path}/dds/ddsrt/static_assert.h")
|
||||||
|
|
||||||
list(APPEND sources
|
list(APPEND sources
|
||||||
"${source_path}/io.c"
|
"${source_path}/io.c"
|
||||||
|
|
|
@ -157,46 +157,46 @@ inline void *ddsrt_atomic_addvoidp_nv (volatile ddsrt_atomic_voidp_t *x, ptrdiff
|
||||||
|
|
||||||
inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
|
inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
|
||||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||||
DDSRT_WARNING_MSVC_OFF(4146)
|
DDSRT_WARNING_MSVC_OFF(4146)
|
||||||
InterlockedExchangeAdd (&x->v, -v);
|
InterlockedExchangeAdd (&x->v, -v);
|
||||||
DDSRT_WARNING_MSVC_ON(4146)
|
DDSRT_WARNING_MSVC_ON(4146)
|
||||||
}
|
}
|
||||||
#if DDSRT_HAVE_ATOMIC64
|
#if DDSRT_HAVE_ATOMIC64
|
||||||
inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
|
inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
|
||||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||||
DDSRT_WARNING_MSVC_OFF(4146)
|
DDSRT_WARNING_MSVC_OFF(4146)
|
||||||
InterlockedExchangeAdd64 (&x->v, -v);
|
InterlockedExchangeAdd64 (&x->v, -v);
|
||||||
DDSRT_WARNING_MSVC_ON(4146)
|
DDSRT_WARNING_MSVC_ON(4146)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
|
inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
|
||||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||||
DDSRT_WARNING_MSVC_OFF(4146)
|
DDSRT_WARNING_MSVC_OFF(4146)
|
||||||
DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v);
|
DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v);
|
||||||
DDSRT_WARNING_MSVC_ON(4146)
|
DDSRT_WARNING_MSVC_ON(4146)
|
||||||
}
|
}
|
||||||
inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) {
|
inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) {
|
||||||
ddsrt_atomic_subptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v);
|
ddsrt_atomic_subptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v);
|
||||||
}
|
}
|
||||||
inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
|
inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
|
||||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||||
DDSRT_WARNING_MSVC_OFF(4146)
|
DDSRT_WARNING_MSVC_OFF(4146)
|
||||||
return InterlockedExchangeAdd (&x->v, -v) - v;
|
return InterlockedExchangeAdd (&x->v, -v) - v;
|
||||||
DDSRT_WARNING_MSVC_ON(4146)
|
DDSRT_WARNING_MSVC_ON(4146)
|
||||||
}
|
}
|
||||||
#if DDSRT_HAVE_ATOMIC64
|
#if DDSRT_HAVE_ATOMIC64
|
||||||
inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
|
inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
|
||||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||||
DDSRT_WARNING_MSVC_OFF(4146)
|
DDSRT_WARNING_MSVC_OFF(4146)
|
||||||
return InterlockedExchangeAdd64 (&x->v, -v) - v;
|
return InterlockedExchangeAdd64 (&x->v, -v) - v;
|
||||||
DDSRT_WARNING_MSVC_ON(4146)
|
DDSRT_WARNING_MSVC_ON(4146)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
inline uintptr_t ddsrt_atomic_subptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
|
inline uintptr_t ddsrt_atomic_subptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
|
||||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||||
DDSRT_WARNING_MSVC_OFF(4146)
|
DDSRT_WARNING_MSVC_OFF(4146)
|
||||||
return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v) - v;
|
return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v) - v;
|
||||||
DDSRT_WARNING_MSVC_ON(4146)
|
DDSRT_WARNING_MSVC_ON(4146)
|
||||||
}
|
}
|
||||||
inline void *ddsrt_atomic_subvoidp_nv (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) {
|
inline void *ddsrt_atomic_subvoidp_nv (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) {
|
||||||
return (void *) ddsrt_atomic_subptr_nv ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v);
|
return (void *) ddsrt_atomic_subptr_nv ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v);
|
||||||
|
@ -280,10 +280,10 @@ inline void ddsrt_atomic_fence (void) {
|
||||||
/* 28113: accessing a local variable tmp via an Interlocked
|
/* 28113: accessing a local variable tmp via an Interlocked
|
||||||
function: This is an unusual usage which could be reconsidered.
|
function: This is an unusual usage which could be reconsidered.
|
||||||
It is too heavyweight, true, but it does the trick. */
|
It is too heavyweight, true, but it does the trick. */
|
||||||
DDSRT_WARNING_MSVC_OFF(28113)
|
DDSRT_WARNING_MSVC_OFF(28113)
|
||||||
volatile LONG tmp = 0;
|
volatile LONG tmp = 0;
|
||||||
InterlockedExchange (&tmp, 0);
|
InterlockedExchange (&tmp, 0);
|
||||||
DDSRT_WARNING_MSVC_ON(28113)
|
DDSRT_WARNING_MSVC_ON(28113)
|
||||||
}
|
}
|
||||||
inline void ddsrt_atomic_fence_ldld (void) {
|
inline void ddsrt_atomic_fence_ldld (void) {
|
||||||
#if !(defined _M_IX86 || defined _M_X64)
|
#if !(defined _M_IX86 || defined _M_X64)
|
||||||
|
|
20
src/ddsrt/include/dds/ddsrt/countargs.h
Normal file
20
src/ddsrt/include/dds/ddsrt/countargs.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2019 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 DDSRT_COUNTARGS_H
|
||||||
|
#define DDSRT_COUNTARGS_H
|
||||||
|
|
||||||
|
#define DDSRT_COUNT_ARGS_MSVC_WORKAROUND(x) x
|
||||||
|
#define DDSRT_COUNT_ARGS(...) DDSRT_COUNT_ARGS1 (__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1,0)
|
||||||
|
#define DDSRT_COUNT_ARGS1(...) DDSRT_COUNT_ARGS_MSVC_WORKAROUND (DDSRT_COUNT_ARGS_ARGN (__VA_ARGS__))
|
||||||
|
#define DDSRT_COUNT_ARGS_ARGN(a,b,c,d,e,f,g,h,i,j,n,...) n
|
||||||
|
|
||||||
|
#endif
|
|
@ -24,11 +24,7 @@ extern "C" {
|
||||||
* @brief Get value for environment variable.
|
* @brief Get value for environment variable.
|
||||||
*
|
*
|
||||||
* @param[in] name Environment variable name.
|
* @param[in] name Environment variable name.
|
||||||
* @param[in] buf Buffer to write value to.
|
* @param[out] value Alias to value of environment variable - must not be modified
|
||||||
* @param[in] sz Size of buffer.
|
|
||||||
* @param[out] reqsz Number of bytes written (excluding the terminating null
|
|
||||||
* byte), or would have been written would @buf have been
|
|
||||||
* sufficiently large enough.
|
|
||||||
*
|
*
|
||||||
* @returns A dds_return_t indicating success or failure.
|
* @returns A dds_return_t indicating success or failure.
|
||||||
*
|
*
|
||||||
|
|
|
@ -106,7 +106,7 @@ ddsrt_proc_create(
|
||||||
* See ddsrt_proc_waitpids() for waiting on all child processes.
|
* See ddsrt_proc_waitpids() for waiting on all child processes.
|
||||||
*
|
*
|
||||||
* @param[in] pid Process ID (PID) to get the exit code from.
|
* @param[in] pid Process ID (PID) to get the exit code from.
|
||||||
* @param[in] timemout Time within the process is expected to finish.
|
* @param[in] timeout Time within the process is expected to finish.
|
||||||
* @param[out] code The exit code of the process.
|
* @param[out] code The exit code of the process.
|
||||||
*
|
*
|
||||||
* @returns A dds_return_t indicating success or failure.
|
* @returns A dds_return_t indicating success or failure.
|
||||||
|
@ -145,7 +145,7 @@ ddsrt_proc_waitpid(
|
||||||
*
|
*
|
||||||
* See ddsrt_proc_waitpid() for waiting on a specific child process.
|
* See ddsrt_proc_waitpid() for waiting on a specific child process.
|
||||||
*
|
*
|
||||||
* @param[in] timemout Time within a process is expected to finish.
|
* @param[in] timeout Time within a process is expected to finish.
|
||||||
* @param[out] pid Process ID (PID) of the finished process.
|
* @param[out] pid Process ID (PID) of the finished process.
|
||||||
* @param[out] code The exit code of the process.
|
* @param[out] code The exit code of the process.
|
||||||
*
|
*
|
||||||
|
|
|
@ -84,7 +84,7 @@ typedef int32_t dds_return_t;
|
||||||
/**
|
/**
|
||||||
* @brief Takes the error value and outputs a string corresponding to it.
|
* @brief Takes the error value and outputs a string corresponding to it.
|
||||||
*
|
*
|
||||||
* @param[in] err Error value to be converted to a string
|
* @param[in] ret Error value to be converted to a string
|
||||||
*
|
*
|
||||||
* @returns String corresponding to the error value
|
* @returns String corresponding to the error value
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -247,7 +247,7 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* @param[in] name Host name to resolve.
|
* @param[in] name Host name to resolve.
|
||||||
* @param[in] af Address family, either AF_INET, AF_INET6 or AF_UNSPEC.
|
* @param[in] af Address family, either AF_INET, AF_INET6 or AF_UNSPEC.
|
||||||
* @param[out] hent Structure of type ddsrt_hostent_t.
|
* @param[out] hentp Structure of type ddsrt_hostent_t.
|
||||||
*
|
*
|
||||||
* @returns A dds_return_t indicating success or failure.
|
* @returns A dds_return_t indicating success or failure.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
* Copyright(c) 2019 ADLINK Technology Limited and others
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials are made available under the
|
* This program and the accompanying materials are made available under the
|
||||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
@ -9,29 +9,34 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
#ifndef Q_STATIC_ASSERT_H
|
#ifndef DDSRT_STATIC_ASSERT_H
|
||||||
#define Q_STATIC_ASSERT_H
|
#define DDSRT_STATIC_ASSERT_H
|
||||||
|
|
||||||
/* There are many tricks to use a constant expression to yield an
|
/* There are many tricks to use a constant expression to yield an
|
||||||
illegal type or expression at compile time, such as zero-sized
|
illegal type or expression at compile time, such as zero-sized
|
||||||
arrays and duplicate case or enum labels. So this is but one of the
|
arrays and duplicate case or enum labels. So this is but one of the
|
||||||
many tricks. */
|
many tricks. */
|
||||||
|
|
||||||
|
#define DDSRT_STATIC_ASSERT2(line, pred) \
|
||||||
|
struct static_assert_##line { \
|
||||||
|
char cond[(pred) ? 1 : -1]; \
|
||||||
|
}
|
||||||
|
#define DDSRT_STATIC_ASSERT1(line, pred) \
|
||||||
|
DDSRT_STATIC_ASSERT2 (line, pred)
|
||||||
|
#define DDSRT_STATIC_ASSERT(pred) \
|
||||||
|
DDSRT_STATIC_ASSERT1 (__LINE__, pred)
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
#define DDSRT_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case (pred): ; } } while (0)
|
||||||
#define Q_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case pred: ; } } while (0)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Temporarily disabling warning C6326: Potential comparison of a
|
/* Temporarily disabling warning C6326: Potential comparison of a
|
||||||
constant with another constant. */
|
constant with another constant. */
|
||||||
#define Q_STATIC_ASSERT_CODE(pred) do { \
|
#define DDSRT_STATIC_ASSERT_CODE(pred) do { \
|
||||||
__pragma (warning (push)) \
|
__pragma (warning (push)) \
|
||||||
__pragma (warning (disable : 6326)) \
|
__pragma (warning (disable : 6326)) \
|
||||||
switch(0) { case 0: case pred: ; } \
|
switch(0) { case 0: case (pred): ; } \
|
||||||
__pragma (warning (pop)) \
|
__pragma (warning (pop)) \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* Q_STATIC_ASSERT_H */
|
#endif
|
|
@ -57,7 +57,7 @@ ddsrt_nonnull((1,2));
|
||||||
*
|
*
|
||||||
* @param[in] str String to split into tokens.
|
* @param[in] str String to split into tokens.
|
||||||
* @param[in] delim Characters that delimit a token.
|
* @param[in] delim Characters that delimit a token.
|
||||||
* @param[inout] saveptr Pointer to a char * used internally.
|
* @param[in,out] saveptr Pointer to a char * used internally.
|
||||||
*
|
*
|
||||||
* @returns The next token or NULL if there are no more tokens.
|
* @returns The next token or NULL if there are no more tokens.
|
||||||
*/
|
*/
|
||||||
|
@ -74,7 +74,7 @@ ddsrt_strtok_r(
|
||||||
* @delim. The delimiter is overwritten with a null byte, terminating the
|
* @delim. The delimiter is overwritten with a null byte, terminating the
|
||||||
* token and @stringp is updated to point past the delimiter.
|
* token and @stringp is updated to point past the delimiter.
|
||||||
*
|
*
|
||||||
* @param[inout] stringp String to extract token from.
|
* @param[in,out] stringp String to extract token from.
|
||||||
* @param[in] delim Characters that delimit a token.
|
* @param[in] delim Characters that delimit a token.
|
||||||
*
|
*
|
||||||
* @returns The original value of @stringp.
|
* @returns The original value of @stringp.
|
||||||
|
@ -153,7 +153,7 @@ ddsrt_nonnull((1,2));
|
||||||
* string is truncated if there is not enough space. The resulting string
|
* string is truncated if there is not enough space. The resulting string
|
||||||
* guaranteed to be null terminated if there is space.
|
* guaranteed to be null terminated if there is space.
|
||||||
*
|
*
|
||||||
* @param[inout] dest Destination buffer.
|
* @param[in,out] dest Destination buffer.
|
||||||
* @param[in] src Null terminated string to append to dest.
|
* @param[in] src Null terminated string to append to dest.
|
||||||
* @param[in] size Number of bytes available in dest.
|
* @param[in] size Number of bytes available in dest.
|
||||||
*
|
*
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include "dds/ddsrt/sync.h"
|
#include "dds/ddsrt/sync.h"
|
||||||
#include "dds/ddsrt/time.h"
|
#include "dds/ddsrt/time.h"
|
||||||
#include "dds/ddsrt/process.h"
|
#include "dds/ddsrt/process.h"
|
||||||
|
#include "dds/ddsrt/static_assert.h"
|
||||||
|
|
||||||
#define N DDSRT_MT19937_N
|
#define N DDSRT_MT19937_N
|
||||||
#define M 397
|
#define M 397
|
||||||
|
@ -186,9 +187,7 @@ void ddsrt_random_init (void)
|
||||||
if (!ddsrt_prng_makeseed (&seed))
|
if (!ddsrt_prng_makeseed (&seed))
|
||||||
{
|
{
|
||||||
/* Poor man's initialisation */
|
/* Poor man's initialisation */
|
||||||
struct lengthof_seed_large_enough {
|
DDSRT_STATIC_ASSERT (sizeof (seed.key) / sizeof (seed.key[0]) >= 3);
|
||||||
char ok[sizeof (seed.key) / sizeof (seed.key[0]) >= 3 ? 1 : -1];
|
|
||||||
};
|
|
||||||
memset (&seed, 0, sizeof (seed));
|
memset (&seed, 0, sizeof (seed));
|
||||||
dds_time_t now = dds_time ();
|
dds_time_t now = dds_time ();
|
||||||
seed.key[0] = (uint32_t) ddsrt_getpid ();
|
seed.key[0] = (uint32_t) ddsrt_getpid ();
|
||||||
|
|
|
@ -305,9 +305,9 @@ static char *unescape_into_utf8 (char *dst, unsigned cp)
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
|
||||||
static int unescape_insitu (char *buffer, size_t *n)
|
static int unescape_insitu (char *buffer, size_t *n)
|
||||||
{
|
{
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
const char *src = buffer;
|
const char *src = buffer;
|
||||||
char const * const srcend = buffer + *n;
|
char const * const srcend = buffer + *n;
|
||||||
char *dst = buffer;
|
char *dst = buffer;
|
||||||
|
@ -361,8 +361,8 @@ static int unescape_insitu (char *buffer, size_t *n)
|
||||||
}
|
}
|
||||||
*n = (size_t) (dst - buffer);
|
*n = (size_t) (dst - buffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
|
||||||
|
|
||||||
static void discard_payload (struct ddsrt_xmlp_state *st)
|
static void discard_payload (struct ddsrt_xmlp_state *st)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue