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_VALUE YES)
|
||||
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES)
|
||||
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DOCUMENTATION_COMMENTS YES)
|
||||
endif()
|
||||
|
||||
# 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_builtintopic.h
|
||||
dds__serdata_builtintopic.h
|
||||
dds__get_status.h
|
||||
)
|
||||
|
||||
generate_export_header(
|
||||
|
|
|
@ -313,7 +313,7 @@ dds_delete(dds_entity_t entity);
|
|||
* For instance, it will return the Publisher that was used when
|
||||
* 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.
|
||||
*
|
||||
|
@ -361,7 +361,7 @@ dds_get_subscriber(dds_entity_t entity);
|
|||
* For instance, it will return the DataReader that was used when
|
||||
* 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.
|
||||
*
|
||||
|
@ -502,7 +502,7 @@ dds_get_status_changes(dds_entity_t entity, uint32_t *status);
|
|||
* This operation returns the status enabled on the entity
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
|
@ -952,6 +952,8 @@ dds_create_topic(
|
|||
const dds_qos_t *qos,
|
||||
const dds_listener_t *listener);
|
||||
|
||||
struct ddsi_sertopic;
|
||||
struct nn_plist;
|
||||
/**
|
||||
* @brief Creates a new topic with arbitrary type handling.
|
||||
*
|
||||
|
@ -972,8 +974,6 @@ dds_create_topic(
|
|||
* Either participant, descriptor, name or qos is invalid.
|
||||
*/
|
||||
/* TODO: Check list of retcodes is complete. */
|
||||
struct ddsi_sertopic;
|
||||
struct nn_plist;
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_create_topic_arbitrary (
|
||||
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
|
||||
*
|
||||
* @param[in] writer The writer entity.
|
||||
* @param[in] cdr CDR serialized value to be written.
|
||||
* @param[in] size Size (in bytes) of CDR encoded data to be written.
|
||||
* @param[in] serdata CDR serialized value to be written.
|
||||
*
|
||||
* @returns A dds_return_t indicating success or failure.
|
||||
*/
|
||||
|
@ -2604,7 +2603,7 @@ dds_take_mask_wl(
|
|||
uint32_t maxs,
|
||||
uint32_t mask);
|
||||
|
||||
DDS_EXPORT int
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_takecdr(
|
||||
dds_entity_t reader_or_condition,
|
||||
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.
|
||||
* 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] 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.
|
||||
*
|
||||
* @param[in,out] dst - Pointer to the destination qos structure
|
||||
* @param[in] src - Pointer to the source qos structure
|
||||
* @param[in,out] a - Pointer to the destination qos structure
|
||||
* @param[in] b - Pointer to the source qos structure
|
||||
*/
|
||||
DDS_EXPORT bool
|
||||
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
|
||||
*
|
||||
* @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_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
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
|
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__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_listener_t *listener);
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ extern "C" {
|
|||
|
||||
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 void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic * st);
|
||||
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) ddsrt_nonnull_all;
|
||||
|
||||
#ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
||||
#define DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
||||
|
|
|
@ -104,12 +104,12 @@ dds_domain;
|
|||
struct dds_entity;
|
||||
typedef struct dds_entity_deriver {
|
||||
/* 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. */
|
||||
dds_return_t (*delete)(struct dds_entity *e);
|
||||
dds_return_t (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled);
|
||||
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) ddsrt_nonnull_all;
|
||||
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;
|
||||
|
||||
|
|
|
@ -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_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;
|
||||
|
||||
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;
|
||||
dds_participant_unlock(p);
|
||||
|
|
|
@ -16,17 +16,13 @@
|
|||
#include "dds__subscriber.h"
|
||||
#include "dds__publisher.h"
|
||||
|
||||
dds_return_t
|
||||
dds_begin_coherent(
|
||||
dds_entity_t entity)
|
||||
dds_return_t 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 };
|
||||
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_end_coherent(
|
||||
dds_entity_t entity)
|
||||
dds_return_t 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 };
|
||||
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);
|
||||
|
|
|
@ -12,27 +12,24 @@
|
|||
#include "dds__domain.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;
|
||||
}
|
||||
|
||||
const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALIZER
|
||||
(
|
||||
offsetof (dds_domain, m_node),
|
||||
offsetof (dds_domain, m_id),
|
||||
(int (*) (const void *, const void *)) dds_domain_compare,
|
||||
0
|
||||
);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
domain = dds_domain_find_locked (id);
|
||||
if (domain == NULL)
|
||||
|
@ -47,7 +44,7 @@ dds_domain * dds_domain_create (dds_domainid_t id)
|
|||
return domain;
|
||||
}
|
||||
|
||||
void dds_domain_free (dds_domain * domain)
|
||||
void dds_domain_free (dds_domain *domain)
|
||||
{
|
||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||
if (--domain->m_refc == 0)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "dds/ddsi/q_entity.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)
|
||||
{
|
||||
|
|
|
@ -23,396 +23,307 @@
|
|||
#include "dds/ddsi/q_thread.h"
|
||||
#include "dds/ddsi/q_globals.h"
|
||||
|
||||
dds_return_t
|
||||
dds_writedispose(
|
||||
dds_entity_t writer,
|
||||
const void *data)
|
||||
dds_return_t 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_dispose(
|
||||
dds_entity_t writer,
|
||||
const void *data)
|
||||
dds_return_t 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_dispose_ih(
|
||||
dds_entity_t writer,
|
||||
dds_instance_handle_t handle)
|
||||
dds_return_t 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*
|
||||
dds_instance_find(
|
||||
const dds_topic *topic,
|
||||
const void *data,
|
||||
const bool create)
|
||||
static struct ddsi_tkmap_instance *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_tkmap_instance * inst = ddsi_tkmap_find (sd, false, create);
|
||||
ddsi_serdata_unref (sd);
|
||||
return inst;
|
||||
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);
|
||||
ddsi_serdata_unref (sd);
|
||||
return inst;
|
||||
}
|
||||
|
||||
static void
|
||||
dds_instance_remove(
|
||||
const dds_topic *topic,
|
||||
const void *data,
|
||||
dds_instance_handle_t handle)
|
||||
static void dds_instance_remove (const dds_topic *topic, const void *data, dds_instance_handle_t handle)
|
||||
{
|
||||
struct ddsi_tkmap_instance * inst;
|
||||
|
||||
if (handle != DDS_HANDLE_NIL)
|
||||
{
|
||||
inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (data);
|
||||
inst = dds_instance_find (topic, data, false);
|
||||
}
|
||||
if (inst)
|
||||
{
|
||||
ddsi_tkmap_instance_unref (inst);
|
||||
}
|
||||
struct ddsi_tkmap_instance *inst;
|
||||
if (handle != DDS_HANDLE_NIL)
|
||||
inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
|
||||
else
|
||||
{
|
||||
assert (data);
|
||||
inst = dds_instance_find (topic, data, false);
|
||||
}
|
||||
if (inst)
|
||||
{
|
||||
ddsi_tkmap_instance_unref (inst);
|
||||
}
|
||||
}
|
||||
|
||||
static const dds_topic *dds_instance_info (dds_entity *e)
|
||||
{
|
||||
const dds_topic *topic;
|
||||
switch (dds_entity_kind (e))
|
||||
{
|
||||
case DDS_KIND_READER:
|
||||
topic = ((dds_reader*) e)->m_topic;
|
||||
break;
|
||||
case DDS_KIND_WRITER:
|
||||
topic = ((dds_writer*) e)->m_topic;
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
topic = NULL;
|
||||
}
|
||||
return topic;
|
||||
const dds_topic *topic;
|
||||
switch (dds_entity_kind (e))
|
||||
{
|
||||
case DDS_KIND_READER:
|
||||
topic = ((dds_reader*) e)->m_topic;
|
||||
break;
|
||||
case DDS_KIND_WRITER:
|
||||
topic = ((dds_writer*) e)->m_topic;
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
topic = NULL;
|
||||
}
|
||||
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;
|
||||
dds_return_t rc;
|
||||
dds_entity *w_or_r;
|
||||
const dds_topic *topic;
|
||||
dds_entity *w_or_r;
|
||||
|
||||
rc = dds_entity_lock(e, DDS_KIND_WRITER, &w_or_r);
|
||||
if (rc == DDS_RETCODE_ILLEGAL_OPERATION)
|
||||
{
|
||||
rc = dds_entity_lock(e, DDS_KIND_READER, &w_or_r);
|
||||
}
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
topic = dds_instance_info(w_or_r);
|
||||
dds_entity_unlock(w_or_r);
|
||||
return topic;
|
||||
if (dds_entity_lock (e, DDS_KIND_DONTCARE, &w_or_r) != DDS_RETCODE_OK)
|
||||
return NULL;
|
||||
|
||||
switch (dds_entity_kind (w_or_r))
|
||||
{
|
||||
case DDS_KIND_WRITER:
|
||||
case DDS_KIND_READER:
|
||||
topic = dds_instance_info (w_or_r);
|
||||
break;
|
||||
default:
|
||||
topic = NULL;
|
||||
break;
|
||||
}
|
||||
dds_entity_unlock (w_or_r);
|
||||
return topic;
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_register_instance(
|
||||
dds_entity_t writer,
|
||||
dds_instance_handle_t *handle,
|
||||
const void *data)
|
||||
dds_return_t dds_register_instance (dds_entity_t writer, dds_instance_handle_t *handle, const void *data)
|
||||
{
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
struct ddsi_tkmap_instance * inst;
|
||||
dds_writer *wr;
|
||||
dds_return_t ret;
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_writer *wr;
|
||||
dds_return_t ret;
|
||||
|
||||
if(data == NULL){
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
if(handle == NULL){
|
||||
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:
|
||||
if (data == NULL || handle == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||
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_unregister_instance(
|
||||
dds_entity_t writer,
|
||||
const void *data)
|
||||
dds_return_t 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_unregister_instance_ih(
|
||||
dds_entity_t writer,
|
||||
dds_instance_handle_t handle)
|
||||
dds_return_t 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_unregister_instance_ts(
|
||||
dds_entity_t writer,
|
||||
const void *data,
|
||||
dds_time_t timestamp)
|
||||
dds_return_t dds_unregister_instance_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_RETCODE_OK;
|
||||
bool autodispose = true;
|
||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||
dds_writer *wr;
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_return_t ret;
|
||||
bool autodispose = true;
|
||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||
dds_writer *wr;
|
||||
|
||||
if (data == NULL){
|
||||
ret = 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 (data == NULL || timestamp < 0)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
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);
|
||||
err:
|
||||
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||
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_unregister_instance_ih_ts(
|
||||
dds_entity_t writer,
|
||||
dds_instance_handle_t handle,
|
||||
dds_time_t timestamp)
|
||||
dds_return_t 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 ();
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool autodispose = true;
|
||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||
dds_writer *wr;
|
||||
struct ddsi_tkmap_instance *tk;
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool autodispose = true;
|
||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||
dds_writer *wr;
|
||||
struct ddsi_tkmap_instance *tk;
|
||||
|
||||
ret = dds_writer_lock(writer, &wr);
|
||||
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:
|
||||
if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||
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_writedispose_ts(
|
||||
dds_entity_t writer,
|
||||
const void *data,
|
||||
dds_time_t timestamp)
|
||||
dds_return_t dds_writedispose_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;
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
||||
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
|
||||
dds_dispose_impl(
|
||||
dds_writer *wr,
|
||||
const void *data,
|
||||
dds_instance_handle_t handle,
|
||||
dds_time_t timestamp)
|
||||
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;
|
||||
|
||||
static dds_return_t dds_dispose_impl (dds_writer *wr, const void *data, dds_instance_handle_t handle, dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret;
|
||||
assert(thread_is_awake ());
|
||||
assert(wr);
|
||||
ret = dds_write_impl(wr, data, timestamp, DDS_WR_ACTION_DISPOSE);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
dds_instance_remove (wr->m_topic, data, handle);
|
||||
}
|
||||
dds_return_t ret;
|
||||
assert (thread_is_awake ());
|
||||
if ((ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_DISPOSE)) == DDS_RETCODE_OK)
|
||||
dds_instance_remove (wr->m_topic, data, handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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_dispose_ts(
|
||||
dds_entity_t writer,
|
||||
const void *data,
|
||||
dds_time_t timestamp)
|
||||
dds_return_t 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 ();
|
||||
dds_return_t ret;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
||||
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_dispose_ih_ts(
|
||||
dds_entity_t writer,
|
||||
dds_instance_handle_t handle,
|
||||
dds_time_t timestamp)
|
||||
dds_instance_handle_t dds_lookup_instance (dds_entity_t entity, const void *data)
|
||||
{
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_return_t ret;
|
||||
dds_writer *wr;
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_instance_handle_t ih = DDS_HANDLE_NIL;
|
||||
const dds_topic *topic;
|
||||
struct ddsi_serdata *sd;
|
||||
|
||||
ret = dds_writer_lock(writer, &wr);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
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);
|
||||
}
|
||||
if (data == NULL)
|
||||
return DDS_HANDLE_NIL;
|
||||
|
||||
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_lookup_instance(
|
||||
dds_entity_t entity,
|
||||
const void *data)
|
||||
dds_instance_handle_t dds_instance_lookup (dds_entity_t entity, const void *data)
|
||||
{
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
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;
|
||||
return dds_lookup_instance (entity, data);
|
||||
}
|
||||
|
||||
dds_instance_handle_t
|
||||
dds_instance_lookup (
|
||||
dds_entity_t entity,
|
||||
const void *data)
|
||||
dds_return_t dds_instance_get_key (dds_entity_t entity, dds_instance_handle_t ih, void *data)
|
||||
{
|
||||
return dds_lookup_instance(entity, data);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_instance_get_key(
|
||||
dds_entity_t entity,
|
||||
dds_instance_handle_t ih,
|
||||
void *data)
|
||||
{
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_return_t ret;
|
||||
const dds_topic * topic;
|
||||
struct ddsi_tkmap_instance * tk;
|
||||
|
||||
if(data == NULL){
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
topic = dds_instance_info_by_hdl (entity);
|
||||
if(topic == NULL){
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
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;
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_return_t ret;
|
||||
const dds_topic *topic;
|
||||
struct ddsi_tkmap_instance *tk;
|
||||
|
||||
if (data == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
if ((topic = dds_instance_info_by_hdl (entity)) == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
thread_state_awake (ts1);
|
||||
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, ih)) == NULL)
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
thread_state_asleep (ts1);
|
||||
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)
|
||||
{
|
||||
dds_merge_listener(dst, src);
|
||||
dds_merge_listener (dst, src);
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Setters
|
||||
************************************************************************************************/
|
||||
|
||||
void
|
||||
dds_lset_data_available (dds_listener_t * __restrict listener, dds_on_data_available_fn callback)
|
||||
void dds_lset_data_available (dds_listener_t * __restrict listener, dds_on_data_available_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_data_available = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_data_available = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_data_on_readers (dds_listener_t * __restrict listener, dds_on_data_on_readers_fn callback)
|
||||
void dds_lset_data_on_readers (dds_listener_t * __restrict listener, dds_on_data_on_readers_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_data_on_readers = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_data_on_readers = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_inconsistent_topic (dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn callback)
|
||||
void dds_lset_inconsistent_topic (dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_inconsistent_topic = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_inconsistent_topic = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_liveliness_changed (dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn callback)
|
||||
void dds_lset_liveliness_changed (dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_liveliness_changed = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_liveliness_changed = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_liveliness_lost (dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn callback)
|
||||
void dds_lset_liveliness_lost (dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_liveliness_lost = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_liveliness_lost = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_offered_deadline_missed (dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn callback)
|
||||
void dds_lset_offered_deadline_missed (dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_offered_deadline_missed = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_offered_deadline_missed = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_offered_incompatible_qos (dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn callback)
|
||||
void dds_lset_offered_incompatible_qos (dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_offered_incompatible_qos = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_offered_incompatible_qos = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_publication_matched (dds_listener_t * __restrict listener, dds_on_publication_matched_fn callback)
|
||||
void dds_lset_publication_matched (dds_listener_t * __restrict listener, dds_on_publication_matched_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_publication_matched = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_publication_matched = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_requested_deadline_missed (dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn callback)
|
||||
void dds_lset_requested_deadline_missed (dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_requested_deadline_missed = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_requested_deadline_missed = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_requested_incompatible_qos (dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn callback)
|
||||
void dds_lset_requested_incompatible_qos (dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_requested_incompatible_qos = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_requested_incompatible_qos = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_sample_lost (dds_listener_t * __restrict listener, dds_on_sample_lost_fn callback)
|
||||
void dds_lset_sample_lost (dds_listener_t * __restrict listener, dds_on_sample_lost_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_sample_lost = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_sample_lost = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_sample_rejected (dds_listener_t * __restrict listener, dds_on_sample_rejected_fn callback)
|
||||
void dds_lset_sample_rejected (dds_listener_t * __restrict listener, dds_on_sample_rejected_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_sample_rejected = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_sample_rejected = callback;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_subscription_matched (dds_listener_t * __restrict listener, dds_on_subscription_matched_fn callback)
|
||||
void dds_lset_subscription_matched (dds_listener_t * __restrict listener, dds_on_subscription_matched_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
listener->on_subscription_matched = callback;
|
||||
} else {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
}
|
||||
if (listener)
|
||||
listener->on_subscription_matched = callback;
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Getters
|
||||
************************************************************************************************/
|
||||
|
||||
void
|
||||
dds_lget_data_available (const dds_listener_t * __restrict listener, dds_on_data_available_fn *callback)
|
||||
void dds_lget_data_available (const dds_listener_t * __restrict listener, dds_on_data_available_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_data_available;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_data_on_readers (const dds_listener_t * __restrict listener, dds_on_data_on_readers_fn *callback)
|
||||
void dds_lget_data_on_readers (const dds_listener_t * __restrict listener, dds_on_data_on_readers_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_data_on_readers;
|
||||
}
|
||||
|
||||
void dds_lget_inconsistent_topic (const dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_inconsistent_topic;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_liveliness_changed (const dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn *callback)
|
||||
void dds_lget_liveliness_changed (const dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_liveliness_changed;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_liveliness_lost (const dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn *callback)
|
||||
void dds_lget_liveliness_lost (const dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_liveliness_lost;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_offered_deadline_missed (const dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn *callback)
|
||||
void dds_lget_offered_deadline_missed (const dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_offered_deadline_missed;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_offered_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn *callback)
|
||||
void dds_lget_offered_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_offered_incompatible_qos;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_publication_matched (const dds_listener_t * __restrict listener, dds_on_publication_matched_fn *callback)
|
||||
void dds_lget_publication_matched (const dds_listener_t * __restrict listener, dds_on_publication_matched_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_publication_matched;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_requested_deadline_missed (const dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn *callback)
|
||||
void dds_lget_requested_deadline_missed (const dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_requested_deadline_missed;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_requested_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn *callback)
|
||||
void dds_lget_requested_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_requested_incompatible_qos;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_sample_lost (const dds_listener_t *__restrict listener, dds_on_sample_lost_fn *callback)
|
||||
void dds_lget_sample_lost (const dds_listener_t *__restrict listener, dds_on_sample_lost_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_sample_lost;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_sample_rejected (const dds_listener_t *__restrict listener, dds_on_sample_rejected_fn *callback)
|
||||
void dds_lget_sample_rejected (const dds_listener_t *__restrict listener, dds_on_sample_rejected_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_sample_rejected;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_subscription_matched (const dds_listener_t * __restrict listener, dds_on_subscription_matched_fn *callback)
|
||||
void dds_lget_subscription_matched (const dds_listener_t * __restrict listener, dds_on_subscription_matched_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR("Argument callback is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR("Argument listener is NULL\n");
|
||||
return ;
|
||||
}
|
||||
if (callback && listener)
|
||||
*callback = listener->on_subscription_matched;
|
||||
}
|
||||
|
|
|
@ -21,260 +21,183 @@
|
|||
#include "dds__participant.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 */
|
||||
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;
|
||||
|
||||
if (mask & ~(DDS_PARTICIPANT_STATUS_MASK)) {
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return (mask & ~DDS_PARTICIPANT_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_participant_delete(
|
||||
dds_entity *e)
|
||||
static dds_return_t dds_participant_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds_participant_delete (dds_entity *e)
|
||||
{
|
||||
dds_entity *prev = NULL;
|
||||
dds_entity *iter;
|
||||
assert (dds_entity_kind (e) == DDS_KIND_PARTICIPANT);
|
||||
|
||||
assert(e);
|
||||
assert(dds_entity_kind(e) == DDS_KIND_PARTICIPANT);
|
||||
thread_state_awake (lookup_thread_state ());
|
||||
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);
|
||||
iter = dds_pp_head;
|
||||
while (iter) {
|
||||
if (iter == e) {
|
||||
if (prev) {
|
||||
prev->m_next = iter->m_next;
|
||||
} else {
|
||||
dds_pp_head = iter->m_next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = iter;
|
||||
iter = iter->m_next;
|
||||
for (dds_entity *iter = dds_pp_head; iter; iter = iter->m_next)
|
||||
{
|
||||
if (iter->m_domainid == domain_id)
|
||||
{
|
||||
if ((size_t) ret < size)
|
||||
participants[ret] = iter->m_hdllink.hdl;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||
|
||||
assert (iter);
|
||||
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
|
||||
/* 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;
|
||||
}
|
||||
ddsrt_mutex_unlock (init_mutex);
|
||||
ddsrt_fini ();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -13,153 +13,102 @@
|
|||
#include <string.h>
|
||||
#include "dds/ddsrt/misc.h"
|
||||
#include "dds__listener.h"
|
||||
#include "dds__participant.h"
|
||||
#include "dds__publisher.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds/ddsi/q_entity.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
|
||||
dds_publisher_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
static dds_return_t dds_publisher_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds_publisher_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||
{
|
||||
(void)e;
|
||||
(void)i;
|
||||
/* TODO: Get/generate proper handle. */
|
||||
DDS_ERROR("Getting publisher instance handle is not supported\n");
|
||||
/* FIXME: Get/generate proper handle. */
|
||||
(void) e;
|
||||
(void) i;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
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_ERROR("Invalid status mask\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
dds_entity_t dds_create_publisher (dds_entity_t participant, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||
{
|
||||
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;
|
||||
|
||||
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_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)
|
||||
dds_return_t dds_suspend (dds_entity_t publisher)
|
||||
{
|
||||
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_resume(
|
||||
dds_entity_t publisher)
|
||||
dds_return_t dds_resume (dds_entity_t publisher)
|
||||
{
|
||||
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_wait_for_acks(
|
||||
dds_entity_t publisher_or_writer,
|
||||
dds_duration_t timeout)
|
||||
dds_return_t dds_wait_for_acks (dds_entity_t publisher_or_writer, dds_duration_t timeout)
|
||||
{
|
||||
if (timeout < 0)
|
||||
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);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_publisher_begin_coherent(
|
||||
dds_entity_t e)
|
||||
dds_return_t dds_publisher_begin_coherent (dds_entity_t publisher)
|
||||
{
|
||||
/* TODO: CHAM-124 Currently unsupported. */
|
||||
(void)e;
|
||||
DDS_ERROR("Using coherency to get a coherent data set is not being supported yet\n");
|
||||
return DDS_RETCODE_UNSUPPORTED;
|
||||
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_publisher_end_coherent(
|
||||
dds_entity_t e)
|
||||
dds_return_t dds_publisher_end_coherent (dds_entity_t publisher)
|
||||
{
|
||||
/* TODO: CHAM-124 Currently unsupported. */
|
||||
(void)e;
|
||||
DDS_ERROR("Using coherency to get a coherent data set is not being supported yet\n");
|
||||
return DDS_RETCODE_UNSUPPORTED;
|
||||
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,32 +21,27 @@
|
|||
#include "dds/ddsi/ddsi_serdata.h"
|
||||
#include "dds/ddsi/ddsi_sertopic.h"
|
||||
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_create_querycondition(
|
||||
dds_entity_t reader,
|
||||
uint32_t mask,
|
||||
dds_querycondition_filter_fn filter)
|
||||
dds_entity_t 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_return_t rc;
|
||||
dds_reader *r;
|
||||
|
||||
rc = dds_reader_lock(reader, &r);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_readcond *cond = dds_create_readcond(r, DDS_KIND_COND_QUERY, mask, filter);
|
||||
assert(cond);
|
||||
const bool success = (cond->m_entity.m_deriver.delete != 0);
|
||||
dds_reader_unlock(r);
|
||||
if (success) {
|
||||
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;
|
||||
dds_readcond *cond = dds_create_readcond (r, DDS_KIND_COND_QUERY, mask, filter);
|
||||
assert (cond);
|
||||
const bool success = (cond->m_entity.m_deriver.delete != 0);
|
||||
dds_reader_unlock (r);
|
||||
if (success)
|
||||
hdl = cond->m_entity.m_hdllink.hdl;
|
||||
else
|
||||
{
|
||||
dds_delete (cond->m_entity.m_hdllink.hdl);
|
||||
hdl = DDS_RETCODE_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
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_thread.h"
|
||||
|
||||
static dds_return_t
|
||||
dds_readcond_delete(
|
||||
dds_entity *e)
|
||||
static dds_return_t dds_readcond_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds_readcond_delete (dds_entity *e)
|
||||
{
|
||||
dds_rhc_remove_readcondition((dds_readcond*)e);
|
||||
return DDS_RETCODE_OK;
|
||||
dds_rhc_remove_readcondition ((dds_readcond *) e);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
dds_readcond*
|
||||
dds_create_readcond(
|
||||
dds_reader *rd,
|
||||
dds_entity_kind_t kind,
|
||||
uint32_t mask,
|
||||
dds_querycondition_filter_fn filter)
|
||||
dds_readcond *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));
|
||||
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);
|
||||
cond->m_entity.m_deriver.delete = dds_readcond_delete;
|
||||
cond->m_rhc = rd->m_rd->rhc;
|
||||
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
|
||||
cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
|
||||
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
|
||||
cond->m_rd_guid = rd->m_entity.m_guid;
|
||||
if (kind == DDS_KIND_COND_QUERY) {
|
||||
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
|
||||
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. */
|
||||
cond->m_entity.m_deriver.delete = 0;
|
||||
}
|
||||
return cond;
|
||||
dds_readcond *cond = dds_alloc (sizeof (*cond));
|
||||
assert ((kind == DDS_KIND_COND_READ && filter == 0) || (kind == DDS_KIND_COND_QUERY && filter != 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_rhc = rd->m_rd->rhc;
|
||||
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
|
||||
cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
|
||||
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
|
||||
cond->m_rd_guid = rd->m_entity.m_guid;
|
||||
if (kind == DDS_KIND_COND_QUERY)
|
||||
{
|
||||
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
|
||||
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. */
|
||||
cond->m_entity.m_deriver.delete = 0;
|
||||
}
|
||||
return cond;
|
||||
}
|
||||
|
||||
dds_entity_t
|
||||
dds_create_readcondition(
|
||||
dds_entity_t reader,
|
||||
uint32_t mask)
|
||||
dds_entity_t 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_reader * rd;
|
||||
dds_return_t rc;
|
||||
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
return hdl;
|
||||
}
|
||||
}
|
||||
|
||||
dds_entity_t dds_get_datareader (dds_entity_t condition)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string.h>
|
||||
#include "dds/dds.h"
|
||||
#include "dds/version.h"
|
||||
#include "dds/ddsrt/static_assert.h"
|
||||
#include "dds__subscriber.h"
|
||||
#include "dds__reader.h"
|
||||
#include "dds__listener.h"
|
||||
|
@ -20,135 +21,96 @@
|
|||
#include "dds__init.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds__topic.h"
|
||||
#include "dds__get_status.h"
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_thread.h"
|
||||
#include "dds/ddsi/q_globals.h"
|
||||
#include "dds__builtin.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 \
|
||||
DDS_SAMPLE_REJECTED_STATUS |\
|
||||
DDS_LIVELINESS_CHANGED_STATUS |\
|
||||
DDS_REQUESTED_DEADLINE_MISSED_STATUS |\
|
||||
DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS |\
|
||||
DDS_DATA_AVAILABLE_STATUS |\
|
||||
DDS_SAMPLE_LOST_STATUS |\
|
||||
DDS_SUBSCRIPTION_MATCHED_STATUS
|
||||
(DDS_SAMPLE_REJECTED_STATUS |\
|
||||
DDS_LIVELINESS_CHANGED_STATUS |\
|
||||
DDS_REQUESTED_DEADLINE_MISSED_STATUS |\
|
||||
DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS |\
|
||||
DDS_DATA_AVAILABLE_STATUS |\
|
||||
DDS_SAMPLE_LOST_STATUS |\
|
||||
DDS_SUBSCRIPTION_MATCHED_STATUS)
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
static dds_return_t dds_reader_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds_reader_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||
{
|
||||
assert(e);
|
||||
assert(i);
|
||||
*i = (dds_instance_handle_t)reader_instance_id(&e->m_guid);
|
||||
return DDS_RETCODE_OK;
|
||||
*i = reader_instance_id (&e->m_guid);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_close(
|
||||
dds_entity *e)
|
||||
static dds_return_t dds_reader_close (dds_entity *e) ddsrt_nonnull_all;
|
||||
|
||||
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 ());
|
||||
if (delete_reader(&e->m_guid) != 0) {
|
||||
DDS_ERROR("Internal error");
|
||||
ret = DDS_RETCODE_ERROR;
|
||||
}
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
static dds_return_t dds_reader_delete (dds_entity *e)
|
||||
{
|
||||
dds_reader * const rd = (dds_reader *) e;
|
||||
dds_return_t ret;
|
||||
if ((ret = dds_delete (rd->m_topic->m_entity.m_hdllink.hdl)) == DDS_RETCODE_OK)
|
||||
{
|
||||
/* 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;
|
||||
/* FIXME: QoS changes. */
|
||||
return (enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK);
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_delete(
|
||||
dds_entity *e)
|
||||
static dds_return_t dds_reader_status_validate (uint32_t mask)
|
||||
{
|
||||
dds_reader *rd = (dds_reader*)e;
|
||||
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;
|
||||
return (mask & ~DDS_READER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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_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_qos_t * rqos;
|
||||
dds_subscriber * sub = NULL;
|
||||
dds_entity_t subscriber;
|
||||
dds_reader * rd;
|
||||
struct rhc * rhc;
|
||||
dds_topic * tp;
|
||||
dds_entity_t reader;
|
||||
dds_entity_t t;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool internal_topic;
|
||||
dds_qos_t *rqos;
|
||||
dds_subscriber *sub = NULL;
|
||||
dds_entity_t subscriber;
|
||||
dds_reader *rd;
|
||||
struct rhc *rhc;
|
||||
dds_topic *tp;
|
||||
dds_entity_t reader;
|
||||
dds_entity_t t;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool internal_topic;
|
||||
|
||||
switch (topic) {
|
||||
case DDS_BUILTIN_TOPIC_DCPSPARTICIPANT:
|
||||
case DDS_BUILTIN_TOPIC_DCPSTOPIC:
|
||||
case DDS_BUILTIN_TOPIC_DCPSPUBLICATION:
|
||||
case DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION:
|
||||
internal_topic = true;
|
||||
subscriber = dds__get_builtin_subscriber(participant_or_subscriber);
|
||||
t = dds__get_builtin_topic (subscriber, topic);
|
||||
break;
|
||||
switch (topic)
|
||||
{
|
||||
case DDS_BUILTIN_TOPIC_DCPSPARTICIPANT:
|
||||
case DDS_BUILTIN_TOPIC_DCPSTOPIC:
|
||||
case DDS_BUILTIN_TOPIC_DCPSPUBLICATION:
|
||||
case DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION:
|
||||
internal_topic = true;
|
||||
subscriber = dds__get_builtin_subscriber (participant_or_subscriber);
|
||||
t = dds__get_builtin_topic (subscriber, topic);
|
||||
break;
|
||||
|
||||
default: {
|
||||
dds_entity *p_or_s;
|
||||
if ((ret = dds_entity_claim (participant_or_subscriber, &p_or_s)) != DDS_RETCODE_OK) {
|
||||
return ret;
|
||||
}
|
||||
if (dds_entity_kind (p_or_s) == DDS_KIND_PARTICIPANT) {
|
||||
subscriber = dds_create_subscriber(participant_or_subscriber, qos, NULL);
|
||||
} else {
|
||||
subscriber = participant_or_subscriber;
|
||||
}
|
||||
dds_entity_release (p_or_s);
|
||||
internal_topic = false;
|
||||
t = topic;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
dds_entity *p_or_s;
|
||||
if ((ret = dds_entity_claim (participant_or_subscriber, &p_or_s)) != DDS_RETCODE_OK)
|
||||
return ret;
|
||||
if (dds_entity_kind (p_or_s) == DDS_KIND_PARTICIPANT)
|
||||
subscriber = dds_create_subscriber (participant_or_subscriber, qos, NULL);
|
||||
else
|
||||
subscriber = participant_or_subscriber;
|
||||
dds_entity_release (p_or_s);
|
||||
internal_topic = false;
|
||||
t = topic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK) {
|
||||
reader = ret;
|
||||
goto err_sub_lock;
|
||||
}
|
||||
if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK)
|
||||
{
|
||||
reader = ret;
|
||||
goto err_sub_lock;
|
||||
}
|
||||
|
||||
if ((subscriber != participant_or_subscriber) && !internal_topic) {
|
||||
/* Delete implicit subscriber if reader creation fails */
|
||||
sub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
||||
}
|
||||
if (subscriber != participant_or_subscriber && !internal_topic)
|
||||
{
|
||||
/* Delete implicit subscriber if reader creation fails */
|
||||
sub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
||||
}
|
||||
|
||||
ret = dds_topic_lock(t, &tp);
|
||||
if (ret != DDS_RETCODE_OK) {
|
||||
DDS_ERROR("Error occurred on locking topic\n");
|
||||
reader = ret;
|
||||
goto err_tp_lock;
|
||||
}
|
||||
assert (tp->m_stopic);
|
||||
assert (sub->m_entity.m_domain == tp->m_entity.m_domain);
|
||||
if ((ret = dds_topic_lock (t, &tp)) != DDS_RETCODE_OK)
|
||||
{
|
||||
reader = ret;
|
||||
goto err_tp_lock;
|
||||
}
|
||||
assert (tp->m_stopic);
|
||||
assert (sub->m_entity.m_domain == tp->m_entity.m_domain);
|
||||
|
||||
/* Merge qos from topic and subscriber */
|
||||
rqos = dds_create_qos ();
|
||||
if (qos) {
|
||||
/* Only returns failure when one of the qos args is NULL, which
|
||||
* is not the case here. */
|
||||
(void)dds_copy_qos(rqos, qos);
|
||||
}
|
||||
/* Merge qos from topic and subscriber, dds_copy_qos only fails when it is passed a null
|
||||
argument, but that isn't the case here */
|
||||
rqos = dds_create_qos ();
|
||||
if (qos)
|
||||
(void) dds_copy_qos (rqos, qos);
|
||||
|
||||
if(sub->m_entity.m_qos){
|
||||
dds_merge_qos (rqos, sub->m_entity.m_qos);
|
||||
}
|
||||
if (sub->m_entity.m_qos)
|
||||
dds_merge_qos (rqos, sub->m_entity.m_qos);
|
||||
|
||||
if (tp->m_entity.m_qos) {
|
||||
dds_merge_qos (rqos, tp->m_entity.m_qos);
|
||||
if (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 */
|
||||
rqos->present &= ~(QP_DURABILITY_SERVICE | QP_TRANSPORT_PRIORITY | QP_LIFESPAN);
|
||||
}
|
||||
nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd);
|
||||
if ((ret = dds_reader_qos_validate (rqos, false)) != DDS_RETCODE_OK)
|
||||
{
|
||||
dds_delete_qos (rqos);
|
||||
reader = ret;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
|
||||
ret = dds_reader_qos_validate (rqos, false);
|
||||
if (ret != 0) {
|
||||
dds_delete_qos(rqos);
|
||||
reader = ret;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
/* Additional checks required for built-in topics: we don't want to
|
||||
run into a resource limit on a built-in topic, it is a needless
|
||||
complication */
|
||||
if (internal_topic && !dds__validate_builtin_reader_qos (topic, qos))
|
||||
{
|
||||
dds_delete_qos (rqos);
|
||||
reader = DDS_RETCODE_INCONSISTENT_POLICY;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
|
||||
/* Additional checks required for built-in topics */
|
||||
if (internal_topic && !dds__validate_builtin_reader_qos(topic, qos)) {
|
||||
dds_delete_qos(rqos);
|
||||
DDS_ERROR("Invalid QoS specified for built-in topic reader");
|
||||
reader = DDS_RETCODE_INCONSISTENT_POLICY;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
/* Create reader and associated read cache */
|
||||
rd = dds_alloc (sizeof (*rd));
|
||||
reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK);
|
||||
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;
|
||||
|
||||
/* Create reader and associated read cache */
|
||||
rd = dds_alloc (sizeof (*rd));
|
||||
reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK);
|
||||
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
|
||||
has deleted its reader as well. This can be known through the callback. */
|
||||
dds_handle_claim_inc (&rd->m_entity.m_hdllink);
|
||||
|
||||
/* Extra claim of this reader to make sure that the delete waits until DDSI
|
||||
* has deleted its reader as well. This can be known through the callback. */
|
||||
dds_handle_claim_inc (&rd->m_entity.m_hdllink);
|
||||
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
|
||||
ddsrt_mutex_unlock (&sub->m_entity.m_mutex);
|
||||
|
||||
ddsrt_mutex_unlock(&tp->m_entity.m_mutex);
|
||||
ddsrt_mutex_unlock(&sub->m_entity.m_mutex);
|
||||
thread_state_awake (lookup_thread_state ());
|
||||
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 ());
|
||||
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);
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
/* For persistent data register reader with durability */
|
||||
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);
|
||||
}
|
||||
dds_topic_unlock (tp);
|
||||
dds_subscriber_unlock (sub);
|
||||
|
||||
/* For persistent data register reader with durability */
|
||||
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);
|
||||
}
|
||||
dds_topic_unlock(tp);
|
||||
dds_subscriber_unlock(sub);
|
||||
|
||||
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;
|
||||
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:
|
||||
dds_topic_unlock(tp);
|
||||
dds_topic_unlock (tp);
|
||||
err_tp_lock:
|
||||
dds_subscriber_unlock(sub);
|
||||
if((sub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
||||
(void)dds_delete(subscriber);
|
||||
}
|
||||
dds_subscriber_unlock (sub);
|
||||
if ((sub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0)
|
||||
(void) dds_delete (subscriber);
|
||||
err_sub_lock:
|
||||
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;
|
||||
if (internal_topic)
|
||||
dds_delete (t);
|
||||
return reader;
|
||||
}
|
||||
|
||||
void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb, void *cbarg)
|
||||
{
|
||||
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;
|
||||
|
||||
if (dds_entity_kind (dds_entity) != DDS_KIND_READER)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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;
|
||||
nn_guid_t pwrguid_next;
|
||||
pwrguid = m->pwr_guid;
|
||||
|
@ -621,169 +570,12 @@ dds_entity_t dds_get_subscriber (dds_entity_t entity)
|
|||
}
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_get_subscription_matched_status (
|
||||
dds_entity_t reader,
|
||||
dds_subscription_matched_status_t * status)
|
||||
{
|
||||
dds_reader *rd;
|
||||
dds_return_t ret;
|
||||
/* Reset sets everything (type) 0, including the reason field, verify that 0 is correct */
|
||||
DDSRT_STATIC_ASSERT ((int) DDS_NOT_REJECTED == 0);
|
||||
|
||||
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_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;
|
||||
}
|
||||
DDS_GET_STATUS (reader, subscription_matched, SUBSCRIPTION_MATCHED, total_count_change, current_count_change)
|
||||
DDS_GET_STATUS (reader, liveliness_changed, LIVELINESS_CHANGED, alive_count_change, not_alive_count_change)
|
||||
DDS_GET_STATUS (reader, sample_rejected, SAMPLE_REJECTED, total_count_change, last_reason)
|
||||
DDS_GET_STATUS (reader, sample_lost, SAMPLE_LOST, total_count_change)
|
||||
DDS_GET_STATUS (reader, requested_deadline_missed, REQUESTED_DEADLINE_MISSED, total_count_change)
|
||||
DDS_GET_STATUS (reader, requested_incompatible_qos, REQUESTED_INCOMPATIBLE_QOS, total_count_change)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
struct check {
|
||||
char x[(DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4) ? 1 : -1];
|
||||
};
|
||||
DDSRT_STATIC_ASSERT (DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -11,199 +11,126 @@
|
|||
*/
|
||||
#include <string.h>
|
||||
#include "dds__listener.h"
|
||||
#include "dds__participant.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__subscriber.h"
|
||||
#include "dds/ddsi/q_entity.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 \
|
||||
DDS_DATA_ON_READERS_STATUS
|
||||
(DDS_DATA_ON_READERS_STATUS)
|
||||
|
||||
static dds_return_t
|
||||
dds_subscriber_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
static dds_return_t dds_subscriber_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds_subscriber_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||
{
|
||||
(void)e;
|
||||
(void)i;
|
||||
/* TODO: Get/generate proper handle. */
|
||||
DDS_ERROR("Generating subscriber instance handle is not supported");
|
||||
return DDS_RETCODE_UNSUPPORTED;
|
||||
(void) e;
|
||||
(void) i;
|
||||
/* FIXME: Get/generate proper handle. */
|
||||
return DDS_RETCODE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds__subscriber_qos_validate(
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, 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);
|
||||
|
||||
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) ddsrt_nonnull_all;
|
||||
|
||||
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 (enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK);
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_subscriber_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
static dds_return_t dds_subscriber_status_validate (uint32_t mask)
|
||||
{
|
||||
dds_return_t ret = dds__subscriber_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 (mask & ~DDS_SUBSCRIBER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
dds_entity_t dds__create_subscriber_l (dds_participant *participant, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||
{
|
||||
/* participant entity lock must be held */
|
||||
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;
|
||||
|
||||
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_subscriber_status_validate(
|
||||
uint32_t mask)
|
||||
dds_entity_t dds_create_subscriber (dds_entity_t participant, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
if (mask & ~(DDS_SUBSCRIBER_STATUS_MASK)) {
|
||||
DDS_ERROR("Invalid status mask\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
dds_participant *par;
|
||||
dds_entity_t hdl;
|
||||
dds_return_t ret;
|
||||
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||
return ret;
|
||||
hdl = dds__create_subscriber_l (par, qos, listener);
|
||||
dds_participant_unlock (par);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
dds_entity_t
|
||||
dds__create_subscriber_l(
|
||||
dds_entity *participant, /* entity-lock must be held */
|
||||
const dds_qos_t *qos,
|
||||
const dds_listener_t *listener)
|
||||
dds_return_t dds_notify_readers (dds_entity_t subscriber)
|
||||
{
|
||||
dds_subscriber * sub;
|
||||
dds_entity_t subscriber;
|
||||
dds_return_t ret;
|
||||
dds_qos_t * new_qos;
|
||||
dds_subscriber *sub;
|
||||
dds_return_t ret;
|
||||
|
||||
/* Validate qos */
|
||||
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:
|
||||
if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK)
|
||||
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_create_subscriber(
|
||||
dds_entity_t participant,
|
||||
const dds_qos_t *qos,
|
||||
const dds_listener_t *listener)
|
||||
dds_return_t dds_subscriber_begin_coherent (dds_entity_t e)
|
||||
{
|
||||
dds_entity * par;
|
||||
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;
|
||||
return dds_generic_unimplemented_operation (e, DDS_KIND_SUBSCRIBER);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_notify_readers(
|
||||
dds_entity_t subscriber)
|
||||
dds_return_t dds_subscriber_end_coherent (dds_entity_t e)
|
||||
{
|
||||
dds_entity *iter;
|
||||
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;
|
||||
return dds_generic_unimplemented_operation (e, DDS_KIND_SUBSCRIBER);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,68 +17,53 @@
|
|||
#include "dds__topic.h"
|
||||
#include "dds__listener.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__participant.h"
|
||||
#include "dds__stream.h"
|
||||
#include "dds__init.h"
|
||||
#include "dds__domain.h"
|
||||
#include "dds__get_status.h"
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_thread.h"
|
||||
#include "dds/ddsi/ddsi_sertopic.h"
|
||||
#include "dds/ddsi/q_ddsi_discovery.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 \
|
||||
DDS_INCONSISTENT_TOPIC_STATUS
|
||||
(DDS_INCONSISTENT_TOPIC_STATUS)
|
||||
|
||||
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),
|
||||
(int (*) (const void *, const void *)) strcmp,
|
||||
0
|
||||
);
|
||||
|
||||
static bool
|
||||
is_valid_name(
|
||||
const char *name)
|
||||
static int strcmp_wrapper (const void *va, const void *vb)
|
||||
{
|
||||
bool valid = false;
|
||||
/* 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;
|
||||
return strcmp (va, vb);
|
||||
}
|
||||
|
||||
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
|
||||
dds_topic_status_validate(
|
||||
uint32_t mask)
|
||||
static bool is_valid_name (const char *name) ddsrt_nonnull_all;
|
||||
|
||||
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)) {
|
||||
DDS_ERROR("Argument mask is invalid\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
return ret;
|
||||
static dds_return_t dds_topic_status_validate (uint32_t mask)
|
||||
{
|
||||
return (mask & ~DDS_TOPIC_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -100,191 +85,135 @@ static void dds_topic_status_cb (struct dds_topic *tp)
|
|||
if (lst->on_inconsistent_topic)
|
||||
{
|
||||
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);
|
||||
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--;
|
||||
ddsrt_cond_broadcast (&tp->m_entity.m_observers_cond);
|
||||
ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock);
|
||||
}
|
||||
|
||||
struct ddsi_sertopic *
|
||||
dds_topic_lookup_locked(
|
||||
dds_domain *domain,
|
||||
const char *name)
|
||||
struct ddsi_sertopic *dds_topic_lookup_locked (dds_domain *domain, const char *name) ddsrt_nonnull_all;
|
||||
|
||||
struct ddsi_sertopic *dds_topic_lookup_locked (dds_domain *domain, const char *name)
|
||||
{
|
||||
struct ddsi_sertopic *st = NULL;
|
||||
ddsrt_avl_iter_t iter;
|
||||
|
||||
assert (domain);
|
||||
assert (name);
|
||||
|
||||
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;
|
||||
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)
|
||||
return st;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ddsi_sertopic *
|
||||
dds_topic_lookup(
|
||||
dds_domain *domain,
|
||||
const char *name)
|
||||
struct ddsi_sertopic *dds_topic_lookup (dds_domain *domain, const char *name)
|
||||
{
|
||||
struct ddsi_sertopic *st;
|
||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||
st = dds_topic_lookup_locked(domain, name);
|
||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||
return st;
|
||||
struct ddsi_sertopic *st;
|
||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||
st = dds_topic_lookup_locked (domain, name);
|
||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||
return st;
|
||||
}
|
||||
|
||||
void
|
||||
dds_topic_free(
|
||||
dds_domainid_t domainid,
|
||||
struct ddsi_sertopic *st)
|
||||
void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic *st)
|
||||
{
|
||||
dds_domain *domain;
|
||||
|
||||
assert (st);
|
||||
|
||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||
domain = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
|
||||
if (domain != NULL) {
|
||||
ddsrt_avl_delete (&dds_topictree_def, &domain->m_topics, st);
|
||||
}
|
||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||
st->status_cb_entity = NULL;
|
||||
ddsi_sertopic_unref (st);
|
||||
dds_domain *domain;
|
||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||
domain = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
|
||||
if (domain != NULL)
|
||||
{
|
||||
assert (ddsrt_avl_lookup (&dds_topictree_def, &domain->m_topics, st->name_type_name) != NULL);
|
||||
ddsrt_avl_delete (&dds_topictree_def, &domain->m_topics, st);
|
||||
}
|
||||
ddsrt_mutex_unlock (&dds_global.m_mutex);
|
||||
st->status_cb_entity = NULL;
|
||||
ddsi_sertopic_unref (st);
|
||||
}
|
||||
|
||||
static void
|
||||
dds_topic_add_locked(
|
||||
dds_domainid_t id,
|
||||
struct ddsi_sertopic *st)
|
||||
static void dds_topic_add_locked (dds_domainid_t id, struct ddsi_sertopic *st)
|
||||
{
|
||||
dds_domain * dom;
|
||||
dom = dds_domain_find_locked (id);
|
||||
assert (dom);
|
||||
ddsrt_avl_insert (&dds_topictree_def, &dom->m_topics, st);
|
||||
dds_domain *dom = dds_domain_find_locked (id);
|
||||
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);
|
||||
}
|
||||
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_find_topic(
|
||||
dds_entity_t participant,
|
||||
const char *name)
|
||||
dds_entity_t dds_find_topic (dds_entity_t participant, const char *name)
|
||||
{
|
||||
dds_entity_t tp;
|
||||
dds_entity *p = NULL;
|
||||
struct ddsi_sertopic *st;
|
||||
dds_return_t rc;
|
||||
dds_entity_t tp;
|
||||
dds_participant *p;
|
||||
struct ddsi_sertopic *st;
|
||||
dds_return_t rc;
|
||||
|
||||
if (name) {
|
||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &p);
|
||||
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;
|
||||
}
|
||||
if (name == NULL)
|
||||
return 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
|
||||
dds_topic_delete(
|
||||
dds_entity *e)
|
||||
static dds_return_t dds_topic_delete (dds_entity *e) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds_topic_delete (dds_entity *e)
|
||||
{
|
||||
dds_topic_free(e->m_domainid, ((dds_topic*) e)->m_stopic);
|
||||
return DDS_RETCODE_OK;
|
||||
dds_topic_free (e->m_domainid, ((dds_topic *) e)->m_stopic);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_topic_qos_validate(
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
assert(qos);
|
||||
static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
|
||||
|
||||
/* Check consistency. */
|
||||
if (!dds_qos_validate_common(qos)) {
|
||||
DDS_ERROR("Argument QoS is not valid\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data)) {
|
||||
DDS_ERROR("Group 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("Lifespan 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);
|
||||
}
|
||||
static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled)
|
||||
{
|
||||
if (!dds_qos_validate_common (qos))
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_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_topic_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||
{
|
||||
/* FIXME: QoS changes */
|
||||
dds_return_t ret;
|
||||
(void) e;
|
||||
if ((ret = dds_topic_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
|
||||
return ret;
|
||||
return enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
|
||||
static dds_return_t
|
||||
dds_topic_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
static bool dupdef_qos_ok (const dds_qos_t *qos, const struct ddsi_sertopic *st)
|
||||
{
|
||||
dds_return_t ret = dds_topic_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 topic QoS is not supported\n");
|
||||
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);
|
||||
}
|
||||
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)
|
||||
|
@ -300,276 +229,213 @@ static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct dds
|
|||
return true;
|
||||
}
|
||||
|
||||
DDS_EXPORT 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_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)
|
||||
{
|
||||
struct ddsi_sertopic *stgeneric;
|
||||
dds_return_t rc;
|
||||
dds_entity *par;
|
||||
dds_topic *top;
|
||||
dds_qos_t *new_qos = NULL;
|
||||
dds_entity_t hdl;
|
||||
struct participant *ddsi_pp;
|
||||
struct ddsi_sertopic *stgeneric;
|
||||
dds_return_t rc;
|
||||
dds_participant *par;
|
||||
dds_topic *top;
|
||||
dds_qos_t *new_qos = NULL;
|
||||
dds_entity_t hdl;
|
||||
struct participant *ddsi_pp;
|
||||
|
||||
if (sertopic == NULL){
|
||||
DDS_ERROR("Topic description is NULL\n");
|
||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
||||
goto bad_param_err;
|
||||
}
|
||||
if (sertopic == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
hdl = rc;
|
||||
goto lock_err;
|
||||
}
|
||||
if (qos && (rc = dds_topic_qos_validate (qos, false)) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
|
||||
/* Validate qos */
|
||||
if (qos) {
|
||||
hdl = dds_topic_qos_validate (qos, false);
|
||||
if (hdl != DDS_RETCODE_OK) {
|
||||
goto qos_err;
|
||||
}
|
||||
}
|
||||
if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
|
||||
/* 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 */
|
||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||
if ((stgeneric = dds_topic_lookup_locked (par->m_domain, sertopic->name)) != NULL) {
|
||||
if (!sertopic_equivalent (stgeneric, sertopic)) {
|
||||
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
||||
DDS_ERROR("Create topic with mismatching type\n");
|
||||
hdl = DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||
} else if (!dupdef_qos_ok(qos, stgeneric)) {
|
||||
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
||||
DDS_ERROR("Create topic with mismatching qos\n");
|
||||
hdl = DDS_RETCODE_INCONSISTENT_POLICY;
|
||||
} 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);
|
||||
/* Check if topic already exists with same name */
|
||||
ddsrt_mutex_lock (&dds_global.m_mutex);
|
||||
if ((stgeneric = dds_topic_lookup_locked (par->m_entity.m_domain, sertopic->name)) != NULL) {
|
||||
if (!sertopic_equivalent (stgeneric, sertopic)) {
|
||||
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
||||
rc = DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||
goto err_mismatch;
|
||||
} else if (!dupdef_qos_ok(qos, stgeneric)) {
|
||||
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
|
||||
rc = DDS_RETCODE_INCONSISTENT_POLICY;
|
||||
goto err_mismatch;
|
||||
} else {
|
||||
if (qos) {
|
||||
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 topic */
|
||||
top = dds_alloc (sizeof (*top));
|
||||
hdl = dds_entity_init (&top->m_entity, par, DDS_KIND_TOPIC, new_qos, listener, DDS_TOPIC_STATUS_MASK);
|
||||
top->m_entity.m_deriver.delete = dds_topic_delete;
|
||||
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_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 ());
|
||||
/* 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 {
|
||||
if (qos)
|
||||
{
|
||||
new_qos = dds_create_qos ();
|
||||
(void)dds_copy_qos (new_qos, qos);
|
||||
}
|
||||
|
||||
qos_err:
|
||||
dds_entity_unlock(par);
|
||||
lock_err:
|
||||
bad_param_err:
|
||||
return hdl;
|
||||
/* Create topic */
|
||||
top = dds_alloc (sizeof (*top));
|
||||
hdl = dds_entity_init (&top->m_entity, &par->m_entity, DDS_KIND_TOPIC, new_qos, listener, DDS_TOPIC_STATUS_MASK);
|
||||
top->m_entity.m_deriver.delete = dds_topic_delete;
|
||||
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_create_topic(
|
||||
dds_entity_t participant,
|
||||
const dds_topic_descriptor_t *desc,
|
||||
const char *name,
|
||||
const dds_qos_t *qos,
|
||||
const dds_listener_t *listener)
|
||||
dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descriptor_t *desc, const char *name, const dds_qos_t *qos, const dds_listener_t *listener)
|
||||
{
|
||||
char *key = NULL;
|
||||
struct ddsi_sertopic_default *st;
|
||||
const char *typename;
|
||||
dds_qos_t *new_qos = NULL;
|
||||
nn_plist_t plist;
|
||||
dds_entity_t hdl;
|
||||
uint32_t index;
|
||||
size_t keysz;
|
||||
char *key = NULL;
|
||||
struct ddsi_sertopic_default *st;
|
||||
const char *typename;
|
||||
dds_qos_t *new_qos = NULL;
|
||||
nn_plist_t plist;
|
||||
dds_entity_t hdl;
|
||||
size_t keysz;
|
||||
|
||||
if (desc == NULL){
|
||||
DDS_ERROR("Topic description is NULL");
|
||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
||||
goto bad_param_err;
|
||||
}
|
||||
if (desc == NULL || name == NULL || !is_valid_name (name))
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
if (name == NULL) {
|
||||
DDS_ERROR("Topic name is NULL");
|
||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
||||
goto bad_param_err;
|
||||
}
|
||||
typename = desc->m_typename;
|
||||
keysz = strlen (name) + strlen (typename) + 2;
|
||||
key = dds_alloc (keysz);
|
||||
(void) snprintf (key, keysz, "%s/%s", name, typename);
|
||||
|
||||
if (!is_valid_name(name)) {
|
||||
DDS_ERROR("Topic name contains characters that are not allowed.");
|
||||
hdl = DDS_RETCODE_BAD_PARAMETER;
|
||||
goto bad_param_err;
|
||||
}
|
||||
st = dds_alloc (sizeof (*st));
|
||||
|
||||
typename = desc->m_typename;
|
||||
keysz = strlen (name) + strlen (typename) + 2;
|
||||
key = (char*) dds_alloc (keysz);
|
||||
(void) snprintf(key, keysz, "%s/%s", name, typename);
|
||||
ddsrt_atomic_st32 (&st->c.refc, 1);
|
||||
st->c.iid = ddsi_iid_gen ();
|
||||
st->c.status_cb = dds_topic_status_cb;
|
||||
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);
|
||||
st->c.iid = ddsi_iid_gen ();
|
||||
st->c.status_cb = dds_topic_status_cb;
|
||||
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);
|
||||
/* Check if topic cannot be optimised (memcpy marshal) */
|
||||
if (!(desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE)) {
|
||||
st->opt_size = dds_stream_check_optimize (desc);
|
||||
}
|
||||
|
||||
st->type = (void*) desc;
|
||||
st->nkeys = desc->m_nkeys;
|
||||
st->keys = desc->m_keys;
|
||||
nn_plist_init_empty (&plist);
|
||||
if (new_qos)
|
||||
dds_merge_qos (&plist.qos, new_qos);
|
||||
|
||||
/* Check if topic cannot be optimised (memcpy marshal) */
|
||||
if ((desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) == 0) {
|
||||
st->opt_size = dds_stream_check_optimize (desc);
|
||||
}
|
||||
/* 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 (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);
|
||||
if (new_qos) {
|
||||
dds_merge_qos (&plist.qos, new_qos);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
hdl = dds_create_topic_arbitrary (participant, &st->c, qos, listener, &plist);
|
||||
ddsi_sertopic_unref (&st->c);
|
||||
nn_plist_fini (&plist);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
static bool
|
||||
dds_topic_chaining_filter(
|
||||
const void *sample,
|
||||
void *ctx)
|
||||
static bool dds_topic_chaining_filter (const void *sample, void *ctx)
|
||||
{
|
||||
dds_topic_filter_fn realf = (dds_topic_filter_fn)ctx;
|
||||
return realf (sample);
|
||||
dds_topic_filter_fn realf = (dds_topic_filter_fn) ctx;
|
||||
return realf (sample);
|
||||
}
|
||||
|
||||
static void
|
||||
dds_topic_mod_filter(
|
||||
dds_entity_t topic,
|
||||
dds_topic_intern_filter_fn *filter,
|
||||
void **ctx,
|
||||
bool set)
|
||||
static void dds_topic_mod_filter (dds_entity_t topic, dds_topic_intern_filter_fn *filter, void **ctx, bool set)
|
||||
{
|
||||
dds_topic *t;
|
||||
if (dds_topic_lock(topic, &t) == DDS_RETCODE_OK) {
|
||||
if (set) {
|
||||
t->filter_fn = *filter;
|
||||
t->filter_ctx = *ctx;
|
||||
} else {
|
||||
*filter = t->filter_fn;
|
||||
*ctx = t->filter_ctx;
|
||||
}
|
||||
dds_topic_unlock(t);
|
||||
dds_topic *t;
|
||||
if (dds_topic_lock (topic, &t) == DDS_RETCODE_OK)
|
||||
{
|
||||
if (set) {
|
||||
t->filter_fn = *filter;
|
||||
t->filter_ctx = *ctx;
|
||||
} else {
|
||||
*filter = 0;
|
||||
*ctx = NULL;
|
||||
*filter = t->filter_fn;
|
||||
*ctx = t->filter_ctx;
|
||||
}
|
||||
dds_topic_unlock (t);
|
||||
}
|
||||
else
|
||||
{
|
||||
*filter = 0;
|
||||
*ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_set_topic_filter(
|
||||
dds_entity_t topic,
|
||||
dds_topic_filter_fn filter)
|
||||
void dds_set_topic_filter (dds_entity_t topic, dds_topic_filter_fn filter)
|
||||
{
|
||||
dds_topic_intern_filter_fn chaining = dds_topic_chaining_filter;
|
||||
void *realf = (void *)filter;
|
||||
dds_topic_mod_filter (topic, &chaining, &realf, true);
|
||||
dds_topic_intern_filter_fn chaining = dds_topic_chaining_filter;
|
||||
void *realf = (void *) filter;
|
||||
dds_topic_mod_filter (topic, &chaining, &realf, true);
|
||||
}
|
||||
|
||||
void
|
||||
dds_topic_set_filter(
|
||||
dds_entity_t topic,
|
||||
dds_topic_filter_fn filter)
|
||||
void 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_get_topic_filter(
|
||||
dds_entity_t topic)
|
||||
dds_topic_filter_fn dds_get_topic_filter (dds_entity_t topic)
|
||||
{
|
||||
dds_topic_intern_filter_fn filter;
|
||||
void *ctx;
|
||||
dds_topic_mod_filter (topic, &filter, &ctx, false);
|
||||
return (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn)ctx : 0;
|
||||
dds_topic_intern_filter_fn filter;
|
||||
void *ctx;
|
||||
dds_topic_mod_filter (topic, &filter, &ctx, false);
|
||||
return (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn) ctx : 0;
|
||||
}
|
||||
|
||||
dds_topic_filter_fn
|
||||
dds_topic_get_filter(
|
||||
dds_entity_t topic)
|
||||
dds_topic_filter_fn dds_topic_get_filter (dds_entity_t topic)
|
||||
{
|
||||
return dds_get_topic_filter(topic);
|
||||
return dds_get_topic_filter (topic);
|
||||
}
|
||||
|
||||
void
|
||||
dds_topic_set_filter_with_ctx(
|
||||
dds_entity_t topic,
|
||||
dds_topic_intern_filter_fn filter,
|
||||
void *ctx)
|
||||
void 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_intern_filter_fn
|
||||
dds_topic_get_filter_with_ctx(
|
||||
dds_entity_t topic)
|
||||
dds_topic_intern_filter_fn dds_topic_get_filter_with_ctx (dds_entity_t topic)
|
||||
{
|
||||
dds_topic_intern_filter_fn filter;
|
||||
void *ctx;
|
||||
|
@ -577,93 +443,32 @@ dds_topic_get_filter_with_ctx(
|
|||
return (filter == dds_topic_chaining_filter) ? 0 : filter;
|
||||
}
|
||||
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_name(
|
||||
dds_entity_t topic,
|
||||
char *name,
|
||||
size_t size)
|
||||
dds_return_t dds_get_name (dds_entity_t topic, char *name, size_t size)
|
||||
{
|
||||
dds_topic *t;
|
||||
dds_return_t ret;
|
||||
|
||||
if(size <= 0){
|
||||
DDS_ERROR("Argument size is smaller than 0\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
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:
|
||||
dds_topic *t;
|
||||
dds_return_t ret;
|
||||
if (size <= 0 || name == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
name[0] = '\0';
|
||||
if ((ret = dds_topic_lock (topic, &t)) != DDS_RETCODE_OK)
|
||||
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_get_type_name(
|
||||
dds_entity_t topic,
|
||||
char *name,
|
||||
size_t size)
|
||||
dds_return_t dds_get_type_name (dds_entity_t topic, char *name, size_t size)
|
||||
{
|
||||
dds_topic *t;
|
||||
dds_return_t ret;
|
||||
|
||||
if(size <= 0){
|
||||
DDS_ERROR("Argument size is smaller than 0\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
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:
|
||||
dds_topic *t;
|
||||
dds_return_t ret;
|
||||
if (size <= 0 || name == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
name[0] = '\0';
|
||||
if ((ret = dds_topic_lock (topic, &t)) != DDS_RETCODE_OK)
|
||||
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_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;
|
||||
}
|
||||
DDS_GET_STATUS(topic, inconsistent_topic, INCONSISTENT_TOPIC, total_count_change)
|
||||
|
|
|
@ -14,424 +14,296 @@
|
|||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/log.h"
|
||||
#include "dds__entity.h"
|
||||
#include "dds__participant.h"
|
||||
#include "dds__querycond.h"
|
||||
#include "dds__readcond.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
|
||||
dds_waitset_swap(
|
||||
dds_attachment **dst,
|
||||
dds_attachment **src,
|
||||
dds_attachment *prev,
|
||||
dds_attachment *idx)
|
||||
static void dds_waitset_swap (dds_attachment **dst, dds_attachment **src, dds_attachment *prev, dds_attachment *idx)
|
||||
{
|
||||
/* Remove from source. */
|
||||
if (prev == NULL) {
|
||||
*src = idx->next;
|
||||
} else {
|
||||
prev->next = idx->next;
|
||||
}
|
||||
/* Remove from source. */
|
||||
if (prev == NULL)
|
||||
*src = idx->next;
|
||||
else
|
||||
prev->next = idx->next;
|
||||
|
||||
/* Add to destination. */
|
||||
idx->next = *dst;
|
||||
*dst = idx;
|
||||
/* Add to destination. */
|
||||
idx->next = *dst;
|
||||
*dst = idx;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_waitset_wait_impl(
|
||||
dds_entity_t waitset,
|
||||
dds_attach_t *xs,
|
||||
size_t nxs,
|
||||
dds_time_t abstimeout,
|
||||
dds_time_t tnow)
|
||||
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 *ws;
|
||||
dds_return_t ret;
|
||||
dds_attachment *idx;
|
||||
dds_attachment *next;
|
||||
dds_attachment *prev;
|
||||
dds_waitset *ws;
|
||||
dds_return_t ret;
|
||||
dds_attachment *idx;
|
||||
dds_attachment *prev;
|
||||
|
||||
if ((xs == NULL) && (nxs != 0)){
|
||||
DDS_ERROR("A size was given, but no array\n");
|
||||
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");
|
||||
}
|
||||
if (xs == NULL && nxs != 0)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
if (xs != NULL && nxs == 0)
|
||||
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. */
|
||||
if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
|
||||
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
|
||||
dds_waitset_close_list(
|
||||
dds_attachment **list,
|
||||
dds_entity_t waitset)
|
||||
static void dds_waitset_close_list (dds_attachment **list, dds_entity_t waitset)
|
||||
{
|
||||
dds_attachment *idx = *list;
|
||||
dds_attachment *next;
|
||||
while (idx != NULL) {
|
||||
next = idx->next;
|
||||
(void)dds_entity_observer_unregister(idx->entity->m_hdllink.hdl, waitset);
|
||||
ddsrt_free(idx);
|
||||
idx = next;
|
||||
}
|
||||
*list = NULL;
|
||||
dds_attachment *idx = *list;
|
||||
dds_attachment *next;
|
||||
while (idx != NULL)
|
||||
{
|
||||
next = idx->next;
|
||||
(void) dds_entity_observer_unregister (idx->entity->m_hdllink.hdl, waitset);
|
||||
ddsrt_free (idx);
|
||||
idx = next;
|
||||
}
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
dds_waitset_remove_from_list(
|
||||
dds_attachment **list,
|
||||
dds_entity_t observed)
|
||||
static bool dds_waitset_remove_from_list (dds_attachment **list, dds_entity_t observed)
|
||||
{
|
||||
dds_attachment *idx = *list;
|
||||
dds_attachment *prev = NULL;
|
||||
|
||||
while (idx != NULL) {
|
||||
if (idx->entity->m_hdllink.hdl == observed) {
|
||||
if (prev == NULL) {
|
||||
*list = idx->next;
|
||||
} else {
|
||||
prev->next = idx->next;
|
||||
}
|
||||
ddsrt_free(idx);
|
||||
|
||||
/* We're done. */
|
||||
return true;
|
||||
}
|
||||
prev = idx;
|
||||
idx = idx->next;
|
||||
}
|
||||
dds_attachment *idx, *prev;
|
||||
for (idx = *list, prev = NULL; idx != NULL; prev = idx, idx = idx->next)
|
||||
if (idx->entity->m_hdllink.hdl == observed)
|
||||
break;
|
||||
if (idx == NULL)
|
||||
return false;
|
||||
|
||||
if (prev == NULL)
|
||||
*list = idx->next;
|
||||
else
|
||||
prev->next = idx->next;
|
||||
ddsrt_free (idx);
|
||||
return true;
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_waitset_close(
|
||||
struct dds_entity *e)
|
||||
dds_return_t dds_waitset_close (struct dds_entity *e)
|
||||
{
|
||||
dds_waitset *ws = (dds_waitset*)e;
|
||||
|
||||
dds_waitset_close_list(&ws->observed, e->m_hdllink.hdl);
|
||||
dds_waitset_close_list(&ws->triggered, e->m_hdllink.hdl);
|
||||
|
||||
/* Trigger waitset to wake up. */
|
||||
ddsrt_cond_broadcast(&e->m_cond);
|
||||
|
||||
return DDS_RETCODE_OK;
|
||||
dds_waitset *ws = (dds_waitset *) e;
|
||||
dds_waitset_close_list (&ws->observed, e->m_hdllink.hdl);
|
||||
dds_waitset_close_list (&ws->triggered, e->m_hdllink.hdl);
|
||||
ddsrt_cond_broadcast (&e->m_cond);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_create_waitset(
|
||||
dds_entity_t participant)
|
||||
dds_entity_t dds_create_waitset (dds_entity_t participant)
|
||||
{
|
||||
dds_entity_t hdl;
|
||||
dds_entity *par;
|
||||
dds_return_t rc;
|
||||
dds_entity_t hdl;
|
||||
dds_participant *par;
|
||||
dds_return_t rc;
|
||||
|
||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
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;
|
||||
}
|
||||
if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
|
||||
return 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_waitset_get_entities(
|
||||
dds_entity_t waitset,
|
||||
dds_entity_t *entities,
|
||||
size_t size)
|
||||
dds_return_t dds_waitset_get_entities (dds_entity_t waitset, dds_entity_t *entities, size_t size)
|
||||
{
|
||||
dds_return_t ret;
|
||||
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");
|
||||
}
|
||||
dds_return_t ret;
|
||||
dds_waitset *ws;
|
||||
|
||||
if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
|
||||
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 *prev = NULL;
|
||||
while (idx != NULL) {
|
||||
if (idx->entity->m_hdllink.hdl == entity) {
|
||||
/* Swap idx from src to dst. */
|
||||
dds_waitset_swap(dst, src, prev, idx);
|
||||
|
||||
/* We're done. */
|
||||
return;
|
||||
}
|
||||
prev = idx;
|
||||
idx = idx->next;
|
||||
}
|
||||
dds_attachment *idx, *prev;
|
||||
for (idx = *src, prev = NULL; idx != NULL; prev = idx, idx = idx->next)
|
||||
if (idx->entity->m_hdllink.hdl == entity)
|
||||
break;
|
||||
if (idx != NULL)
|
||||
{
|
||||
/* Swap idx from src to dst. */
|
||||
dds_waitset_swap (dst, src, prev, idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dds_waitset_remove(
|
||||
dds_waitset *ws,
|
||||
dds_entity_t observed)
|
||||
static void dds_waitset_remove (dds_waitset *ws, dds_entity_t observed)
|
||||
{
|
||||
if (!dds_waitset_remove_from_list(&(ws->observed), observed)) {
|
||||
(void)dds_waitset_remove_from_list(&(ws->triggered), observed);
|
||||
}
|
||||
if (!dds_waitset_remove_from_list (&ws->observed, observed))
|
||||
(void) dds_waitset_remove_from_list (&ws->triggered, observed);
|
||||
}
|
||||
|
||||
/* This is called when the observed entity signals a status change. */
|
||||
void
|
||||
dds_waitset_observer(
|
||||
dds_entity_t observer,
|
||||
dds_entity_t observed,
|
||||
uint32_t status)
|
||||
void dds_waitset_observer (dds_entity_t observer, dds_entity_t observed, uint32_t status)
|
||||
{
|
||||
dds_waitset *ws;
|
||||
if (dds_waitset_lock(observer, &ws) == DDS_RETCODE_OK) {
|
||||
if (status & DDS_DELETING_STATUS) {
|
||||
/* Remove this observed entity, which is being deleted, from the waitset. */
|
||||
dds_waitset_remove(ws, observed);
|
||||
/* Our registration to this observed entity will be removed automatically. */
|
||||
} else if (status != 0) {
|
||||
/* Move observed entity to triggered list. */
|
||||
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);
|
||||
dds_waitset *ws;
|
||||
if (dds_waitset_lock (observer, &ws) == DDS_RETCODE_OK) {
|
||||
if (status & DDS_DELETING_STATUS) {
|
||||
/* Remove this observed entity, which is being deleted, from the waitset. */
|
||||
dds_waitset_remove (ws, observed);
|
||||
/* Our registration to this observed entity will be removed automatically. */
|
||||
} else if (status != 0) {
|
||||
/* Move observed entity to triggered list. */
|
||||
dds_waitset_move (&ws->observed, &ws->triggered, observed);
|
||||
} 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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Trigger waitset to wake up. */
|
||||
ddsrt_cond_broadcast (&ws->m_entity.m_cond);
|
||||
dds_waitset_unlock (ws);
|
||||
}
|
||||
}
|
||||
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_waitset_detach(
|
||||
dds_entity_t waitset,
|
||||
dds_entity_t entity)
|
||||
dds_return_t dds_waitset_attach (dds_entity_t waitset, dds_entity_t entity, dds_attach_t x)
|
||||
{
|
||||
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");
|
||||
}
|
||||
dds_entity *e;
|
||||
dds_waitset *ws;
|
||||
dds_return_t ret;
|
||||
|
||||
if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
|
||||
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_waitset_wait_until(
|
||||
dds_entity_t waitset,
|
||||
dds_attach_t *xs,
|
||||
size_t nxs,
|
||||
dds_time_t abstimeout)
|
||||
dds_return_t dds_waitset_detach (dds_entity_t waitset, dds_entity_t entity)
|
||||
{
|
||||
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_waitset_wait(
|
||||
dds_entity_t waitset,
|
||||
dds_attach_t *xs,
|
||||
size_t nxs,
|
||||
dds_duration_t reltimeout)
|
||||
dds_return_t dds_waitset_wait_until (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_time_t abstimeout)
|
||||
{
|
||||
dds_entity_t ret;
|
||||
return dds_waitset_wait_impl(waitset, xs, nxs, abstimeout);
|
||||
}
|
||||
|
||||
if (reltimeout >= 0) {
|
||||
dds_time_t tnow = dds_time();
|
||||
dds_time_t abstimeout = (DDS_INFINITY - reltimeout <= tnow) ? DDS_NEVER : (tnow + reltimeout);
|
||||
ret = dds_waitset_wait_impl(waitset, xs, nxs, abstimeout, tnow);
|
||||
} else{
|
||||
DDS_ERROR("Negative timeout\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
return ret;
|
||||
dds_return_t dds_waitset_wait (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_duration_t reltimeout)
|
||||
{
|
||||
if (reltimeout < 0)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
const dds_time_t tnow = dds_time ();
|
||||
const dds_time_t abstimeout = (DDS_INFINITY - reltimeout <= tnow) ? DDS_NEVER : (tnow + reltimeout);
|
||||
return dds_waitset_wait_impl (waitset, xs, nxs, abstimeout);
|
||||
}
|
||||
|
||||
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);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ struct whc_node {
|
|||
struct whc_node *next_seq; /* next in this interval */
|
||||
struct whc_node *prev_seq; /* prev in this interval */
|
||||
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;
|
||||
uint64_t total_bytes; /* cumulative number of bytes up to and including this node */
|
||||
size_t size;
|
||||
|
@ -43,7 +43,7 @@ struct whc_node {
|
|||
unsigned unacked: 1; /* counted in whc::unacked_bytes iff 1 */
|
||||
unsigned borrowed: 1; /* at most one can borrow it at any time */
|
||||
nn_mtime_t last_rexmit_ts;
|
||||
unsigned rexmit_count;
|
||||
uint32_t rexmit_count;
|
||||
struct ddsi_serdata *serdata;
|
||||
};
|
||||
|
||||
|
@ -59,7 +59,7 @@ struct whc_idxnode {
|
|||
uint64_t iid;
|
||||
seqno_t prune_seq;
|
||||
struct ddsi_tkmap_instance *tk;
|
||||
unsigned headidx;
|
||||
uint32_t headidx;
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
struct whc_node *hist[];
|
||||
#else
|
||||
|
@ -77,14 +77,14 @@ struct whc_seq_entry {
|
|||
struct whc_impl {
|
||||
struct whc common;
|
||||
ddsrt_mutex_t lock;
|
||||
unsigned seq_size;
|
||||
uint32_t seq_size;
|
||||
size_t unacked_bytes;
|
||||
size_t sample_overhead;
|
||||
uint64_t total_bytes; /* total number of bytes pushed in */
|
||||
unsigned is_transient_local: 1;
|
||||
unsigned hdepth; /* 0 = unlimited */
|
||||
unsigned 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 hdepth; /* 0 = unlimited */
|
||||
uint32_t tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
|
||||
uint32_t idxdepth; /* = max (hdepth, tldepth) */
|
||||
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_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 */
|
||||
struct whc_sample_iter_sizecheck {
|
||||
char fits_in_generic_type[sizeof(struct whc_sample_iter_impl) <= sizeof(struct whc_sample_iter) ? 1 : -1];
|
||||
};
|
||||
DDSRT_STATIC_ASSERT (sizeof (struct whc_sample_iter_impl) <= sizeof (struct whc_sample_iter));
|
||||
|
||||
/* Hash + interval tree adminitration of samples-by-sequence number
|
||||
* - by definition contains all samples in WHC (unchanged from older versions)
|
||||
* 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
|
||||
* - each sample (i.e., whc_node): backpointer into index
|
||||
* - 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 int compare_seq (const void *va, const void *vb);
|
||||
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 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_full (struct whc_impl *whc, seqno_t max_drop_seq, 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_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 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_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 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 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 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 = {
|
||||
.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
|
||||
initialized lazily and cleaned up automatically when the last WHC is freed.
|
||||
Protected by dds_global.m_mutex.
|
||||
initialized lazily and cleaned up automatically when the last WHC is freed.
|
||||
Protected by dds_global.m_mutex.
|
||||
|
||||
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,
|
||||
maximum message size and a short round-trip time */
|
||||
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,
|
||||
maximum message size and a short round-trip time */
|
||||
#define MAX_FREELIST_SIZE 8192
|
||||
static uint32_t whc_count;
|
||||
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;
|
||||
/* we hash the lower 32 bits, on the assumption that with 4 billion
|
||||
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;
|
||||
return (unsigned) ((x * c) >> 32);
|
||||
return (uint32_t) ((x * c) >> 32);
|
||||
}
|
||||
|
||||
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;
|
||||
/* we hash the lower 32 bits, on the assumption that with 4 billion
|
||||
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;
|
||||
return (unsigned) ((x * c) >> 32);
|
||||
return (uint32_t) ((x * c) >> 32);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* there's much more we can check, but it gets expensive quite
|
||||
quickly: all nodes but open_intv non-empty, non-overlapping and
|
||||
non-contiguous; min & maxp1 of intervals correct; each interval
|
||||
contiguous; all samples in seq & in seqhash; tlidx \subseteq seq;
|
||||
seq-number ordered list correct; &c. */
|
||||
quickly: all nodes but open_intv non-empty, non-overlapping and
|
||||
non-contiguous; min & maxp1 of intervals correct; each interval
|
||||
contiguous; all samples in seq & in seqhash; tlidx \subseteq seq;
|
||||
seq-number ordered list correct; &c. */
|
||||
assert (whc->open_intv != NULL);
|
||||
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);
|
||||
|
@ -269,7 +267,7 @@ static void check_whc (const struct whc_impl *whc)
|
|||
}
|
||||
assert (whc->maxseq_node == whc_findmax_procedurally (whc));
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#if !defined (NDEBUG)
|
||||
if (config.enabled_xchecks & DDS_XCHECK_WHC)
|
||||
{
|
||||
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
|
||||
struct whc_seq_entry e = { .seq = whcn->seq, .whcn = whcn };
|
||||
if (!ddsrt_ehh_add (whc->seq_hash, &e))
|
||||
assert(0);
|
||||
assert (0);
|
||||
#else
|
||||
if (!ddsrt_hh_add (whc->seq_hash, whcn))
|
||||
assert(0);
|
||||
assert (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -307,11 +305,11 @@ static void remove_whcn_from_hash (struct whc_impl *whc, struct whc_node *whcn)
|
|||
/* precondition: whcn is in hash */
|
||||
#if USE_EHH
|
||||
struct whc_seq_entry e = { .seq = whcn->seq };
|
||||
if (!ddsrt_ehh_remove(whc->seq_hash, &e))
|
||||
assert(0);
|
||||
if (!ddsrt_ehh_remove (whc->seq_hash, &e))
|
||||
assert (0);
|
||||
#else
|
||||
if (!ddsrt_hh_remove(whc->seq_hash, whcn))
|
||||
assert(0);
|
||||
if (!ddsrt_hh_remove (whc->seq_hash, whcn))
|
||||
assert (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -319,14 +317,14 @@ static struct whc_node *whc_findseq (const struct whc_impl *whc, seqno_t seq)
|
|||
{
|
||||
#if USE_EHH
|
||||
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;
|
||||
else
|
||||
return NULL;
|
||||
#else
|
||||
struct whc_node template;
|
||||
template.seq = seq;
|
||||
return ddsrt_hh_lookup(whc->seq_hash, &template);
|
||||
return ddsrt_hh_lookup (whc->seq_hash, &template);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -334,11 +332,11 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
|
|||
{
|
||||
union {
|
||||
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;
|
||||
struct whc_idxnode *n;
|
||||
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);
|
||||
if (n == 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 */
|
||||
struct whc_impl *whc;
|
||||
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->common.ops = &whc_ops;
|
||||
|
@ -372,11 +370,11 @@ struct whc *whc_new (int is_transient_local, unsigned hdepth, unsigned tldepth)
|
|||
#if USE_EHH
|
||||
whc->seq_hash = ddsrt_ehh_new (sizeof (struct whc_seq_entry), 32, whc_seq_entry_hash, whc_seq_entry_eq);
|
||||
#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
|
||||
|
||||
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
|
||||
whc->idx_hash = NULL;
|
||||
|
||||
|
@ -417,9 +415,9 @@ void whc_default_free (struct whc *whc_generic)
|
|||
{
|
||||
struct ddsrt_hh_iter it;
|
||||
struct whc_idxnode *n;
|
||||
for (n = ddsrt_hh_iter_first(whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next(&it))
|
||||
ddsrt_free(n);
|
||||
ddsrt_hh_free(whc->idx_hash);
|
||||
for (n = ddsrt_hh_iter_first (whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next (&it))
|
||||
ddsrt_free (n);
|
||||
ddsrt_hh_free (whc->idx_hash);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -427,10 +425,10 @@ void whc_default_free (struct whc *whc_generic)
|
|||
while (whcn)
|
||||
{
|
||||
struct whc_node *tmp = whcn;
|
||||
/* The compiler doesn't realize that whcn->prev_seq is always initialized. */
|
||||
DDSRT_WARNING_MSVC_OFF(6001);
|
||||
/* The compiler doesn't realize that whcn->prev_seq is always initialized. */
|
||||
DDSRT_WARNING_MSVC_OFF (6001);
|
||||
whcn = whcn->prev_seq;
|
||||
DDSRT_WARNING_MSVC_ON(6001);
|
||||
DDSRT_WARNING_MSVC_ON (6001);
|
||||
free_whc_node_contents (tmp);
|
||||
ddsrt_free (tmp);
|
||||
}
|
||||
|
@ -452,7 +450,7 @@ DDSRT_WARNING_MSVC_ON(6001);
|
|||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
||||
check_whc (whc);
|
||||
get_state_locked(whc, st);
|
||||
get_state_locked (whc, st);
|
||||
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)
|
||||
{
|
||||
/* 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 <
|
||||
SEQ < Y can't exist */
|
||||
contiguous, so if we don't know seq, an interval [X,Y) with X <
|
||||
SEQ < Y can't exist */
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
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
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
unsigned i;
|
||||
for (i = 0; i < whc->idxdepth; i++)
|
||||
for (uint32_t i = 0; i < whc->idxdepth; i++)
|
||||
assert (i == idxn->headidx || idxn->hist[i] == NULL);
|
||||
#endif
|
||||
if (!ddsrt_hh_remove (whc->idx_hash, idxn))
|
||||
assert (0);
|
||||
ddsi_tkmap_instance_unref(idxn->tk);
|
||||
ddsi_tkmap_instance_unref (idxn->tk);
|
||||
ddsrt_free (idxn);
|
||||
}
|
||||
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)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < whc->idxdepth; i++)
|
||||
for (uint32_t i = 0; i < whc->idxdepth; 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;
|
||||
if (oldn->seq <= max_drop_seq)
|
||||
{
|
||||
DDS_LOG(DDS_LC_WHC, " prune tl whcn %p\n", (void *)oldn);
|
||||
assert(oldn != whc->maxseq_node);
|
||||
DDS_LOG (DDS_LC_WHC, " prune tl whcn %p\n", (void *)oldn);
|
||||
assert (oldn != whc->maxseq_node);
|
||||
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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
return 0;
|
||||
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);
|
||||
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;
|
||||
seqno_t old_max_drop_seq;
|
||||
struct whc_node *deferred_free_list;
|
||||
unsigned cnt;
|
||||
uint32_t cnt;
|
||||
|
||||
/* 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);
|
||||
check_whc (whc);
|
||||
|
||||
if (whc->idxdepth == 0)
|
||||
{
|
||||
/* 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);
|
||||
return 0;
|
||||
}
|
||||
|
@ -625,29 +621,29 @@ static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, stru
|
|||
assert (!whc->is_transient_local);
|
||||
if (whc->tldepth > 0)
|
||||
{
|
||||
assert(whc->hdepth == 0 || whc->tldepth <= whc->hdepth);
|
||||
assert (whc->hdepth == 0 || whc->tldepth <= whc->hdepth);
|
||||
whc->tldepth = 0;
|
||||
if (whc->hdepth == 0)
|
||||
{
|
||||
struct ddsrt_hh_iter it;
|
||||
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);
|
||||
ddsrt_hh_free(whc->idx_hash);
|
||||
ddsrt_hh_free (whc->idx_hash);
|
||||
whc->idxdepth = 0;
|
||||
whc->idx_hash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Immediately drop them from the WHC (used to delay it until the
|
||||
next ack); but need to make sure remove_acked_messages processes
|
||||
them all. */
|
||||
next ack); but need to make sure remove_acked_messages processes
|
||||
them all. */
|
||||
old_max_drop_seq = whc->max_drop_seq;
|
||||
whc->max_drop_seq = 0;
|
||||
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);
|
||||
assert (whc->max_drop_seq == old_max_drop_seq);
|
||||
get_state_locked(whc, st);
|
||||
get_state_locked (whc, st);
|
||||
ddsrt_mutex_unlock (&whc->lock);
|
||||
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)
|
||||
{
|
||||
/* Removes *p_whcn, possibly deleting or splitting *p_intv, as the
|
||||
case may be. Does *NOT* update whc->seq_size. *p_intv must be
|
||||
the interval containing *p_whcn (&& both must actually exist).
|
||||
case may be. Does *NOT* update whc->seq_size. *p_intv must be
|
||||
the interval containing *p_whcn (&& both must actually exist).
|
||||
|
||||
Returns:
|
||||
- 0 if delete failed (only possible cause is memory exhaustion),
|
||||
in which case *p_intv & *p_whcn are undefined;
|
||||
- 1 if successful, in which case *p_intv & *p_whcn are set
|
||||
correctly for the next sample in sequence number order */
|
||||
Returns:
|
||||
- 0 if delete failed (only possible cause is memory exhaustion),
|
||||
in which case *p_intv & *p_whcn are undefined;
|
||||
- 1 if successful, in which case *p_intv & *p_whcn are set
|
||||
correctly for the next sample in sequence number order */
|
||||
struct whc_intvnode *intv = *p_intv;
|
||||
struct whc_node *whcn = *p_whcn;
|
||||
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
|
||||
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). */
|
||||
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). */
|
||||
remove_whcn_from_hash (whc, whcn);
|
||||
|
||||
/* We may have introduced a hole & have to split the interval
|
||||
node, or we may have nibbled of the first one, or even the
|
||||
last one. */
|
||||
node, or we may have nibbled of the first one, or even the
|
||||
last one. */
|
||||
if (whcn == intv->first)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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 (whcn->prev_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
|
||||
{
|
||||
/* somewhere in the middle => split the interval (ideally,
|
||||
would split it lazily, but it really is a transient-local
|
||||
issue only, and so we can (for now) get away with splitting
|
||||
it greedily */
|
||||
would split it lazily, but it really is a transient-local
|
||||
issue only, and so we can (for now) get away with splitting
|
||||
it greedily */
|
||||
struct whc_intvnode *new_intv;
|
||||
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);
|
||||
|
||||
/* 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)
|
||||
assert (0);
|
||||
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);
|
||||
}
|
||||
|
||||
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_node *whcn;
|
||||
unsigned ndropped = 0;
|
||||
uint32_t ndropped = 0;
|
||||
|
||||
/* In the trivial case of an empty WHC, get out quickly */
|
||||
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,
|
||||
and there can only be a single interval */
|
||||
and there can only be a single interval */
|
||||
#ifndef NDEBUG
|
||||
whcn = find_nextseq_intv (&intv, whc, whc->max_drop_seq);
|
||||
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;
|
||||
|
||||
/* 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 (max_drop_seq < intv->min)
|
||||
{
|
||||
/* 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
|
||||
ack, whc->max_drop_seq < max_drop_seq = MIN(readers max ack) < intv->min */
|
||||
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 */
|
||||
if (max_drop_seq > whc->max_drop_seq)
|
||||
whc->max_drop_seq = max_drop_seq;
|
||||
*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;
|
||||
ndropped = (unsigned) (whcn->seq - intv->min + 1);
|
||||
ndropped = (uint32_t) (whcn->seq - intv->min + 1);
|
||||
|
||||
intv->first = whcn->next_seq;
|
||||
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;
|
||||
}
|
||||
|
||||
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_node *whcn;
|
||||
struct whc_node *prev_seq;
|
||||
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)
|
||||
{
|
||||
/* 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;
|
||||
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;
|
||||
while (whcn && whcn->seq <= max_drop_seq)
|
||||
{
|
||||
DDS_LOG(DDS_LC_WHC, " whcn %p %"PRId64, (void *) whcn, whcn->seq);
|
||||
if (whcn_in_tlidx(whc, whcn->idxnode, whcn->idxnode_pos))
|
||||
DDS_LOG (DDS_LC_WHC, " whcn %p %"PRId64, (void *) whcn, whcn->seq);
|
||||
if (whcn_in_tlidx (whc, whcn->idxnode, whcn->idxnode_pos))
|
||||
{
|
||||
/* quickly skip over samples in tlidx */
|
||||
DDS_LOG(DDS_LC_WHC, " tl:keep");
|
||||
DDS_LOG (DDS_LC_WHC, " tl:keep");
|
||||
if (whcn->unacked)
|
||||
{
|
||||
assert (whc->unacked_bytes >= whcn->size);
|
||||
|
@ -920,13 +916,13 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
|||
}
|
||||
else
|
||||
{
|
||||
DDS_LOG(DDS_LC_WHC, " delete");
|
||||
DDS_LOG (DDS_LC_WHC, " delete");
|
||||
last_to_free->next_seq = whcn;
|
||||
last_to_free = last_to_free->next_seq;
|
||||
whc_delete_one_intv (whc, &intv, &whcn);
|
||||
ndropped++;
|
||||
}
|
||||
DDS_LOG(DDS_LC_WHC, "\n");
|
||||
DDS_LOG (DDS_LC_WHC, "\n");
|
||||
}
|
||||
if (prev_seq)
|
||||
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;
|
||||
|
||||
/* 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
|
||||
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.
|
||||
Thus, we had better prune them. */
|
||||
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
|
||||
out, but if the difference is large and the update rate low, it may take a long time.
|
||||
Thus, we had better prune them. */
|
||||
if (whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
|
||||
{
|
||||
assert(whc->hdepth == whc->idxdepth);
|
||||
DDS_LOG(DDS_LC_WHC, " idxdepth %u > tldepth %u > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
|
||||
assert (whc->hdepth == whc->idxdepth);
|
||||
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
|
||||
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 */
|
||||
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 */
|
||||
whcn = find_nextseq_intv (&intv, whc, whc->max_drop_seq);
|
||||
while (whcn && whcn->seq <= max_drop_seq)
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
|
@ -977,27 +973,27 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
|||
if ((oldn = idxn->hist[idx]) != NULL)
|
||||
{
|
||||
/* 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
|
||||
struct whc_node whcn_template;
|
||||
union {
|
||||
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.idxn.headidx = 0;
|
||||
template.idxn.hist[0] = &whcn_template;
|
||||
whcn_template.serdata = ddsi_serdata_ref(oldn->serdata);
|
||||
assert(oldn->seq < whcn->seq);
|
||||
whcn_template.serdata = ddsi_serdata_ref (oldn->serdata);
|
||||
assert (oldn->seq < whcn->seq);
|
||||
#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);
|
||||
#ifndef NDEBUG
|
||||
assert(ddsrt_hh_lookup(whc->idx_hash, &template) == idxn);
|
||||
ddsi_serdata_unref(whcn_template.serdata);
|
||||
assert (ddsrt_hh_lookup (whc->idx_hash, &template) == idxn);
|
||||
ddsi_serdata_unref (whcn_template.serdata);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
DDS_LOG(DDS_LC_WHC, "\n");
|
||||
DDS_LOG (DDS_LC_WHC, "\n");
|
||||
whcn = whcn->next_seq;
|
||||
}
|
||||
}
|
||||
|
@ -1011,22 +1007,22 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
|||
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;
|
||||
unsigned cnt;
|
||||
uint32_t cnt;
|
||||
|
||||
ddsrt_mutex_lock (&whc->lock);
|
||||
assert (max_drop_seq < MAX_SEQ_NUMBER);
|
||||
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;
|
||||
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: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n",
|
||||
tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
||||
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: [%"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);
|
||||
}
|
||||
|
||||
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);
|
||||
else
|
||||
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);
|
||||
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;
|
||||
union {
|
||||
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;
|
||||
|
||||
ddsrt_mutex_lock (&whc->lock);
|
||||
check_whc (whc);
|
||||
|
||||
if (dds_get_log_mask() & DDS_LC_WHC)
|
||||
if (dds_get_log_mask () & DDS_LC_WHC)
|
||||
{
|
||||
struct whc_state 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: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n",
|
||||
whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
||||
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: [%"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 >= whc->max_drop_seq);
|
||||
|
||||
/* Seq must be greater than what is currently stored. Usually it'll
|
||||
be the next sequence number, but if there are no readers
|
||||
temporarily, a gap may be among the possibilities */
|
||||
be the next sequence number, but if there are no readers
|
||||
temporarily, a gap may be among the possibilities */
|
||||
assert (whc->seq_size == 0 || seq > whc->maxseq_node->seq);
|
||||
|
||||
/* Always insert in seq admin */
|
||||
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 */
|
||||
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);
|
||||
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)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
if (newn->seq <= max_drop_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->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;
|
||||
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;
|
||||
}
|
||||
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))
|
||||
{
|
||||
DDS_LOG(DDS_LC_WHC, " prune whcn %p", (void *)oldn);
|
||||
assert(oldn != whc->maxseq_node);
|
||||
DDS_LOG (DDS_LC_WHC, " prune whcn %p", (void *)oldn);
|
||||
assert (oldn != whc->maxseq_node);
|
||||
whc_delete_one (whc, oldn);
|
||||
}
|
||||
|
||||
/* 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
|
||||
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). */
|
||||
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
|
||||
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)
|
||||
{
|
||||
unsigned pos = idxn->headidx + whc->idxdepth - whc->tldepth;
|
||||
uint32_t pos = idxn->headidx + whc->idxdepth - whc->tldepth;
|
||||
if (pos >= whc->idxdepth)
|
||||
pos -= whc->idxdepth;
|
||||
if ((oldn = idxn->hist[pos]) != NULL)
|
||||
{
|
||||
DDS_LOG(DDS_LC_WHC, " prune tl whcn %p", (void *)oldn);
|
||||
assert(oldn != whc->maxseq_node);
|
||||
DDS_LOG (DDS_LC_WHC, " prune tl whcn %p", (void *)oldn);
|
||||
assert (oldn != whc->maxseq_node);
|
||||
whc_delete_one (whc, oldn);
|
||||
}
|
||||
}
|
||||
DDS_LOG(DDS_LC_WHC, "\n");
|
||||
DDS_LOG (DDS_LC_WHC, "\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DDS_LOG(DDS_LC_WHC, " newkey");
|
||||
DDS_LOG (DDS_LC_WHC, " newkey");
|
||||
/* Ignore unregisters, but insert everything else */
|
||||
if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER))
|
||||
{
|
||||
unsigned i;
|
||||
idxn = ddsrt_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0]));
|
||||
DDS_LOG(DDS_LC_WHC, " idxn %p", (void *)idxn);
|
||||
ddsi_tkmap_instance_ref(tk);
|
||||
DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
|
||||
ddsi_tkmap_instance_ref (tk);
|
||||
idxn->iid = tk->m_iid;
|
||||
idxn->tk = tk;
|
||||
idxn->prune_seq = 0;
|
||||
idxn->headidx = 0;
|
||||
idxn->hist[0] = newn;
|
||||
for (i = 1; i < whc->idxdepth; i++)
|
||||
for (uint32_t i = 1; i < whc->idxdepth; i++)
|
||||
idxn->hist[i] = NULL;
|
||||
newn->idxnode = idxn;
|
||||
newn->idxnode_pos = 0;
|
||||
|
@ -1225,24 +1221,24 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
|||
}
|
||||
else
|
||||
{
|
||||
DDS_LOG(DDS_LC_WHC, " unreg:skip");
|
||||
DDS_LOG (DDS_LC_WHC, " unreg:skip");
|
||||
if (newn->seq <= max_drop_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->maxseq_node = prev_seq;
|
||||
}
|
||||
}
|
||||
DDS_LOG(DDS_LC_WHC, "\n");
|
||||
DDS_LOG (DDS_LC_WHC, "\n");
|
||||
}
|
||||
ddsrt_mutex_unlock (&whc->lock);
|
||||
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;
|
||||
sample->seq = whcn->seq;
|
||||
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;
|
||||
bool found;
|
||||
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
|
||||
if ((whcn = whc_findseq(whc, seq)) == NULL)
|
||||
if ((whcn = whc_findseq (whc, seq)) == NULL)
|
||||
found = false;
|
||||
else
|
||||
{
|
||||
make_borrowed_sample(sample, whcn);
|
||||
make_borrowed_sample (sample, whcn);
|
||||
found = true;
|
||||
}
|
||||
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;
|
||||
bool found;
|
||||
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;
|
||||
else
|
||||
{
|
||||
make_borrowed_sample(sample, whcn);
|
||||
make_borrowed_sample (sample, whcn);
|
||||
found = true;
|
||||
}
|
||||
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 */
|
||||
ddsi_serdata_unref (sample->serdata);
|
||||
if (sample->plist) {
|
||||
if (sample->plist)
|
||||
{
|
||||
nn_plist_fini (sample->plist);
|
||||
ddsrt_free (sample->plist);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(whcn->borrowed);
|
||||
assert (whcn->borrowed);
|
||||
whcn->borrowed = 0;
|
||||
if (update_retransmit_info)
|
||||
{
|
||||
|
@ -1338,7 +1335,7 @@ static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_
|
|||
if (!it->first)
|
||||
{
|
||||
seq = sample->seq;
|
||||
return_sample_locked(whc, sample, false);
|
||||
return_sample_locked (whc, sample, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1349,7 +1346,7 @@ static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_
|
|||
valid = false;
|
||||
else
|
||||
{
|
||||
make_borrowed_sample(sample, whcn);
|
||||
make_borrowed_sample (sample, whcn);
|
||||
valid = true;
|
||||
}
|
||||
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 */
|
||||
struct bwhc_sample_iter_sizecheck {
|
||||
char fits_in_generic_type[sizeof(struct bwhc_iter) <= sizeof(struct whc_sample_iter) ? 1 : -1];
|
||||
};
|
||||
DDSRT_STATIC_ASSERT (sizeof (struct bwhc_iter) <= sizeof (struct whc_sample_iter));
|
||||
|
||||
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
|
||||
{
|
||||
/* When deleting, pwr is no longer accessible via the hash
|
||||
tables, and consequently, a reader may be deleted without
|
||||
it being possible to remove it from rdary. The primary
|
||||
reason rdary exists is to avoid locking the proxy writer
|
||||
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
|
||||
samples we received from it. As writer being deleted any
|
||||
reliable samples that are rejected are simply discarded. */
|
||||
tables, and consequently, a reader may be deleted without
|
||||
it being possible to remove it from rdary. The primary
|
||||
reason rdary exists is to avoid locking the proxy writer
|
||||
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
|
||||
samples we received from it. As writer being deleted any
|
||||
reliable samples that are rejected are simply discarded. */
|
||||
ddsrt_avl_iter_t it;
|
||||
struct pwr_rd_match *m;
|
||||
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;
|
||||
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL)
|
||||
{
|
||||
DDS_TRACE("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
|
||||
/* Copied the return value ignore from DDSI deliver_user_data() function. */
|
||||
DDS_TRACE ("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
|
||||
/* 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)
|
||||
break;
|
||||
}
|
||||
|
@ -152,40 +152,34 @@ dds_return_t dds_write_impl (dds_writer *wr, const void * data, dds_time_t tstam
|
|||
int w_rc;
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
DDS_ERROR("No data buffer provided\n");
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check for topic filter */
|
||||
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;
|
||||
|
||||
thread_state_awake (ts1);
|
||||
|
||||
/* Serialize and write data or key */
|
||||
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;
|
||||
ddsi_serdata_ref (d);
|
||||
tk = ddsi_tkmap_lookup_instance_ref (d);
|
||||
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 */
|
||||
if (!config.whc_batch)
|
||||
nn_xpack_send (wr->m_xp, false);
|
||||
ret = DDS_RETCODE_OK;
|
||||
} 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;
|
||||
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
|
||||
DDS_ERROR ("Invalid data provided\n");
|
||||
ret = DDS_RETCODE_ERROR;
|
||||
} else {
|
||||
DDS_ERROR ("Internal error\n");
|
||||
ret = DDS_RETCODE_ERROR;
|
||||
}
|
||||
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);
|
||||
ret = DDS_RETCODE_OK;
|
||||
} 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;
|
||||
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
|
||||
DDS_ERROR ("Invalid data provided\n");
|
||||
ret = DDS_RETCODE_ERROR;
|
||||
} else {
|
||||
DDS_ERROR ("Internal error\n");
|
||||
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)
|
||||
abort ();
|
||||
/* 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;
|
||||
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_return_t rc;
|
||||
thread_state_awake (ts1);
|
||||
if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||
DDS_ERROR ("Error occurred on locking writer\n");
|
||||
else
|
||||
if ((rc = dds_writer_lock (writer, &wr)) == DDS_RETCODE_OK)
|
||||
{
|
||||
nn_xpack_send (wr->m_xp, true);
|
||||
dds_writer_unlock (wr);
|
||||
|
|
|
@ -24,40 +24,29 @@
|
|||
#include "dds__init.h"
|
||||
#include "dds__publisher.h"
|
||||
#include "dds__topic.h"
|
||||
#include "dds__get_status.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.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 \
|
||||
DDS_LIVELINESS_LOST_STATUS |\
|
||||
DDS_OFFERED_DEADLINE_MISSED_STATUS |\
|
||||
DDS_OFFERED_INCOMPATIBLE_QOS_STATUS |\
|
||||
DDS_PUBLICATION_MATCHED_STATUS
|
||||
(DDS_LIVELINESS_LOST_STATUS |\
|
||||
DDS_OFFERED_DEADLINE_MISSED_STATUS |\
|
||||
DDS_OFFERED_INCOMPATIBLE_QOS_STATUS |\
|
||||
DDS_PUBLICATION_MATCHED_STATUS)
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
static dds_return_t dds_writer_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
|
||||
|
||||
static dds_return_t dds_writer_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
|
||||
{
|
||||
assert(e);
|
||||
assert(i);
|
||||
*i = (dds_instance_handle_t)writer_instance_id(&e->m_guid);
|
||||
return DDS_RETCODE_OK;
|
||||
*i = writer_instance_id(&e->m_guid);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_status_validate(
|
||||
uint32_t mask)
|
||||
static dds_return_t dds_writer_status_validate (uint32_t mask)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
if (mask & ~(DDS_WRITER_STATUS_MASK)) {
|
||||
DDS_ERROR("Invalid status mask\n");
|
||||
ret = DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return (mask & ~DDS_WRITER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_bandwidth_limit(
|
||||
nn_transport_priority_qospolicy_t transport_priority)
|
||||
static uint32_t get_bandwidth_limit (nn_transport_priority_qospolicy_t transport_priority)
|
||||
{
|
||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
||||
struct config_channel_listelem *channel = find_channel (transport_priority);
|
||||
return channel->data_bandwidth_limit;
|
||||
#else
|
||||
(void)transport_priority;
|
||||
(void) transport_priority;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_close(
|
||||
dds_entity *e)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
dds_writer *wr = (dds_writer*)e;
|
||||
static dds_return_t dds_writer_close (dds_entity *e) ddsrt_nonnull_all;
|
||||
|
||||
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 ());
|
||||
nn_xpack_send (wr->m_xp, false);
|
||||
if (delete_writer (&e->m_guid) != 0) {
|
||||
DDS_ERROR("Internal error");
|
||||
ret = DDS_RETCODE_ERROR;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
ddsi_wr->xqos->ownership_strength.value = qos->ownership_strength.value;
|
||||
ddsrt_mutex_unlock (&ddsi_wr->e.lock);
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enabled)
|
||||
ret = DDS_RETCODE_UNSUPPORTED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
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)
|
||||
static struct whc *make_whc (const dds_qos_t *qos)
|
||||
{
|
||||
bool handle_as_transient_local;
|
||||
unsigned hdepth, tldepth;
|
||||
uint32_t hdepth, tldepth;
|
||||
/* Construct WHC -- if aggressive_keep_last1 is set, the WHC will
|
||||
drop all samples for which a later update is available. This
|
||||
forces it to maintain a tlidx. */
|
||||
drop all samples for which a later update is available. This
|
||||
forces it to maintain a tlidx. */
|
||||
handle_as_transient_local = (qos->durability.kind == NN_TRANSIENT_LOCAL_DURABILITY_QOS);
|
||||
if (qos->history.kind == NN_KEEP_ALL_HISTORY_QOS)
|
||||
hdepth = 0;
|
||||
else
|
||||
hdepth = (unsigned)qos->history.depth;
|
||||
if (handle_as_transient_local) {
|
||||
hdepth = (unsigned) qos->history.depth;
|
||||
if (!handle_as_transient_local)
|
||||
tldepth = 0;
|
||||
else
|
||||
{
|
||||
if (qos->durability_service.history.kind == NN_KEEP_ALL_HISTORY_QOS)
|
||||
tldepth = 0;
|
||||
else
|
||||
tldepth = (unsigned)qos->durability_service.history.depth;
|
||||
} else {
|
||||
tldepth = 0;
|
||||
tldepth = (unsigned) qos->durability_service.history.depth;
|
||||
}
|
||||
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_qos_t * wqos;
|
||||
dds_writer * wr;
|
||||
dds_entity_t writer;
|
||||
dds_publisher * pub = NULL;
|
||||
dds_topic * tp;
|
||||
dds_entity_t publisher;
|
||||
ddsi_tran_conn_t conn = gv.data_conn_uc;
|
||||
dds_return_t ret;
|
||||
dds_return_t rc;
|
||||
dds_qos_t *wqos;
|
||||
dds_writer *wr;
|
||||
dds_entity_t writer;
|
||||
dds_publisher *pub = NULL;
|
||||
dds_topic *tp;
|
||||
dds_entity_t publisher;
|
||||
ddsi_tran_conn_t conn = gv.data_conn_uc;
|
||||
|
||||
{
|
||||
dds_entity *p_or_p;
|
||||
if ((rc = dds_entity_claim (participant_or_publisher, &p_or_p)) != DDS_RETCODE_OK) {
|
||||
return rc;
|
||||
}
|
||||
if (dds_entity_kind (p_or_p) == DDS_KIND_PARTICIPANT) {
|
||||
publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
|
||||
} else {
|
||||
publisher = participant_or_publisher;
|
||||
}
|
||||
dds_entity_release (p_or_p);
|
||||
}
|
||||
{
|
||||
dds_entity *p_or_p;
|
||||
if ((rc = dds_entity_claim (participant_or_publisher, &p_or_p)) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
if (dds_entity_kind (p_or_p) == DDS_KIND_PARTICIPANT)
|
||||
publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
|
||||
else
|
||||
publisher = participant_or_publisher;
|
||||
dds_entity_release (p_or_p);
|
||||
}
|
||||
|
||||
if ((rc = dds_publisher_lock(publisher, &pub)) != DDS_RETCODE_OK) {
|
||||
writer = rc;
|
||||
goto err_pub_lock;
|
||||
}
|
||||
if ((rc = dds_publisher_lock (publisher, &pub)) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
|
||||
if (publisher != participant_or_publisher) {
|
||||
pub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
||||
}
|
||||
if (publisher != participant_or_publisher)
|
||||
pub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
|
||||
|
||||
rc = dds_topic_lock(topic, &tp);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
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);
|
||||
if ((rc = dds_topic_lock (topic, &tp)) != DDS_RETCODE_OK)
|
||||
goto err_tp_lock;
|
||||
|
||||
/* Merge Topic & Publisher qos */
|
||||
wqos = dds_create_qos();
|
||||
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);
|
||||
}
|
||||
assert (tp->m_stopic);
|
||||
assert (pub->m_entity.m_domain == tp->m_entity.m_domain);
|
||||
|
||||
if (pub->m_entity.m_qos) {
|
||||
dds_merge_qos(wqos, pub->m_entity.m_qos);
|
||||
}
|
||||
/* Merge Topic & Publisher 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) {
|
||||
/* merge topic qos data to writer qos */
|
||||
dds_merge_qos(wqos, tp->m_entity.m_qos);
|
||||
}
|
||||
nn_xqos_mergein_missing(wqos, &gv.default_xqos_wr);
|
||||
if ((rc = dds_writer_qos_validate (wqos, false)) != DDS_RETCODE_OK)
|
||||
{
|
||||
dds_delete_qos(wqos);
|
||||
goto err_bad_qos;
|
||||
}
|
||||
|
||||
ret = dds_writer_qos_validate(wqos, false);
|
||||
if (ret != 0) {
|
||||
dds_delete_qos(wqos);
|
||||
writer = ret;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
/* Create writer */
|
||||
wr = dds_alloc (sizeof (*wr));
|
||||
writer = dds_entity_init (&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
|
||||
|
||||
/* Create writer */
|
||||
wr = dds_alloc(sizeof (*wr));
|
||||
writer = dds_entity_init(&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
|
||||
wr->m_topic = tp;
|
||||
dds_entity_add_ref_nolock (&tp->m_entity);
|
||||
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;
|
||||
dds_entity_add_ref_nolock(&tp->m_entity);
|
||||
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);
|
||||
/* Extra claim of this writer to make sure that the delete waits until DDSI
|
||||
* has deleted its writer as well. This can be known through the callback. */
|
||||
dds_handle_claim_inc (&wr->m_entity.m_hdllink);
|
||||
|
||||
/* Extra claim of this writer to make sure that the delete waits until DDSI
|
||||
* has deleted its writer as well. This can be known through the callback. */
|
||||
dds_handle_claim_inc (&wr->m_entity.m_hdllink);
|
||||
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
|
||||
ddsrt_mutex_unlock (&pub->m_entity.m_mutex);
|
||||
|
||||
ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
|
||||
ddsrt_mutex_unlock (&pub->m_entity.m_mutex);
|
||||
|
||||
thread_state_awake (lookup_thread_state ());
|
||||
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);
|
||||
ddsrt_mutex_lock (&pub->m_entity.m_mutex);
|
||||
ddsrt_mutex_lock (&tp->m_entity.m_mutex);
|
||||
assert(ret == DDS_RETCODE_OK);
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
dds_topic_unlock(tp);
|
||||
dds_publisher_unlock(pub);
|
||||
return writer;
|
||||
thread_state_awake (lookup_thread_state ());
|
||||
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);
|
||||
ddsrt_mutex_lock (&tp->m_entity.m_mutex);
|
||||
assert(rc == DDS_RETCODE_OK);
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
dds_topic_unlock (tp);
|
||||
dds_publisher_unlock (pub);
|
||||
return writer;
|
||||
|
||||
err_bad_qos:
|
||||
dds_topic_unlock(tp);
|
||||
dds_topic_unlock (tp);
|
||||
err_tp_lock:
|
||||
dds_publisher_unlock(pub);
|
||||
if((pub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
||||
(void)dds_delete(publisher);
|
||||
}
|
||||
err_pub_lock:
|
||||
return writer;
|
||||
dds_publisher_unlock (pub);
|
||||
if ((pub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
||||
(void )dds_delete (publisher);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
dds_entity_t
|
||||
dds_get_publisher(
|
||||
dds_entity_t writer)
|
||||
dds_entity_t dds_get_publisher (dds_entity_t writer)
|
||||
{
|
||||
dds_entity *e;
|
||||
dds_return_t rc;
|
||||
|
@ -472,115 +393,7 @@ dds_get_publisher(
|
|||
}
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_get_publication_matched_status (
|
||||
dds_entity_t writer,
|
||||
dds_publication_matched_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_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;
|
||||
}
|
||||
DDS_GET_STATUS(writer, publication_matched, PUBLICATION_MATCHED, total_count_change, current_count_change)
|
||||
DDS_GET_STATUS(writer, liveliness_lost, LIVELINESS_LOST, total_count_change)
|
||||
DDS_GET_STATUS(writer, offered_deadline_missed, OFFERED_DEADLINE_MISSED, total_count_change)
|
||||
DDS_GET_STATUS(writer, offered_incompatible_qos, OFFERED_INCOMPATIBLE_QOS, total_count_change)
|
||||
|
|
|
@ -105,7 +105,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
|||
q_rtps.h
|
||||
q_security.h
|
||||
q_sockwaitset.h
|
||||
q_static_assert.h
|
||||
q_thread.h
|
||||
q_time.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
|
||||
* @param[in] plist
|
||||
* 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.
|
||||
*
|
||||
|
@ -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_clear_retransmitting (struct writer *wr);
|
||||
|
||||
int delete_writer (const struct nn_guid *guid);
|
||||
int delete_writer_nolinger (const struct nn_guid *guid);
|
||||
int delete_writer_nolinger_locked (struct writer *wr);
|
||||
dds_return_t delete_writer (const struct nn_guid *guid);
|
||||
dds_return_t delete_writer_nolinger (const struct nn_guid *guid);
|
||||
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);
|
||||
|
||||
struct local_orphan_writer {
|
||||
|
|
|
@ -18,9 +18,7 @@ extern "C" {
|
|||
|
||||
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 is_wildcard_partition (const char *str);
|
||||
|
||||
/* Returns -1 on success, or QoS id of first mismatch (>=0) */
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "dds/ddsrt/atomics.h"
|
||||
#include "dds/ddsrt/sync.h"
|
||||
#include "dds/ddsrt/threads.h"
|
||||
#include "dds/ddsi/q_static_assert.h"
|
||||
#include "dds/ddsrt/static_assert.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -332,8 +332,9 @@ static enum ddsi_locator_from_string_result ddsi_raweth_address_from_string (dds
|
|||
memset (loc->address, 0, sizeof (loc->address));
|
||||
while (i < 6 && *str != 0)
|
||||
{
|
||||
int o, p;
|
||||
if (sscanf (str, "%x%n", &o, &p) != 1 || o < 0 || o > 255)
|
||||
unsigned o;
|
||||
int p;
|
||||
if (sscanf (str, "%x%n", &o, &p) != 1 || o > 255)
|
||||
return AFSR_INVALID;
|
||||
loc->address[10 + i++] = (unsigned char) o;
|
||||
str += p;
|
||||
|
|
|
@ -127,12 +127,12 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
|
|||
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)
|
||||
{
|
||||
/* 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
|
||||
*/
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
char *addrs_copy, *ip, *cursor, *a;
|
||||
int retval = -1;
|
||||
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 (addrs_copy);
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
int pos;
|
||||
double v_dbl;
|
||||
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" */
|
||||
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)
|
||||
{
|
||||
|
@ -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_) \
|
||||
struct en_##type_##_vs_ms_check { \
|
||||
char length_eq[(sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
|
||||
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)) ? 1 : -1]; \
|
||||
}; \
|
||||
DDSRT_STATIC_ASSERT (sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
|
||||
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)); \
|
||||
\
|
||||
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, "");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
|
||||
int pos;
|
||||
if (ddsrt_strcasecmp (value, "default") == 0) {
|
||||
|
@ -1788,8 +1786,8 @@ static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem con
|
|||
} else {
|
||||
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)
|
||||
{
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
|
||||
int pos;
|
||||
if (ddsrt_strcasecmp (value, "any") == 0) {
|
||||
|
@ -1955,8 +1953,8 @@ static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const
|
|||
} else {
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -1099,10 +1099,10 @@ static void rebuild_make_locs_nrds(int **locs_nrds, int nreaders, int nlocs, con
|
|||
if (covered[j * nlocs + i] >= 0)
|
||||
n++;
|
||||
|
||||
/* The compiler doesn't realize that ln is large enough. */
|
||||
DDSRT_WARNING_MSVC_OFF(6386);
|
||||
/* The compiler doesn't realize that ln is large enough. */
|
||||
DDSRT_WARNING_MSVC_OFF(6386);
|
||||
ln[i] = n;
|
||||
DDSRT_WARNING_MSVC_ON(6386);
|
||||
DDSRT_WARNING_MSVC_ON(6386);
|
||||
}
|
||||
*locs_nrds = ln;
|
||||
}
|
||||
|
@ -3002,7 +3002,7 @@ static void writer_set_state (struct writer *wr, enum writer_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));
|
||||
ASSERT_MUTEX_HELD (&wr->e.lock);
|
||||
|
@ -3014,7 +3014,7 @@ int delete_writer_nolinger_locked (struct writer *wr)
|
|||
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;
|
||||
/* 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);
|
||||
}
|
||||
|
||||
int delete_writer (const struct nn_guid *guid)
|
||||
dds_return_t delete_writer (const struct nn_guid *guid)
|
||||
{
|
||||
struct writer *wr;
|
||||
struct whc_state whcst;
|
||||
|
@ -3409,7 +3409,7 @@ static void gc_delete_reader (struct gcreq *gcreq)
|
|||
ddsrt_free (rd);
|
||||
}
|
||||
|
||||
int delete_reader (const struct nn_guid *guid)
|
||||
dds_return_t delete_reader (const struct nn_guid *guid)
|
||||
{
|
||||
struct reader *rd;
|
||||
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]);
|
||||
ddsrt_free(fl->inner[i].m);
|
||||
}
|
||||
/* The compiler can't make sense of all these linked lists and doesn't
|
||||
* realize that the next pointers are always initialized here. */
|
||||
DDSRT_WARNING_MSVC_OFF(6001);
|
||||
/* The compiler can't make sense of all these linked lists and doesn't
|
||||
* realize that the next pointers are always initialized here. */
|
||||
DDSRT_WARNING_MSVC_OFF(6001);
|
||||
while ((m = fl->mlist) != NULL)
|
||||
{
|
||||
fl->mlist = m->next;
|
||||
|
@ -155,7 +155,7 @@ DDSRT_WARNING_MSVC_OFF(6001);
|
|||
fl->emlist = m->next;
|
||||
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);
|
||||
|
|
|
@ -415,43 +415,43 @@ static int check_thread_properties (void)
|
|||
return ok;
|
||||
}
|
||||
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
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)
|
||||
{
|
||||
config.enabled_logcats = 0;
|
||||
config.tracingOutputFile = NULL;
|
||||
status = 1;
|
||||
}
|
||||
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stdout") == 0)
|
||||
{
|
||||
config.tracingOutputFile = stdout;
|
||||
status = 1;
|
||||
}
|
||||
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stderr") == 0)
|
||||
{
|
||||
config.tracingOutputFile = stderr;
|
||||
status = 1;
|
||||
}
|
||||
else if ((config.tracingOutputFile = fopen (config.tracingOutputFileName, config.tracingAppendToFile ? "a" : "w")) == NULL)
|
||||
{
|
||||
DDS_ERROR("%s: cannot open for writing\n", config.tracingOutputFileName);
|
||||
status = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 1;
|
||||
}
|
||||
if (config.tracingOutputFileName == NULL || *config.tracingOutputFileName == 0 || config.enabled_logcats == 0)
|
||||
{
|
||||
config.enabled_logcats = 0;
|
||||
config.tracingOutputFile = NULL;
|
||||
status = 1;
|
||||
}
|
||||
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stdout") == 0)
|
||||
{
|
||||
config.tracingOutputFile = stdout;
|
||||
status = 1;
|
||||
}
|
||||
else if (ddsrt_strcasecmp (config.tracingOutputFileName, "stderr") == 0)
|
||||
{
|
||||
config.tracingOutputFile = stderr;
|
||||
status = 1;
|
||||
}
|
||||
else if ((config.tracingOutputFile = fopen (config.tracingOutputFileName, config.tracingAppendToFile ? "a" : "w")) == NULL)
|
||||
{
|
||||
DDS_ERROR("%s: cannot open for writing\n", config.tracingOutputFileName);
|
||||
status = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 1;
|
||||
}
|
||||
|
||||
dds_set_log_mask(config.enabled_logcats);
|
||||
dds_set_trace_file(config.tracingOutputFile);
|
||||
dds_set_log_mask(config.enabled_logcats);
|
||||
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)
|
||||
{
|
||||
|
@ -1654,10 +1654,10 @@ void rtps_fini (void)
|
|||
while (gv.recvips)
|
||||
{
|
||||
struct config_in_addr_node *n = gv.recvips;
|
||||
/* The compiler doesn't realize that n->next is always initialized. */
|
||||
DDSRT_WARNING_MSVC_OFF(6001);
|
||||
/* The compiler doesn't realize that n->next is always initialized. */
|
||||
DDSRT_WARNING_MSVC_OFF(6001);
|
||||
gv.recvips = n->next;
|
||||
DDSRT_WARNING_MSVC_ON(6001);
|
||||
DDSRT_WARNING_MSVC_ON(6001);
|
||||
ddsrt_free (n);
|
||||
}
|
||||
|
||||
|
|
|
@ -77,9 +77,9 @@ static const ipv4_hdr_t ipv4_hdr_template = {
|
|||
#define IPV4_HDR_SIZE 20
|
||||
#define UDP_HDR_SIZE 8
|
||||
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
FILE *new_pcap_file (const char *name)
|
||||
{
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
FILE *fp;
|
||||
pcap_hdr_t hdr;
|
||||
|
||||
|
@ -99,8 +99,8 @@ FILE *new_pcap_file (const char *name)
|
|||
fwrite (&hdr, sizeof (hdr), 1, 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)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "dds/ddsrt/log.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/static_assert.h"
|
||||
|
||||
#include "dds/ddsi/q_log.h"
|
||||
|
||||
|
@ -30,7 +31,6 @@
|
|||
#include "dds/ddsi/q_globals.h"
|
||||
#include "dds/ddsi/q_protocol.h" /* for NN_STATUSINFO_... */
|
||||
#include "dds/ddsi/q_radmin.h" /* for nn_plist_quickscan */
|
||||
#include "dds/ddsi/q_static_assert.h"
|
||||
|
||||
#include "dds/ddsrt/avl.h"
|
||||
#include "dds/ddsi/q_misc.h" /* for vendor_is_... */
|
||||
|
@ -407,8 +407,8 @@ void nn_plist_fini (nn_plist_t *ps)
|
|||
int i;
|
||||
nn_xqos_fini (&ps->qos);
|
||||
|
||||
/* The compiler doesn't understand how offsetof is used in the arrays. */
|
||||
DDSRT_WARNING_MSVC_OFF(6001);
|
||||
/* The compiler doesn't understand how offsetof is used in the arrays. */
|
||||
DDSRT_WARNING_MSVC_OFF(6001);
|
||||
for (i = 0; i < (int) (sizeof (simple) / sizeof (*simple)); i++)
|
||||
{
|
||||
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))
|
||||
free_locators ((nn_locators_t *) ((char *) ps + locs[i].off));
|
||||
}
|
||||
DDSRT_WARNING_MSVC_ON(6001);
|
||||
DDSRT_WARNING_MSVC_ON(6001);
|
||||
|
||||
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))
|
||||
{
|
||||
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));
|
||||
statusinfox = fromBE4u (statusinfox);
|
||||
if (statusinfox & NN_STATUSINFOX_OSPL_AUTO)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "dds/ddsi/q_misc.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, '?');
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
/* inf counts as <= inf */
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "dds/ddsrt/md5.h"
|
||||
#include "dds/ddsrt/sync.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/static_assert.h"
|
||||
|
||||
#include "dds/ddsrt/avl.h"
|
||||
#include "dds__stream.h"
|
||||
|
@ -46,7 +47,6 @@
|
|||
|
||||
#include "dds/ddsi/q_transmit.h"
|
||||
#include "dds/ddsi/q_globals.h"
|
||||
#include "dds/ddsi/q_static_assert.h"
|
||||
#include "dds/ddsi/q_init.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.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.
|
||||
When the result is either ACCEPT or a sample chain, it clearly
|
||||
meant something. */
|
||||
Q_STATIC_ASSERT_CODE (NN_REORDER_ACCEPT == 0);
|
||||
DDSRT_STATIC_ASSERT_CODE (NN_REORDER_ACCEPT == 0);
|
||||
if (res >= 0)
|
||||
gap_was_valuable = 1;
|
||||
|
||||
|
@ -1877,7 +1877,7 @@ unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr)
|
|||
case SMID_DATA_FRAG:
|
||||
{
|
||||
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)
|
||||
return common | DATA_FLAG_KEYFLAG;
|
||||
else
|
||||
|
|
|
@ -89,15 +89,15 @@ void thread_states_init (unsigned maxthreads)
|
|||
thread_states.ts =
|
||||
ddsrt_malloc_aligned_cacheline (maxthreads * sizeof (*thread_states.ts));
|
||||
memset (thread_states.ts, 0, maxthreads * sizeof (*thread_states.ts));
|
||||
/* The compiler doesn't realize that ts is large enough. */
|
||||
DDSRT_WARNING_MSVC_OFF(6386);
|
||||
/* The compiler doesn't realize that ts is large enough. */
|
||||
DDSRT_WARNING_MSVC_OFF(6386);
|
||||
for (i = 0; i < thread_states.nthreads; i++)
|
||||
{
|
||||
thread_states.ts[i].state = THREAD_STATE_ZERO;
|
||||
thread_states.ts[i].vtime = 0u;
|
||||
thread_states.ts[i].name = NULL;
|
||||
}
|
||||
DDSRT_WARNING_MSVC_ON(6386);
|
||||
DDSRT_WARNING_MSVC_ON(6386);
|
||||
}
|
||||
|
||||
void thread_states_fini (void)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/sync.h"
|
||||
#include "dds/ddsrt/static_assert.h"
|
||||
|
||||
#include "dds/ddsrt/avl.h"
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
|
@ -30,7 +31,6 @@
|
|||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_unused.h"
|
||||
#include "dds/ddsi/q_hbcontrol.h"
|
||||
#include "dds/ddsi/q_static_assert.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.h"
|
||||
#include "dds/ddsi/ddsi_serdata.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)
|
||||
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));
|
||||
|
||||
if (fragnum == 0)
|
||||
|
|
|
@ -111,7 +111,9 @@ list(APPEND headers
|
|||
"${include_path}/dds/ddsrt/process.h"
|
||||
"${include_path}/dds/ddsrt/strtod.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
|
||||
"${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) {
|
||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
InterlockedExchangeAdd (&x->v, -v);
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
}
|
||||
#if DDSRT_HAVE_ATOMIC64
|
||||
inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
|
||||
/* disable unary minus applied to unsigned type, result still unsigned */
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
InterlockedExchangeAdd64 (&x->v, -v);
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
}
|
||||
#endif
|
||||
inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
|
||||
/* 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_WARNING_MSVC_ON(4146)
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
}
|
||||
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);
|
||||
}
|
||||
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 */
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
return InterlockedExchangeAdd (&x->v, -v) - v;
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
}
|
||||
#if DDSRT_HAVE_ATOMIC64
|
||||
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 */
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
return InterlockedExchangeAdd64 (&x->v, -v) - v;
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
DDSRT_WARNING_MSVC_ON(4146)
|
||||
}
|
||||
#endif
|
||||
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 */
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
DDSRT_WARNING_MSVC_OFF(4146)
|
||||
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) {
|
||||
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
|
||||
function: This is an unusual usage which could be reconsidered.
|
||||
It is too heavyweight, true, but it does the trick. */
|
||||
DDSRT_WARNING_MSVC_OFF(28113)
|
||||
DDSRT_WARNING_MSVC_OFF(28113)
|
||||
volatile LONG tmp = 0;
|
||||
InterlockedExchange (&tmp, 0);
|
||||
DDSRT_WARNING_MSVC_ON(28113)
|
||||
DDSRT_WARNING_MSVC_ON(28113)
|
||||
}
|
||||
inline void ddsrt_atomic_fence_ldld (void) {
|
||||
#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.
|
||||
*
|
||||
* @param[in] name Environment variable name.
|
||||
* @param[in] buf Buffer to write value to.
|
||||
* @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.
|
||||
* @param[out] value Alias to value of environment variable - must not be modified
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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] 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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
|
|
@ -247,7 +247,7 @@ typedef struct {
|
|||
*
|
||||
* @param[in] name Host name to resolve.
|
||||
* @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.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
* 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
|
||||
*/
|
||||
#ifndef Q_STATIC_ASSERT_H
|
||||
#define Q_STATIC_ASSERT_H
|
||||
#ifndef DDSRT_STATIC_ASSERT_H
|
||||
#define DDSRT_STATIC_ASSERT_H
|
||||
|
||||
/* There are many tricks to use a constant expression to yield an
|
||||
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
|
||||
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
|
||||
|
||||
#define Q_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case pred: ; } } while (0)
|
||||
|
||||
#define DDSRT_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case (pred): ; } } while (0)
|
||||
#else
|
||||
|
||||
/* Temporarily disabling warning C6326: Potential comparison of a
|
||||
constant with another constant. */
|
||||
#define Q_STATIC_ASSERT_CODE(pred) do { \
|
||||
#define DDSRT_STATIC_ASSERT_CODE(pred) do { \
|
||||
__pragma (warning (push)) \
|
||||
__pragma (warning (disable : 6326)) \
|
||||
switch(0) { case 0: case pred: ; } \
|
||||
switch(0) { case 0: case (pred): ; } \
|
||||
__pragma (warning (pop)) \
|
||||
} while (0)
|
||||
|
||||
#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] 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.
|
||||
*/
|
||||
|
@ -74,7 +74,7 @@ ddsrt_strtok_r(
|
|||
* @delim. The delimiter is overwritten with a null byte, terminating the
|
||||
* 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.
|
||||
*
|
||||
* @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
|
||||
* 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] size Number of bytes available in dest.
|
||||
*
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "dds/ddsrt/sync.h"
|
||||
#include "dds/ddsrt/time.h"
|
||||
#include "dds/ddsrt/process.h"
|
||||
#include "dds/ddsrt/static_assert.h"
|
||||
|
||||
#define N DDSRT_MT19937_N
|
||||
#define M 397
|
||||
|
@ -186,9 +187,7 @@ void ddsrt_random_init (void)
|
|||
if (!ddsrt_prng_makeseed (&seed))
|
||||
{
|
||||
/* Poor man's initialisation */
|
||||
struct lengthof_seed_large_enough {
|
||||
char ok[sizeof (seed.key) / sizeof (seed.key[0]) >= 3 ? 1 : -1];
|
||||
};
|
||||
DDSRT_STATIC_ASSERT (sizeof (seed.key) / sizeof (seed.key[0]) >= 3);
|
||||
memset (&seed, 0, sizeof (seed));
|
||||
dds_time_t now = dds_time ();
|
||||
seed.key[0] = (uint32_t) ddsrt_getpid ();
|
||||
|
|
|
@ -305,9 +305,9 @@ static char *unescape_into_utf8 (char *dst, unsigned cp)
|
|||
return dst;
|
||||
}
|
||||
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
static int unescape_insitu (char *buffer, size_t *n)
|
||||
{
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
const char *src = buffer;
|
||||
char const * const srcend = buffer + *n;
|
||||
char *dst = buffer;
|
||||
|
@ -361,8 +361,8 @@ static int unescape_insitu (char *buffer, size_t *n)
|
|||
}
|
||||
*n = (size_t) (dst - buffer);
|
||||
return 0;
|
||||
DDSRT_WARNING_MSVC_ON(4996);
|
||||
}
|
||||
DDSRT_WARNING_MSVC_ON(4996);
|
||||
|
||||
static void discard_payload (struct ddsrt_xmlp_state *st)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue