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:
Erik Boasson 2019-05-23 20:40:51 +02:00 committed by eboasson
parent 19aec98b8a
commit 13480616e0
56 changed files with 2856 additions and 4542 deletions

View file

@ -130,6 +130,7 @@ if(${CMAKE_GENERATOR} STREQUAL "Xcode")
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER YES) set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES) set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES) set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DOCUMENTATION_COMMENTS YES)
endif() endif()
# Make it easy to enable one of Clang's/gcc's analyzers, and default to using # Make it easy to enable one of Clang's/gcc's analyzers, and default to using

View file

@ -74,6 +74,7 @@ PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src"
dds__whc.h dds__whc.h
dds__whc_builtintopic.h dds__whc_builtintopic.h
dds__serdata_builtintopic.h dds__serdata_builtintopic.h
dds__get_status.h
) )
generate_export_header( generate_export_header(

View file

@ -313,7 +313,7 @@ dds_delete(dds_entity_t entity);
* For instance, it will return the Publisher that was used when * For instance, it will return the Publisher that was used when
* creating a DataWriter (when that DataWriter was provided here). * creating a DataWriter (when that DataWriter was provided here).
* *
* @param[in] entity Entity from which to get its publisher. * @param[in] writer Entity from which to get its publisher.
* *
* @returns A valid entity or an error code. * @returns A valid entity or an error code.
* *
@ -361,7 +361,7 @@ dds_get_subscriber(dds_entity_t entity);
* For instance, it will return the DataReader that was used when * For instance, it will return the DataReader that was used when
* creating a ReadCondition (when that ReadCondition was provided here). * creating a ReadCondition (when that ReadCondition was provided here).
* *
* @param[in] entity Entity from which to get its datareader. * @param[in] condition Entity from which to get its datareader.
* *
* @returns A valid reader handle or an error code. * @returns A valid reader handle or an error code.
* *
@ -502,7 +502,7 @@ dds_get_status_changes(dds_entity_t entity, uint32_t *status);
* This operation returns the status enabled on the entity * This operation returns the status enabled on the entity
* *
* @param[in] entity Entity to get the status. * @param[in] entity Entity to get the status.
* @param[out] status Status set on the entity. * @param[out] mask Mask of enabled statuses set on the entity.
* *
* @returns A dds_return_t indicating success or failure. * @returns A dds_return_t indicating success or failure.
* *
@ -952,6 +952,8 @@ dds_create_topic(
const dds_qos_t *qos, const dds_qos_t *qos,
const dds_listener_t *listener); const dds_listener_t *listener);
struct ddsi_sertopic;
struct nn_plist;
/** /**
* @brief Creates a new topic with arbitrary type handling. * @brief Creates a new topic with arbitrary type handling.
* *
@ -972,8 +974,6 @@ dds_create_topic(
* Either participant, descriptor, name or qos is invalid. * Either participant, descriptor, name or qos is invalid.
*/ */
/* TODO: Check list of retcodes is complete. */ /* TODO: Check list of retcodes is complete. */
struct ddsi_sertopic;
struct nn_plist;
DDS_EXPORT dds_entity_t DDS_EXPORT dds_entity_t
dds_create_topic_arbitrary ( dds_create_topic_arbitrary (
dds_entity_t participant, dds_entity_t participant,
@ -1650,8 +1650,7 @@ dds_write_flush(dds_entity_t writer);
* @brief Write a CDR serialized value of a data instance * @brief Write a CDR serialized value of a data instance
* *
* @param[in] writer The writer entity. * @param[in] writer The writer entity.
* @param[in] cdr CDR serialized value to be written. * @param[in] serdata CDR serialized value to be written.
* @param[in] size Size (in bytes) of CDR encoded data to be written.
* *
* @returns A dds_return_t indicating success or failure. * @returns A dds_return_t indicating success or failure.
*/ */
@ -2604,7 +2603,7 @@ dds_take_mask_wl(
uint32_t maxs, uint32_t maxs,
uint32_t mask); uint32_t mask);
DDS_EXPORT int DDS_EXPORT dds_return_t
dds_takecdr( dds_takecdr(
dds_entity_t reader_or_condition, dds_entity_t reader_or_condition,
struct ddsi_serdata **buf, struct ddsi_serdata **buf,
@ -2898,7 +2897,7 @@ dds_read_next_wl(
* the memory is released so that the buffer can be reused during a successive read/take operation. * the memory is released so that the buffer can be reused during a successive read/take operation.
* When a condition is provided, the reader to which the condition belongs is looked up. * When a condition is provided, the reader to which the condition belongs is looked up.
* *
* @param[in] rd_or_cnd Reader or condition that belongs to a reader. * @param[in] reader_or_condition Reader or condition that belongs to a reader.
* @param[in] buf An array of (pointers to) samples. * @param[in] buf An array of (pointers to) samples.
* @param[in] bufsz The number of (pointers to) samples stored in buf. * @param[in] bufsz The number of (pointers to) samples stored in buf.
* *

View file

@ -212,8 +212,8 @@ dds_qos_merge (dds_qos_t * __restrict dst, const dds_qos_t * __restrict src);
* *
* Policies are copied from src to dst, unless src already has the policy set to a non-default value. * Policies are copied from src to dst, unless src already has the policy set to a non-default value.
* *
* @param[in,out] dst - Pointer to the destination qos structure * @param[in,out] a - Pointer to the destination qos structure
* @param[in] src - Pointer to the source qos structure * @param[in] b - Pointer to the source qos structure
*/ */
DDS_EXPORT bool DDS_EXPORT bool
dds_qos_equal (const dds_qos_t * __restrict a, const dds_qos_t * __restrict b); dds_qos_equal (const dds_qos_t * __restrict a, const dds_qos_t * __restrict b);
@ -448,7 +448,7 @@ dds_qset_destination_order (
* @brief Set the writer data-lifecycle policy of a qos structure * @brief Set the writer data-lifecycle policy of a qos structure
* *
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy * @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
* @param[in] autodispose_unregistered_instances - Automatic disposal of unregistered instances * @param[in] autodispose - Automatic disposal of unregistered instances
*/ */
DDS_EXPORT void DDS_EXPORT void
dds_qset_writer_data_lifecycle (dds_qos_t * __restrict qos, bool autodispose); dds_qset_writer_data_lifecycle (dds_qos_t * __restrict qos, bool autodispose);
@ -738,7 +738,7 @@ dds_qget_destination_order (
* @brief Get the writer data-lifecycle qos policy * @brief Get the writer data-lifecycle qos policy
* *
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in] qos - Pointer to a dds_qos_t structure storing the policy
* @param[in,out] autodispose_unregistered_instances - Pointer that will store the autodispose unregistered instances enable value * @param[in,out] autodispose - Pointer that will store the autodispose unregistered instances enable value
* *
* @returns - false iff any of the arguments is invalid or the qos is not present in the qos object * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object
*/ */

View 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

View file

@ -23,7 +23,7 @@ DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_subscriber, DDS_KIND_SUBSCRIBER)
dds_entity_t dds_entity_t
dds__create_subscriber_l( dds__create_subscriber_l(
struct dds_entity *participant, /* entity-lock must be held */ struct dds_participant *participant, /* entity-lock must be held */
const dds_qos_t *qos, const dds_qos_t *qos,
const dds_listener_t *listener); const dds_listener_t *listener);

View file

@ -21,8 +21,8 @@ extern "C" {
DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_topic, DDS_KIND_TOPIC) DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_topic, DDS_KIND_TOPIC)
DDS_EXPORT struct ddsi_sertopic * dds_topic_lookup (dds_domain * domain, const char * name); DDS_EXPORT struct ddsi_sertopic * dds_topic_lookup (dds_domain * domain, const char * name) ddsrt_nonnull_all;
DDS_EXPORT void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic * st); DDS_EXPORT void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic * st) ddsrt_nonnull_all;
#ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED #ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED
#define DDS_TOPIC_INTERN_FILTER_FN_DEFINED #define DDS_TOPIC_INTERN_FILTER_FN_DEFINED

View file

@ -104,12 +104,12 @@ dds_domain;
struct dds_entity; struct dds_entity;
typedef struct dds_entity_deriver { typedef struct dds_entity_deriver {
/* Close can be used to terminate (blocking) actions on a entity before actually deleting it. */ /* Close can be used to terminate (blocking) actions on a entity before actually deleting it. */
dds_return_t (*close)(struct dds_entity *e); dds_return_t (*close)(struct dds_entity *e) ddsrt_nonnull_all;
/* Delete is used to actually free the entity. */ /* Delete is used to actually free the entity. */
dds_return_t (*delete)(struct dds_entity *e); dds_return_t (*delete)(struct dds_entity *e) ddsrt_nonnull_all;
dds_return_t (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled); dds_return_t (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_return_t (*validate_status)(uint32_t mask); dds_return_t (*validate_status)(uint32_t mask);
dds_return_t (*get_instance_hdl)(struct dds_entity *e, dds_instance_handle_t *i); dds_return_t (*get_instance_hdl)(struct dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
} }
dds_entity_deriver; dds_entity_deriver;

View file

@ -132,7 +132,7 @@ bool dds__validate_builtin_reader_qos (dds_entity_t topic, const dds_qos_t *qos)
} }
} }
static dds_entity_t dds__create_builtin_subscriber (dds_entity *participant) static dds_entity_t dds__create_builtin_subscriber (dds_participant *participant)
{ {
dds_qos_t *qos = dds__create_builtin_qos (); dds_qos_t *qos = dds__create_builtin_qos ();
dds_entity_t sub = dds__create_subscriber_l (participant, qos, NULL); dds_entity_t sub = dds__create_subscriber_l (participant, qos, NULL);
@ -153,7 +153,7 @@ dds_entity_t dds__get_builtin_subscriber (dds_entity_t e)
return ret; return ret;
if (p->m_builtin_subscriber <= 0) { if (p->m_builtin_subscriber <= 0) {
p->m_builtin_subscriber = dds__create_builtin_subscriber (&p->m_entity); p->m_builtin_subscriber = dds__create_builtin_subscriber (p);
} }
sub = p->m_builtin_subscriber; sub = p->m_builtin_subscriber;
dds_participant_unlock(p); dds_participant_unlock(p);

View file

@ -16,17 +16,13 @@
#include "dds__subscriber.h" #include "dds__subscriber.h"
#include "dds__publisher.h" #include "dds__publisher.h"
dds_return_t dds_return_t dds_begin_coherent (dds_entity_t entity)
dds_begin_coherent(
dds_entity_t entity)
{ {
static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER }; static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER };
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds); return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);
} }
dds_return_t dds_return_t dds_end_coherent (dds_entity_t entity)
dds_end_coherent(
dds_entity_t entity)
{ {
static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER }; static const dds_entity_kind_t kinds[] = { DDS_KIND_READER, DDS_KIND_WRITER, DDS_KIND_PUBLISHER, DDS_KIND_SUBSCRIBER };
return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds); return dds_generic_unimplemented_operation_manykinds (entity, sizeof (kinds) / sizeof (kinds[0]), kinds);

View file

@ -12,27 +12,24 @@
#include "dds__domain.h" #include "dds__domain.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
static int dds_domain_compare (const int32_t * a, const int32_t * b) static int dds_domain_compare (const void *va, const void *vb)
{ {
const int32_t *a = va;
const int32_t *b = vb;
return (*a == *b) ? 0 : (*a < *b) ? -1 : 1; return (*a == *b) ? 0 : (*a < *b) ? -1 : 1;
} }
const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALIZER const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALIZER (
( offsetof (dds_domain, m_node), offsetof (dds_domain, m_id), dds_domain_compare, 0);
offsetof (dds_domain, m_node),
offsetof (dds_domain, m_id),
(int (*) (const void *, const void *)) dds_domain_compare,
0
);
dds_domain * dds_domain_find_locked (dds_domainid_t id) dds_domain *dds_domain_find_locked (dds_domainid_t id)
{ {
return ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &id); return ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &id);
} }
dds_domain * dds_domain_create (dds_domainid_t id) dds_domain *dds_domain_create (dds_domainid_t id)
{ {
dds_domain * domain; dds_domain *domain;
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
domain = dds_domain_find_locked (id); domain = dds_domain_find_locked (id);
if (domain == NULL) if (domain == NULL)
@ -47,7 +44,7 @@ dds_domain * dds_domain_create (dds_domainid_t id)
return domain; return domain;
} }
void dds_domain_free (dds_domain * domain) void dds_domain_free (dds_domain *domain)
{ {
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
if (--domain->m_refc == 0) if (--domain->m_refc == 0)

View file

@ -18,7 +18,7 @@
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_guardcond) DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_guardcond)
dds_entity_t dds_create_guardcondition (dds_entity_t participant) dds_entity_t dds_create_guardcondition (dds_entity_t participant)
{ {

View file

@ -23,54 +23,34 @@
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
#include "dds/ddsi/q_globals.h" #include "dds/ddsi/q_globals.h"
dds_return_t dds_return_t dds_writedispose (dds_entity_t writer, const void *data)
dds_writedispose(
dds_entity_t writer,
const void *data)
{ {
return dds_writedispose_ts(writer, data, dds_time()); return dds_writedispose_ts (writer, data, dds_time ());
} }
dds_return_t dds_return_t dds_dispose (dds_entity_t writer, const void *data)
dds_dispose(
dds_entity_t writer,
const void *data)
{ {
return dds_dispose_ts(writer, data, dds_time()); return dds_dispose_ts (writer, data, dds_time ());
} }
dds_return_t dds_return_t dds_dispose_ih (dds_entity_t writer, dds_instance_handle_t handle)
dds_dispose_ih(
dds_entity_t writer,
dds_instance_handle_t handle)
{ {
return dds_dispose_ih_ts(writer, handle, dds_time()); return dds_dispose_ih_ts (writer, handle, dds_time ());
} }
static struct ddsi_tkmap_instance* static struct ddsi_tkmap_instance *dds_instance_find (const dds_topic *topic, const void *data, const bool create)
dds_instance_find(
const dds_topic *topic,
const void *data,
const bool create)
{ {
struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data); struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
struct ddsi_tkmap_instance * inst = ddsi_tkmap_find (sd, false, create); struct ddsi_tkmap_instance *inst = ddsi_tkmap_find (sd, false, create);
ddsi_serdata_unref (sd); ddsi_serdata_unref (sd);
return inst; return inst;
} }
static void static void dds_instance_remove (const dds_topic *topic, const void *data, dds_instance_handle_t handle)
dds_instance_remove(
const dds_topic *topic,
const void *data,
dds_instance_handle_t handle)
{ {
struct ddsi_tkmap_instance * inst; struct ddsi_tkmap_instance *inst;
if (handle != DDS_HANDLE_NIL) if (handle != DDS_HANDLE_NIL)
{
inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle); inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle);
}
else else
{ {
assert (data); assert (data);
@ -100,122 +80,94 @@ static const dds_topic *dds_instance_info (dds_entity *e)
return topic; return topic;
} }
static const dds_topic * dds_instance_info_by_hdl (dds_entity_t e) static const dds_topic *dds_instance_info_by_hdl (dds_entity_t e)
{ {
const dds_topic * topic = NULL; const dds_topic *topic;
dds_return_t rc;
dds_entity *w_or_r; dds_entity *w_or_r;
rc = dds_entity_lock(e, DDS_KIND_WRITER, &w_or_r); if (dds_entity_lock (e, DDS_KIND_DONTCARE, &w_or_r) != DDS_RETCODE_OK)
if (rc == DDS_RETCODE_ILLEGAL_OPERATION)
{
rc = dds_entity_lock(e, DDS_KIND_READER, &w_or_r);
}
if (rc != DDS_RETCODE_OK)
{
return NULL; 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;
} }
topic = dds_instance_info(w_or_r); dds_entity_unlock (w_or_r);
dds_entity_unlock(w_or_r);
return topic; return topic;
} }
dds_return_t dds_return_t dds_register_instance (dds_entity_t writer, dds_instance_handle_t *handle, const void *data)
dds_register_instance(
dds_entity_t writer,
dds_instance_handle_t *handle,
const void *data)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
struct ddsi_tkmap_instance * inst;
dds_writer *wr; dds_writer *wr;
dds_return_t ret; dds_return_t ret;
if(data == NULL){ if (data == NULL || handle == NULL)
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
}
if(handle == NULL){ if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
return DDS_RETCODE_BAD_PARAMETER; return ret;
}
ret = dds_writer_lock(writer, &wr);
if (ret != DDS_RETCODE_OK) {
goto err;
}
thread_state_awake (ts1); thread_state_awake (ts1);
inst = dds_instance_find (wr->m_topic, data, true); struct ddsi_tkmap_instance * const inst = dds_instance_find (wr->m_topic, data, true);
if(inst != NULL){ if (inst == NULL)
ret = DDS_RETCODE_ERROR;
else
{
*handle = inst->m_iid; *handle = inst->m_iid;
ret = DDS_RETCODE_OK; ret = DDS_RETCODE_OK;
} else {
ret = DDS_RETCODE_ERROR;
} }
thread_state_asleep (ts1); thread_state_asleep (ts1);
dds_writer_unlock(wr); dds_writer_unlock (wr);
err:
return ret; return ret;
} }
dds_return_t dds_return_t dds_unregister_instance (dds_entity_t writer, const void *data)
dds_unregister_instance(
dds_entity_t writer,
const void *data)
{ {
return dds_unregister_instance_ts (writer, data, dds_time()); return dds_unregister_instance_ts (writer, data, dds_time ());
} }
dds_return_t dds_return_t dds_unregister_instance_ih (dds_entity_t writer, dds_instance_handle_t handle)
dds_unregister_instance_ih(
dds_entity_t writer,
dds_instance_handle_t handle)
{ {
return dds_unregister_instance_ih_ts(writer, handle, dds_time()); return dds_unregister_instance_ih_ts (writer, handle, dds_time ());
} }
dds_return_t dds_return_t dds_unregister_instance_ts (dds_entity_t writer, const void *data, dds_time_t timestamp)
dds_unregister_instance_ts(
dds_entity_t writer,
const void *data,
dds_time_t timestamp)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret;
bool autodispose = true; bool autodispose = true;
dds_write_action action = DDS_WR_ACTION_UNREGISTER; dds_write_action action = DDS_WR_ACTION_UNREGISTER;
dds_writer *wr; dds_writer *wr;
if (data == NULL){ if (data == NULL || timestamp < 0)
ret = DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
goto err;
}
if(timestamp < 0){
ret = DDS_RETCODE_BAD_PARAMETER;
goto err;
}
ret = dds_writer_lock(writer, &wr);
if (ret != DDS_RETCODE_OK) {
goto err;
}
if (wr->m_entity.m_qos) { if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
return ret;
if (wr->m_entity.m_qos)
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose); dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
}
thread_state_awake (ts1); thread_state_awake (ts1);
if (autodispose) { if (autodispose)
{
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL); dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
action |= DDS_WR_DISPOSE_BIT; action |= DDS_WR_DISPOSE_BIT;
} }
ret = dds_write_impl (wr, data, timestamp, action); ret = dds_write_impl (wr, data, timestamp, action);
thread_state_asleep (ts1); thread_state_asleep (ts1);
dds_writer_unlock(wr); dds_writer_unlock (wr);
err:
return ret; return ret;
} }
dds_return_t dds_return_t dds_unregister_instance_ih_ts (dds_entity_t writer, dds_instance_handle_t handle, dds_time_t timestamp)
dds_unregister_instance_ih_ts(
dds_entity_t writer,
dds_instance_handle_t handle,
dds_time_t timestamp)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret = DDS_RETCODE_OK;
@ -224,195 +176,154 @@ dds_unregister_instance_ih_ts(
dds_writer *wr; dds_writer *wr;
struct ddsi_tkmap_instance *tk; struct ddsi_tkmap_instance *tk;
ret = dds_writer_lock(writer, &wr); if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
if (ret != DDS_RETCODE_OK) { return ret;
goto err;
}
if (wr->m_entity.m_qos) { if (wr->m_entity.m_qos)
dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose); dds_qget_writer_data_lifecycle (wr->m_entity.m_qos, &autodispose);
}
thread_state_awake (ts1); thread_state_awake (ts1);
if (autodispose) { if (autodispose)
{
dds_instance_remove (wr->m_topic, NULL, handle); dds_instance_remove (wr->m_topic, NULL, handle);
action |= DDS_WR_DISPOSE_BIT; action |= DDS_WR_DISPOSE_BIT;
} }
tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle); if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) == NULL)
if (tk) { ret = DDS_RETCODE_PRECONDITION_NOT_MET;
else
{
struct ddsi_sertopic *tp = wr->m_topic->m_stopic; struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
void *sample = ddsi_sertopic_alloc_sample (tp); void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL); ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk); ddsi_tkmap_instance_unref (tk);
ret = dds_write_impl (wr, sample, timestamp, action); ret = dds_write_impl (wr, sample, timestamp, action);
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL); ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
} else {
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
} }
thread_state_asleep (ts1); thread_state_asleep (ts1);
dds_writer_unlock(wr); dds_writer_unlock (wr);
err:
return ret; return ret;
} }
dds_return_t dds_return_t dds_writedispose_ts (dds_entity_t writer, const void *data, dds_time_t timestamp)
dds_writedispose_ts(
dds_entity_t writer,
const void *data,
dds_time_t timestamp)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret; dds_return_t ret;
dds_writer *wr; dds_writer *wr;
ret = dds_writer_lock(writer, &wr); if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
thread_state_awake (ts1); thread_state_awake (ts1);
ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_WRITE_DISPOSE); if ((ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_WRITE_DISPOSE)) == DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) {
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL); dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
}
thread_state_asleep (ts1); thread_state_asleep (ts1);
dds_writer_unlock(wr); dds_writer_unlock (wr);
}
return ret; return ret;
} }
static dds_return_t static dds_return_t dds_dispose_impl (dds_writer *wr, const void *data, dds_instance_handle_t handle, dds_time_t timestamp) ddsrt_nonnull_all;
dds_dispose_impl(
dds_writer *wr, static dds_return_t dds_dispose_impl (dds_writer *wr, const void *data, dds_instance_handle_t handle, dds_time_t timestamp)
const void *data,
dds_instance_handle_t handle,
dds_time_t timestamp)
{ {
dds_return_t ret; dds_return_t ret;
assert(thread_is_awake ()); assert (thread_is_awake ());
assert(wr); if ((ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_DISPOSE)) == DDS_RETCODE_OK)
ret = dds_write_impl(wr, data, timestamp, DDS_WR_ACTION_DISPOSE);
if (ret == DDS_RETCODE_OK) {
dds_instance_remove (wr->m_topic, data, handle); dds_instance_remove (wr->m_topic, data, handle);
}
return ret; return ret;
} }
dds_return_t dds_return_t dds_dispose_ts (dds_entity_t writer, const void *data, dds_time_t timestamp)
dds_dispose_ts(
dds_entity_t writer,
const void *data,
dds_time_t timestamp)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret; dds_return_t ret;
dds_writer *wr; dds_writer *wr;
ret = dds_writer_lock(writer, &wr); if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
thread_state_awake (ts1); thread_state_awake (ts1);
ret = dds_dispose_impl(wr, data, DDS_HANDLE_NIL, timestamp); ret = dds_dispose_impl (wr, data, DDS_HANDLE_NIL, timestamp);
thread_state_asleep (ts1); thread_state_asleep (ts1);
dds_writer_unlock(wr); dds_writer_unlock(wr);
}
return ret; return ret;
} }
dds_return_t dds_return_t dds_dispose_ih_ts (dds_entity_t writer, dds_instance_handle_t handle, dds_time_t timestamp)
dds_dispose_ih_ts(
dds_entity_t writer,
dds_instance_handle_t handle,
dds_time_t timestamp)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret; dds_return_t ret;
dds_writer *wr; dds_writer *wr;
ret = dds_writer_lock(writer, &wr); if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
struct ddsi_tkmap_instance *tk; struct ddsi_tkmap_instance *tk;
thread_state_awake (ts1); thread_state_awake (ts1);
if ((tk = ddsi_tkmap_find_by_id (gv.m_tkmap, handle)) != NULL) { 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; struct ddsi_sertopic *tp = wr->m_topic->m_stopic;
void *sample = ddsi_sertopic_alloc_sample (tp); void *sample = ddsi_sertopic_alloc_sample (tp);
ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL); ddsi_serdata_topicless_to_sample (tp, tk->m_sample, sample, NULL, NULL);
ddsi_tkmap_instance_unref (tk); ddsi_tkmap_instance_unref (tk);
ret = dds_dispose_impl (wr, sample, handle, timestamp); ret = dds_dispose_impl (wr, sample, handle, timestamp);
ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL); ddsi_sertopic_free_sample (tp, sample, DDS_FREE_ALL);
} else {
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
} }
thread_state_asleep (ts1); thread_state_asleep (ts1);
dds_writer_unlock(wr); dds_writer_unlock (wr);
}
return ret; return ret;
} }
dds_instance_handle_t dds_instance_handle_t dds_lookup_instance (dds_entity_t entity, const void *data)
dds_lookup_instance(
dds_entity_t entity,
const void *data)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_instance_handle_t ih = DDS_HANDLE_NIL; dds_instance_handle_t ih = DDS_HANDLE_NIL;
const dds_topic * topic; const dds_topic *topic;
struct ddsi_tkmap * map = gv.m_tkmap;
struct ddsi_serdata *sd; struct ddsi_serdata *sd;
if(data == NULL){ if (data == NULL)
goto err; return DDS_HANDLE_NIL;
}
if ((topic = dds_instance_info_by_hdl (entity)) == NULL)
return DDS_HANDLE_NIL;
topic = dds_instance_info_by_hdl (entity);
if (topic) {
thread_state_awake (ts1); thread_state_awake (ts1);
sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data); sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
ih = ddsi_tkmap_lookup (map, sd); ih = ddsi_tkmap_lookup (gv.m_tkmap, sd);
ddsi_serdata_unref (sd); ddsi_serdata_unref (sd);
thread_state_asleep (ts1); thread_state_asleep (ts1);
}
err:
return ih; return ih;
} }
dds_instance_handle_t dds_instance_handle_t dds_instance_lookup (dds_entity_t entity, const void *data)
dds_instance_lookup (
dds_entity_t entity,
const void *data)
{ {
return dds_lookup_instance(entity, data); return dds_lookup_instance (entity, data);
} }
dds_return_t dds_return_t dds_instance_get_key (dds_entity_t entity, dds_instance_handle_t ih, void *data)
dds_instance_get_key(
dds_entity_t entity,
dds_instance_handle_t ih,
void *data)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret; dds_return_t ret;
const dds_topic * topic; const dds_topic *topic;
struct ddsi_tkmap_instance * tk; struct ddsi_tkmap_instance *tk;
if(data == NULL){ if (data == NULL)
ret = DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
goto err;
} if ((topic = dds_instance_info_by_hdl (entity)) == NULL)
return DDS_RETCODE_BAD_PARAMETER;
topic = dds_instance_info_by_hdl (entity);
if(topic == NULL){
ret = DDS_RETCODE_BAD_PARAMETER;
goto err;
}
thread_state_awake (ts1); thread_state_awake (ts1);
if ((tk = ddsi_tkmap_find_by_id(gv.m_tkmap, ih)) != NULL) { 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_sertopic_zero_sample (topic->m_stopic, data);
ddsi_serdata_topicless_to_sample (topic->m_stopic, tk->m_sample, data, NULL, NULL); ddsi_serdata_topicless_to_sample (topic->m_stopic, tk->m_sample, data, NULL, NULL);
ddsi_tkmap_instance_unref (tk); ddsi_tkmap_instance_unref (tk);
ret = DDS_RETCODE_OK; ret = DDS_RETCODE_OK;
} else {
ret = DDS_RETCODE_BAD_PARAMETER;
} }
thread_state_asleep (ts1); thread_state_asleep (ts1);
err:
return ret; return ret;
} }

View file

@ -207,324 +207,169 @@ void dds_merge_listener (dds_listener_t * __restrict dst, const dds_listener_t *
void dds_listener_merge (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src) void dds_listener_merge (dds_listener_t * __restrict dst, const dds_listener_t * __restrict src)
{ {
dds_merge_listener(dst, src); dds_merge_listener (dst, src);
} }
/************************************************************************************************ /************************************************************************************************
* Setters * Setters
************************************************************************************************/ ************************************************************************************************/
void void dds_lset_data_available (dds_listener_t * __restrict listener, dds_on_data_available_fn callback)
dds_lset_data_available (dds_listener_t * __restrict listener, dds_on_data_available_fn callback)
{ {
if (listener) { if (listener)
listener->on_data_available = callback; listener->on_data_available = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_data_on_readers (dds_listener_t * __restrict listener, dds_on_data_on_readers_fn callback)
dds_lset_data_on_readers (dds_listener_t * __restrict listener, dds_on_data_on_readers_fn callback)
{ {
if (listener) { if (listener)
listener->on_data_on_readers = callback; listener->on_data_on_readers = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_inconsistent_topic (dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn callback)
dds_lset_inconsistent_topic (dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn callback)
{ {
if (listener) { if (listener)
listener->on_inconsistent_topic = callback; listener->on_inconsistent_topic = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_liveliness_changed (dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn callback)
dds_lset_liveliness_changed (dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn callback)
{ {
if (listener) { if (listener)
listener->on_liveliness_changed = callback; listener->on_liveliness_changed = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_liveliness_lost (dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn callback)
dds_lset_liveliness_lost (dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn callback)
{ {
if (listener) { if (listener)
listener->on_liveliness_lost = callback; listener->on_liveliness_lost = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_offered_deadline_missed (dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn callback)
dds_lset_offered_deadline_missed (dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn callback)
{ {
if (listener) { if (listener)
listener->on_offered_deadline_missed = callback; listener->on_offered_deadline_missed = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_offered_incompatible_qos (dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn callback)
dds_lset_offered_incompatible_qos (dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn callback)
{ {
if (listener) { if (listener)
listener->on_offered_incompatible_qos = callback; listener->on_offered_incompatible_qos = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_publication_matched (dds_listener_t * __restrict listener, dds_on_publication_matched_fn callback)
dds_lset_publication_matched (dds_listener_t * __restrict listener, dds_on_publication_matched_fn callback)
{ {
if (listener) { if (listener)
listener->on_publication_matched = callback; listener->on_publication_matched = callback;
} else {
DDS_ERROR("Argument listener is NULL");
}
} }
void void dds_lset_requested_deadline_missed (dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn callback)
dds_lset_requested_deadline_missed (dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn callback)
{ {
if (listener) { if (listener)
listener->on_requested_deadline_missed = callback; listener->on_requested_deadline_missed = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_requested_incompatible_qos (dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn callback)
dds_lset_requested_incompatible_qos (dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn callback)
{ {
if (listener) { if (listener)
listener->on_requested_incompatible_qos = callback; listener->on_requested_incompatible_qos = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_sample_lost (dds_listener_t * __restrict listener, dds_on_sample_lost_fn callback)
dds_lset_sample_lost (dds_listener_t * __restrict listener, dds_on_sample_lost_fn callback)
{ {
if (listener) { if (listener)
listener->on_sample_lost = callback; listener->on_sample_lost = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_sample_rejected (dds_listener_t * __restrict listener, dds_on_sample_rejected_fn callback)
dds_lset_sample_rejected (dds_listener_t * __restrict listener, dds_on_sample_rejected_fn callback)
{ {
if (listener) { if (listener)
listener->on_sample_rejected = callback; listener->on_sample_rejected = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
void void dds_lset_subscription_matched (dds_listener_t * __restrict listener, dds_on_subscription_matched_fn callback)
dds_lset_subscription_matched (dds_listener_t * __restrict listener, dds_on_subscription_matched_fn callback)
{ {
if (listener) { if (listener)
listener->on_subscription_matched = callback; listener->on_subscription_matched = callback;
} else {
DDS_ERROR("Argument listener is NULL\n");
}
} }
/************************************************************************************************ /************************************************************************************************
* Getters * Getters
************************************************************************************************/ ************************************************************************************************/
void void dds_lget_data_available (const dds_listener_t * __restrict listener, dds_on_data_available_fn *callback)
dds_lget_data_available (const dds_listener_t * __restrict listener, dds_on_data_available_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_data_available; *callback = listener->on_data_available;
} }
void void dds_lget_data_on_readers (const dds_listener_t * __restrict listener, dds_on_data_on_readers_fn *callback)
dds_lget_data_on_readers (const dds_listener_t * __restrict listener, dds_on_data_on_readers_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_data_on_readers; *callback = listener->on_data_on_readers;
} }
void dds_lget_inconsistent_topic (const dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn *callback) void dds_lget_inconsistent_topic (const dds_listener_t * __restrict listener, dds_on_inconsistent_topic_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_inconsistent_topic; *callback = listener->on_inconsistent_topic;
} }
void void dds_lget_liveliness_changed (const dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn *callback)
dds_lget_liveliness_changed (const dds_listener_t * __restrict listener, dds_on_liveliness_changed_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_liveliness_changed; *callback = listener->on_liveliness_changed;
} }
void void dds_lget_liveliness_lost (const dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn *callback)
dds_lget_liveliness_lost (const dds_listener_t * __restrict listener, dds_on_liveliness_lost_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_liveliness_lost; *callback = listener->on_liveliness_lost;
} }
void void dds_lget_offered_deadline_missed (const dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn *callback)
dds_lget_offered_deadline_missed (const dds_listener_t * __restrict listener, dds_on_offered_deadline_missed_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_offered_deadline_missed; *callback = listener->on_offered_deadline_missed;
} }
void void dds_lget_offered_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn *callback)
dds_lget_offered_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_offered_incompatible_qos_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_offered_incompatible_qos; *callback = listener->on_offered_incompatible_qos;
} }
void void dds_lget_publication_matched (const dds_listener_t * __restrict listener, dds_on_publication_matched_fn *callback)
dds_lget_publication_matched (const dds_listener_t * __restrict listener, dds_on_publication_matched_fn *callback)
{ {
if(!callback){ if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_publication_matched; *callback = listener->on_publication_matched;
} }
void void dds_lget_requested_deadline_missed (const dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn *callback)
dds_lget_requested_deadline_missed (const dds_listener_t * __restrict listener, dds_on_requested_deadline_missed_fn *callback)
{ {
if(!callback) { if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_requested_deadline_missed; *callback = listener->on_requested_deadline_missed;
} }
void void dds_lget_requested_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn *callback)
dds_lget_requested_incompatible_qos (const dds_listener_t * __restrict listener, dds_on_requested_incompatible_qos_fn *callback)
{ {
if(!callback) { if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_requested_incompatible_qos; *callback = listener->on_requested_incompatible_qos;
} }
void void dds_lget_sample_lost (const dds_listener_t *__restrict listener, dds_on_sample_lost_fn *callback)
dds_lget_sample_lost (const dds_listener_t *__restrict listener, dds_on_sample_lost_fn *callback)
{ {
if(!callback) { if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_sample_lost; *callback = listener->on_sample_lost;
} }
void void dds_lget_sample_rejected (const dds_listener_t *__restrict listener, dds_on_sample_rejected_fn *callback)
dds_lget_sample_rejected (const dds_listener_t *__restrict listener, dds_on_sample_rejected_fn *callback)
{ {
if(!callback) { if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_sample_rejected; *callback = listener->on_sample_rejected;
} }
void void dds_lget_subscription_matched (const dds_listener_t * __restrict listener, dds_on_subscription_matched_fn *callback)
dds_lget_subscription_matched (const dds_listener_t * __restrict listener, dds_on_subscription_matched_fn *callback)
{ {
if(!callback) { if (callback && listener)
DDS_ERROR("Argument callback is NULL\n");
return ;
}
if (!listener) {
DDS_ERROR("Argument listener is NULL\n");
return ;
}
*callback = listener->on_subscription_matched; *callback = listener->on_subscription_matched;
} }

View file

@ -21,185 +21,126 @@
#include "dds__participant.h" #include "dds__participant.h"
#include "dds__builtin.h" #include "dds__builtin.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_participant) DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_participant)
#define DDS_PARTICIPANT_STATUS_MASK 0u #define DDS_PARTICIPANT_STATUS_MASK (0u)
/* List of created participants */ /* List of created participants */
static dds_entity *dds_pp_head = NULL;
static dds_entity * dds_pp_head = NULL; static dds_return_t dds_participant_status_validate (uint32_t mask)
static dds_return_t
dds_participant_status_validate(
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK; return (mask & ~DDS_PARTICIPANT_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
if (mask & ~(DDS_PARTICIPANT_STATUS_MASK)) {
ret = DDS_RETCODE_BAD_PARAMETER;
}
return ret;
} }
static dds_return_t static dds_return_t dds_participant_delete (dds_entity *e) ddsrt_nonnull_all;
dds_participant_delete(
dds_entity *e)
{
dds_entity *prev = NULL;
dds_entity *iter;
assert(e); static dds_return_t dds_participant_delete (dds_entity *e)
assert(dds_entity_kind(e) == DDS_KIND_PARTICIPANT); {
assert (dds_entity_kind (e) == DDS_KIND_PARTICIPANT);
thread_state_awake (lookup_thread_state ()); thread_state_awake (lookup_thread_state ());
dds_domain_free (e->m_domain); dds_domain_free (e->m_domain);
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
iter = dds_pp_head; dds_entity *prev, *iter;
while (iter) { for (iter = dds_pp_head, prev = NULL; iter; prev = iter, iter = iter->m_next)
if (iter == e) { {
if (prev) { if (iter == e)
prev->m_next = iter->m_next;
} else {
dds_pp_head = iter->m_next;
}
break; break;
} }
prev = iter;
iter = iter->m_next;
}
ddsrt_mutex_unlock (&dds_global.m_mutex);
assert (iter); 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_asleep (lookup_thread_state ());
/* Every dds_init needs a dds_fini. */ /* Every dds_init needs a dds_fini. */
dds_fini(); dds_fini ();
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
static dds_return_t static dds_return_t dds_participant_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
dds_participant_instance_hdl(
dds_entity *e, static dds_return_t dds_participant_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
dds_instance_handle_t *i)
{ {
assert(e); *i = participant_instance_id (&e->m_guid);
assert(i);
*i = (dds_instance_handle_t)participant_instance_id(&e->m_guid);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
static dds_return_t static dds_return_t dds_participant_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_participant_qos_validate(
const dds_qos_t *qos, static dds_return_t dds_participant_qos_validate (const dds_qos_t *qos, bool enabled)
bool enabled)
{ {
dds_return_t ret = DDS_RETCODE_OK;
assert(qos);
(void)enabled; (void)enabled;
/* Check consistency. */ if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
if ((qos->present & QP_USER_DATA) && !validate_octetseq(&qos->user_data)) { return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("User data QoS policy is inconsistent and caused an error\n"); if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
ret = DDS_RETCODE_INCONSISTENT_POLICY; return DDS_RETCODE_INCONSISTENT_POLICY;
}
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)) { return DDS_RETCODE_OK;
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) ddsrt_nonnull_all;
static dds_return_t static dds_return_t dds_participant_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
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_return_t ret;
dds_entity_t e; (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; nn_guid_t guid;
dds_participant * pp; dds_participant * pp;
nn_plist_t plist; nn_plist_t plist;
dds_qos_t * new_qos = NULL; dds_qos_t *new_qos = NULL;
/* Make sure DDS instance is initialized. */ /* Make sure DDS instance is initialized. */
ret = dds_init(domain); if ((ret = dds_init (domain)) != DDS_RETCODE_OK)
if (ret != DDS_RETCODE_OK) { goto err_dds_init;
e = (dds_entity_t)ret;
goto fail_dds_init;
}
/* Check domain id */ /* Check domain id */
ret = dds__check_domain (domain); if ((ret = dds__check_domain (domain)) != DDS_RETCODE_OK)
if (ret != DDS_RETCODE_OK) { goto err_domain_check;
e = (dds_entity_t)ret;
goto fail_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;
/* 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 (); new_qos = dds_create_qos ();
/* Only returns failure when one of the qos args is NULL, which if (qos != NULL)
* is not the case here. */ (void) dds_copy_qos (new_qos, qos);
(void)dds_copy_qos(new_qos, qos);
} else {
/* Use default qos. */
new_qos = dds_create_qos ();
}
/* Translate qos */ /* Translate qos */
nn_plist_init_empty(&plist); nn_plist_init_empty (&plist);
dds_merge_qos (&plist.qos, new_qos); dds_merge_qos (&plist.qos, new_qos);
thread_state_awake (lookup_thread_state ()); thread_state_awake (lookup_thread_state ());
q_rc = new_participant (&guid, 0, &plist); ret = new_participant (&guid, 0, &plist);
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());
nn_plist_fini (&plist); nn_plist_fini (&plist);
if (q_rc != 0) { if (ret < 0)
DDS_ERROR("Internal error"); {
e = DDS_RETCODE_ERROR; ret = DDS_RETCODE_ERROR;
goto fail_new_participant; goto err_new_participant;
} }
pp = dds_alloc (sizeof (*pp)); pp = dds_alloc (sizeof (*pp));
e = dds_entity_init (&pp->m_entity, NULL, DDS_KIND_PARTICIPANT, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK); if ((ret = dds_entity_init (&pp->m_entity, NULL, DDS_KIND_PARTICIPANT, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK)) < 0)
if (e < 0) { goto err_entity_init;
goto fail_entity_init;
}
pp->m_entity.m_guid = guid; pp->m_entity.m_guid = guid;
pp->m_entity.m_domain = dds_domain_create (dds_domain_default()); pp->m_entity.m_domain = dds_domain_create (dds_domain_default ());
pp->m_entity.m_domainid = 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.delete = dds_participant_delete;
pp->m_entity.m_deriver.set_qos = dds_participant_qos_set; 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.get_instance_hdl = dds_participant_instance_hdl;
@ -211,70 +152,52 @@ dds_create_participant(
pp->m_entity.m_next = dds_pp_head; pp->m_entity.m_next = dds_pp_head;
dds_pp_head = &pp->m_entity; dds_pp_head = &pp->m_entity;
ddsrt_mutex_unlock (&dds_global.m_mutex); ddsrt_mutex_unlock (&dds_global.m_mutex);
return ret;
return e; err_entity_init:
dds_free (pp);
fail_entity_init: err_new_participant:
dds_free(pp); dds_delete_qos (new_qos);
fail_new_participant: err_qos_validation:
dds_delete_qos(new_qos); err_domain_check:
fail_qos_validation: dds_fini ();
fail_domain_check: err_dds_init:
dds_fini(); return ret;
fail_dds_init:
return e;
} }
dds_entity_t dds_entity_t dds_lookup_participant (dds_domainid_t domain_id, dds_entity_t *participants, size_t size)
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; ddsrt_mutex_t *init_mutex;
/* Be sure the DDS lifecycle resources are initialized. */ ddsrt_init ();
ddsrt_init(); init_mutex = ddsrt_get_singleton_mutex ();
init_mutex = ddsrt_get_singleton_mutex();
if ((participants != NULL) && ((size <= 0) || (size >= INT32_MAX))) { if ((participants != NULL && (size <= 0 || size >= INT32_MAX)) || (participants == NULL && size != 0))
DDS_ERROR("Array is given, but with invalid size\n"); {
ret = DDS_RETCODE_BAD_PARAMETER; ddsrt_fini ();
goto err; return DDS_RETCODE_BAD_PARAMETER;
}
if ((participants == NULL) && (size != 0)) {
DDS_ERROR("Size is given, but no array\n");
ret = DDS_RETCODE_BAD_PARAMETER;
goto err;
} }
if(participants){ if (participants)
participants[0] = 0; participants[0] = 0;
}
dds_return_t ret = 0;
ddsrt_mutex_lock (init_mutex); ddsrt_mutex_lock (init_mutex);
if (dds_global.m_init_count > 0)
/* Check if dds is intialized. */ {
if (dds_global.m_init_count > 0) {
dds_entity* iter;
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
iter = dds_pp_head; for (dds_entity *iter = dds_pp_head; iter; iter = iter->m_next)
while (iter) { {
if (iter->m_domainid == domain_id) { if (iter->m_domainid == domain_id)
if ((size_t)ret < size) { {
if ((size_t) ret < size)
participants[ret] = iter->m_hdllink.hdl; participants[ret] = iter->m_hdllink.hdl;
}
ret++; ret++;
} }
iter = iter->m_next;
} }
ddsrt_mutex_unlock (&dds_global.m_mutex); ddsrt_mutex_unlock (&dds_global.m_mutex);
} }
ddsrt_mutex_unlock (init_mutex); ddsrt_mutex_unlock (init_mutex);
ddsrt_fini ();
err:
ddsrt_fini();
return ret; return ret;
} }

View file

@ -13,153 +13,102 @@
#include <string.h> #include <string.h>
#include "dds/ddsrt/misc.h" #include "dds/ddsrt/misc.h"
#include "dds__listener.h" #include "dds__listener.h"
#include "dds__participant.h"
#include "dds__publisher.h" #include "dds__publisher.h"
#include "dds__qos.h" #include "dds__qos.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/version.h" #include "dds/version.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_publisher) DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_publisher)
#define DDS_PUBLISHER_STATUS_MASK 0u #define DDS_PUBLISHER_STATUS_MASK (0u)
static dds_return_t static dds_return_t dds_publisher_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
dds_publisher_instance_hdl(
dds_entity *e, static dds_return_t dds_publisher_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
dds_instance_handle_t *i)
{ {
(void)e; /* FIXME: Get/generate proper handle. */
(void)i; (void) e;
/* TODO: Get/generate proper handle. */ (void) i;
DDS_ERROR("Getting publisher instance handle is not supported\n");
return DDS_RETCODE_UNSUPPORTED; return DDS_RETCODE_UNSUPPORTED;
} }
static dds_return_t static dds_return_t dds_publisher_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_publisher_qos_validate(
const dds_qos_t *qos,
bool enabled)
{
dds_return_t ret = DDS_RETCODE_OK;
assert(qos);
/* Check consistency. */ static dds_return_t dds_publisher_qos_validate (const dds_qos_t *qos, bool enabled)
if((qos->present & QP_GROUP_DATA) && !validate_octetseq(&qos->group_data)){ {
DDS_ERROR("Group data policy is inconsistent and caused an error\n"); if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
ret = DDS_RETCODE_INCONSISTENT_POLICY; return DDS_RETCODE_INCONSISTENT_POLICY;
} if ((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy (&qos->presentation) < 0)
if((qos->present & QP_PRESENTATION) && (validate_presentation_qospolicy(&qos->presentation) != 0)){ return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("Presentation policy is inconsistent and caused an error\n"); if ((qos->present & QP_PARTITION) && !validate_stringseq (&qos->partition))
ret = DDS_RETCODE_INCONSISTENT_POLICY; return DDS_RETCODE_INCONSISTENT_POLICY;
} if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
if((qos->present & QP_PARTITION) && !validate_stringseq(&qos->partition)){ return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("Partition policy is inconsistent and caused an error\n"); /* FIXME: Improve/check immutable check. */
ret = DDS_RETCODE_INCONSISTENT_POLICY; if (enabled && (qos->present & QP_PRESENTATION))
} return DDS_RETCODE_IMMUTABLE_POLICY;
if((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)){ return DDS_RETCODE_OK;
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 static dds_return_t dds_publisher_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_publisher_qos_set(
dds_entity *e, static dds_return_t dds_publisher_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
const dds_qos_t *qos,
bool enabled)
{ {
dds_return_t ret = dds_publisher_qos_validate(qos, enabled); dds_return_t ret;
(void)e; (void)e;
if (ret == DDS_RETCODE_OK) { if ((ret = dds_publisher_qos_validate (qos, enabled)) != 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 ret;
if (enabled) /* FIXME: QoS changes. */
return DDS_RETCODE_UNSUPPORTED;
return DDS_RETCODE_OK;
} }
static dds_return_t dds_publisher_status_validate (uint32_t mask) static dds_return_t dds_publisher_status_validate (uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK; return (mask & ~DDS_PUBLISHER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
if (mask & ~(DDS_PUBLISHER_STATUS_MASK)) {
DDS_ERROR("Invalid status mask\n");
ret = DDS_RETCODE_BAD_PARAMETER;
}
return ret;
} }
dds_entity_t dds_entity_t dds_create_publisher (dds_entity_t participant, const dds_qos_t *qos, const dds_listener_t *listener)
dds_create_publisher(
dds_entity_t participant,
const dds_qos_t *qos,
const dds_listener_t *listener)
{ {
dds_entity * par; dds_participant *par;
dds_publisher * pub; dds_publisher *pub;
dds_entity_t hdl; dds_entity_t hdl;
dds_qos_t * new_qos = NULL; dds_qos_t *new_qos = NULL;
dds_return_t ret; dds_return_t ret;
ret = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par); if (qos && (ret = dds_publisher_qos_validate (qos, false)) != DDS_RETCODE_OK)
if (ret != DDS_RETCODE_OK) { return ret;
DDS_ERROR("Error occurred on locking participant\n");
hdl = ret;
goto lock_err;
}
/* Validate qos */ if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
if (qos) { return ret;
ret = dds_publisher_qos_validate(qos, false);
if (ret != DDS_RETCODE_OK) { if (qos)
hdl = ret; {
goto qos_err;
}
new_qos = dds_create_qos (); new_qos = dds_create_qos ();
/* Only returns failure when one of the qos args is NULL, which (void) dds_copy_qos (new_qos, qos);
* is not the case here. */
(void)dds_copy_qos(new_qos, qos);
} }
/* Create publisher */
pub = dds_alloc (sizeof (*pub)); pub = dds_alloc (sizeof (*pub));
hdl = dds_entity_init (&pub->m_entity, par, DDS_KIND_PUBLISHER, new_qos, listener, DDS_PUBLISHER_STATUS_MASK); 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.set_qos = dds_publisher_qos_set;
pub->m_entity.m_deriver.get_instance_hdl = dds_publisher_instance_hdl; pub->m_entity.m_deriver.get_instance_hdl = dds_publisher_instance_hdl;
pub->m_entity.m_deriver.validate_status = dds_publisher_status_validate; pub->m_entity.m_deriver.validate_status = dds_publisher_status_validate;
dds_participant_unlock (par);
qos_err:
dds_entity_unlock(par);
lock_err:
return hdl; return hdl;
} }
DDS_EXPORT dds_return_t dds_return_t dds_suspend (dds_entity_t publisher)
dds_suspend(
dds_entity_t publisher)
{ {
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER); return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
} }
dds_return_t dds_return_t dds_resume (dds_entity_t publisher)
dds_resume(
dds_entity_t publisher)
{ {
return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER); return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
} }
dds_return_t dds_return_t dds_wait_for_acks (dds_entity_t publisher_or_writer, dds_duration_t timeout)
dds_wait_for_acks(
dds_entity_t publisher_or_writer,
dds_duration_t timeout)
{ {
if (timeout < 0) if (timeout < 0)
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
@ -167,23 +116,12 @@ dds_wait_for_acks(
return dds_generic_unimplemented_operation_manykinds (publisher_or_writer, sizeof (kinds) / sizeof (kinds[0]), kinds); return dds_generic_unimplemented_operation_manykinds (publisher_or_writer, sizeof (kinds) / sizeof (kinds[0]), kinds);
} }
dds_return_t dds_return_t dds_publisher_begin_coherent (dds_entity_t publisher)
dds_publisher_begin_coherent(
dds_entity_t e)
{ {
/* TODO: CHAM-124 Currently unsupported. */ return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
(void)e;
DDS_ERROR("Using coherency to get a coherent data set is not being supported yet\n");
return DDS_RETCODE_UNSUPPORTED;
} }
dds_return_t dds_return_t dds_publisher_end_coherent (dds_entity_t publisher)
dds_publisher_end_coherent(
dds_entity_t e)
{ {
/* TODO: CHAM-124 Currently unsupported. */ return dds_generic_unimplemented_operation (publisher, DDS_KIND_PUBLISHER);
(void)e;
DDS_ERROR("Using coherency to get a coherent data set is not being supported yet\n");
return DDS_RETCODE_UNSUPPORTED;
} }

File diff suppressed because it is too large Load diff

View file

@ -21,32 +21,27 @@
#include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_serdata.h"
#include "dds/ddsi/ddsi_sertopic.h" #include "dds/ddsi/ddsi_sertopic.h"
DDS_EXPORT dds_entity_t dds_entity_t dds_create_querycondition (dds_entity_t reader, uint32_t mask, dds_querycondition_filter_fn filter)
dds_create_querycondition(
dds_entity_t reader,
uint32_t mask,
dds_querycondition_filter_fn filter)
{ {
dds_entity_t hdl;
dds_return_t rc; dds_return_t rc;
dds_reader *r; dds_reader *r;
rc = dds_reader_lock(reader, &r); if ((rc = dds_reader_lock (reader, &r)) != DDS_RETCODE_OK)
if (rc == DDS_RETCODE_OK) { return rc;
dds_readcond *cond = dds_create_readcond(r, DDS_KIND_COND_QUERY, mask, filter); else
assert(cond); {
dds_entity_t hdl;
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); const bool success = (cond->m_entity.m_deriver.delete != 0);
dds_reader_unlock(r); dds_reader_unlock (r);
if (success) { if (success)
hdl = cond->m_entity.m_hdllink.hdl; hdl = cond->m_entity.m_hdllink.hdl;
} else { else
{
dds_delete (cond->m_entity.m_hdllink.hdl); dds_delete (cond->m_entity.m_hdllink.hdl);
hdl = DDS_RETCODE_OUT_OF_RESOURCES; hdl = DDS_RETCODE_OUT_OF_RESOURCES;
} }
} else {
DDS_ERROR("Error occurred on locking reader\n");
hdl = rc;
}
return hdl; return hdl;
}
} }

View file

@ -38,19 +38,16 @@ static dds_return_t dds_read_lock (dds_entity_t hdl, dds_reader **reader, dds_re
else if (only_reader) else if (only_reader)
{ {
dds_entity_unlock (entity); dds_entity_unlock (entity);
DDS_ERROR ("Given entity is not a reader\n");
return DDS_RETCODE_ILLEGAL_OPERATION; return DDS_RETCODE_ILLEGAL_OPERATION;
} }
else if (dds_entity_kind (entity) != DDS_KIND_COND_READ && dds_entity_kind (entity) != DDS_KIND_COND_QUERY) else if (dds_entity_kind (entity) != DDS_KIND_COND_READ && dds_entity_kind (entity) != DDS_KIND_COND_QUERY)
{ {
dds_entity_unlock (entity); dds_entity_unlock (entity);
DDS_ERROR ("Given entity is a reader nor a condition\n");
return DDS_RETCODE_ILLEGAL_OPERATION; return DDS_RETCODE_ILLEGAL_OPERATION;
} }
else if ((rc = dds_entity_lock (entity->m_parent->m_hdllink.hdl, DDS_KIND_READER, &parent_entity)) != DDS_RETCODE_OK) else if ((rc = dds_entity_lock (entity->m_parent->m_hdllink.hdl, DDS_KIND_READER, &parent_entity)) != DDS_RETCODE_OK)
{ {
dds_entity_unlock (entity); dds_entity_unlock (entity);
DDS_ERROR ("Failed to lock condition's reader\n");
return rc; return rc;
} }
else else
@ -75,85 +72,57 @@ static void dds_read_unlock (dds_reader *reader, dds_readcond *condition)
has been locked. This is used to support C++ API reading length unlimited has been locked. This is used to support C++ API reading length unlimited
which is interpreted as "all relevant samples in cache". which is interpreted as "all relevant samples in cache".
*/ */
static dds_return_t static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition, void **buf, size_t bufsz, uint32_t maxs, dds_sample_info_t *si, uint32_t mask, dds_instance_handle_t hand, bool lock, bool only_reader)
dds_read_impl(
bool take,
dds_entity_t reader_or_condition,
void **buf,
size_t bufsz,
uint32_t maxs,
dds_sample_info_t *si,
uint32_t mask,
dds_instance_handle_t hand,
bool lock,
bool only_reader)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret = DDS_RETCODE_OK;
struct dds_reader * rd; struct dds_reader *rd;
struct dds_readcond * cond; struct dds_readcond *cond;
unsigned nodata_cleanups = 0; unsigned nodata_cleanups = 0;
#define NC_CLEAR_LOAN_OUT 1u #define NC_CLEAR_LOAN_OUT 1u
#define NC_FREE_BUF 2u #define NC_FREE_BUF 2u
#define NC_RESET_BUF 4u #define NC_RESET_BUF 4u
if (buf == NULL) { if (buf == NULL || si == NULL || maxs == 0 || bufsz == 0 || bufsz < maxs)
DDS_ERROR("The provided buffer is NULL\n"); return DDS_RETCODE_BAD_PARAMETER;
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
if (si == NULL) {
DDS_ERROR("Provided pointer to an array of dds_sample_info_t is NULL\n");
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
if (maxs == 0) {
DDS_ERROR("The maximum number of samples to read is zero\n");
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
if (bufsz == 0) {
DDS_ERROR("The size of buffer is zero\n");
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
if (bufsz < maxs) {
DDS_ERROR("The provided size of buffer is smaller than the maximum number of samples to read\n");
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
thread_state_awake (ts1); thread_state_awake (ts1);
ret = dds_read_lock(reader_or_condition, &rd, &cond, only_reader); if ((ret = dds_read_lock (reader_or_condition, &rd, &cond, only_reader)) != DDS_RETCODE_OK)
if (ret != DDS_RETCODE_OK) {
goto fail_awake; goto fail_awake;
}
if (hand != DDS_HANDLE_NIL) { if (hand != DDS_HANDLE_NIL)
if (ddsi_tkmap_find_by_id(gv.m_tkmap, hand) == NULL) { {
DDS_ERROR("Could not find instance\n"); if (ddsi_tkmap_find_by_id (gv.m_tkmap, hand) == NULL) {
ret = DDS_RETCODE_PRECONDITION_NOT_MET; ret = DDS_RETCODE_PRECONDITION_NOT_MET;
dds_read_unlock(rd, cond); goto fail_awake_lock;
goto fail_awake;
} }
} }
/* Allocate samples if not provided (assuming all or none provided) */ /* Allocate samples if not provided (assuming all or none provided) */
if (buf[0] == NULL) { if (buf[0] == NULL)
{
/* Allocate, use or reallocate loan cached on reader */ /* Allocate, use or reallocate loan cached on reader */
if (rd->m_loan_out) { if (rd->m_loan_out)
{
ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs); ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs);
nodata_cleanups = NC_FREE_BUF | NC_RESET_BUF; nodata_cleanups = NC_FREE_BUF | NC_RESET_BUF;
} else { }
if (rd->m_loan) { else
if (rd->m_loan_size < maxs) { {
if (rd->m_loan)
{
if (rd->m_loan_size >= maxs)
buf[0] = rd->m_loan;
else
{
ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, rd->m_loan, rd->m_loan_size, maxs); ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, rd->m_loan, rd->m_loan_size, maxs);
rd->m_loan = buf[0]; rd->m_loan = buf[0];
rd->m_loan_size = maxs; rd->m_loan_size = maxs;
nodata_cleanups = NC_RESET_BUF; }
} else {
buf[0] = rd->m_loan;
nodata_cleanups = NC_RESET_BUF; nodata_cleanups = NC_RESET_BUF;
} }
} else { else
{
ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs); ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs);
rd->m_loan = buf[0]; rd->m_loan = buf[0];
rd->m_loan_size = maxs; rd->m_loan_size = maxs;
@ -168,54 +137,48 @@ dds_read_impl(
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock); ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
dds_entity_status_reset (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS); dds_entity_status_reset (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
/* reset DATA_ON_READERS status on subscriber after successful read/take */ /* reset DATA_ON_READERS status on subscriber after successful read/take */
if (dds_entity_kind (rd->m_entity.m_parent) == DDS_KIND_SUBSCRIBER) { if (dds_entity_kind (rd->m_entity.m_parent) == DDS_KIND_SUBSCRIBER)
dds_entity_status_reset (rd->m_entity.m_parent, DDS_DATA_ON_READERS_STATUS); dds_entity_status_reset (rd->m_entity.m_parent, DDS_DATA_ON_READERS_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock); ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
if (take) { if (take)
ret = (dds_return_t) dds_rhc_take (rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond); ret = dds_rhc_take (rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
} else { else
ret = (dds_return_t) dds_rhc_read (rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond); ret = dds_rhc_read (rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
}
/* if no data read, restore the state to what it was before the call, with the sole /* if no data read, restore the state to what it was before the call, with the sole
exception of holding on to a buffer we just allocated and that is pointed to by exception of holding on to a buffer we just allocated and that is pointed to by
rd->m_loan */ rd->m_loan */
if (ret <= 0 && nodata_cleanups) { if (ret <= 0 && nodata_cleanups)
if (nodata_cleanups & NC_CLEAR_LOAN_OUT) { {
if (nodata_cleanups & NC_CLEAR_LOAN_OUT)
rd->m_loan_out = false; rd->m_loan_out = false;
} if (nodata_cleanups & NC_FREE_BUF)
if (nodata_cleanups & NC_FREE_BUF) {
ddsi_sertopic_free_samples (rd->m_topic->m_stopic, buf[0], maxs, DDS_FREE_ALL); ddsi_sertopic_free_samples (rd->m_topic->m_stopic, buf[0], maxs, DDS_FREE_ALL);
} if (nodata_cleanups & NC_RESET_BUF)
if (nodata_cleanups & NC_RESET_BUF) {
buf[0] = NULL; buf[0] = NULL;
} }
}
dds_read_unlock(rd, cond); dds_read_unlock(rd, cond);
thread_state_asleep (ts1);
return ret;
#undef NC_CLEAR_LOAN_OUT
#undef NC_FREE_BUF
#undef NC_RESET_BUF
fail_awake_lock:
dds_read_unlock (rd, cond);
fail_awake: fail_awake:
thread_state_asleep (ts1); thread_state_asleep (ts1);
fail:
return ret; return ret;
} }
static dds_return_t static dds_return_t dds_readcdr_impl (bool take, dds_entity_t reader_or_condition, struct ddsi_serdata **buf, uint32_t maxs, dds_sample_info_t *si, uint32_t mask, dds_instance_handle_t hand, bool lock)
dds_readcdr_impl(
bool take,
dds_entity_t reader_or_condition,
struct ddsi_serdata ** buf,
uint32_t maxs,
dds_sample_info_t * si,
uint32_t mask,
dds_instance_handle_t hand,
bool lock)
{ {
struct thread_state1 * const ts1 = lookup_thread_state (); struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret = DDS_RETCODE_OK;
struct dds_reader * rd; struct dds_reader *rd;
struct dds_readcond * cond; struct dds_readcond *cond;
assert (take); assert (take);
assert (buf); assert (buf);
@ -225,227 +188,143 @@ dds_readcdr_impl(
(void)take; (void)take;
thread_state_awake (ts1); thread_state_awake (ts1);
ret = dds_read_lock(reader_or_condition, &rd, &cond, false); if ((ret = dds_read_lock (reader_or_condition, &rd, &cond, false)) == DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { {
/* read/take resets data available status -- must reset before reading because /* read/take resets data available status -- must reset before reading because
the actual writing is protected by RHC lock, not by rd->m_entity.m_lock */ the actual writing is protected by RHC lock, not by rd->m_entity.m_lock */
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock); ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
dds_entity_status_reset (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS); dds_entity_status_reset (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
/* reset DATA_ON_READERS status on subscriber after successful read/take */ /* reset DATA_ON_READERS status on subscriber after successful read/take */
if (dds_entity_kind (rd->m_entity.m_parent) == DDS_KIND_SUBSCRIBER) { if (dds_entity_kind (rd->m_entity.m_parent) == DDS_KIND_SUBSCRIBER)
dds_entity_status_reset (rd->m_entity.m_parent, DDS_DATA_ON_READERS_STATUS); dds_entity_status_reset (rd->m_entity.m_parent, DDS_DATA_ON_READERS_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock); ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
ret = dds_rhc_takecdr ret = dds_rhc_takecdr (rd->m_rd->rhc, lock, buf, si, maxs, mask & DDS_ANY_SAMPLE_STATE, mask & DDS_ANY_VIEW_STATE, mask & DDS_ANY_INSTANCE_STATE, hand);
( dds_read_unlock (rd, cond);
rd->m_rd->rhc, lock, buf, si, maxs,
mask & DDS_ANY_SAMPLE_STATE,
mask & DDS_ANY_VIEW_STATE,
mask & DDS_ANY_INSTANCE_STATE,
hand
);
dds_read_unlock(rd, cond);
} }
thread_state_asleep (ts1); thread_state_asleep (ts1);
return ret; return ret;
} }
dds_return_t dds_return_t dds_read (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs)
dds_read(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
size_t bufsz,
uint32_t maxs)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs, so use bufsz instead. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */ maxs = (uint32_t) bufsz;
maxs = (uint32_t)bufsz;
} }
return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false); return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
} }
dds_return_t dds_return_t dds_read_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs)
dds_read_wl(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
uint32_t maxs)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false); return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
} }
dds_return_t dds_return_t dds_read_mask (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs, uint32_t mask)
dds_read_mask(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
size_t bufsz,
uint32_t maxs,
uint32_t mask)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs, so use bufsz instead. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = (uint32_t)bufsz; maxs = (uint32_t)bufsz;
} }
return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false); return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
} }
dds_return_t dds_return_t dds_read_mask_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs, uint32_t mask)
dds_read_mask_wl(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
uint32_t maxs,
uint32_t mask)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false); return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
} }
dds_return_t dds_return_t dds_read_instance (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs, dds_instance_handle_t handle)
dds_read_instance(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
size_t bufsz,
uint32_t maxs,
dds_instance_handle_t handle)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) { if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false); return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_read_instance_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs, dds_instance_handle_t handle)
dds_read_instance_wl(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
uint32_t maxs,
dds_instance_handle_t handle)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) { if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false); return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_read_instance_mask (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs, dds_instance_handle_t handle, uint32_t mask)
dds_read_instance_mask(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
size_t bufsz,
uint32_t maxs,
dds_instance_handle_t handle,
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) { if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(false, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false); return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_read_instance_mask_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs, dds_instance_handle_t handle, uint32_t mask)
dds_read_instance_mask_wl(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
uint32_t maxs,
dds_instance_handle_t handle,
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail; if (maxs == DDS_READ_WITHOUT_LOCK)
} {
if (maxs == DDS_READ_WITHOUT_LOCK) {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(false, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false); return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_read_next (dds_entity_t reader, void **buf, dds_sample_info_t *si)
dds_read_next( {
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
return dds_read_impl (false, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
}
dds_return_t dds_read_next_wl (
dds_entity_t reader, dds_entity_t reader,
void **buf, void **buf,
dds_sample_info_t *si) dds_sample_info_t *si)
@ -454,283 +333,167 @@ dds_read_next(
return dds_read_impl (false, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true); return dds_read_impl (false, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
} }
dds_return_t dds_return_t dds_take (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs)
dds_read_next_wl(
dds_entity_t reader,
void **buf,
dds_sample_info_t *si)
{
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
return dds_read_impl (false, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
}
dds_return_t
dds_take(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
size_t bufsz,
uint32_t maxs)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs, so use bufsz instead. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = (uint32_t)bufsz; maxs = (uint32_t)bufsz;
} }
return dds_read_impl (true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false); return dds_read_impl (true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
} }
dds_return_t dds_return_t dds_take_wl (dds_entity_t rd_or_cnd, void ** buf, dds_sample_info_t * si, uint32_t maxs)
dds_take_wl(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
uint32_t maxs)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
return dds_read_impl (true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false); return dds_read_impl (true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
} }
dds_return_t dds_return_t dds_take_mask (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs, uint32_t mask)
dds_take_mask(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
size_t bufsz,
uint32_t maxs,
uint32_t mask)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs, so use bufsz instead. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */ maxs = (uint32_t) bufsz;
maxs = (uint32_t)bufsz;
} }
return dds_read_impl (true, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false); return dds_read_impl (true, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
} }
dds_return_t dds_return_t dds_take_mask_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs, uint32_t mask)
dds_take_mask_wl(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
uint32_t maxs,
uint32_t mask)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
return dds_read_impl (true, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false); return dds_read_impl (true, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
} }
int dds_return_t dds_takecdr (dds_entity_t rd_or_cnd, struct ddsi_serdata **buf, uint32_t maxs, dds_sample_info_t *si, uint32_t mask)
dds_takecdr(
dds_entity_t rd_or_cnd,
struct ddsi_serdata **buf,
uint32_t maxs,
dds_sample_info_t *si,
uint32_t mask)
{ {
bool lock = true; bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK)
if (maxs == DDS_READ_WITHOUT_LOCK) { {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
return dds_readcdr_impl (true, rd_or_cnd, buf, maxs, si, mask, DDS_HANDLE_NIL, lock); return dds_readcdr_impl (true, rd_or_cnd, buf, maxs, si, mask, DDS_HANDLE_NIL, lock);
} }
dds_return_t dds_return_t dds_take_instance (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs, dds_instance_handle_t handle)
dds_take_instance(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
size_t bufsz,
uint32_t maxs,
dds_instance_handle_t handle)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) { if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false); return dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_take_instance_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs, dds_instance_handle_t handle)
dds_take_instance_wl(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
uint32_t maxs,
dds_instance_handle_t handle)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail; if (maxs == DDS_READ_WITHOUT_LOCK)
} {
if (maxs == DDS_READ_WITHOUT_LOCK) {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false); return dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_take_instance_mask (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs, dds_instance_handle_t handle, uint32_t mask)
dds_take_instance_mask(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
size_t bufsz,
uint32_t maxs,
dds_instance_handle_t handle,
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail; if (maxs == DDS_READ_WITHOUT_LOCK)
} {
if (maxs == DDS_READ_WITHOUT_LOCK) {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false); return dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_take_instance_mask_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs, dds_instance_handle_t handle, uint32_t mask)
dds_take_instance_mask_wl(
dds_entity_t rd_or_cnd,
void **buf,
dds_sample_info_t *si,
uint32_t maxs,
dds_instance_handle_t handle,
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK;
bool lock = true; bool lock = true;
if (handle == DDS_HANDLE_NIL) { if (handle == DDS_HANDLE_NIL)
DDS_ERROR("DDS_HANDLE_NIL was provided\n"); return DDS_RETCODE_PRECONDITION_NOT_MET;
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail; if (maxs == DDS_READ_WITHOUT_LOCK)
} {
if (maxs == DDS_READ_WITHOUT_LOCK) {
lock = false; lock = false;
/* Use a more sensible maxs. Just an arbitrarily number. /* FIXME: Fix the interface. */
* CHAM-306 will remove this ugly piece of code. */
maxs = 100; maxs = 100;
} }
ret = dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false); return dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
fail:
return ret;
} }
dds_return_t dds_return_t dds_take_next (dds_entity_t reader, void **buf, dds_sample_info_t *si)
dds_take_next(
dds_entity_t reader,
void **buf,
dds_sample_info_t *si)
{ {
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE; uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
return dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true); return dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
} }
dds_return_t dds_return_t dds_take_next_wl (dds_entity_t reader, void **buf, dds_sample_info_t *si)
dds_take_next_wl(
dds_entity_t reader,
void **buf,
dds_sample_info_t *si)
{ {
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE; uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
return dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true); return dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
} }
dds_return_t dds_return_t dds_return_loan (dds_entity_t reader_or_condition, void **buf, int32_t bufsz)
dds_return_loan(
dds_entity_t reader_or_condition,
void **buf,
int32_t bufsz)
{ {
const struct ddsi_sertopic *st; const struct ddsi_sertopic *st;
dds_reader *rd; dds_reader *rd;
dds_readcond *cond; dds_readcond *cond;
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret = DDS_RETCODE_OK;
if (!buf) { if (buf == NULL || (*buf == NULL && bufsz > 0))
DDS_ERROR("Argument buf is NULL\n"); return DDS_RETCODE_BAD_PARAMETER;
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail; if ((ret = dds_read_lock(reader_or_condition, &rd, &cond, false)) != DDS_RETCODE_OK)
} return ret;
if (*buf == NULL && bufsz > 0) {
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
ret = dds_read_lock(reader_or_condition, &rd, &cond, false);
if (ret != DDS_RETCODE_OK) {
goto fail;
}
st = rd->m_topic->m_stopic; st = rd->m_topic->m_stopic;
for (int32_t i = 0; i < bufsz; i++)
for (int32_t i = 0; i < bufsz; i++) {
ddsi_sertopic_free_sample (st, buf[i], DDS_FREE_CONTENTS); ddsi_sertopic_free_sample (st, buf[i], DDS_FREE_CONTENTS);
}
/* If possible return loan buffer to reader */ /* If possible return loan buffer to reader */
if (rd->m_loan != 0 && (buf[0] == rd->m_loan)) { if (rd->m_loan != 0 && (buf[0] == rd->m_loan))
{
rd->m_loan_out = false; rd->m_loan_out = false;
ddsi_sertopic_zero_samples (st, rd->m_loan, rd->m_loan_size); ddsi_sertopic_zero_samples (st, rd->m_loan, rd->m_loan_size);
buf[0] = NULL; buf[0] = NULL;
} }
dds_read_unlock(rd, cond); dds_read_unlock(rd, cond);
fail: return DDS_RETCODE_OK;
return ret;
} }

View file

@ -18,35 +18,32 @@
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
static dds_return_t static dds_return_t dds_readcond_delete (dds_entity *e) ddsrt_nonnull_all;
dds_readcond_delete(
dds_entity *e) static dds_return_t dds_readcond_delete (dds_entity *e)
{ {
dds_rhc_remove_readcondition((dds_readcond*)e); dds_rhc_remove_readcondition ((dds_readcond *) e);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
dds_readcond* dds_readcond *dds_create_readcond (dds_reader *rd, dds_entity_kind_t kind, uint32_t mask, dds_querycondition_filter_fn filter)
dds_create_readcond(
dds_reader *rd,
dds_entity_kind_t kind,
uint32_t mask,
dds_querycondition_filter_fn filter)
{ {
dds_readcond * cond = dds_alloc(sizeof(*cond)); dds_readcond *cond = dds_alloc (sizeof (*cond));
assert((kind == DDS_KIND_COND_READ && filter == 0) || (kind == DDS_KIND_COND_QUERY && filter != 0)); assert ((kind == DDS_KIND_COND_READ && filter == 0) || (kind == DDS_KIND_COND_QUERY && filter != 0));
(void) dds_entity_init(&cond->m_entity, (dds_entity*)rd, kind, NULL, NULL, 0); (void) dds_entity_init (&cond->m_entity, &rd->m_entity, kind, NULL, NULL, 0);
cond->m_entity.m_deriver.delete = dds_readcond_delete; cond->m_entity.m_deriver.delete = dds_readcond_delete;
cond->m_rhc = rd->m_rd->rhc; cond->m_rhc = rd->m_rd->rhc;
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE; cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
cond->m_view_states = mask & DDS_ANY_VIEW_STATE; cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE; cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
cond->m_rd_guid = rd->m_entity.m_guid; cond->m_rd_guid = rd->m_entity.m_guid;
if (kind == DDS_KIND_COND_QUERY) { if (kind == DDS_KIND_COND_QUERY)
{
cond->m_query.m_filter = filter; cond->m_query.m_filter = filter;
cond->m_query.m_qcmask = 0; cond->m_query.m_qcmask = 0;
} }
if (!dds_rhc_add_readcondition (cond)) { if (!dds_rhc_add_readcondition (cond))
{
/* FIXME: current entity management code can't deal with an error late in the creation of the /* 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 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. */ to the caller and let that one handle it. */
@ -55,28 +52,22 @@ dds_create_readcond(
return cond; return cond;
} }
dds_entity_t dds_entity_t dds_create_readcondition (dds_entity_t reader, uint32_t mask)
dds_create_readcondition(
dds_entity_t reader,
uint32_t mask)
{ {
dds_entity_t hdl; dds_reader *rd;
dds_reader * rd;
dds_return_t rc; dds_return_t rc;
if ((rc = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK)
rc = dds_reader_lock(reader, &rd); return rc;
if (rc == DDS_RETCODE_OK) { else
{
dds_entity_t hdl;
dds_readcond *cond = dds_create_readcond(rd, DDS_KIND_COND_READ, mask, 0); dds_readcond *cond = dds_create_readcond(rd, DDS_KIND_COND_READ, mask, 0);
assert(cond); assert (cond);
assert(cond->m_entity.m_deriver.delete); assert (cond->m_entity.m_deriver.delete);
hdl = cond->m_entity.m_hdllink.hdl; hdl = cond->m_entity.m_hdllink.hdl;
dds_reader_unlock(rd); dds_reader_unlock (rd);
} else {
DDS_ERROR("Error occurred on locking reader\n");
hdl = rc;
}
return hdl; return hdl;
}
} }
dds_entity_t dds_get_datareader (dds_entity_t condition) dds_entity_t dds_get_datareader (dds_entity_t condition)

View file

@ -13,6 +13,7 @@
#include <string.h> #include <string.h>
#include "dds/dds.h" #include "dds/dds.h"
#include "dds/version.h" #include "dds/version.h"
#include "dds/ddsrt/static_assert.h"
#include "dds__subscriber.h" #include "dds__subscriber.h"
#include "dds__reader.h" #include "dds__reader.h"
#include "dds__listener.h" #include "dds__listener.h"
@ -20,135 +21,96 @@
#include "dds__init.h" #include "dds__init.h"
#include "dds__rhc.h" #include "dds__rhc.h"
#include "dds__topic.h" #include "dds__topic.h"
#include "dds__get_status.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
#include "dds/ddsi/q_globals.h" #include "dds/ddsi/q_globals.h"
#include "dds__builtin.h" #include "dds__builtin.h"
#include "dds/ddsi/ddsi_sertopic.h" #include "dds/ddsi/ddsi_sertopic.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_reader) DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_reader)
#define DDS_READER_STATUS_MASK \ #define DDS_READER_STATUS_MASK \
DDS_SAMPLE_REJECTED_STATUS |\ (DDS_SAMPLE_REJECTED_STATUS |\
DDS_LIVELINESS_CHANGED_STATUS |\ DDS_LIVELINESS_CHANGED_STATUS |\
DDS_REQUESTED_DEADLINE_MISSED_STATUS |\ DDS_REQUESTED_DEADLINE_MISSED_STATUS |\
DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS |\ DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS |\
DDS_DATA_AVAILABLE_STATUS |\ DDS_DATA_AVAILABLE_STATUS |\
DDS_SAMPLE_LOST_STATUS |\ DDS_SAMPLE_LOST_STATUS |\
DDS_SUBSCRIPTION_MATCHED_STATUS DDS_SUBSCRIPTION_MATCHED_STATUS)
static dds_return_t static dds_return_t dds_reader_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
dds_reader_instance_hdl(
dds_entity *e, static dds_return_t dds_reader_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
dds_instance_handle_t *i)
{ {
assert(e); *i = reader_instance_id (&e->m_guid);
assert(i);
*i = (dds_instance_handle_t)reader_instance_id(&e->m_guid);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
static dds_return_t static dds_return_t dds_reader_close (dds_entity *e) ddsrt_nonnull_all;
dds_reader_close(
dds_entity *e) static dds_return_t dds_reader_close (dds_entity *e)
{ {
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret = DDS_RETCODE_OK;
assert(e);
thread_state_awake (lookup_thread_state ()); thread_state_awake (lookup_thread_state ());
if (delete_reader(&e->m_guid) != 0) { if (delete_reader (&e->m_guid) != 0)
DDS_ERROR("Internal error");
ret = DDS_RETCODE_ERROR; ret = DDS_RETCODE_ERROR;
}
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());
return ret; return ret;
} }
static dds_return_t static dds_return_t dds_reader_delete (dds_entity *e) ddsrt_nonnull_all;
dds_reader_delete(
dds_entity *e) static dds_return_t dds_reader_delete (dds_entity *e)
{ {
dds_reader *rd = (dds_reader*)e; dds_reader * const rd = (dds_reader *) e;
dds_return_t ret; dds_return_t ret;
assert(e); if ((ret = dds_delete (rd->m_topic->m_entity.m_hdllink.hdl)) == DDS_RETCODE_OK)
ret = dds_delete(rd->m_topic->m_entity.m_hdllink.hdl); {
if(ret == DDS_RETCODE_OK){ /* Delete an implicitly created parent; for normal ones, this is expected
ret = dds_delete_impl(e->m_parent->m_hdllink.hdl, true); to fail with BAD_PARAMETER - FIXME: there must be a cleaner way */
if(ret == DDS_RETCODE_BAD_PARAMETER){ ret = dds_delete_impl (e->m_parent->m_hdllink.hdl, true);
if (ret == DDS_RETCODE_BAD_PARAMETER)
ret = DDS_RETCODE_OK; ret = DDS_RETCODE_OK;
} }
} dds_free (rd->m_loan);
dds_free(rd->m_loan);
return ret; return ret;
} }
static dds_return_t static dds_return_t dds_reader_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_reader_qos_validate(
const dds_qos_t *qos, static dds_return_t dds_reader_qos_validate (const dds_qos_t *qos, bool enabled)
bool enabled)
{ {
dds_return_t ret = DDS_RETCODE_OK; if (!dds_qos_validate_common (qos))
return DDS_RETCODE_ERROR;
assert(qos); if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
/* Check consistency. */ if ((qos->present & QP_PRISMTECH_READER_DATA_LIFECYCLE) && validate_reader_data_lifecycle (&qos->reader_data_lifecycle) < 0)
if(!dds_qos_validate_common(qos)) { return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("Argument Qos is not valid\n"); if ((qos->present & QP_TIME_BASED_FILTER) && validate_duration (&qos->time_based_filter.minimum_separation) < 0)
ret = DDS_RETCODE_ERROR; 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)
if((qos->present & QP_USER_DATA) && !(validate_octetseq (&qos->user_data))) { return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("User data policy is inconsistent and caused an error\n"); 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))
ret = DDS_RETCODE_INCONSISTENT_POLICY; return DDS_RETCODE_INCONSISTENT_POLICY;
} return (enabled ? dds_qos_validate_mutable_common (qos) : DDS_RETCODE_OK);
if((qos->present & QP_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 static dds_return_t dds_reader_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_reader_qos_set(
dds_entity *e, static dds_return_t dds_reader_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
const dds_qos_t *qos,
bool enabled)
{ {
dds_return_t ret = dds_reader_qos_validate(qos, enabled); dds_return_t ret;
(void)e; (void) e;
if (ret == DDS_RETCODE_OK) { if ((ret = dds_reader_qos_validate (qos, enabled)) != 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; return ret;
/* FIXME: QoS changes. */
return (enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK);
} }
static dds_return_t static dds_return_t dds_reader_status_validate (uint32_t mask)
dds_reader_status_validate(
uint32_t mask)
{ {
return (mask & ~(DDS_READER_STATUS_MASK)) ? return (mask & ~DDS_READER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
DDS_RETCODE_BAD_PARAMETER :
DDS_RETCODE_OK;
} }
void dds_reader_data_available_cb (struct dds_reader *rd) void dds_reader_data_available_cb (struct dds_reader *rd)
@ -349,44 +311,38 @@ void dds_reader_status_cb (void *ventity, const status_cb_data_t *data)
ddsrt_mutex_unlock (&entity->m_observers_lock); ddsrt_mutex_unlock (&entity->m_observers_lock);
} }
dds_entity_t dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener)
dds_create_reader(
dds_entity_t participant_or_subscriber,
dds_entity_t topic,
const dds_qos_t *qos,
const dds_listener_t *listener)
{ {
dds_qos_t * rqos; dds_qos_t *rqos;
dds_subscriber * sub = NULL; dds_subscriber *sub = NULL;
dds_entity_t subscriber; dds_entity_t subscriber;
dds_reader * rd; dds_reader *rd;
struct rhc * rhc; struct rhc *rhc;
dds_topic * tp; dds_topic *tp;
dds_entity_t reader; dds_entity_t reader;
dds_entity_t t; dds_entity_t t;
dds_return_t ret = DDS_RETCODE_OK; dds_return_t ret = DDS_RETCODE_OK;
bool internal_topic; bool internal_topic;
switch (topic) { switch (topic)
{
case DDS_BUILTIN_TOPIC_DCPSPARTICIPANT: case DDS_BUILTIN_TOPIC_DCPSPARTICIPANT:
case DDS_BUILTIN_TOPIC_DCPSTOPIC: case DDS_BUILTIN_TOPIC_DCPSTOPIC:
case DDS_BUILTIN_TOPIC_DCPSPUBLICATION: case DDS_BUILTIN_TOPIC_DCPSPUBLICATION:
case DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION: case DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION:
internal_topic = true; internal_topic = true;
subscriber = dds__get_builtin_subscriber(participant_or_subscriber); subscriber = dds__get_builtin_subscriber (participant_or_subscriber);
t = dds__get_builtin_topic (subscriber, topic); t = dds__get_builtin_topic (subscriber, topic);
break; break;
default: { default: {
dds_entity *p_or_s; dds_entity *p_or_s;
if ((ret = dds_entity_claim (participant_or_subscriber, &p_or_s)) != DDS_RETCODE_OK) { if ((ret = dds_entity_claim (participant_or_subscriber, &p_or_s)) != DDS_RETCODE_OK)
return ret; return ret;
} if (dds_entity_kind (p_or_s) == DDS_KIND_PARTICIPANT)
if (dds_entity_kind (p_or_s) == DDS_KIND_PARTICIPANT) { subscriber = dds_create_subscriber (participant_or_subscriber, qos, NULL);
subscriber = dds_create_subscriber(participant_or_subscriber, qos, NULL); else
} else {
subscriber = participant_or_subscriber; subscriber = participant_or_subscriber;
}
dds_entity_release (p_or_s); dds_entity_release (p_or_s);
internal_topic = false; internal_topic = false;
t = topic; t = topic;
@ -394,56 +350,56 @@ dds_create_reader(
} }
} }
if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK) { if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK)
{
reader = ret; reader = ret;
goto err_sub_lock; goto err_sub_lock;
} }
if ((subscriber != participant_or_subscriber) && !internal_topic) { if (subscriber != participant_or_subscriber && !internal_topic)
{
/* Delete implicit subscriber if reader creation fails */ /* Delete implicit subscriber if reader creation fails */
sub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT; sub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
} }
ret = dds_topic_lock(t, &tp); if ((ret = dds_topic_lock (t, &tp)) != DDS_RETCODE_OK)
if (ret != DDS_RETCODE_OK) { {
DDS_ERROR("Error occurred on locking topic\n");
reader = ret; reader = ret;
goto err_tp_lock; goto err_tp_lock;
} }
assert (tp->m_stopic); assert (tp->m_stopic);
assert (sub->m_entity.m_domain == tp->m_entity.m_domain); assert (sub->m_entity.m_domain == tp->m_entity.m_domain);
/* Merge qos from topic and subscriber */ /* Merge qos from topic and subscriber, dds_copy_qos only fails when it is passed a null
argument, but that isn't the case here */
rqos = dds_create_qos (); rqos = dds_create_qos ();
if (qos) { if (qos)
/* Only returns failure when one of the qos args is NULL, which (void) dds_copy_qos (rqos, qos);
* is not the case here. */
(void)dds_copy_qos(rqos, qos);
}
if(sub->m_entity.m_qos){ if (sub->m_entity.m_qos)
dds_merge_qos (rqos, sub->m_entity.m_qos); dds_merge_qos (rqos, sub->m_entity.m_qos);
}
if (tp->m_entity.m_qos) { if (tp->m_entity.m_qos)
{
dds_merge_qos (rqos, tp->m_entity.m_qos); dds_merge_qos (rqos, tp->m_entity.m_qos);
/* reset the following qos policies if set during topic qos merge as they aren't applicable for reader */ /* 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); rqos->present &= ~(QP_DURABILITY_SERVICE | QP_TRANSPORT_PRIORITY | QP_LIFESPAN);
} }
nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd); nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd);
ret = dds_reader_qos_validate (rqos, false); if ((ret = dds_reader_qos_validate (rqos, false)) != DDS_RETCODE_OK)
if (ret != 0) { {
dds_delete_qos(rqos); dds_delete_qos (rqos);
reader = ret; reader = ret;
goto err_bad_qos; goto err_bad_qos;
} }
/* Additional checks required for built-in topics */ /* Additional checks required for built-in topics: we don't want to
if (internal_topic && !dds__validate_builtin_reader_qos(topic, qos)) { run into a resource limit on a built-in topic, it is a needless
dds_delete_qos(rqos); complication */
DDS_ERROR("Invalid QoS specified for built-in topic reader"); if (internal_topic && !dds__validate_builtin_reader_qos (topic, qos))
{
dds_delete_qos (rqos);
reader = DDS_RETCODE_INCONSISTENT_POLICY; reader = DDS_RETCODE_INCONSISTENT_POLICY;
goto err_bad_qos; goto err_bad_qos;
} }
@ -462,57 +418,50 @@ dds_create_reader(
rd->m_entity.m_deriver.get_instance_hdl = dds_reader_instance_hdl; 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 /* 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. */ has deleted its reader as well. This can be known through the callback. */
dds_handle_claim_inc (&rd->m_entity.m_hdllink); dds_handle_claim_inc (&rd->m_entity.m_hdllink);
ddsrt_mutex_unlock(&tp->m_entity.m_mutex); ddsrt_mutex_unlock (&tp->m_entity.m_mutex);
ddsrt_mutex_unlock(&sub->m_entity.m_mutex); ddsrt_mutex_unlock (&sub->m_entity.m_mutex);
thread_state_awake (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, 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);
rqos, rhc, dds_reader_status_cb, rd); ddsrt_mutex_lock (&sub->m_entity.m_mutex);
ddsrt_mutex_lock(&sub->m_entity.m_mutex); ddsrt_mutex_lock (&tp->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 */
assert (ret == DDS_RETCODE_OK);
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());
/* For persistent data register reader with durability */ /* 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)) { 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_global.m_dur_reader) (rd, rhc);
} }
dds_topic_unlock(tp); dds_topic_unlock (tp);
dds_subscriber_unlock(sub); dds_subscriber_unlock (sub);
if (internal_topic) { if (internal_topic)
/* If topic is builtin, then the topic entity is local and should {
* be deleted because the application won't. */ /* If topic is builtin, then the topic entity is local and should be deleted because the application won't. */
dds_delete(t); dds_delete (t);
} }
return reader; return reader;
err_bad_qos: err_bad_qos:
dds_topic_unlock(tp); dds_topic_unlock (tp);
err_tp_lock: err_tp_lock:
dds_subscriber_unlock(sub); dds_subscriber_unlock (sub);
if((sub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){ if ((sub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0)
(void)dds_delete(subscriber); (void) dds_delete (subscriber);
}
err_sub_lock: err_sub_lock:
if (internal_topic) { if (internal_topic)
/* If topic is builtin, then the topic entity is local and should dds_delete (t);
* be deleted because the application won't. */
dds_delete(t);
}
return reader; return reader;
} }
void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb, void *cbarg) void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb, void *cbarg)
{ {
dds_entity *dds_entity; dds_entity *dds_entity;
if (dds_entity_claim(entity, &dds_entity) != DDS_RETCODE_OK) if (dds_entity_claim (entity, &dds_entity) != DDS_RETCODE_OK)
return; return;
if (dds_entity_kind (dds_entity) != DDS_KIND_READER) if (dds_entity_kind (dds_entity) != DDS_KIND_READER)
{ {
dds_entity_release (dds_entity); dds_entity_release (dds_entity);
@ -621,169 +570,12 @@ dds_entity_t dds_get_subscriber (dds_entity_t entity)
} }
} }
dds_return_t /* Reset sets everything (type) 0, including the reason field, verify that 0 is correct */
dds_get_subscription_matched_status ( DDSRT_STATIC_ASSERT ((int) DDS_NOT_REJECTED == 0);
dds_entity_t reader,
dds_subscription_matched_status_t * status)
{
dds_reader *rd;
dds_return_t ret;
ret = dds_reader_lock(reader, &rd); DDS_GET_STATUS (reader, subscription_matched, SUBSCRIPTION_MATCHED, total_count_change, current_count_change)
if (ret != DDS_RETCODE_OK) { DDS_GET_STATUS (reader, liveliness_changed, LIVELINESS_CHANGED, alive_count_change, not_alive_count_change)
DDS_ERROR("Error occurred on locking reader\n"); DDS_GET_STATUS (reader, sample_rejected, SAMPLE_REJECTED, total_count_change, last_reason)
goto fail; DDS_GET_STATUS (reader, sample_lost, SAMPLE_LOST, total_count_change)
} DDS_GET_STATUS (reader, requested_deadline_missed, REQUESTED_DEADLINE_MISSED, total_count_change)
/* status = NULL, application do not need the status, but reset the counter & triggered bit */ DDS_GET_STATUS (reader, requested_incompatible_qos, REQUESTED_INCOMPATIBLE_QOS, total_count_change)
if (status) {
*status = rd->m_subscription_matched_status;
}
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
if (rd->m_entity.m_status_enable & DDS_SUBSCRIPTION_MATCHED_STATUS) {
rd->m_subscription_matched_status.total_count_change = 0;
rd->m_subscription_matched_status.current_count_change = 0;
dds_entity_status_reset(&rd->m_entity, DDS_SUBSCRIPTION_MATCHED_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
dds_reader_unlock(rd);
fail:
return ret;
}
dds_return_t
dds_get_liveliness_changed_status (
dds_entity_t reader,
dds_liveliness_changed_status_t * status)
{
dds_reader *rd;
dds_return_t ret;
ret = dds_reader_lock(reader, &rd);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking reader\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = rd->m_liveliness_changed_status;
}
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
if (rd->m_entity.m_status_enable & DDS_LIVELINESS_CHANGED_STATUS) {
rd->m_liveliness_changed_status.alive_count_change = 0;
rd->m_liveliness_changed_status.not_alive_count_change = 0;
dds_entity_status_reset(&rd->m_entity, DDS_LIVELINESS_CHANGED_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
dds_reader_unlock(rd);
fail:
return ret;
}
dds_return_t dds_get_sample_rejected_status (
dds_entity_t reader,
dds_sample_rejected_status_t * status)
{
dds_reader *rd;
dds_return_t ret;
ret = dds_reader_lock(reader, &rd);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking reader\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = rd->m_sample_rejected_status;
}
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
if (rd->m_entity.m_status_enable & DDS_SAMPLE_REJECTED_STATUS) {
rd->m_sample_rejected_status.total_count_change = 0;
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
dds_entity_status_reset(&rd->m_entity, DDS_SAMPLE_REJECTED_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
dds_reader_unlock(rd);
fail:
return ret;
}
dds_return_t dds_get_sample_lost_status (
dds_entity_t reader,
dds_sample_lost_status_t * status)
{
dds_reader *rd;
dds_return_t ret;
ret = dds_reader_lock(reader, &rd);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking reader\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = rd->m_sample_lost_status;
}
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
if (rd->m_entity.m_status_enable & DDS_SAMPLE_LOST_STATUS) {
rd->m_sample_lost_status.total_count_change = 0;
dds_entity_status_reset(&rd->m_entity, DDS_SAMPLE_LOST_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
dds_reader_unlock(rd);
fail:
return ret;
}
dds_return_t dds_get_requested_deadline_missed_status (
dds_entity_t reader,
dds_requested_deadline_missed_status_t * status)
{
dds_reader *rd;
dds_return_t ret;
ret = dds_reader_lock(reader, &rd);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking reader\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = rd->m_requested_deadline_missed_status;
}
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
if (rd->m_entity.m_status_enable & DDS_REQUESTED_DEADLINE_MISSED_STATUS) {
rd->m_requested_deadline_missed_status.total_count_change = 0;
dds_entity_status_reset(&rd->m_entity, DDS_REQUESTED_DEADLINE_MISSED_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
dds_reader_unlock(rd);
fail:
return ret;
}
dds_return_t dds_get_requested_incompatible_qos_status (
dds_entity_t reader,
dds_requested_incompatible_qos_status_t * status)
{
dds_reader *rd;
dds_return_t ret;
ret = dds_reader_lock(reader, &rd);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking reader\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = rd->m_requested_incompatible_qos_status;
}
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
if (rd->m_entity.m_status_enable & DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS) {
rd->m_requested_incompatible_qos_status.total_count_change = 0;
dds_entity_status_reset(&rd->m_entity, DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
dds_reader_unlock(rd);
fail:
return ret;
}

View file

@ -204,9 +204,7 @@ static void dds_os_put_bytes_aligned (dds_ostream_t * __restrict s, const void *
static uint32_t get_type_size (enum dds_stream_typecode type) static uint32_t get_type_size (enum dds_stream_typecode type)
{ {
struct check { DDSRT_STATIC_ASSERT (DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4);
char x[(DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4) ? 1 : -1];
};
assert (type == DDS_OP_VAL_1BY || type == DDS_OP_VAL_2BY || type == DDS_OP_VAL_4BY || type == DDS_OP_VAL_8BY); assert (type == DDS_OP_VAL_1BY || type == DDS_OP_VAL_2BY || type == DDS_OP_VAL_4BY || type == DDS_OP_VAL_8BY);
return (uint32_t)1 << ((uint32_t) type - 1); return (uint32_t)1 << ((uint32_t) type - 1);
} }

View file

@ -11,199 +11,126 @@
*/ */
#include <string.h> #include <string.h>
#include "dds__listener.h" #include "dds__listener.h"
#include "dds__participant.h"
#include "dds__qos.h" #include "dds__qos.h"
#include "dds__subscriber.h" #include "dds__subscriber.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/version.h" #include "dds/version.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_subscriber) DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_subscriber)
#define DDS_SUBSCRIBER_STATUS_MASK \ #define DDS_SUBSCRIBER_STATUS_MASK \
DDS_DATA_ON_READERS_STATUS (DDS_DATA_ON_READERS_STATUS)
static dds_return_t static dds_return_t dds_subscriber_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
dds_subscriber_instance_hdl(
dds_entity *e, static dds_return_t dds_subscriber_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
dds_instance_handle_t *i)
{ {
(void)e; (void) e;
(void)i; (void) i;
/* TODO: Get/generate proper handle. */ /* FIXME: Get/generate proper handle. */
DDS_ERROR("Generating subscriber instance handle is not supported");
return DDS_RETCODE_UNSUPPORTED; return DDS_RETCODE_UNSUPPORTED;
} }
static dds_return_t static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds__subscriber_qos_validate(
const dds_qos_t *qos, static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, bool enabled)
bool enabled)
{ {
dds_return_t ret = DDS_RETCODE_OK; if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
assert(qos); if ((qos->present & QP_PARTITION) && !validate_stringseq (&qos->partition))
return DDS_RETCODE_INCONSISTENT_POLICY;
if((qos->present & QP_GROUP_DATA) && !validate_octetseq(&qos->group_data)) { if ((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy (&qos->presentation) < 0)
DDS_ERROR("Group data policy is inconsistent and caused an error\n"); return DDS_RETCODE_INCONSISTENT_POLICY;
ret = DDS_RETCODE_INCONSISTENT_POLICY; if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
} return DDS_RETCODE_INCONSISTENT_POLICY;
if((qos->present & QP_PARTITION) && !validate_stringseq(&qos->partition)) { /* FIXME: Improve/check immutable check. */
DDS_ERROR("Partition policy is inconsistent and caused an error\n"); return (enabled && (qos->present & QP_PRESENTATION)) ? DDS_RETCODE_IMMUTABLE_POLICY : DDS_RETCODE_OK;
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;
}
return ret;
} }
static dds_return_t static dds_return_t dds_subscriber_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_subscriber_qos_set(
dds_entity *e, static dds_return_t dds_subscriber_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
const dds_qos_t *qos,
bool enabled)
{ {
dds_return_t ret = dds__subscriber_qos_validate(qos, enabled); /* FIXME: QoS changes. */
(void)e; dds_return_t ret;
if (ret == DDS_RETCODE_OK) { (void) e;
if (enabled) { if ((ret = dds__subscriber_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
/* 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 ret;
return (enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK);
} }
static dds_return_t static dds_return_t dds_subscriber_status_validate (uint32_t mask)
dds_subscriber_status_validate(
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK; return (mask & ~DDS_SUBSCRIBER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
if (mask & ~(DDS_SUBSCRIBER_STATUS_MASK)) {
DDS_ERROR("Invalid status mask\n");
ret = DDS_RETCODE_BAD_PARAMETER;
}
return ret;
} }
dds_entity_t dds_entity_t dds__create_subscriber_l (dds_participant *participant, const dds_qos_t *qos, const dds_listener_t *listener)
dds__create_subscriber_l(
dds_entity *participant, /* entity-lock must be held */
const dds_qos_t *qos,
const dds_listener_t *listener)
{ {
dds_subscriber * sub; /* participant entity lock must be held */
dds_subscriber *sub;
dds_entity_t subscriber; dds_entity_t subscriber;
dds_return_t ret; dds_return_t ret;
dds_qos_t * new_qos; dds_qos_t *new_qos;
/* Validate qos */ /* Validate qos */
if (qos) { if (qos && (ret = dds__subscriber_qos_validate (qos, false)) != DDS_RETCODE_OK)
if ((ret = dds__subscriber_qos_validate(qos, false)) != DDS_RETCODE_OK) { return ret;
goto err_param;
} if (qos == NULL)
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; new_qos = NULL;
else
{
new_qos = dds_create_qos ();
(void) dds_copy_qos (new_qos, qos);
} }
/* Create subscriber */ sub = dds_alloc (sizeof (*sub));
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);
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.set_qos = dds_subscriber_qos_set;
sub->m_entity.m_deriver.validate_status = dds_subscriber_status_validate; sub->m_entity.m_deriver.validate_status = dds_subscriber_status_validate;
sub->m_entity.m_deriver.get_instance_hdl = dds_subscriber_instance_hdl; sub->m_entity.m_deriver.get_instance_hdl = dds_subscriber_instance_hdl;
return subscriber; return subscriber;
/* Error handling */
err_param:
return ret;
} }
dds_entity_t dds_entity_t dds_create_subscriber (dds_entity_t participant, const dds_qos_t *qos, const dds_listener_t *listener)
dds_create_subscriber(
dds_entity_t participant,
const dds_qos_t *qos,
const dds_listener_t *listener)
{ {
dds_entity * par; dds_participant *par;
dds_entity_t hdl; dds_entity_t hdl;
dds_return_t errnr; dds_return_t ret;
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
errnr = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par); return ret;
if (errnr != DDS_RETCODE_OK) { hdl = dds__create_subscriber_l (par, qos, listener);
DDS_ERROR("Error occurred on locking participant\n"); dds_participant_unlock (par);
hdl = errnr;
return hdl;
}
hdl = dds__create_subscriber_l(par, qos, listener);
dds_entity_unlock(par);
return hdl; return hdl;
} }
dds_return_t dds_return_t dds_notify_readers (dds_entity_t subscriber)
dds_notify_readers(
dds_entity_t subscriber)
{ {
dds_entity *iter; dds_subscriber *sub;
dds_entity *sub;
dds_return_t ret; dds_return_t ret;
ret = dds_entity_lock(subscriber, DDS_KIND_SUBSCRIBER, &sub); if ((ret = dds_subscriber_lock (subscriber, &sub)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
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");
}
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; return ret;
} }
dds_return_t dds_return_t dds_subscriber_begin_coherent (dds_entity_t e)
dds_subscriber_begin_coherent(
dds_entity_t e)
{ {
/* TODO: CHAM-124 Currently unsupported. */ return dds_generic_unimplemented_operation (e, DDS_KIND_SUBSCRIBER);
(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_return_t dds_subscriber_end_coherent (dds_entity_t e)
dds_subscriber_end_coherent(
dds_entity_t e)
{ {
/* TODO: CHAM-124 Currently unsupported. */ return dds_generic_unimplemented_operation (e, DDS_KIND_SUBSCRIBER);
(void)e;
DDS_ERROR("Using coherency to get a coherent data set is not currently being supported\n");
return DDS_RETCODE_UNSUPPORTED;
} }

View file

@ -17,33 +17,33 @@
#include "dds__topic.h" #include "dds__topic.h"
#include "dds__listener.h" #include "dds__listener.h"
#include "dds__qos.h" #include "dds__qos.h"
#include "dds__participant.h"
#include "dds__stream.h" #include "dds__stream.h"
#include "dds__init.h" #include "dds__init.h"
#include "dds__domain.h" #include "dds__domain.h"
#include "dds__get_status.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_thread.h" #include "dds/ddsi/q_thread.h"
#include "dds/ddsi/ddsi_sertopic.h" #include "dds/ddsi/ddsi_sertopic.h"
#include "dds/ddsi/q_ddsi_discovery.h" #include "dds/ddsi/q_ddsi_discovery.h"
#include "dds/ddsi/ddsi_iid.h" #include "dds/ddsi/ddsi_iid.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_topic) DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_topic)
#define DDS_TOPIC_STATUS_MASK \ #define DDS_TOPIC_STATUS_MASK \
DDS_INCONSISTENT_TOPIC_STATUS (DDS_INCONSISTENT_TOPIC_STATUS)
const ddsrt_avl_treedef_t dds_topictree_def = DDSRT_AVL_TREEDEF_INITIALIZER_INDKEY static int strcmp_wrapper (const void *va, const void *vb)
( {
offsetof (struct ddsi_sertopic, avlnode), return strcmp (va, vb);
offsetof (struct ddsi_sertopic, name_type_name), }
(int (*) (const void *, const void *)) strcmp,
0 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 bool is_valid_name (const char *name) ddsrt_nonnull_all;
static bool
is_valid_name( static bool is_valid_name (const char *name)
const char *name)
{ {
bool valid = false;
/* DDS Spec: /* DDS Spec:
* | TOPICNAME - A topic name is an identifier for a topic, and is defined as any series of characters * | TOPICNAME - A topic name is an identifier for a topic, and is defined as any series of characters
* | 'a', ..., 'z', * | 'a', ..., 'z',
@ -53,32 +53,17 @@ is_valid_name(
* It is considered that '-' is an error in the spec and should say '_'. So, that's what we'll check for. * 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 * | '/' got added for ROS2
*/ */
assert(name); if (name[0] == '\0' || isdigit ((unsigned char) name[0]))
if ((name[0] != '\0') && (!isdigit((unsigned char)name[0]))) { return false;
while (isalnum((unsigned char)*name) || (*name == '_') || (*name == '/')) { for (size_t i = 0; name[i]; i++)
name++; if (!(isalnum ((unsigned char) name[i]) || name[i] == '_' || name[i] == '/'))
} return false;
if (*name == '\0') { return true;
valid = true;
}
}
return valid;
} }
static dds_return_t dds_topic_status_validate (uint32_t mask)
static dds_return_t
dds_topic_status_validate(
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK; return (mask & ~DDS_TOPIC_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
if (mask & ~(DDS_TOPIC_STATUS_MASK)) {
DDS_ERROR("Argument mask is invalid\n");
ret = DDS_RETCODE_BAD_PARAMETER;
}
return ret;
} }
/* /*
@ -100,62 +85,45 @@ static void dds_topic_status_cb (struct dds_topic *tp)
if (lst->on_inconsistent_topic) if (lst->on_inconsistent_topic)
{ {
ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock); ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock);
dds_entity_invoke_listener(&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS_ID, &tp->m_inconsistent_topic_status); dds_entity_invoke_listener (&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS_ID, &tp->m_inconsistent_topic_status);
ddsrt_mutex_lock (&tp->m_entity.m_observers_lock); ddsrt_mutex_lock (&tp->m_entity.m_observers_lock);
tp->m_inconsistent_topic_status.total_count_change = 0; tp->m_inconsistent_topic_status.total_count_change = 0;
} }
dds_entity_status_set(&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS); dds_entity_status_set (&tp->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
tp->m_entity.m_cb_count--; tp->m_entity.m_cb_count--;
ddsrt_cond_broadcast (&tp->m_entity.m_observers_cond); ddsrt_cond_broadcast (&tp->m_entity.m_observers_cond);
ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock); ddsrt_mutex_unlock (&tp->m_entity.m_observers_lock);
} }
struct ddsi_sertopic * struct ddsi_sertopic *dds_topic_lookup_locked (dds_domain *domain, const char *name) ddsrt_nonnull_all;
dds_topic_lookup_locked(
dds_domain *domain, struct ddsi_sertopic *dds_topic_lookup_locked (dds_domain *domain, const char *name)
const char *name)
{ {
struct ddsi_sertopic *st = NULL;
ddsrt_avl_iter_t iter; ddsrt_avl_iter_t iter;
for (struct ddsi_sertopic *st = ddsrt_avl_iter_first (&dds_topictree_def, &domain->m_topics, &iter); st; st = ddsrt_avl_iter_next (&iter))
assert (domain); if (strcmp (st->name, name) == 0)
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; return st;
return NULL;
} }
struct ddsi_sertopic * struct ddsi_sertopic *dds_topic_lookup (dds_domain *domain, const char *name)
dds_topic_lookup(
dds_domain *domain,
const char *name)
{ {
struct ddsi_sertopic *st; struct ddsi_sertopic *st;
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
st = dds_topic_lookup_locked(domain, name); st = dds_topic_lookup_locked (domain, name);
ddsrt_mutex_unlock (&dds_global.m_mutex); ddsrt_mutex_unlock (&dds_global.m_mutex);
return st; return st;
} }
void void dds_topic_free (dds_domainid_t domainid, struct ddsi_sertopic *st)
dds_topic_free(
dds_domainid_t domainid,
struct ddsi_sertopic *st)
{ {
dds_domain *domain; dds_domain *domain;
assert (st);
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
domain = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &domainid); domain = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
if (domain != NULL) { 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_avl_delete (&dds_topictree_def, &domain->m_topics, st);
} }
ddsrt_mutex_unlock (&dds_global.m_mutex); ddsrt_mutex_unlock (&dds_global.m_mutex);
@ -163,33 +131,32 @@ dds_topic_free(
ddsi_sertopic_unref (st); ddsi_sertopic_unref (st);
} }
static void static void dds_topic_add_locked (dds_domainid_t id, struct ddsi_sertopic *st)
dds_topic_add_locked(
dds_domainid_t id,
struct ddsi_sertopic *st)
{ {
dds_domain * dom; dds_domain *dom = dds_domain_find_locked (id);
dom = dds_domain_find_locked (id);
assert (dom); assert (dom);
assert (ddsrt_avl_lookup (&dds_topictree_def, &dom->m_topics, st->name_type_name) == NULL);
ddsrt_avl_insert (&dds_topictree_def, &dom->m_topics, st); ddsrt_avl_insert (&dds_topictree_def, &dom->m_topics, st);
} }
DDS_EXPORT dds_entity_t dds_entity_t dds_find_topic (dds_entity_t participant, const char *name)
dds_find_topic(
dds_entity_t participant,
const char *name)
{ {
dds_entity_t tp; dds_entity_t tp;
dds_entity *p = NULL; dds_participant *p;
struct ddsi_sertopic *st; struct ddsi_sertopic *st;
dds_return_t rc; dds_return_t rc;
if (name) { if (name == NULL)
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &p); return DDS_RETCODE_BAD_PARAMETER;
if (rc == DDS_RETCODE_OK) {
if ((rc = dds_participant_lock (participant, &p)) != DDS_RETCODE_OK)
return rc;
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
st = dds_topic_lookup_locked (p->m_domain, name); if ((st = dds_topic_lookup_locked (p->m_entity.m_domain, name)) == NULL)
if (st) { tp = DDS_RETCODE_PRECONDITION_NOT_MET;
else
{
/* FIXME: calling addref is wrong because the Cyclone library has no /* FIXME: calling addref is wrong because the Cyclone library has no
knowledge of the reference and hence simply deleting the participant 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 won't make the ref count drop to 0. On the other hand, the DDS spec
@ -197,94 +164,56 @@ dds_find_topic(
proxy that must separately be deleted. */ proxy that must separately be deleted. */
dds_entity_add_ref (&st->status_cb_entity->m_entity); dds_entity_add_ref (&st->status_cb_entity->m_entity);
tp = st->status_cb_entity->m_entity.m_hdllink.hdl; 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); ddsrt_mutex_unlock (&dds_global.m_mutex);
dds_entity_unlock(p); dds_participant_unlock (p);
} else {
tp = rc;
}
} else {
DDS_ERROR("Argument name is not valid\n");
tp = DDS_RETCODE_BAD_PARAMETER;
}
return tp; return tp;
} }
static dds_return_t static dds_return_t dds_topic_delete (dds_entity *e) ddsrt_nonnull_all;
dds_topic_delete(
dds_entity *e) static dds_return_t dds_topic_delete (dds_entity *e)
{ {
dds_topic_free(e->m_domainid, ((dds_topic*) e)->m_stopic); dds_topic_free (e->m_domainid, ((dds_topic *) e)->m_stopic);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
static dds_return_t static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled) ddsrt_nonnull_all;
dds_topic_qos_validate(
const dds_qos_t *qos,
bool enabled)
{
dds_return_t ret = DDS_RETCODE_OK;
assert(qos);
/* Check consistency. */ static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled)
if (!dds_qos_validate_common(qos)) { {
DDS_ERROR("Argument QoS is not valid\n"); if (!dds_qos_validate_common (qos))
ret = DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
} if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data)) { return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("Group data QoS policy is inconsistent and caused an error\n"); if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy(&qos->durability_service) < 0)
ret = DDS_RETCODE_INCONSISTENT_POLICY; return DDS_RETCODE_INCONSISTENT_POLICY;
} if ((qos->present & QP_LIFESPAN) && validate_duration(&qos->lifespan.duration) < 0)
if ((qos->present & QP_DURABILITY_SERVICE) && (validate_durability_service_qospolicy(&qos->durability_service) != 0)) { return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("Durability service QoS policy is inconsistent and caused an error\n"); if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && validate_history_and_resource_limits(&qos->history, &qos->resource_limits) < 0)
ret = DDS_RETCODE_INCONSISTENT_POLICY; return DDS_RETCODE_INCONSISTENT_POLICY;
} return enabled ? dds_qos_validate_mutable_common(qos) : DDS_RETCODE_OK;
if ((qos->present & QP_LIFESPAN) && (validate_duration(&qos->lifespan.duration) != 0)) {
DDS_ERROR("Lifespan QoS policy is inconsistent and caused an error\n");
ret = DDS_RETCODE_INCONSISTENT_POLICY;
}
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);
}
return ret;
} }
static dds_return_t static dds_return_t dds_topic_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
dds_topic_qos_set(
dds_entity *e,
const dds_qos_t *qos,
bool enabled)
{ {
dds_return_t ret = dds_topic_qos_validate(qos, enabled); /* FIXME: QoS changes */
(void)e; dds_return_t ret;
if (ret == DDS_RETCODE_OK) { (void) e;
if (enabled) { if ((ret = dds_topic_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
/* 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; return ret;
return enabled ? DDS_RETCODE_UNSUPPORTED : DDS_RETCODE_OK;
} }
static bool dupdef_qos_ok(const dds_qos_t *qos, const struct ddsi_sertopic *st) static 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)) { if ((qos == NULL) != (st->status_cb_entity->m_entity.m_qos == NULL))
return false; return false;
} else if (qos == NULL) { else if (qos == NULL)
return true; return true;
} else { else
return dds_qos_equal(st->status_cb_entity->m_entity.m_qos, qos); return dds_qos_equal (st->status_cb_entity->m_entity.m_qos, qos);
}
} }
static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct ddsi_sertopic *b) static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct ddsi_sertopic *b)
@ -300,55 +229,38 @@ static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct dds
return true; return true;
} }
DDS_EXPORT dds_entity_t dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_sertopic *sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const nn_plist_t *sedp_plist)
dds_create_topic_arbitrary (
dds_entity_t participant,
struct ddsi_sertopic *sertopic,
const dds_qos_t *qos,
const dds_listener_t *listener,
const nn_plist_t *sedp_plist)
{ {
struct ddsi_sertopic *stgeneric; struct ddsi_sertopic *stgeneric;
dds_return_t rc; dds_return_t rc;
dds_entity *par; dds_participant *par;
dds_topic *top; dds_topic *top;
dds_qos_t *new_qos = NULL; dds_qos_t *new_qos = NULL;
dds_entity_t hdl; dds_entity_t hdl;
struct participant *ddsi_pp; struct participant *ddsi_pp;
if (sertopic == NULL){ if (sertopic == NULL)
DDS_ERROR("Topic description is NULL\n"); return DDS_RETCODE_BAD_PARAMETER;
hdl = DDS_RETCODE_BAD_PARAMETER;
goto bad_param_err;
}
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par); if (qos && (rc = dds_topic_qos_validate (qos, false)) != DDS_RETCODE_OK)
if (rc != DDS_RETCODE_OK) { return rc;
hdl = rc;
goto lock_err;
}
/* Validate qos */ if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
if (qos) { return rc;
hdl = dds_topic_qos_validate (qos, false);
if (hdl != DDS_RETCODE_OK) {
goto qos_err;
}
}
/* FIXME: I find it weird that qos may be NULL in the entity */ /* FIXME: I find it weird that qos may be NULL in the entity */
/* Check if topic already exists with same name */ /* Check if topic already exists with same name */
ddsrt_mutex_lock (&dds_global.m_mutex); ddsrt_mutex_lock (&dds_global.m_mutex);
if ((stgeneric = dds_topic_lookup_locked (par->m_domain, sertopic->name)) != NULL) { if ((stgeneric = dds_topic_lookup_locked (par->m_entity.m_domain, sertopic->name)) != NULL) {
if (!sertopic_equivalent (stgeneric, sertopic)) { if (!sertopic_equivalent (stgeneric, sertopic)) {
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */ /* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
DDS_ERROR("Create topic with mismatching type\n"); rc = DDS_RETCODE_PRECONDITION_NOT_MET;
hdl = DDS_RETCODE_PRECONDITION_NOT_MET; goto err_mismatch;
} else if (!dupdef_qos_ok(qos, stgeneric)) { } else if (!dupdef_qos_ok(qos, stgeneric)) {
/* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */ /* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */
DDS_ERROR("Create topic with mismatching qos\n"); rc = DDS_RETCODE_INCONSISTENT_POLICY;
hdl = DDS_RETCODE_INCONSISTENT_POLICY; goto err_mismatch;
} else { } else {
/* FIXME: calling addref is wrong because the Cyclone library has no /* FIXME: calling addref is wrong because the Cyclone library has no
knowledge of the reference and hence simply deleting the participant knowledge of the reference and hence simply deleting the participant
@ -360,16 +272,15 @@ dds_create_topic_arbitrary (
} }
ddsrt_mutex_unlock (&dds_global.m_mutex); ddsrt_mutex_unlock (&dds_global.m_mutex);
} else { } else {
if (qos) { if (qos)
new_qos = dds_create_qos(); {
/* Only returns failure when one of the qos args is NULL, which new_qos = dds_create_qos ();
* is not the case here. */ (void)dds_copy_qos (new_qos, qos);
(void)dds_copy_qos(new_qos, qos);
} }
/* Create topic */ /* Create topic */
top = dds_alloc (sizeof (*top)); top = dds_alloc (sizeof (*top));
hdl = dds_entity_init (&top->m_entity, par, DDS_KIND_TOPIC, new_qos, listener, DDS_TOPIC_STATUS_MASK); 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.delete = dds_topic_delete;
top->m_entity.m_deriver.set_qos = dds_topic_qos_set; top->m_entity.m_deriver.set_qos = dds_topic_qos_set;
top->m_entity.m_deriver.validate_status = dds_topic_status_validate; top->m_entity.m_deriver.validate_status = dds_topic_status_validate;
@ -377,33 +288,27 @@ dds_create_topic_arbitrary (
sertopic->status_cb_entity = top; sertopic->status_cb_entity = top;
/* Add topic to extent */ /* Add topic to extent */
dds_topic_add_locked (par->m_domainid, sertopic); dds_topic_add_locked (par->m_entity.m_domainid, sertopic);
ddsrt_mutex_unlock (&dds_global.m_mutex); ddsrt_mutex_unlock (&dds_global.m_mutex);
/* Publish Topic */ /* Publish Topic */
thread_state_awake (lookup_thread_state ()); thread_state_awake (lookup_thread_state ());
ddsi_pp = ephash_lookup_participant_guid (&par->m_guid); ddsi_pp = ephash_lookup_participant_guid (&par->m_entity.m_guid);
assert (ddsi_pp); assert (ddsi_pp);
if (sedp_plist) { if (sedp_plist)
sedp_write_topic (ddsi_pp, sedp_plist); sedp_write_topic (ddsi_pp, sedp_plist);
}
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());
} }
dds_participant_unlock (par);
qos_err:
dds_entity_unlock(par);
lock_err:
bad_param_err:
return hdl; return hdl;
err_mismatch:
ddsrt_mutex_unlock (&dds_global.m_mutex);
dds_participant_unlock (par);
return rc;
} }
DDS_EXPORT dds_entity_t dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descriptor_t *desc, const char *name, const dds_qos_t *qos, const dds_listener_t *listener)
dds_create_topic(
dds_entity_t participant,
const dds_topic_descriptor_t *desc,
const char *name,
const dds_qos_t *qos,
const dds_listener_t *listener)
{ {
char *key = NULL; char *key = NULL;
struct ddsi_sertopic_default *st; struct ddsi_sertopic_default *st;
@ -411,31 +316,15 @@ dds_create_topic(
dds_qos_t *new_qos = NULL; dds_qos_t *new_qos = NULL;
nn_plist_t plist; nn_plist_t plist;
dds_entity_t hdl; dds_entity_t hdl;
uint32_t index;
size_t keysz; size_t keysz;
if (desc == NULL){ if (desc == NULL || name == NULL || !is_valid_name (name))
DDS_ERROR("Topic description is NULL"); return DDS_RETCODE_BAD_PARAMETER;
hdl = DDS_RETCODE_BAD_PARAMETER;
goto bad_param_err;
}
if (name == NULL) {
DDS_ERROR("Topic name is NULL");
hdl = DDS_RETCODE_BAD_PARAMETER;
goto bad_param_err;
}
if (!is_valid_name(name)) {
DDS_ERROR("Topic name contains characters that are not allowed.");
hdl = DDS_RETCODE_BAD_PARAMETER;
goto bad_param_err;
}
typename = desc->m_typename; typename = desc->m_typename;
keysz = strlen (name) + strlen (typename) + 2; keysz = strlen (name) + strlen (typename) + 2;
key = (char*) dds_alloc (keysz); key = dds_alloc (keysz);
(void) snprintf(key, keysz, "%s/%s", name, typename); (void) snprintf (key, keysz, "%s/%s", name, typename);
st = dds_alloc (sizeof (*st)); st = dds_alloc (sizeof (*st));
@ -456,59 +345,50 @@ dds_create_topic(
st->keys = desc->m_keys; st->keys = desc->m_keys;
/* Check if topic cannot be optimised (memcpy marshal) */ /* Check if topic cannot be optimised (memcpy marshal) */
if ((desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) == 0) { if (!(desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE)) {
st->opt_size = dds_stream_check_optimize (desc); st->opt_size = dds_stream_check_optimize (desc);
} }
nn_plist_init_empty (&plist); nn_plist_init_empty (&plist);
if (new_qos) { if (new_qos)
dds_merge_qos (&plist.qos, new_qos); dds_merge_qos (&plist.qos, new_qos);
}
/* Set Topic meta data (for SEDP publication) */ /* Set Topic meta data (for SEDP publication) */
plist.qos.topic_name = dds_string_dup (st->c.name); plist.qos.topic_name = dds_string_dup (st->c.name);
plist.qos.type_name = dds_string_dup (st->c.type_name); plist.qos.type_name = dds_string_dup (st->c.type_name);
plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME); plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME);
if (desc->m_meta) { if (desc->m_meta)
{
plist.type_description = dds_string_dup (desc->m_meta); plist.type_description = dds_string_dup (desc->m_meta);
plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION; plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION;
} }
if (desc->m_nkeys) { if (desc->m_nkeys)
{
plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS; plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS;
plist.qos.subscription_keys.use_key_list = 1; plist.qos.subscription_keys.use_key_list = 1;
plist.qos.subscription_keys.key_list.n = desc->m_nkeys; plist.qos.subscription_keys.key_list.n = desc->m_nkeys;
plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*)); plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*));
for (index = 0; index < desc->m_nkeys; index++) { 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); 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); hdl = dds_create_topic_arbitrary (participant, &st->c, qos, listener, &plist);
ddsi_sertopic_unref (&st->c); ddsi_sertopic_unref (&st->c);
nn_plist_fini (&plist); nn_plist_fini (&plist);
bad_param_err:
return hdl; return hdl;
} }
static bool static bool dds_topic_chaining_filter (const void *sample, void *ctx)
dds_topic_chaining_filter(
const void *sample,
void *ctx)
{ {
dds_topic_filter_fn realf = (dds_topic_filter_fn)ctx; dds_topic_filter_fn realf = (dds_topic_filter_fn) ctx;
return realf (sample); return realf (sample);
} }
static void static void dds_topic_mod_filter (dds_entity_t topic, dds_topic_intern_filter_fn *filter, void **ctx, bool set)
dds_topic_mod_filter(
dds_entity_t topic,
dds_topic_intern_filter_fn *filter,
void **ctx,
bool set)
{ {
dds_topic *t; dds_topic *t;
if (dds_topic_lock(topic, &t) == DDS_RETCODE_OK) { if (dds_topic_lock (topic, &t) == DDS_RETCODE_OK)
{
if (set) { if (set) {
t->filter_fn = *filter; t->filter_fn = *filter;
t->filter_ctx = *ctx; t->filter_ctx = *ctx;
@ -516,60 +396,46 @@ dds_topic_mod_filter(
*filter = t->filter_fn; *filter = t->filter_fn;
*ctx = t->filter_ctx; *ctx = t->filter_ctx;
} }
dds_topic_unlock(t); dds_topic_unlock (t);
} else { }
else
{
*filter = 0; *filter = 0;
*ctx = NULL; *ctx = NULL;
} }
} }
void void dds_set_topic_filter (dds_entity_t topic, dds_topic_filter_fn filter)
dds_set_topic_filter(
dds_entity_t topic,
dds_topic_filter_fn filter)
{ {
dds_topic_intern_filter_fn chaining = dds_topic_chaining_filter; dds_topic_intern_filter_fn chaining = dds_topic_chaining_filter;
void *realf = (void *)filter; void *realf = (void *) filter;
dds_topic_mod_filter (topic, &chaining, &realf, true); dds_topic_mod_filter (topic, &chaining, &realf, true);
} }
void void dds_topic_set_filter (dds_entity_t topic, dds_topic_filter_fn filter)
dds_topic_set_filter(
dds_entity_t topic,
dds_topic_filter_fn filter)
{ {
dds_set_topic_filter(topic, filter); dds_set_topic_filter (topic, filter);
} }
dds_topic_filter_fn dds_topic_filter_fn dds_get_topic_filter (dds_entity_t topic)
dds_get_topic_filter(
dds_entity_t topic)
{ {
dds_topic_intern_filter_fn filter; dds_topic_intern_filter_fn filter;
void *ctx; void *ctx;
dds_topic_mod_filter (topic, &filter, &ctx, false); dds_topic_mod_filter (topic, &filter, &ctx, false);
return (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn)ctx : 0; return (filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn) ctx : 0;
} }
dds_topic_filter_fn dds_topic_filter_fn dds_topic_get_filter (dds_entity_t topic)
dds_topic_get_filter(
dds_entity_t topic)
{ {
return dds_get_topic_filter(topic); return dds_get_topic_filter (topic);
} }
void void dds_topic_set_filter_with_ctx (dds_entity_t topic, dds_topic_intern_filter_fn filter, void *ctx)
dds_topic_set_filter_with_ctx(
dds_entity_t topic,
dds_topic_intern_filter_fn filter,
void *ctx)
{ {
dds_topic_mod_filter (topic, &filter, &ctx, true); dds_topic_mod_filter (topic, &filter, &ctx, true);
} }
dds_topic_intern_filter_fn dds_topic_intern_filter_fn dds_topic_get_filter_with_ctx (dds_entity_t topic)
dds_topic_get_filter_with_ctx(
dds_entity_t topic)
{ {
dds_topic_intern_filter_fn filter; dds_topic_intern_filter_fn filter;
void *ctx; void *ctx;
@ -577,93 +443,32 @@ dds_topic_get_filter_with_ctx(
return (filter == dds_topic_chaining_filter) ? 0 : filter; return (filter == dds_topic_chaining_filter) ? 0 : filter;
} }
DDS_EXPORT dds_return_t dds_return_t dds_get_name (dds_entity_t topic, char *name, size_t size)
dds_get_name(
dds_entity_t topic,
char *name,
size_t size)
{ {
dds_topic *t; dds_topic *t;
dds_return_t ret; dds_return_t ret;
if (size <= 0 || name == NULL)
if(size <= 0){ return DDS_RETCODE_BAD_PARAMETER;
DDS_ERROR("Argument size is smaller than 0\n");
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'; name[0] = '\0';
ret = dds_topic_lock(topic, &t); if ((ret = dds_topic_lock (topic, &t)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) {
(void)snprintf(name, size, "%s", t->m_stopic->name);
dds_topic_unlock(t);
} else {
DDS_ERROR("Error occurred on locking topic\n");
goto fail;
}
fail:
return ret; return ret;
(void) snprintf (name, size, "%s", t->m_stopic->name);
dds_topic_unlock (t);
return DDS_RETCODE_OK;
} }
DDS_EXPORT dds_return_t dds_return_t dds_get_type_name (dds_entity_t topic, char *name, size_t size)
dds_get_type_name(
dds_entity_t topic,
char *name,
size_t size)
{ {
dds_topic *t; dds_topic *t;
dds_return_t ret; dds_return_t ret;
if (size <= 0 || name == NULL)
if(size <= 0){ return DDS_RETCODE_BAD_PARAMETER;
DDS_ERROR("Argument size is smaller than 0\n");
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'; name[0] = '\0';
ret = dds_topic_lock(topic, &t); if ((ret = dds_topic_lock (topic, &t)) != DDS_RETCODE_OK)
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking topic\n");
goto fail;
}
(void)snprintf(name, size, "%s", t->m_stopic->type_name);
dds_topic_unlock(t);
fail:
return ret; return ret;
(void) snprintf (name, size, "%s", t->m_stopic->type_name);
dds_topic_unlock (t);
return DDS_RETCODE_OK;
} }
dds_return_t DDS_GET_STATUS(topic, inconsistent_topic, INCONSISTENT_TOPIC, total_count_change)
dds_get_inconsistent_topic_status(
dds_entity_t topic,
dds_inconsistent_topic_status_t *status)
{
dds_topic *t;
dds_return_t ret;
ret = dds_topic_lock(topic, &t);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking topic\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = t->m_inconsistent_topic_status;
}
ddsrt_mutex_lock (&t->m_entity.m_observers_lock);
if (t->m_entity.m_status_enable & DDS_INCONSISTENT_TOPIC_STATUS) {
t->m_inconsistent_topic_status.total_count_change = 0;
dds_entity_status_reset(&t->m_entity, DDS_INCONSISTENT_TOPIC_STATUS);
}
ddsrt_mutex_unlock (&t->m_entity.m_observers_lock);
dds_topic_unlock(t);
fail:
return ret;
}

View file

@ -14,336 +14,241 @@
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h" #include "dds/ddsrt/log.h"
#include "dds__entity.h" #include "dds__entity.h"
#include "dds__participant.h"
#include "dds__querycond.h" #include "dds__querycond.h"
#include "dds__readcond.h" #include "dds__readcond.h"
#include "dds__rhc.h" #include "dds__rhc.h"
DEFINE_ENTITY_LOCK_UNLOCK(static, dds_waitset, DDS_KIND_WAITSET) DEFINE_ENTITY_LOCK_UNLOCK (static, dds_waitset, DDS_KIND_WAITSET)
static void static void dds_waitset_swap (dds_attachment **dst, dds_attachment **src, dds_attachment *prev, dds_attachment *idx)
dds_waitset_swap(
dds_attachment **dst,
dds_attachment **src,
dds_attachment *prev,
dds_attachment *idx)
{ {
/* Remove from source. */ /* Remove from source. */
if (prev == NULL) { if (prev == NULL)
*src = idx->next; *src = idx->next;
} else { else
prev->next = idx->next; prev->next = idx->next;
}
/* Add to destination. */ /* Add to destination. */
idx->next = *dst; idx->next = *dst;
*dst = idx; *dst = idx;
} }
static dds_return_t static dds_return_t dds_waitset_wait_impl (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_time_t abstimeout)
dds_waitset_wait_impl(
dds_entity_t waitset,
dds_attach_t *xs,
size_t nxs,
dds_time_t abstimeout,
dds_time_t tnow)
{ {
dds_waitset *ws; dds_waitset *ws;
dds_return_t ret; dds_return_t ret;
dds_attachment *idx; dds_attachment *idx;
dds_attachment *next;
dds_attachment *prev; dds_attachment *prev;
if ((xs == NULL) && (nxs != 0)){ if (xs == NULL && nxs != 0)
DDS_ERROR("A size was given, but no array\n");
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
} if (xs != NULL && nxs == 0)
if ((xs != NULL) && (nxs == 0)){
DDS_ERROR("Array is given with an invalid size\n");
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
}
/* Locking the waitset here will delay a possible deletion until it is /* Locking the waitset here will delay a possible deletion until it is
* unlocked. Even when the related mutex is unlocked by a conditioned wait. */ * unlocked. Even when the related mutex is unlocked by a conditioned wait. */
ret = dds_waitset_lock(waitset, &ws); if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
/* Check if any of any previous triggered entities has changed there status
* and thus it trigger value could be false now. */ /* Move any previously but no longer triggering entities back to the observed list */
idx = ws->triggered; idx = ws->triggered;
prev = NULL; prev = NULL;
while (idx != NULL) { while (idx != NULL)
next = idx->next; {
if (idx->entity->m_trigger == 0) { dds_attachment *next = idx->next;
/* Move observed entity to triggered list. */ if (idx->entity->m_trigger == 0)
dds_waitset_swap(&(ws->observed), &(ws->triggered), prev, idx); dds_waitset_swap (&ws->observed, &ws->triggered, prev, idx);
} else { else
prev = idx; prev = idx;
}
idx = next; idx = next;
} }
/* Check if any of the entities have been triggered. */ /* Check if any of the observed entities are currently triggered, moving them
to the triggered list */
idx = ws->observed; idx = ws->observed;
prev = NULL; prev = NULL;
while (idx != NULL) { while (idx != NULL)
next = idx->next; {
if (idx->entity->m_trigger > 0) { dds_attachment *next = idx->next;
/* Move observed entity to triggered list. */ if (idx->entity->m_trigger > 0)
dds_waitset_swap(&(ws->triggered), &(ws->observed), prev, idx); dds_waitset_swap (&ws->triggered, &ws->observed, prev, idx);
} else { else
prev = idx; prev = idx;
}
idx = next; idx = next;
} }
/* Only wait/keep waiting when whe have something to observer and there aren't any triggers yet. */ /* Only wait/keep waiting when we have something to observe and there aren't any triggers yet. */
while ((ws->observed != NULL) && (ws->triggered == NULL) && (ret == DDS_RETCODE_OK)) { while (ws->observed != NULL && ws->triggered == NULL)
if (abstimeout == DDS_NEVER) { if (!ddsrt_cond_waituntil (&ws->m_entity.m_cond, &ws->m_entity.m_mutex, abstimeout))
ddsrt_cond_wait(&ws->m_entity.m_cond, &ws->m_entity.m_mutex); break;
} 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 /* Get number of triggered entities
* - set attach array when needed * - set attach array when needed
* - swap them back to observed */ * - swap them back to observed */
if (ret == DDS_RETCODE_OK) {
ret = 0; ret = 0;
idx = ws->triggered; idx = ws->triggered;
while (idx != NULL) { while (idx != NULL)
if ((uint32_t)ret < (uint32_t)nxs) { {
if ((uint32_t) ret < (uint32_t) nxs)
xs[ret] = idx->arg; xs[ret] = idx->arg;
}
ret++; ret++;
next = idx->next;
/* The idx is always the first in triggered, so no prev. */ /* The idx is always the first in triggered, so no prev. */
dds_waitset_swap(&(ws->observed), &(ws->triggered), NULL, idx); dds_attachment *next = idx->next;
dds_waitset_swap (&ws->observed, &ws->triggered, NULL, idx);
idx = next; idx = next;
} }
} else if (ret == DDS_RETCODE_TIMEOUT) { dds_waitset_unlock (ws);
ret = 0;
} else {
DDS_ERROR("Internal error");
}
dds_waitset_unlock(ws);
} else {
DDS_ERROR("Error occurred on locking waitset\n");
}
return ret; return ret;
} }
static void static void dds_waitset_close_list (dds_attachment **list, dds_entity_t waitset)
dds_waitset_close_list(
dds_attachment **list,
dds_entity_t waitset)
{ {
dds_attachment *idx = *list; dds_attachment *idx = *list;
dds_attachment *next; dds_attachment *next;
while (idx != NULL) { while (idx != NULL)
{
next = idx->next; next = idx->next;
(void)dds_entity_observer_unregister(idx->entity->m_hdllink.hdl, waitset); (void) dds_entity_observer_unregister (idx->entity->m_hdllink.hdl, waitset);
ddsrt_free(idx); ddsrt_free (idx);
idx = next; idx = next;
} }
*list = NULL; *list = NULL;
} }
static bool static bool dds_waitset_remove_from_list (dds_attachment **list, dds_entity_t observed)
dds_waitset_remove_from_list(
dds_attachment **list,
dds_entity_t observed)
{ {
dds_attachment *idx = *list; dds_attachment *idx, *prev;
dds_attachment *prev = NULL; for (idx = *list, prev = NULL; idx != NULL; prev = idx, idx = idx->next)
if (idx->entity->m_hdllink.hdl == observed)
while (idx != NULL) { break;
if (idx->entity->m_hdllink.hdl == observed) { if (idx == NULL)
if (prev == NULL) {
*list = idx->next;
} else {
prev->next = idx->next;
}
ddsrt_free(idx);
/* We're done. */
return true;
}
prev = idx;
idx = idx->next;
}
return false; return false;
if (prev == NULL)
*list = idx->next;
else
prev->next = idx->next;
ddsrt_free (idx);
return true;
} }
dds_return_t dds_return_t dds_waitset_close (struct dds_entity *e)
dds_waitset_close(
struct dds_entity *e)
{ {
dds_waitset *ws = (dds_waitset*)e; dds_waitset *ws = (dds_waitset *) e;
dds_waitset_close_list (&ws->observed, e->m_hdllink.hdl);
dds_waitset_close_list(&ws->observed, e->m_hdllink.hdl); dds_waitset_close_list (&ws->triggered, e->m_hdllink.hdl);
dds_waitset_close_list(&ws->triggered, e->m_hdllink.hdl); ddsrt_cond_broadcast (&e->m_cond);
/* Trigger waitset to wake up. */
ddsrt_cond_broadcast(&e->m_cond);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
DDS_EXPORT dds_entity_t dds_entity_t dds_create_waitset (dds_entity_t participant)
dds_create_waitset(
dds_entity_t participant)
{ {
dds_entity_t hdl; dds_entity_t hdl;
dds_entity *par; dds_participant *par;
dds_return_t rc; dds_return_t rc;
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par); if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
if (rc == DDS_RETCODE_OK) { return rc;
dds_waitset *waitset = dds_alloc(sizeof(*waitset));
hdl = dds_entity_init(&waitset->m_entity, par, DDS_KIND_WAITSET, NULL, NULL, 0); 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->m_entity.m_deriver.close = dds_waitset_close;
waitset->observed = NULL; waitset->observed = NULL;
waitset->triggered = NULL; waitset->triggered = NULL;
dds_entity_unlock(par); dds_participant_unlock (par);
} else {
hdl = rc;
}
return hdl; return hdl;
} }
DDS_EXPORT dds_return_t dds_return_t dds_waitset_get_entities (dds_entity_t waitset, dds_entity_t *entities, size_t size)
dds_waitset_get_entities(
dds_entity_t waitset,
dds_entity_t *entities,
size_t size)
{ {
dds_return_t ret; dds_return_t ret;
dds_waitset *ws; dds_waitset *ws;
ret = dds_waitset_lock(waitset, &ws); if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
dds_attachment* iter;
ret = 0; ret = 0;
iter = ws->observed; for (dds_attachment *iter = ws->observed; iter != NULL; iter = iter->next)
while (iter) { {
if (((size_t)ret < size) && (entities != NULL)) { if ((size_t) ret < size && entities != NULL)
entities[ret] = iter->entity->m_hdllink.hdl; entities[ret] = iter->entity->m_hdllink.hdl;
}
ret++; ret++;
iter = iter->next;
} }
for (dds_attachment *iter = ws->triggered; iter != NULL; iter = iter->next)
iter = ws->triggered; {
while (iter) { if ((size_t) ret < size && entities != NULL)
if (((size_t)ret < size) && (entities != NULL)) {
entities[ret] = iter->entity->m_hdllink.hdl; entities[ret] = iter->entity->m_hdllink.hdl;
}
ret++; ret++;
iter = iter->next;
} }
dds_waitset_unlock(ws); dds_waitset_unlock(ws);
} else {
DDS_ERROR("Error occurred on locking waitset\n");
}
return ret; return ret;
} }
static void dds_waitset_move (dds_attachment **src, dds_attachment **dst, dds_entity_t entity)
static void
dds_waitset_move(
dds_attachment **src,
dds_attachment **dst,
dds_entity_t entity)
{ {
dds_attachment *idx = *src; dds_attachment *idx, *prev;
dds_attachment *prev = NULL; for (idx = *src, prev = NULL; idx != NULL; prev = idx, idx = idx->next)
while (idx != NULL) { if (idx->entity->m_hdllink.hdl == entity)
if (idx->entity->m_hdllink.hdl == entity) { break;
if (idx != NULL)
{
/* Swap idx from src to dst. */ /* Swap idx from src to dst. */
dds_waitset_swap(dst, src, prev, idx); dds_waitset_swap (dst, src, prev, idx);
/* We're done. */
return;
}
prev = idx;
idx = idx->next;
} }
} }
static void static void dds_waitset_remove (dds_waitset *ws, dds_entity_t observed)
dds_waitset_remove(
dds_waitset *ws,
dds_entity_t observed)
{ {
if (!dds_waitset_remove_from_list(&(ws->observed), observed)) { if (!dds_waitset_remove_from_list (&ws->observed, observed))
(void)dds_waitset_remove_from_list(&(ws->triggered), observed); (void) dds_waitset_remove_from_list (&ws->triggered, observed);
}
} }
/* This is called when the observed entity signals a status change. */ /* This is called when the observed entity signals a status change. */
void void dds_waitset_observer (dds_entity_t observer, dds_entity_t observed, uint32_t status)
dds_waitset_observer(
dds_entity_t observer,
dds_entity_t observed,
uint32_t status)
{ {
dds_waitset *ws; dds_waitset *ws;
if (dds_waitset_lock(observer, &ws) == DDS_RETCODE_OK) { if (dds_waitset_lock (observer, &ws) == DDS_RETCODE_OK) {
if (status & DDS_DELETING_STATUS) { if (status & DDS_DELETING_STATUS) {
/* Remove this observed entity, which is being deleted, from the waitset. */ /* Remove this observed entity, which is being deleted, from the waitset. */
dds_waitset_remove(ws, observed); dds_waitset_remove (ws, observed);
/* Our registration to this observed entity will be removed automatically. */ /* Our registration to this observed entity will be removed automatically. */
} else if (status != 0) { } else if (status != 0) {
/* Move observed entity to triggered list. */ /* Move observed entity to triggered list. */
dds_waitset_move(&(ws->observed), &(ws->triggered), observed); dds_waitset_move (&ws->observed, &ws->triggered, observed);
} else { } else {
/* Remove observed entity from triggered list (which it possibly resides in). */ /* Remove observed entity from triggered list (which it possibly resides in). */
dds_waitset_move(&(ws->triggered), &(ws->observed), observed); dds_waitset_move (&ws->triggered, &ws->observed, observed);
} }
/* Trigger waitset to wake up. */ /* Trigger waitset to wake up. */
ddsrt_cond_broadcast(&ws->m_entity.m_cond); ddsrt_cond_broadcast (&ws->m_entity.m_cond);
dds_waitset_unlock(ws); dds_waitset_unlock (ws);
} }
} }
DDS_EXPORT dds_return_t dds_return_t dds_waitset_attach (dds_entity_t waitset, dds_entity_t entity, dds_attach_t x)
dds_waitset_attach(
dds_entity_t waitset,
dds_entity_t entity,
dds_attach_t x)
{ {
dds_entity *e = NULL; dds_entity *e;
dds_waitset *ws; dds_waitset *ws;
dds_return_t ret; dds_return_t ret;
ret = dds_waitset_lock(waitset, &ws); if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
if (waitset != entity) {
ret = dds_entity_lock(entity, DDS_KIND_DONTCARE, &e); if (waitset == entity)
if (ret != DDS_RETCODE_OK) {
e = NULL;
}
} else {
e = &ws->m_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). */ /* This will fail if given entity is already attached (or deleted). */
if (ret == DDS_RETCODE_OK) { if ((ret = dds_entity_observer_register_nl (e, waitset, dds_waitset_observer)) != DDS_RETCODE_OK)
ret = dds_entity_observer_register_nl(e, waitset, dds_waitset_observer); goto err_entity;
}
if (ret == DDS_RETCODE_OK) { dds_attachment *a = ddsrt_malloc (sizeof (*a));
dds_attachment *a = ddsrt_malloc(sizeof(dds_attachment));
a->arg = x; a->arg = x;
a->entity = e; a->entity = e;
if (e->m_trigger > 0) { if (e->m_trigger > 0) {
@ -353,85 +258,52 @@ dds_waitset_attach(
a->next = ws->observed; a->next = ws->observed;
ws->observed = a; ws->observed = a;
} }
ret = DDS_RETCODE_OK;
} else if (ret != DDS_RETCODE_PRECONDITION_NOT_MET) {
DDS_ERROR("Entity is not valid\n");
ret = DDS_RETCODE_BAD_PARAMETER;
} else {
DDS_ERROR("Entity is already attached\n");
}
if ((e != NULL) && (waitset != entity)) {
dds_entity_unlock(e);
}
dds_waitset_unlock(ws);
} else {
DDS_ERROR("Error occurred on locking waitset\n");
}
err_entity:
if (e != &ws->m_entity)
dds_entity_unlock (e);
err_waitset:
dds_waitset_unlock (ws);
return ret; return ret;
} }
DDS_EXPORT dds_return_t dds_return_t dds_waitset_detach (dds_entity_t waitset, dds_entity_t entity)
dds_waitset_detach(
dds_entity_t waitset,
dds_entity_t entity)
{ {
dds_waitset *ws; dds_waitset *ws;
dds_return_t ret; dds_return_t ret;
ret = dds_waitset_lock(waitset, &ws); if ((ret = dds_waitset_lock (waitset, &ws)) != DDS_RETCODE_OK)
if (ret == DDS_RETCODE_OK) { return ret;
/* Possibly fails when entity was not attached. */ /* Possibly fails when entity was not attached. */
if (waitset == entity) { if (waitset == entity)
ret = dds_entity_observer_unregister_nl(&ws->m_entity, waitset); ret = dds_entity_observer_unregister_nl (&ws->m_entity, waitset);
} else { else
ret = dds_entity_observer_unregister(entity, waitset); ret = dds_entity_observer_unregister (entity, waitset);
}
if (ret == DDS_RETCODE_OK) {
dds_waitset_remove(ws, entity);
} else if (ret != DDS_RETCODE_PRECONDITION_NOT_MET) {
DDS_ERROR("The given entity to detach is invalid\n");
ret = DDS_RETCODE_BAD_PARAMETER;
} else {
DDS_ERROR("The given entity to detach was not attached previously\n");
}
dds_waitset_unlock(ws);
} else {
DDS_ERROR("Error occurred on locking waitset\n");
}
if (ret == DDS_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; return ret;
} }
dds_return_t dds_return_t dds_waitset_wait_until (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_time_t abstimeout)
dds_waitset_wait_until(
dds_entity_t waitset,
dds_attach_t *xs,
size_t nxs,
dds_time_t abstimeout)
{ {
return dds_waitset_wait_impl(waitset, xs, nxs, abstimeout, dds_time()); return dds_waitset_wait_impl(waitset, xs, nxs, abstimeout);
} }
dds_return_t dds_return_t dds_waitset_wait (dds_entity_t waitset, dds_attach_t *xs, size_t nxs, dds_duration_t reltimeout)
dds_waitset_wait(
dds_entity_t waitset,
dds_attach_t *xs,
size_t nxs,
dds_duration_t reltimeout)
{ {
dds_entity_t ret; if (reltimeout < 0)
return DDS_RETCODE_BAD_PARAMETER;
if (reltimeout >= 0) { const dds_time_t tnow = dds_time ();
dds_time_t tnow = dds_time(); const dds_time_t abstimeout = (DDS_INFINITY - reltimeout <= tnow) ? DDS_NEVER : (tnow + reltimeout);
dds_time_t abstimeout = (DDS_INFINITY - reltimeout <= tnow) ? DDS_NEVER : (tnow + reltimeout); return dds_waitset_wait_impl (waitset, xs, nxs, abstimeout);
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_set_trigger (dds_entity_t waitset, bool trigger) dds_return_t dds_waitset_set_trigger (dds_entity_t waitset, bool trigger)
@ -455,4 +327,3 @@ dds_return_t dds_waitset_set_trigger (dds_entity_t waitset, bool trigger)
dds_waitset_unlock (ws); dds_waitset_unlock (ws);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }

View file

@ -35,7 +35,7 @@ struct whc_node {
struct whc_node *next_seq; /* next in this interval */ struct whc_node *next_seq; /* next in this interval */
struct whc_node *prev_seq; /* prev in this interval */ struct whc_node *prev_seq; /* prev in this interval */
struct whc_idxnode *idxnode; /* NULL if not in index */ struct whc_idxnode *idxnode; /* NULL if not in index */
unsigned idxnode_pos; /* index in idxnode.hist */ uint32_t idxnode_pos; /* index in idxnode.hist */
seqno_t seq; seqno_t seq;
uint64_t total_bytes; /* cumulative number of bytes up to and including this node */ uint64_t total_bytes; /* cumulative number of bytes up to and including this node */
size_t size; size_t size;
@ -43,7 +43,7 @@ struct whc_node {
unsigned unacked: 1; /* counted in whc::unacked_bytes iff 1 */ unsigned unacked: 1; /* counted in whc::unacked_bytes iff 1 */
unsigned borrowed: 1; /* at most one can borrow it at any time */ unsigned borrowed: 1; /* at most one can borrow it at any time */
nn_mtime_t last_rexmit_ts; nn_mtime_t last_rexmit_ts;
unsigned rexmit_count; uint32_t rexmit_count;
struct ddsi_serdata *serdata; struct ddsi_serdata *serdata;
}; };
@ -59,7 +59,7 @@ struct whc_idxnode {
uint64_t iid; uint64_t iid;
seqno_t prune_seq; seqno_t prune_seq;
struct ddsi_tkmap_instance *tk; struct ddsi_tkmap_instance *tk;
unsigned headidx; uint32_t headidx;
#if __STDC_VERSION__ >= 199901L #if __STDC_VERSION__ >= 199901L
struct whc_node *hist[]; struct whc_node *hist[];
#else #else
@ -77,14 +77,14 @@ struct whc_seq_entry {
struct whc_impl { struct whc_impl {
struct whc common; struct whc common;
ddsrt_mutex_t lock; ddsrt_mutex_t lock;
unsigned seq_size; uint32_t seq_size;
size_t unacked_bytes; size_t unacked_bytes;
size_t sample_overhead; size_t sample_overhead;
uint64_t total_bytes; /* total number of bytes pushed in */ uint64_t total_bytes; /* total number of bytes pushed in */
unsigned is_transient_local: 1; unsigned is_transient_local: 1;
unsigned hdepth; /* 0 = unlimited */ uint32_t hdepth; /* 0 = unlimited */
unsigned tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */ uint32_t tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
unsigned idxdepth; /* = max(hdepth, tldepth) */ uint32_t idxdepth; /* = max (hdepth, tldepth) */
seqno_t max_drop_seq; /* samples in whc with seq <= max_drop_seq => transient-local */ seqno_t max_drop_seq; /* samples in whc with seq <= max_drop_seq => transient-local */
struct whc_intvnode *open_intv; /* interval where next sample will go (usually) */ struct whc_intvnode *open_intv; /* interval where next sample will go (usually) */
struct whc_node *maxseq_node; /* NULL if empty; if not in open_intv, open_intv is empty */ struct whc_node *maxseq_node; /* NULL if empty; if not in open_intv, open_intv is empty */
@ -103,14 +103,12 @@ struct whc_sample_iter_impl {
}; };
/* check that our definition of whc_sample_iter fits in the type that callers allocate */ /* check that our definition of whc_sample_iter fits in the type that callers allocate */
struct whc_sample_iter_sizecheck { DDSRT_STATIC_ASSERT (sizeof (struct whc_sample_iter_impl) <= sizeof (struct whc_sample_iter));
char fits_in_generic_type[sizeof(struct whc_sample_iter_impl) <= sizeof(struct whc_sample_iter) ? 1 : -1];
};
/* Hash + interval tree adminitration of samples-by-sequence number /* Hash + interval tree adminitration of samples-by-sequence number
* - by definition contains all samples in WHC (unchanged from older versions) * - by definition contains all samples in WHC (unchanged from older versions)
* Circular array of samples per instance, inited to all 0 * Circular array of samples per instance, inited to all 0
* - length is max(durability_service.history_depth, history.depth), KEEP_ALL => as-if 0 * - length is max (durability_service.history_depth, history.depth), KEEP_ALL => as-if 0
* - no instance index if above length 0 * - no instance index if above length 0
* - each sample (i.e., whc_node): backpointer into index * - each sample (i.e., whc_node): backpointer into index
* - maintain index of latest sample, end of history then trivially follows from index arithmetic * - maintain index of latest sample, end of history then trivially follows from index arithmetic
@ -124,24 +122,24 @@ static void insert_whcn_in_hash (struct whc_impl *whc, struct whc_node *whcn);
static void whc_delete_one (struct whc_impl *whc, struct whc_node *whcn); static void whc_delete_one (struct whc_impl *whc, struct whc_node *whcn);
static int compare_seq (const void *va, const void *vb); static int compare_seq (const void *va, const void *vb);
static void free_deferred_free_list (struct whc_node *deferred_free_list); static void free_deferred_free_list (struct whc_node *deferred_free_list);
static void get_state_locked(const struct whc_impl *whc, struct whc_state *st); static void get_state_locked (const struct whc_impl *whc, struct whc_state *st);
static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list); static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list);
static unsigned whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); static uint32_t whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);
static void whc_default_get_state(const struct whc *whc, struct whc_state *st); static void whc_default_get_state (const struct whc *whc, struct whc_state *st);
static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq); static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq);
static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample);
static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample);
static void whc_default_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info); static void whc_default_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info);
static unsigned whc_default_downgrade_to_volatile (struct whc *whc, struct whc_state *st); static uint32_t whc_default_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
static void whc_default_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it); static void whc_default_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it);
static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample); static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample);
static void whc_default_free (struct whc *whc); static void whc_default_free (struct whc *whc);
static const ddsrt_avl_treedef_t whc_seq_treedef = static const ddsrt_avl_treedef_t whc_seq_treedef =
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct whc_intvnode, avlnode), offsetof (struct whc_intvnode, min), compare_seq, 0); DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct whc_intvnode, avlnode), offsetof (struct whc_intvnode, min), compare_seq, 0);
static const struct whc_ops whc_ops = { static const struct whc_ops whc_ops = {
.insert = whc_default_insert, .insert = whc_default_insert,
@ -175,9 +173,9 @@ static uint32_t whc_seq_entry_hash (const void *vn)
const struct whc_seq_entry *n = vn; const struct whc_seq_entry *n = vn;
/* we hash the lower 32 bits, on the assumption that with 4 billion /* we hash the lower 32 bits, on the assumption that with 4 billion
samples in between there won't be significant correlation */ samples in between there won't be significant correlation */
const uint64_t c = UINT64_C(16292676669999574021); const uint64_t c = UINT64_C (16292676669999574021);
const uint32_t x = (uint32_t) n->seq; const uint32_t x = (uint32_t) n->seq;
return (unsigned) ((x * c) >> 32); return (uint32_t) ((x * c) >> 32);
} }
static int whc_seq_entry_eq (const void *va, const void *vb) static int whc_seq_entry_eq (const void *va, const void *vb)
@ -192,9 +190,9 @@ static uint32_t whc_node_hash (const void *vn)
const struct whc_node *n = vn; const struct whc_node *n = vn;
/* we hash the lower 32 bits, on the assumption that with 4 billion /* we hash the lower 32 bits, on the assumption that with 4 billion
samples in between there won't be significant correlation */ samples in between there won't be significant correlation */
const uint64_t c = UINT64_C(16292676669999574021); const uint64_t c = UINT64_C (16292676669999574021);
const uint32_t x = (uint32_t) n->seq; const uint32_t x = (uint32_t) n->seq;
return (unsigned) ((x * c) >> 32); return (uint32_t) ((x * c) >> 32);
} }
static int whc_node_eq (const void *va, const void *vb) static int whc_node_eq (const void *va, const void *vb)
@ -269,7 +267,7 @@ static void check_whc (const struct whc_impl *whc)
} }
assert (whc->maxseq_node == whc_findmax_procedurally (whc)); assert (whc->maxseq_node == whc_findmax_procedurally (whc));
#if !defined(NDEBUG) #if !defined (NDEBUG)
if (config.enabled_xchecks & DDS_XCHECK_WHC) if (config.enabled_xchecks & DDS_XCHECK_WHC)
{ {
struct whc_intvnode *firstintv; struct whc_intvnode *firstintv;
@ -295,10 +293,10 @@ static void insert_whcn_in_hash (struct whc_impl *whc, struct whc_node *whcn)
#if USE_EHH #if USE_EHH
struct whc_seq_entry e = { .seq = whcn->seq, .whcn = whcn }; struct whc_seq_entry e = { .seq = whcn->seq, .whcn = whcn };
if (!ddsrt_ehh_add (whc->seq_hash, &e)) if (!ddsrt_ehh_add (whc->seq_hash, &e))
assert(0); assert (0);
#else #else
if (!ddsrt_hh_add (whc->seq_hash, whcn)) if (!ddsrt_hh_add (whc->seq_hash, whcn))
assert(0); assert (0);
#endif #endif
} }
@ -307,11 +305,11 @@ static void remove_whcn_from_hash (struct whc_impl *whc, struct whc_node *whcn)
/* precondition: whcn is in hash */ /* precondition: whcn is in hash */
#if USE_EHH #if USE_EHH
struct whc_seq_entry e = { .seq = whcn->seq }; struct whc_seq_entry e = { .seq = whcn->seq };
if (!ddsrt_ehh_remove(whc->seq_hash, &e)) if (!ddsrt_ehh_remove (whc->seq_hash, &e))
assert(0); assert (0);
#else #else
if (!ddsrt_hh_remove(whc->seq_hash, whcn)) if (!ddsrt_hh_remove (whc->seq_hash, whcn))
assert(0); assert (0);
#endif #endif
} }
@ -319,14 +317,14 @@ static struct whc_node *whc_findseq (const struct whc_impl *whc, seqno_t seq)
{ {
#if USE_EHH #if USE_EHH
struct whc_seq_entry e = { .seq = seq }, *r; struct whc_seq_entry e = { .seq = seq }, *r;
if ((r = ddsrt_ehh_lookup(whc->seq_hash, &e)) != NULL) if ((r = ddsrt_ehh_lookup (whc->seq_hash, &e)) != NULL)
return r->whcn; return r->whcn;
else else
return NULL; return NULL;
#else #else
struct whc_node template; struct whc_node template;
template.seq = seq; template.seq = seq;
return ddsrt_hh_lookup(whc->seq_hash, &template); return ddsrt_hh_lookup (whc->seq_hash, &template);
#endif #endif
} }
@ -334,11 +332,11 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
{ {
union { union {
struct whc_idxnode idxn; struct whc_idxnode idxn;
char pad[sizeof(struct whc_idxnode) + sizeof(struct whc_node *)]; char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
} template; } template;
struct whc_idxnode *n; struct whc_idxnode *n;
check_whc (whc); check_whc (whc);
template.idxn.iid = ddsi_tkmap_lookup(gv.m_tkmap, serdata_key); template.idxn.iid = ddsi_tkmap_lookup (gv.m_tkmap, serdata_key);
n = ddsrt_hh_lookup (whc->idx_hash, &template.idxn); n = ddsrt_hh_lookup (whc->idx_hash, &template.idxn);
if (n == NULL) if (n == NULL)
return NULL; return NULL;
@ -349,13 +347,13 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
} }
} }
struct whc *whc_new (int is_transient_local, unsigned hdepth, unsigned tldepth) struct whc *whc_new (int is_transient_local, uint32_t hdepth, uint32_t tldepth)
{ {
size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */ size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */
struct whc_impl *whc; struct whc_impl *whc;
struct whc_intvnode *intv; struct whc_intvnode *intv;
assert((hdepth == 0 || tldepth <= hdepth) || is_transient_local); assert ((hdepth == 0 || tldepth <= hdepth) || is_transient_local);
whc = ddsrt_malloc (sizeof (*whc)); whc = ddsrt_malloc (sizeof (*whc));
whc->common.ops = &whc_ops; whc->common.ops = &whc_ops;
@ -372,11 +370,11 @@ struct whc *whc_new (int is_transient_local, unsigned hdepth, unsigned tldepth)
#if USE_EHH #if USE_EHH
whc->seq_hash = ddsrt_ehh_new (sizeof (struct whc_seq_entry), 32, whc_seq_entry_hash, whc_seq_entry_eq); whc->seq_hash = ddsrt_ehh_new (sizeof (struct whc_seq_entry), 32, whc_seq_entry_hash, whc_seq_entry_eq);
#else #else
whc->seq_hash = ddsrt_hh_new(32, whc_node_hash, whc_node_eq); whc->seq_hash = ddsrt_hh_new (32, whc_node_hash, whc_node_eq);
#endif #endif
if (whc->idxdepth > 0) if (whc->idxdepth > 0)
whc->idx_hash = ddsrt_hh_new(32, whc_idxnode_hash_key, whc_idxnode_eq_key); whc->idx_hash = ddsrt_hh_new (32, whc_idxnode_hash_key, whc_idxnode_eq_key);
else else
whc->idx_hash = NULL; whc->idx_hash = NULL;
@ -417,9 +415,9 @@ void whc_default_free (struct whc *whc_generic)
{ {
struct ddsrt_hh_iter it; struct ddsrt_hh_iter it;
struct whc_idxnode *n; struct whc_idxnode *n;
for (n = ddsrt_hh_iter_first(whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next(&it)) for (n = ddsrt_hh_iter_first (whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next (&it))
ddsrt_free(n); ddsrt_free (n);
ddsrt_hh_free(whc->idx_hash); ddsrt_hh_free (whc->idx_hash);
} }
{ {
@ -427,10 +425,10 @@ void whc_default_free (struct whc *whc_generic)
while (whcn) while (whcn)
{ {
struct whc_node *tmp = whcn; struct whc_node *tmp = whcn;
/* The compiler doesn't realize that whcn->prev_seq is always initialized. */ /* The compiler doesn't realize that whcn->prev_seq is always initialized. */
DDSRT_WARNING_MSVC_OFF(6001); DDSRT_WARNING_MSVC_OFF (6001);
whcn = whcn->prev_seq; whcn = whcn->prev_seq;
DDSRT_WARNING_MSVC_ON(6001); DDSRT_WARNING_MSVC_ON (6001);
free_whc_node_contents (tmp); free_whc_node_contents (tmp);
ddsrt_free (tmp); ddsrt_free (tmp);
} }
@ -452,7 +450,7 @@ DDSRT_WARNING_MSVC_ON(6001);
ddsrt_free (whc); ddsrt_free (whc);
} }
static void get_state_locked(const struct whc_impl *whc, struct whc_state *st) static void get_state_locked (const struct whc_impl *whc, struct whc_state *st)
{ {
if (whc->seq_size == 0) if (whc->seq_size == 0)
{ {
@ -473,12 +471,12 @@ static void get_state_locked(const struct whc_impl *whc, struct whc_state *st)
} }
} }
static void whc_default_get_state(const struct whc *whc_generic, struct whc_state *st) static void whc_default_get_state (const struct whc *whc_generic, struct whc_state *st)
{ {
const struct whc_impl * const whc = (const struct whc_impl *)whc_generic; const struct whc_impl * const whc = (const struct whc_impl *)whc_generic;
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock); ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
check_whc (whc); check_whc (whc);
get_state_locked(whc, st); get_state_locked (whc, st);
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock); ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
} }
@ -551,13 +549,12 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w
else else
{ {
#ifndef NDEBUG #ifndef NDEBUG
unsigned i; for (uint32_t i = 0; i < whc->idxdepth; i++)
for (i = 0; i < whc->idxdepth; i++)
assert (i == idxn->headidx || idxn->hist[i] == NULL); assert (i == idxn->headidx || idxn->hist[i] == NULL);
#endif #endif
if (!ddsrt_hh_remove (whc->idx_hash, idxn)) if (!ddsrt_hh_remove (whc->idx_hash, idxn))
assert (0); assert (0);
ddsi_tkmap_instance_unref(idxn->tk); ddsi_tkmap_instance_unref (idxn->tk);
ddsrt_free (idxn); ddsrt_free (idxn);
} }
whcn->idxnode = NULL; whcn->idxnode = NULL;
@ -565,8 +562,7 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w
static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn) static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn)
{ {
unsigned i; for (uint32_t i = 0; i < whc->idxdepth; i++)
for (i = 0; i < whc->idxdepth; i++)
{ {
if (idxn->hist[i]) if (idxn->hist[i])
{ {
@ -574,13 +570,13 @@ static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_s
oldn->idxnode = NULL; oldn->idxnode = NULL;
if (oldn->seq <= max_drop_seq) if (oldn->seq <= max_drop_seq)
{ {
DDS_LOG(DDS_LC_WHC, " prune tl whcn %p\n", (void *)oldn); DDS_LOG (DDS_LC_WHC, " prune tl whcn %p\n", (void *)oldn);
assert(oldn != whc->maxseq_node); assert (oldn != whc->maxseq_node);
whc_delete_one (whc, oldn); whc_delete_one (whc, oldn);
} }
} }
} }
ddsrt_free(idxn); ddsrt_free (idxn);
} }
static void delete_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn) static void delete_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn)
@ -590,24 +586,24 @@ static void delete_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop
free_one_instance_from_idx (whc, max_drop_seq, idxn); free_one_instance_from_idx (whc, max_drop_seq, idxn);
} }
static int whcn_in_tlidx (const struct whc_impl *whc, const struct whc_idxnode *idxn, unsigned pos) static int whcn_in_tlidx (const struct whc_impl *whc, const struct whc_idxnode *idxn, uint32_t pos)
{ {
if (idxn == NULL) if (idxn == NULL)
return 0; return 0;
else else
{ {
unsigned d = (idxn->headidx + (pos > idxn->headidx ? whc->idxdepth : 0)) - pos; uint32_t d = (idxn->headidx + (pos > idxn->headidx ? whc->idxdepth : 0)) - pos;
assert (d < whc->idxdepth); assert (d < whc->idxdepth);
return d < whc->tldepth; return d < whc->tldepth;
} }
} }
static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st) static uint32_t whc_default_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st)
{ {
struct whc_impl * const whc = (struct whc_impl *)whc_generic; struct whc_impl * const whc = (struct whc_impl *)whc_generic;
seqno_t old_max_drop_seq; seqno_t old_max_drop_seq;
struct whc_node *deferred_free_list; struct whc_node *deferred_free_list;
unsigned cnt; uint32_t cnt;
/* We only remove them from whc->tlidx: we don't remove them from /* We only remove them from whc->tlidx: we don't remove them from
whc->seq yet. That'll happen eventually. */ whc->seq yet. That'll happen eventually. */
@ -617,7 +613,7 @@ static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, stru
if (whc->idxdepth == 0) if (whc->idxdepth == 0)
{ {
/* if not maintaining an index at all, this is nonsense */ /* if not maintaining an index at all, this is nonsense */
get_state_locked(whc, st); get_state_locked (whc, st);
ddsrt_mutex_unlock (&whc->lock); ddsrt_mutex_unlock (&whc->lock);
return 0; return 0;
} }
@ -625,15 +621,15 @@ static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, stru
assert (!whc->is_transient_local); assert (!whc->is_transient_local);
if (whc->tldepth > 0) if (whc->tldepth > 0)
{ {
assert(whc->hdepth == 0 || whc->tldepth <= whc->hdepth); assert (whc->hdepth == 0 || whc->tldepth <= whc->hdepth);
whc->tldepth = 0; whc->tldepth = 0;
if (whc->hdepth == 0) if (whc->hdepth == 0)
{ {
struct ddsrt_hh_iter it; struct ddsrt_hh_iter it;
struct whc_idxnode *n; struct whc_idxnode *n;
for (n = ddsrt_hh_iter_first(whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next(&it)) for (n = ddsrt_hh_iter_first (whc->idx_hash, &it); n != NULL; n = ddsrt_hh_iter_next (&it))
free_one_instance_from_idx (whc, 0, n); free_one_instance_from_idx (whc, 0, n);
ddsrt_hh_free(whc->idx_hash); ddsrt_hh_free (whc->idx_hash);
whc->idxdepth = 0; whc->idxdepth = 0;
whc->idx_hash = NULL; whc->idx_hash = NULL;
} }
@ -647,7 +643,7 @@ static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, stru
cnt = whc_default_remove_acked_messages_full (whc, old_max_drop_seq, &deferred_free_list); cnt = whc_default_remove_acked_messages_full (whc, old_max_drop_seq, &deferred_free_list);
whc_default_free_deferred_free_list (whc_generic, deferred_free_list); whc_default_free_deferred_free_list (whc_generic, deferred_free_list);
assert (whc->max_drop_seq == old_max_drop_seq); assert (whc->max_drop_seq == old_max_drop_seq);
get_state_locked(whc, st); get_state_locked (whc, st);
ddsrt_mutex_unlock (&whc->lock); ddsrt_mutex_unlock (&whc->lock);
return cnt; return cnt;
} }
@ -801,11 +797,11 @@ static void whc_default_free_deferred_free_list (struct whc *whc_generic, struct
free_deferred_free_list (deferred_free_list); free_deferred_free_list (deferred_free_list);
} }
static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list) static uint32_t whc_default_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
{ {
struct whc_intvnode *intv; struct whc_intvnode *intv;
struct whc_node *whcn; struct whc_node *whcn;
unsigned ndropped = 0; uint32_t ndropped = 0;
/* In the trivial case of an empty WHC, get out quickly */ /* In the trivial case of an empty WHC, get out quickly */
if (max_drop_seq <= whc->max_drop_seq || whc->maxseq_node == NULL) if (max_drop_seq <= whc->max_drop_seq || whc->maxseq_node == NULL)
@ -833,7 +829,7 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
{ {
/* at startup, whc->max_drop_seq = 0 and reader states have max ack'd seq taken from wr->seq; /* at startup, whc->max_drop_seq = 0 and reader states have max ack'd seq taken from wr->seq;
so if multiple readers are matched and the writer runs ahead of the readers, for the first so if multiple readers are matched and the writer runs ahead of the readers, for the first
ack, whc->max_drop_seq < max_drop_seq = MIN(readers max ack) < intv->min */ ack, whc->max_drop_seq < max_drop_seq = MIN (readers max ack) < intv->min */
if (max_drop_seq > whc->max_drop_seq) if (max_drop_seq > whc->max_drop_seq)
whc->max_drop_seq = max_drop_seq; whc->max_drop_seq = max_drop_seq;
*deferred_free_list = NULL; *deferred_free_list = NULL;
@ -847,7 +843,7 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
} }
*deferred_free_list = intv->first; *deferred_free_list = intv->first;
ndropped = (unsigned) (whcn->seq - intv->min + 1); ndropped = (uint32_t) (whcn->seq - intv->min + 1);
intv->first = whcn->next_seq; intv->first = whcn->next_seq;
intv->min = max_drop_seq + 1; intv->min = max_drop_seq + 1;
@ -877,18 +873,18 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
return ndropped; return ndropped;
} }
static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list) static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
{ {
struct whc_intvnode *intv; struct whc_intvnode *intv;
struct whc_node *whcn; struct whc_node *whcn;
struct whc_node *prev_seq; struct whc_node *prev_seq;
struct whc_node deferred_list_head, *last_to_free = &deferred_list_head; struct whc_node deferred_list_head, *last_to_free = &deferred_list_head;
unsigned ndropped = 0; uint32_t ndropped = 0;
if (whc->is_transient_local && whc->tldepth == 0) if (whc->is_transient_local && whc->tldepth == 0)
{ {
/* KEEP_ALL on transient local, so we can never ever delete anything */ /* KEEP_ALL on transient local, so we can never ever delete anything */
DDS_LOG(DDS_LC_WHC, " KEEP_ALL transient-local: do nothing\n"); DDS_LOG (DDS_LC_WHC, " KEEP_ALL transient-local: do nothing\n");
*deferred_free_list = NULL; *deferred_free_list = NULL;
return 0; return 0;
} }
@ -898,11 +894,11 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
prev_seq = whcn ? whcn->prev_seq : NULL; prev_seq = whcn ? whcn->prev_seq : NULL;
while (whcn && whcn->seq <= max_drop_seq) while (whcn && whcn->seq <= max_drop_seq)
{ {
DDS_LOG(DDS_LC_WHC, " whcn %p %"PRId64, (void *) whcn, whcn->seq); DDS_LOG (DDS_LC_WHC, " whcn %p %"PRId64, (void *) whcn, whcn->seq);
if (whcn_in_tlidx(whc, whcn->idxnode, whcn->idxnode_pos)) if (whcn_in_tlidx (whc, whcn->idxnode, whcn->idxnode_pos))
{ {
/* quickly skip over samples in tlidx */ /* quickly skip over samples in tlidx */
DDS_LOG(DDS_LC_WHC, " tl:keep"); DDS_LOG (DDS_LC_WHC, " tl:keep");
if (whcn->unacked) if (whcn->unacked)
{ {
assert (whc->unacked_bytes >= whcn->size); assert (whc->unacked_bytes >= whcn->size);
@ -920,13 +916,13 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
} }
else else
{ {
DDS_LOG(DDS_LC_WHC, " delete"); DDS_LOG (DDS_LC_WHC, " delete");
last_to_free->next_seq = whcn; last_to_free->next_seq = whcn;
last_to_free = last_to_free->next_seq; last_to_free = last_to_free->next_seq;
whc_delete_one_intv (whc, &intv, &whcn); whc_delete_one_intv (whc, &intv, &whcn);
ndropped++; ndropped++;
} }
DDS_LOG(DDS_LC_WHC, "\n"); DDS_LOG (DDS_LC_WHC, "\n");
} }
if (prev_seq) if (prev_seq)
prev_seq->next_seq = whcn; prev_seq->next_seq = whcn;
@ -942,8 +938,8 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
Thus, we had better prune them. */ Thus, we had better prune them. */
if (whc->tldepth > 0 && whc->idxdepth > whc->tldepth) if (whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
{ {
assert(whc->hdepth == whc->idxdepth); assert (whc->hdepth == whc->idxdepth);
DDS_LOG(DDS_LC_WHC, " idxdepth %u > tldepth %u > 0 -- must prune\n", whc->idxdepth, whc->tldepth); DDS_LOG (DDS_LC_WHC, " idxdepth %"PRIu32" > tldepth %"PRIu32" > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
/* Do a second pass over the sequence number range we just processed: this time we only /* Do a second pass over the sequence number range we just processed: this time we only
encounter samples that were retained because of the transient-local durability setting encounter samples that were retained because of the transient-local durability setting
@ -952,16 +948,16 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
while (whcn && whcn->seq <= max_drop_seq) while (whcn && whcn->seq <= max_drop_seq)
{ {
struct whc_idxnode * const idxn = whcn->idxnode; struct whc_idxnode * const idxn = whcn->idxnode;
unsigned cnt, idx; uint32_t cnt, idx;
DDS_LOG(DDS_LC_WHC, " whcn %p %"PRId64" idxn %p prune_seq %"PRId64":", (void *)whcn, whcn->seq, (void *)idxn, idxn->prune_seq); DDS_LOG (DDS_LC_WHC, " whcn %p %"PRId64" idxn %p prune_seq %"PRId64":", (void *) whcn, whcn->seq, (void *) idxn, idxn->prune_seq);
assert(whcn_in_tlidx(whc, idxn, whcn->idxnode_pos)); assert (whcn_in_tlidx (whc, idxn, whcn->idxnode_pos));
assert (idxn->prune_seq <= max_drop_seq); assert (idxn->prune_seq <= max_drop_seq);
if (idxn->prune_seq == max_drop_seq) if (idxn->prune_seq == max_drop_seq)
{ {
DDS_LOG(DDS_LC_WHC, " already pruned\n"); DDS_LOG (DDS_LC_WHC, " already pruned\n");
whcn = whcn->next_seq; whcn = whcn->next_seq;
continue; continue;
} }
@ -982,22 +978,22 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
struct whc_node whcn_template; struct whc_node whcn_template;
union { union {
struct whc_idxnode idxn; struct whc_idxnode idxn;
char pad[sizeof(struct whc_idxnode) + sizeof(struct whc_node *)]; char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
} template; } template;
template.idxn.headidx = 0; template.idxn.headidx = 0;
template.idxn.hist[0] = &whcn_template; template.idxn.hist[0] = &whcn_template;
whcn_template.serdata = ddsi_serdata_ref(oldn->serdata); whcn_template.serdata = ddsi_serdata_ref (oldn->serdata);
assert(oldn->seq < whcn->seq); assert (oldn->seq < whcn->seq);
#endif #endif
DDS_LOG(DDS_LC_WHC, " del %p %"PRId64, (void *) oldn, oldn->seq); DDS_LOG (DDS_LC_WHC, " del %p %"PRId64, (void *) oldn, oldn->seq);
whc_delete_one (whc, oldn); whc_delete_one (whc, oldn);
#ifndef NDEBUG #ifndef NDEBUG
assert(ddsrt_hh_lookup(whc->idx_hash, &template) == idxn); assert (ddsrt_hh_lookup (whc->idx_hash, &template) == idxn);
ddsi_serdata_unref(whcn_template.serdata); ddsi_serdata_unref (whcn_template.serdata);
#endif #endif
} }
} }
DDS_LOG(DDS_LC_WHC, "\n"); DDS_LOG (DDS_LC_WHC, "\n");
whcn = whcn->next_seq; whcn = whcn->next_seq;
} }
} }
@ -1011,21 +1007,21 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
return ndropped; return ndropped;
} }
static unsigned whc_default_remove_acked_messages (struct whc *whc_generic, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list) static uint32_t whc_default_remove_acked_messages (struct whc *whc_generic, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list)
{ {
struct whc_impl * const whc = (struct whc_impl *)whc_generic; struct whc_impl * const whc = (struct whc_impl *)whc_generic;
unsigned cnt; uint32_t cnt;
ddsrt_mutex_lock (&whc->lock); ddsrt_mutex_lock (&whc->lock);
assert (max_drop_seq < MAX_SEQ_NUMBER); assert (max_drop_seq < MAX_SEQ_NUMBER);
assert (max_drop_seq >= whc->max_drop_seq); assert (max_drop_seq >= whc->max_drop_seq);
if (dds_get_log_mask() & DDS_LC_WHC) if (dds_get_log_mask () & DDS_LC_WHC)
{ {
struct whc_state tmp; struct whc_state tmp;
get_state_locked(whc, &tmp); get_state_locked (whc, &tmp);
DDS_LOG(DDS_LC_WHC, "whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq); DDS_LOG (DDS_LC_WHC, "whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq);
DDS_LOG(DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n", DDS_LOG (DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth); tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
} }
@ -1035,7 +1031,7 @@ static unsigned whc_default_remove_acked_messages (struct whc *whc_generic, seqn
cnt = whc_default_remove_acked_messages_noidx (whc, max_drop_seq, deferred_free_list); cnt = whc_default_remove_acked_messages_noidx (whc, max_drop_seq, deferred_free_list);
else else
cnt = whc_default_remove_acked_messages_full (whc, max_drop_seq, deferred_free_list); cnt = whc_default_remove_acked_messages_full (whc, max_drop_seq, deferred_free_list);
get_state_locked(whc, whcst); get_state_locked (whc, whcst);
ddsrt_mutex_unlock (&whc->lock); ddsrt_mutex_unlock (&whc->lock);
return cnt; return cnt;
} }
@ -1108,18 +1104,19 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
struct whc_idxnode *idxn; struct whc_idxnode *idxn;
union { union {
struct whc_idxnode idxn; struct whc_idxnode idxn;
char pad[sizeof(struct whc_idxnode) + sizeof(struct whc_node *)]; char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
} template; } template;
ddsrt_mutex_lock (&whc->lock); ddsrt_mutex_lock (&whc->lock);
check_whc (whc); check_whc (whc);
if (dds_get_log_mask() & DDS_LC_WHC) if (dds_get_log_mask () & DDS_LC_WHC)
{ {
struct whc_state whcst; struct whc_state whcst;
get_state_locked(whc, &whcst); get_state_locked (whc, &whcst);
DDS_LOG(DDS_LC_WHC, "whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash); DDS_LOG (DDS_LC_WHC, "whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n",
DDS_LOG(DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash);
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); whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
} }
@ -1134,12 +1131,12 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
/* Always insert in seq admin */ /* Always insert in seq admin */
newn = whc_default_insert_seq (whc, max_drop_seq, seq, plist, serdata); newn = whc_default_insert_seq (whc, max_drop_seq, seq, plist, serdata);
DDS_LOG(DDS_LC_WHC, " whcn %p:", (void*)newn); DDS_LOG (DDS_LC_WHC, " whcn %p:", (void*)newn);
/* Special case of empty data (such as commit messages) can't go into index, and if we're not maintaining an index, we're done, too */ /* Special case of empty data (such as commit messages) can't go into index, and if we're not maintaining an index, we're done, too */
if (serdata->kind == SDK_EMPTY || whc->idxdepth == 0) if (serdata->kind == SDK_EMPTY || whc->idxdepth == 0)
{ {
DDS_LOG(DDS_LC_WHC, " empty or no hist\n"); DDS_LOG (DDS_LC_WHC, " empty or no hist\n");
ddsrt_mutex_unlock (&whc->lock); ddsrt_mutex_unlock (&whc->lock);
return 0; return 0;
} }
@ -1148,15 +1145,15 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
if ((idxn = ddsrt_hh_lookup (whc->idx_hash, &template)) != NULL) if ((idxn = ddsrt_hh_lookup (whc->idx_hash, &template)) != NULL)
{ {
/* Unregisters cause deleting of index entry, non-unregister of adding/overwriting in history */ /* Unregisters cause deleting of index entry, non-unregister of adding/overwriting in history */
DDS_LOG(DDS_LC_WHC, " idxn %p", (void *)idxn); DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
if (serdata->statusinfo & NN_STATUSINFO_UNREGISTER) if (serdata->statusinfo & NN_STATUSINFO_UNREGISTER)
{ {
DDS_LOG(DDS_LC_WHC, " unreg:delete\n"); DDS_LOG (DDS_LC_WHC, " unreg:delete\n");
delete_one_instance_from_idx (whc, max_drop_seq, idxn); delete_one_instance_from_idx (whc, max_drop_seq, idxn);
if (newn->seq <= max_drop_seq) if (newn->seq <= max_drop_seq)
{ {
struct whc_node *prev_seq = newn->prev_seq; struct whc_node *prev_seq = newn->prev_seq;
DDS_LOG(DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n"); DDS_LOG (DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
whc_delete_one (whc, newn); whc_delete_one (whc, newn);
whc->maxseq_node = prev_seq; whc->maxseq_node = prev_seq;
} }
@ -1168,7 +1165,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
idxn->headidx = 0; idxn->headidx = 0;
if ((oldn = idxn->hist[idxn->headidx]) != NULL) if ((oldn = idxn->hist[idxn->headidx]) != NULL)
{ {
DDS_LOG(DDS_LC_WHC, " overwrite whcn %p", (void *)oldn); DDS_LOG (DDS_LC_WHC, " overwrite whcn %p", (void *)oldn);
oldn->idxnode = NULL; oldn->idxnode = NULL;
} }
idxn->hist[idxn->headidx] = newn; idxn->hist[idxn->headidx] = newn;
@ -1177,8 +1174,8 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
if (oldn && (whc->hdepth > 0 || oldn->seq <= max_drop_seq)) if (oldn && (whc->hdepth > 0 || oldn->seq <= max_drop_seq))
{ {
DDS_LOG(DDS_LC_WHC, " prune whcn %p", (void *)oldn); DDS_LOG (DDS_LC_WHC, " prune whcn %p", (void *)oldn);
assert(oldn != whc->maxseq_node); assert (oldn != whc->maxseq_node);
whc_delete_one (whc, oldn); whc_delete_one (whc, oldn);
} }
@ -1188,35 +1185,34 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
whc_default_remove_acked_messages, but that never happens when there are no readers). */ whc_default_remove_acked_messages, but that never happens when there are no readers). */
if (seq <= max_drop_seq && whc->tldepth > 0 && whc->idxdepth > whc->tldepth) if (seq <= max_drop_seq && whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
{ {
unsigned pos = idxn->headidx + whc->idxdepth - whc->tldepth; uint32_t pos = idxn->headidx + whc->idxdepth - whc->tldepth;
if (pos >= whc->idxdepth) if (pos >= whc->idxdepth)
pos -= whc->idxdepth; pos -= whc->idxdepth;
if ((oldn = idxn->hist[pos]) != NULL) if ((oldn = idxn->hist[pos]) != NULL)
{ {
DDS_LOG(DDS_LC_WHC, " prune tl whcn %p", (void *)oldn); DDS_LOG (DDS_LC_WHC, " prune tl whcn %p", (void *)oldn);
assert(oldn != whc->maxseq_node); assert (oldn != whc->maxseq_node);
whc_delete_one (whc, oldn); whc_delete_one (whc, oldn);
} }
} }
DDS_LOG(DDS_LC_WHC, "\n"); DDS_LOG (DDS_LC_WHC, "\n");
} }
} }
else else
{ {
DDS_LOG(DDS_LC_WHC, " newkey"); DDS_LOG (DDS_LC_WHC, " newkey");
/* Ignore unregisters, but insert everything else */ /* Ignore unregisters, but insert everything else */
if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER)) if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER))
{ {
unsigned i;
idxn = ddsrt_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0])); idxn = ddsrt_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0]));
DDS_LOG(DDS_LC_WHC, " idxn %p", (void *)idxn); DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
ddsi_tkmap_instance_ref(tk); ddsi_tkmap_instance_ref (tk);
idxn->iid = tk->m_iid; idxn->iid = tk->m_iid;
idxn->tk = tk; idxn->tk = tk;
idxn->prune_seq = 0; idxn->prune_seq = 0;
idxn->headidx = 0; idxn->headidx = 0;
idxn->hist[0] = newn; idxn->hist[0] = newn;
for (i = 1; i < whc->idxdepth; i++) for (uint32_t i = 1; i < whc->idxdepth; i++)
idxn->hist[i] = NULL; idxn->hist[i] = NULL;
newn->idxnode = idxn; newn->idxnode = idxn;
newn->idxnode_pos = 0; newn->idxnode_pos = 0;
@ -1225,24 +1221,24 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
} }
else else
{ {
DDS_LOG(DDS_LC_WHC, " unreg:skip"); DDS_LOG (DDS_LC_WHC, " unreg:skip");
if (newn->seq <= max_drop_seq) if (newn->seq <= max_drop_seq)
{ {
struct whc_node *prev_seq = newn->prev_seq; struct whc_node *prev_seq = newn->prev_seq;
DDS_LOG(DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n"); DDS_LOG (DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
whc_delete_one (whc, newn); whc_delete_one (whc, newn);
whc->maxseq_node = prev_seq; whc->maxseq_node = prev_seq;
} }
} }
DDS_LOG(DDS_LC_WHC, "\n"); DDS_LOG (DDS_LC_WHC, "\n");
} }
ddsrt_mutex_unlock (&whc->lock); ddsrt_mutex_unlock (&whc->lock);
return 0; return 0;
} }
static void make_borrowed_sample(struct whc_borrowed_sample *sample, struct whc_node *whcn) static void make_borrowed_sample (struct whc_borrowed_sample *sample, struct whc_node *whcn)
{ {
assert(!whcn->borrowed); assert (!whcn->borrowed);
whcn->borrowed = 1; whcn->borrowed = 1;
sample->seq = whcn->seq; sample->seq = whcn->seq;
sample->plist = whcn->plist; sample->plist = whcn->plist;
@ -1258,11 +1254,11 @@ static bool whc_default_borrow_sample (const struct whc *whc_generic, seqno_t se
struct whc_node *whcn; struct whc_node *whcn;
bool found; bool found;
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock); ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
if ((whcn = whc_findseq(whc, seq)) == NULL) if ((whcn = whc_findseq (whc, seq)) == NULL)
found = false; found = false;
else else
{ {
make_borrowed_sample(sample, whcn); make_borrowed_sample (sample, whcn);
found = true; found = true;
} }
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock); ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
@ -1275,11 +1271,11 @@ static bool whc_default_borrow_sample_key (const struct whc *whc_generic, const
struct whc_node *whcn; struct whc_node *whcn;
bool found; bool found;
ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock); ddsrt_mutex_lock ((ddsrt_mutex_t *)&whc->lock);
if ((whcn = whc_findkey(whc, serdata_key)) == NULL) if ((whcn = whc_findkey (whc, serdata_key)) == NULL)
found = false; found = false;
else else
{ {
make_borrowed_sample(sample, whcn); make_borrowed_sample (sample, whcn);
found = true; found = true;
} }
ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock); ddsrt_mutex_unlock ((ddsrt_mutex_t *)&whc->lock);
@ -1293,14 +1289,15 @@ static void return_sample_locked (struct whc_impl *whc, struct whc_borrowed_samp
{ {
/* data no longer present in WHC - that means ownership for serdata, plist shifted to the borrowed copy and "returning" it really becomes "destroying" it */ /* data no longer present in WHC - that means ownership for serdata, plist shifted to the borrowed copy and "returning" it really becomes "destroying" it */
ddsi_serdata_unref (sample->serdata); ddsi_serdata_unref (sample->serdata);
if (sample->plist) { if (sample->plist)
{
nn_plist_fini (sample->plist); nn_plist_fini (sample->plist);
ddsrt_free (sample->plist); ddsrt_free (sample->plist);
} }
} }
else else
{ {
assert(whcn->borrowed); assert (whcn->borrowed);
whcn->borrowed = 0; whcn->borrowed = 0;
if (update_retransmit_info) if (update_retransmit_info)
{ {
@ -1338,7 +1335,7 @@ static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_
if (!it->first) if (!it->first)
{ {
seq = sample->seq; seq = sample->seq;
return_sample_locked(whc, sample, false); return_sample_locked (whc, sample, false);
} }
else else
{ {
@ -1349,7 +1346,7 @@ static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_
valid = false; valid = false;
else else
{ {
make_borrowed_sample(sample, whcn); make_borrowed_sample (sample, whcn);
valid = true; valid = true;
} }
ddsrt_mutex_unlock (&whc->lock); ddsrt_mutex_unlock (&whc->lock);

View file

@ -44,9 +44,7 @@ struct bwhc_iter {
}; };
/* check that our definition of whc_sample_iter fits in the type that callers allocate */ /* check that our definition of whc_sample_iter fits in the type that callers allocate */
struct bwhc_sample_iter_sizecheck { DDSRT_STATIC_ASSERT (sizeof (struct bwhc_iter) <= sizeof (struct whc_sample_iter));
char fits_in_generic_type[sizeof(struct bwhc_iter) <= sizeof(struct whc_sample_iter) ? 1 : -1];
};
static void bwhc_free (struct whc *whc_generic) static void bwhc_free (struct whc *whc_generic)
{ {

View file

@ -130,8 +130,8 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
struct reader *rd; struct reader *rd;
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL) if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL)
{ {
DDS_TRACE("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid)); DDS_TRACE ("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
/* Copied the return value ignore from DDSI deliver_user_data() function. */ /* Copied the return value ignore from DDSI deliver_user_data () function. */
if ((ret = try_store (rd->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK) if ((ret = try_store (rd->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK)
break; break;
} }
@ -152,40 +152,34 @@ dds_return_t dds_write_impl (dds_writer *wr, const void * data, dds_time_t tstam
int w_rc; int w_rc;
if (data == NULL) if (data == NULL)
{
DDS_ERROR("No data buffer provided\n");
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
}
/* Check for topic filter */ /* Check for topic filter */
if (wr->m_topic->filter_fn && !writekey) if (wr->m_topic->filter_fn && !writekey)
if (!(wr->m_topic->filter_fn) (data, wr->m_topic->filter_ctx)) if (! wr->m_topic->filter_fn (data, wr->m_topic->filter_ctx))
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
thread_state_awake (ts1); thread_state_awake (ts1);
/* Serialize and write data or key */ /* Serialize and write data or key */
d = ddsi_serdata_from_sample (ddsi_wr->topic, writekey ? SDK_KEY : SDK_DATA, data); d = ddsi_serdata_from_sample (ddsi_wr->topic, writekey ? SDK_KEY : SDK_DATA, data);
d->statusinfo = ((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) | ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0); d->statusinfo = (((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) |
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0));
d->timestamp.v = tstamp; d->timestamp.v = tstamp;
ddsi_serdata_ref (d); ddsi_serdata_ref (d);
tk = ddsi_tkmap_lookup_instance_ref (d); tk = ddsi_tkmap_lookup_instance_ref (d);
w_rc = write_sample_gc (ts1, wr->m_xp, ddsi_wr, d, tk); w_rc = write_sample_gc (ts1, wr->m_xp, ddsi_wr, d, tk);
if (w_rc >= 0) if (w_rc >= 0) {
{
/* Flush out write unless configured to batch */ /* Flush out write unless configured to batch */
if (!config.whc_batch) if (!config.whc_batch)
nn_xpack_send (wr->m_xp, false); nn_xpack_send (wr->m_xp, false);
ret = DDS_RETCODE_OK; ret = DDS_RETCODE_OK;
} else if (w_rc == DDS_RETCODE_TIMEOUT) { } else if (w_rc == DDS_RETCODE_TIMEOUT) {
DDS_ERROR ("The writer could not deliver data on time, probably due to a reader resources being full\n");
ret = DDS_RETCODE_TIMEOUT; ret = DDS_RETCODE_TIMEOUT;
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) { } else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
DDS_ERROR ("Invalid data provided\n");
ret = DDS_RETCODE_ERROR; ret = DDS_RETCODE_ERROR;
} else { } else {
DDS_ERROR ("Internal error\n");
ret = DDS_RETCODE_ERROR; ret = DDS_RETCODE_ERROR;
} }
if (ret == DDS_RETCODE_OK) if (ret == DDS_RETCODE_OK)
@ -213,13 +207,10 @@ dds_return_t dds_writecdr_impl_lowlevel (struct writer *ddsi_wr, struct nn_xpack
nn_xpack_send (xp, false); nn_xpack_send (xp, false);
ret = DDS_RETCODE_OK; ret = DDS_RETCODE_OK;
} else if (w_rc == DDS_RETCODE_TIMEOUT) { } else if (w_rc == DDS_RETCODE_TIMEOUT) {
DDS_ERROR ("The writer could not deliver data on time, probably due to a reader resources being full\n");
ret = DDS_RETCODE_TIMEOUT; ret = DDS_RETCODE_TIMEOUT;
} else if (w_rc == DDS_RETCODE_BAD_PARAMETER) { } else if (w_rc == DDS_RETCODE_BAD_PARAMETER) {
DDS_ERROR ("Invalid data provided\n");
ret = DDS_RETCODE_ERROR; ret = DDS_RETCODE_ERROR;
} else { } else {
DDS_ERROR ("Internal error\n");
ret = DDS_RETCODE_ERROR; ret = DDS_RETCODE_ERROR;
} }
@ -236,7 +227,8 @@ dds_return_t dds_writecdr_impl (dds_writer *wr, struct ddsi_serdata *d, dds_time
if (wr->m_topic->filter_fn) if (wr->m_topic->filter_fn)
abort (); abort ();
/* Set if disposing or unregistering */ /* Set if disposing or unregistering */
d->statusinfo = ((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) | ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0); d->statusinfo = (((action & DDS_WR_DISPOSE_BIT) ? NN_STATUSINFO_DISPOSE : 0) |
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0));
d->timestamp.v = tstamp; d->timestamp.v = tstamp;
return dds_writecdr_impl_lowlevel (wr->m_wr, wr->m_xp, d); return dds_writecdr_impl_lowlevel (wr->m_wr, wr->m_xp, d);
} }
@ -252,9 +244,7 @@ void dds_write_flush (dds_entity_t writer)
dds_writer *wr; dds_writer *wr;
dds_return_t rc; dds_return_t rc;
thread_state_awake (ts1); thread_state_awake (ts1);
if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) if ((rc = dds_writer_lock (writer, &wr)) == DDS_RETCODE_OK)
DDS_ERROR ("Error occurred on locking writer\n");
else
{ {
nn_xpack_send (wr->m_xp, true); nn_xpack_send (wr->m_xp, true);
dds_writer_unlock (wr); dds_writer_unlock (wr);

View file

@ -24,40 +24,29 @@
#include "dds__init.h" #include "dds__init.h"
#include "dds__publisher.h" #include "dds__publisher.h"
#include "dds__topic.h" #include "dds__topic.h"
#include "dds__get_status.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
#include "dds__whc.h" #include "dds__whc.h"
DECL_ENTITY_LOCK_UNLOCK(extern inline, dds_writer) DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_writer)
#define DDS_WRITER_STATUS_MASK \ #define DDS_WRITER_STATUS_MASK \
DDS_LIVELINESS_LOST_STATUS |\ (DDS_LIVELINESS_LOST_STATUS |\
DDS_OFFERED_DEADLINE_MISSED_STATUS |\ DDS_OFFERED_DEADLINE_MISSED_STATUS |\
DDS_OFFERED_INCOMPATIBLE_QOS_STATUS |\ DDS_OFFERED_INCOMPATIBLE_QOS_STATUS |\
DDS_PUBLICATION_MATCHED_STATUS DDS_PUBLICATION_MATCHED_STATUS)
static dds_return_t static dds_return_t dds_writer_instance_hdl (dds_entity *e, dds_instance_handle_t *i) ddsrt_nonnull_all;
dds_writer_instance_hdl(
dds_entity *e, static dds_return_t dds_writer_instance_hdl (dds_entity *e, dds_instance_handle_t *i)
dds_instance_handle_t *i)
{ {
assert(e); *i = writer_instance_id(&e->m_guid);
assert(i);
*i = (dds_instance_handle_t)writer_instance_id(&e->m_guid);
return DDS_RETCODE_OK; return DDS_RETCODE_OK;
} }
static dds_return_t static dds_return_t dds_writer_status_validate (uint32_t mask)
dds_writer_status_validate(
uint32_t mask)
{ {
dds_return_t ret = DDS_RETCODE_OK; return (mask & ~DDS_WRITER_STATUS_MASK) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK;
if (mask & ~(DDS_WRITER_STATUS_MASK)) {
DDS_ERROR("Invalid status mask\n");
ret = DDS_RETCODE_BAD_PARAMETER;
}
return ret;
} }
/* /*
@ -173,147 +162,105 @@ static void dds_writer_status_cb (void *ventity, const status_cb_data_t *data)
ddsrt_mutex_unlock (&entity->m_observers_lock); ddsrt_mutex_unlock (&entity->m_observers_lock);
} }
static uint32_t static uint32_t get_bandwidth_limit (nn_transport_priority_qospolicy_t transport_priority)
get_bandwidth_limit(
nn_transport_priority_qospolicy_t transport_priority)
{ {
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS #ifdef DDSI_INCLUDE_NETWORK_CHANNELS
struct config_channel_listelem *channel = find_channel (transport_priority); struct config_channel_listelem *channel = find_channel (transport_priority);
return channel->data_bandwidth_limit; return channel->data_bandwidth_limit;
#else #else
(void)transport_priority; (void) transport_priority;
return 0; return 0;
#endif #endif
} }
static dds_return_t static dds_return_t dds_writer_close (dds_entity *e) ddsrt_nonnull_all;
dds_writer_close(
dds_entity *e) static dds_return_t dds_writer_close (dds_entity *e)
{ {
dds_return_t ret = DDS_RETCODE_OK; dds_writer * const wr = (dds_writer *) e;
dds_writer *wr = (dds_writer*)e; dds_return_t ret;
assert(e);
thread_state_awake (lookup_thread_state ()); thread_state_awake (lookup_thread_state ());
nn_xpack_send (wr->m_xp, false); nn_xpack_send (wr->m_xp, false);
if (delete_writer (&e->m_guid) != 0) { if ((ret = delete_writer (&e->m_guid)) < 0)
DDS_ERROR("Internal error");
ret = DDS_RETCODE_ERROR; ret = DDS_RETCODE_ERROR;
}
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());
return ret; return ret;
} }
static dds_return_t static dds_return_t dds_writer_delete (dds_entity *e) ddsrt_nonnull_all;
dds_writer_delete(
dds_entity *e) static dds_return_t dds_writer_delete (dds_entity *e)
{ {
dds_writer *wr = (dds_writer*)e; dds_writer * const wr = (dds_writer *) e;
dds_return_t ret; dds_return_t ret;
/* FIXME: not freeing WHC here because it is owned by the DDSI entity */ /* FIXME: not freeing WHC here because it is owned by the DDSI entity */
thread_state_awake (lookup_thread_state ()); thread_state_awake (lookup_thread_state ());
nn_xpack_free(wr->m_xp); nn_xpack_free (wr->m_xp);
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());
ret = dds_delete(wr->m_topic->m_entity.m_hdllink.hdl); if ((ret = dds_delete (wr->m_topic->m_entity.m_hdllink.hdl)) == DDS_RETCODE_OK)
if(ret == DDS_RETCODE_OK){ {
ret = dds_delete_impl(e->m_parent->m_hdllink.hdl, true); ret = dds_delete_impl (e->m_parent->m_hdllink.hdl, true);
if(ret == DDS_RETCODE_BAD_PARAMETER){ if (ret == DDS_RETCODE_BAD_PARAMETER)
ret = DDS_RETCODE_OK; ret = DDS_RETCODE_OK;
} }
}
return ret; return ret;
} }
static dds_return_t dds_writer_qos_validate (const dds_qos_t *qos, bool enabled)
static dds_return_t
dds_writer_qos_validate(
const dds_qos_t *qos,
bool enabled)
{ {
dds_return_t ret = DDS_RETCODE_OK; if (!dds_qos_validate_common(qos))
return DDS_RETCODE_INCONSISTENT_POLICY;
assert(qos); if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
/* Check consistency. */ if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy (&qos->durability_service) < 0)
if(dds_qos_validate_common(qos) != true){ return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("Provided inconsistent QoS policy\n"); if ((qos->present & QP_LIFESPAN) && validate_duration (&qos->lifespan.duration) < 0)
ret = DDS_RETCODE_INCONSISTENT_POLICY; 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)
if((qos->present & QP_USER_DATA) && validate_octetseq(&qos->user_data) != true){ return DDS_RETCODE_INCONSISTENT_POLICY;
DDS_ERROR("User Data QoS policy is inconsistent and caused an error\n"); return enabled ? dds_qos_validate_mutable_common (qos) : DDS_RETCODE_OK;
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 static dds_return_t dds_writer_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
dds_writer_qos_set(
dds_entity *e,
const dds_qos_t *qos,
bool enabled)
{ {
dds_return_t ret = dds_writer_qos_validate(qos, enabled); /* FIXME: QoS changes */
if (ret == DDS_RETCODE_OK) { dds_return_t ret;
/*
* TODO: CHAM-95: DDSI does not support changing QoS policies. if ((ret = dds_writer_qos_validate (qos, enabled)) != DDS_RETCODE_OK)
* return ret;
* Only Ownership is required for the minimum viable product. This seems
* to be the only QoS policy that DDSI supports changes on. /* Sort-of support updating ownership strength */
*/ if ((qos->present & QP_OWNERSHIP_STRENGTH) && (qos->present & ~QP_OWNERSHIP_STRENGTH) == 0)
if (qos->present & QP_OWNERSHIP_STRENGTH) { {
dds_ownership_kind_t kind; 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); dds_qget_ownership (e->m_qos, &kind);
if (kind == DDS_OWNERSHIP_EXCLUSIVE) { if (kind != DDS_OWNERSHIP_EXCLUSIVE)
struct writer * ddsi_wr = ((dds_writer*)e)->m_wr; return DDS_RETCODE_ERROR;
struct writer *ddsi_wr = ((dds_writer *) e)->m_wr;
dds_qset_ownership_strength (e->m_qos, qos->ownership_strength.value); dds_qset_ownership_strength (e->m_qos, qos->ownership_strength.value);
thread_state_awake (lookup_thread_state ()); 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 */ /* 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); 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; ddsi_wr->xqos->ownership_strength.value = qos->ownership_strength.value;
}
ddsrt_mutex_unlock (&ddsi_wr->e.lock); ddsrt_mutex_unlock (&ddsi_wr->e.lock);
thread_state_asleep (lookup_thread_state ()); 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 { else
if (enabled) { {
DDS_ERROR(DDS_PROJECT_NAME" does not support changing QoS policies yet\n"); if (enabled)
ret = DDS_RETCODE_UNSUPPORTED; ret = DDS_RETCODE_UNSUPPORTED;
} }
}
}
return ret; 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; bool handle_as_transient_local;
unsigned hdepth, tldepth; uint32_t hdepth, tldepth;
/* Construct WHC -- if aggressive_keep_last1 is set, the WHC will /* Construct WHC -- if aggressive_keep_last1 is set, the WHC will
drop all samples for which a later update is available. This drop all samples for which a later update is available. This
forces it to maintain a tlidx. */ forces it to maintain a tlidx. */
@ -321,99 +268,76 @@ static struct whc *make_whc(const dds_qos_t *qos)
if (qos->history.kind == NN_KEEP_ALL_HISTORY_QOS) if (qos->history.kind == NN_KEEP_ALL_HISTORY_QOS)
hdepth = 0; hdepth = 0;
else else
hdepth = (unsigned)qos->history.depth; hdepth = (unsigned) qos->history.depth;
if (handle_as_transient_local) { if (!handle_as_transient_local)
tldepth = 0;
else
{
if (qos->durability_service.history.kind == NN_KEEP_ALL_HISTORY_QOS) if (qos->durability_service.history.kind == NN_KEEP_ALL_HISTORY_QOS)
tldepth = 0; tldepth = 0;
else else
tldepth = (unsigned)qos->durability_service.history.depth; tldepth = (unsigned) qos->durability_service.history.depth;
} else {
tldepth = 0;
} }
return whc_new (handle_as_transient_local, hdepth, tldepth); return whc_new (handle_as_transient_local, hdepth, tldepth);
} }
dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener)
dds_entity_t
dds_create_writer(
dds_entity_t participant_or_publisher,
dds_entity_t topic,
const dds_qos_t *qos,
const dds_listener_t *listener)
{ {
dds_return_t rc; dds_return_t rc;
dds_qos_t * wqos; dds_qos_t *wqos;
dds_writer * wr; dds_writer *wr;
dds_entity_t writer; dds_entity_t writer;
dds_publisher * pub = NULL; dds_publisher *pub = NULL;
dds_topic * tp; dds_topic *tp;
dds_entity_t publisher; dds_entity_t publisher;
ddsi_tran_conn_t conn = gv.data_conn_uc; ddsi_tran_conn_t conn = gv.data_conn_uc;
dds_return_t ret;
{ {
dds_entity *p_or_p; dds_entity *p_or_p;
if ((rc = dds_entity_claim (participant_or_publisher, &p_or_p)) != DDS_RETCODE_OK) { if ((rc = dds_entity_claim (participant_or_publisher, &p_or_p)) != DDS_RETCODE_OK)
return rc; return rc;
} if (dds_entity_kind (p_or_p) == DDS_KIND_PARTICIPANT)
if (dds_entity_kind (p_or_p) == DDS_KIND_PARTICIPANT) {
publisher = dds_create_publisher(participant_or_publisher, qos, NULL); publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
} else { else
publisher = participant_or_publisher; publisher = participant_or_publisher;
}
dds_entity_release (p_or_p); dds_entity_release (p_or_p);
} }
if ((rc = dds_publisher_lock(publisher, &pub)) != DDS_RETCODE_OK) { if ((rc = dds_publisher_lock (publisher, &pub)) != DDS_RETCODE_OK)
writer = rc; return rc;
goto err_pub_lock;
}
if (publisher != participant_or_publisher) { if (publisher != participant_or_publisher)
pub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT; pub->m_entity.m_flags |= DDS_ENTITY_IMPLICIT;
}
rc = dds_topic_lock(topic, &tp); if ((rc = dds_topic_lock (topic, &tp)) != DDS_RETCODE_OK)
if (rc != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking topic\n");
writer = rc;
goto err_tp_lock; goto err_tp_lock;
}
assert(tp->m_stopic); assert (tp->m_stopic);
assert(pub->m_entity.m_domain == tp->m_entity.m_domain); assert (pub->m_entity.m_domain == tp->m_entity.m_domain);
/* Merge Topic & Publisher qos */ /* Merge Topic & Publisher qos */
wqos = dds_create_qos(); wqos = dds_create_qos ();
if (qos) { if (qos)
/* Only returns failure when one of the qos args is NULL, which (void) dds_copy_qos (wqos, qos);
* is not the case here. */ if (pub->m_entity.m_qos)
(void)dds_copy_qos(wqos, 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 (pub->m_entity.m_qos) { if ((rc = dds_writer_qos_validate (wqos, false)) != DDS_RETCODE_OK)
dds_merge_qos(wqos, pub->m_entity.m_qos); {
}
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);
ret = dds_writer_qos_validate(wqos, false);
if (ret != 0) {
dds_delete_qos(wqos); dds_delete_qos(wqos);
writer = ret;
goto err_bad_qos; goto err_bad_qos;
} }
/* Create writer */ /* Create writer */
wr = dds_alloc(sizeof (*wr)); wr = dds_alloc (sizeof (*wr));
writer = dds_entity_init(&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK); writer = dds_entity_init (&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
wr->m_topic = tp; wr->m_topic = tp;
dds_entity_add_ref_nolock(&tp->m_entity); 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_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.close = dds_writer_close;
wr->m_entity.m_deriver.delete = dds_writer_delete; 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.set_qos = dds_writer_qos_set;
@ -429,29 +353,26 @@ dds_create_writer(
ddsrt_mutex_unlock (&pub->m_entity.m_mutex); ddsrt_mutex_unlock (&pub->m_entity.m_mutex);
thread_state_awake (lookup_thread_state ()); 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); 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 (&pub->m_entity.m_mutex);
ddsrt_mutex_lock (&tp->m_entity.m_mutex); ddsrt_mutex_lock (&tp->m_entity.m_mutex);
assert(ret == DDS_RETCODE_OK); assert(rc == DDS_RETCODE_OK);
thread_state_asleep (lookup_thread_state ()); thread_state_asleep (lookup_thread_state ());
dds_topic_unlock(tp); dds_topic_unlock (tp);
dds_publisher_unlock(pub); dds_publisher_unlock (pub);
return writer; return writer;
err_bad_qos: err_bad_qos:
dds_topic_unlock(tp); dds_topic_unlock (tp);
err_tp_lock: err_tp_lock:
dds_publisher_unlock(pub); dds_publisher_unlock (pub);
if((pub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){ if ((pub->m_entity.m_flags & DDS_ENTITY_IMPLICIT) != 0){
(void)dds_delete(publisher); (void )dds_delete (publisher);
} }
err_pub_lock: return rc;
return writer;
} }
dds_entity_t dds_entity_t dds_get_publisher (dds_entity_t writer)
dds_get_publisher(
dds_entity_t writer)
{ {
dds_entity *e; dds_entity *e;
dds_return_t rc; dds_return_t rc;
@ -472,115 +393,7 @@ dds_get_publisher(
} }
} }
dds_return_t DDS_GET_STATUS(writer, publication_matched, PUBLICATION_MATCHED, total_count_change, current_count_change)
dds_get_publication_matched_status ( DDS_GET_STATUS(writer, liveliness_lost, LIVELINESS_LOST, total_count_change)
dds_entity_t writer, DDS_GET_STATUS(writer, offered_deadline_missed, OFFERED_DEADLINE_MISSED, total_count_change)
dds_publication_matched_status_t * status) DDS_GET_STATUS(writer, offered_incompatible_qos, OFFERED_INCOMPATIBLE_QOS, total_count_change)
{
dds_writer *wr;
dds_return_t ret;
ret = dds_writer_lock(writer, &wr);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = wr->m_publication_matched_status;
}
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
if (wr->m_entity.m_status_enable & DDS_PUBLICATION_MATCHED_STATUS) {
wr->m_publication_matched_status.total_count_change = 0;
wr->m_publication_matched_status.current_count_change = 0;
dds_entity_status_reset(&wr->m_entity, DDS_PUBLICATION_MATCHED_STATUS);
}
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
dds_writer_unlock(wr);
fail:
return ret;
}
dds_return_t
dds_get_liveliness_lost_status (
dds_entity_t writer,
dds_liveliness_lost_status_t * status)
{
dds_writer *wr;
dds_return_t ret;
ret = dds_writer_lock(writer, &wr);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = wr->m_liveliness_lost_status;
}
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
if (wr->m_entity.m_status_enable & DDS_LIVELINESS_LOST_STATUS) {
wr->m_liveliness_lost_status.total_count_change = 0;
dds_entity_status_reset(&wr->m_entity, DDS_LIVELINESS_LOST_STATUS);
}
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
dds_writer_unlock(wr);
fail:
return ret;
}
dds_return_t
dds_get_offered_deadline_missed_status(
dds_entity_t writer,
dds_offered_deadline_missed_status_t *status)
{
dds_writer *wr;
dds_return_t ret;
ret = dds_writer_lock(writer, &wr);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = wr->m_offered_deadline_missed_status;
}
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
if (wr->m_entity.m_status_enable & DDS_OFFERED_DEADLINE_MISSED_STATUS) {
wr->m_offered_deadline_missed_status.total_count_change = 0;
dds_entity_status_reset(&wr->m_entity, DDS_OFFERED_DEADLINE_MISSED_STATUS);
}
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
dds_writer_unlock(wr);
fail:
return ret;
}
dds_return_t
dds_get_offered_incompatible_qos_status (
dds_entity_t writer,
dds_offered_incompatible_qos_status_t * status)
{
dds_writer *wr;
dds_return_t ret;
ret = dds_writer_lock(writer, &wr);
if (ret != DDS_RETCODE_OK) {
DDS_ERROR("Error occurred on locking writer\n");
goto fail;
}
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
if (status) {
*status = wr->m_offered_incompatible_qos_status;
}
ddsrt_mutex_lock (&wr->m_entity.m_observers_lock);
if (wr->m_entity.m_status_enable & DDS_OFFERED_INCOMPATIBLE_QOS_STATUS) {
wr->m_offered_incompatible_qos_status.total_count_change = 0;
dds_entity_status_reset(&wr->m_entity, DDS_OFFERED_INCOMPATIBLE_QOS_STATUS);
}
ddsrt_mutex_unlock (&wr->m_entity.m_observers_lock);
dds_writer_unlock(wr);
fail:
return ret;
}

View file

@ -105,7 +105,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
q_rtps.h q_rtps.h
q_security.h q_security.h
q_sockwaitset.h q_sockwaitset.h
q_static_assert.h
q_thread.h q_thread.h
q_time.h q_time.h
q_transmit.h q_transmit.h

View file

@ -467,17 +467,6 @@ nn_vendorid_t get_entity_vendorid (const struct entity_common *e);
* - RTPS_PF_ONLY_LOCAL FIXME: not used, it seems * - RTPS_PF_ONLY_LOCAL FIXME: not used, it seems
* @param[in] plist * @param[in] plist
* Parameters/QoS for this participant * Parameters/QoS for this participant
* @param[out] dest
* Filled with the recognized parameters in the input if successful, otherwise
* initialized to an empty parameter list. Where possible, pointers alias the
* input (indicated by the "aliased" bits in the plist/xqos structures), but
* some things cannot be aliased (e.g., the array of pointers to strings for a
* sequence of strings).
* Generally, nn_plist_fini should be called when done with the parameter list,
* even when nn_plist_unlias or nn_xqos_unlias hasn't been called.
* @param[out] nextafterplist
* If non-NULL, *nextafterplist is set to the first byte following the parameter
* list sentinel on successful parse, or to NULL on failure
* *
* @returns A dds_return_t indicating success or failure. * @returns A dds_return_t indicating success or failure.
* *
@ -562,11 +551,11 @@ int writer_must_have_hb_scheduled (const struct writer *wr, const struct whc_sta
void writer_set_retransmitting (struct writer *wr); void writer_set_retransmitting (struct writer *wr);
void writer_clear_retransmitting (struct writer *wr); void writer_clear_retransmitting (struct writer *wr);
int delete_writer (const struct nn_guid *guid); dds_return_t delete_writer (const struct nn_guid *guid);
int delete_writer_nolinger (const struct nn_guid *guid); dds_return_t delete_writer_nolinger (const struct nn_guid *guid);
int delete_writer_nolinger_locked (struct writer *wr); dds_return_t delete_writer_nolinger_locked (struct writer *wr);
int delete_reader (const struct nn_guid *guid); dds_return_t delete_reader (const struct nn_guid *guid);
uint64_t reader_instance_id (const struct nn_guid *guid); uint64_t reader_instance_id (const struct nn_guid *guid);
struct local_orphan_writer { struct local_orphan_writer {

View file

@ -18,9 +18,7 @@ extern "C" {
struct nn_xqos; struct nn_xqos;
int partition_match_based_on_wildcard_in_left_operand (const struct nn_xqos *a, const struct nn_xqos *b, const char **realname);
int partitions_match_p (const struct nn_xqos *a, const struct nn_xqos *b); int partitions_match_p (const struct nn_xqos *a, const struct nn_xqos *b);
int is_wildcard_partition (const char *str);
/* Returns -1 on success, or QoS id of first mismatch (>=0) */ /* Returns -1 on success, or QoS id of first mismatch (>=0) */

View file

@ -17,7 +17,7 @@
#include "dds/ddsrt/atomics.h" #include "dds/ddsrt/atomics.h"
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/threads.h" #include "dds/ddsrt/threads.h"
#include "dds/ddsi/q_static_assert.h" #include "dds/ddsrt/static_assert.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -125,7 +125,7 @@ DDS_EXPORT inline bool vtime_asleep_p (vtime_t vtime)
DDS_EXPORT inline bool vtime_gt (vtime_t vtime1, vtime_t vtime0) DDS_EXPORT inline bool vtime_gt (vtime_t vtime1, vtime_t vtime0)
{ {
Q_STATIC_ASSERT_CODE (sizeof (vtime_t) == sizeof (svtime_t)); DDSRT_STATIC_ASSERT_CODE (sizeof (vtime_t) == sizeof (svtime_t));
return (svtime_t) ((vtime1 & VTIME_TIME_MASK) - (vtime0 & VTIME_TIME_MASK)) > 0; return (svtime_t) ((vtime1 & VTIME_TIME_MASK) - (vtime0 & VTIME_TIME_MASK)) > 0;
} }

View file

@ -332,8 +332,9 @@ static enum ddsi_locator_from_string_result ddsi_raweth_address_from_string (dds
memset (loc->address, 0, sizeof (loc->address)); memset (loc->address, 0, sizeof (loc->address));
while (i < 6 && *str != 0) while (i < 6 && *str != 0)
{ {
int o, p; unsigned o;
if (sscanf (str, "%x%n", &o, &p) != 1 || o < 0 || o > 255) int p;
if (sscanf (str, "%x%n", &o, &p) != 1 || o > 255)
return AFSR_INVALID; return AFSR_INVALID;
loc->address[10 + i++] = (unsigned char) o; loc->address[10 + i++] = (unsigned char) o;
str += p; str += p;

View file

@ -127,12 +127,12 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
return 0; return 0;
} }
DDSRT_WARNING_MSVC_OFF(4996);
int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc) int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc)
{ {
/* port_mode: -1 => take from string, if 0 & unicast, add for a range of participant indices; /* port_mode: -1 => take from string, if 0 & unicast, add for a range of participant indices;
port_mode >= 0 => always set port to port_mode port_mode >= 0 => always set port to port_mode
*/ */
DDSRT_WARNING_MSVC_OFF(4996);
char *addrs_copy, *ip, *cursor, *a; char *addrs_copy, *ip, *cursor, *a;
int retval = -1; int retval = -1;
addrs_copy = ddsrt_strdup (addrs); addrs_copy = ddsrt_strdup (addrs);
@ -179,8 +179,8 @@ int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mo
ddsrt_free (ip); ddsrt_free (ip);
ddsrt_free (addrs_copy); ddsrt_free (addrs_copy);
return retval; return retval;
DDSRT_WARNING_MSVC_ON(4996);
} }
DDSRT_WARNING_MSVC_ON(4996);
int compare_locators (const nn_locator_t *a, const nn_locator_t *b) int compare_locators (const nn_locator_t *a, const nn_locator_t *b)
{ {

View file

@ -1335,9 +1335,9 @@ static void do_print_uint32_bitset (struct cfgst *cfgst, uint32_t mask, size_t n
cfg_logelem (cfgst, sources, "%s%s", res, suffix); cfg_logelem (cfgst, sources, "%s%s", res, suffix);
} }
DDSRT_WARNING_MSVC_OFF(4996);
static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *value, const struct unit *unittab, int64_t def_mult, int64_t min, int64_t max) static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *value, const struct unit *unittab, int64_t def_mult, int64_t min, int64_t max)
{ {
DDSRT_WARNING_MSVC_OFF(4996);
int pos; int pos;
double v_dbl; double v_dbl;
int64_t v_int; int64_t v_int;
@ -1364,8 +1364,8 @@ static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *valu
*elem = 0; /* some static analyzers don't "get it" */ *elem = 0; /* some static analyzers don't "get it" */
return cfg_error (cfgst, "%s: invalid value", value); return cfg_error (cfgst, "%s: invalid value", value);
} }
DDSRT_WARNING_MSVC_ON(4996);
} }
DDSRT_WARNING_MSVC_ON(4996);
static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources, const struct unit *unittab, const char *zero_unit) static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources, const struct unit *unittab, const char *zero_unit)
{ {
@ -1393,10 +1393,8 @@ static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources,
} }
#define GENERIC_ENUM_CTYPE_UF(type_, c_type_) \ #define GENERIC_ENUM_CTYPE_UF(type_, c_type_) \
struct en_##type_##_vs_ms_check { \ DDSRT_STATIC_ASSERT (sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
char length_eq[(sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \ sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)); \
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)) ? 1 : -1]; \
}; \
\ \
static int uf_##type_ (struct cfgst *cfgst, void *parent, UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) \ static int uf_##type_ (struct cfgst *cfgst, void *parent, UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) \
{ \ { \
@ -1773,9 +1771,9 @@ static void pf_allow_multicast(struct cfgst *cfgst, void *parent, struct cfgelem
do_print_uint32_bitset (cfgst, *p, sizeof (allow_multicast_codes) / sizeof (*allow_multicast_codes), allow_multicast_names, allow_multicast_codes, sources, ""); do_print_uint32_bitset (cfgst, *p, sizeof (allow_multicast_codes) / sizeof (*allow_multicast_codes), allow_multicast_names, allow_multicast_codes, sources, "");
} }
DDSRT_WARNING_MSVC_OFF(4996);
static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{ {
DDSRT_WARNING_MSVC_OFF(4996);
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem); struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
int pos; int pos;
if (ddsrt_strcasecmp (value, "default") == 0) { if (ddsrt_strcasecmp (value, "default") == 0) {
@ -1788,8 +1786,8 @@ static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem con
} else { } else {
return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value); return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value);
} }
DDSRT_WARNING_MSVC_ON(4996);
} }
DDSRT_WARNING_MSVC_ON(4996);
static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources) static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
{ {
@ -1940,9 +1938,9 @@ static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const
pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s"); pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s");
} }
DDSRT_WARNING_MSVC_OFF(4996);
static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{ {
DDSRT_WARNING_MSVC_OFF(4996);
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem); struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
int pos; int pos;
if (ddsrt_strcasecmp (value, "any") == 0) { if (ddsrt_strcasecmp (value, "any") == 0) {
@ -1955,8 +1953,8 @@ static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const
} else { } else {
return cfg_error (cfgst, "'%s': neither 'any' nor a decimal integer in 0 .. 230\n", value); return cfg_error (cfgst, "'%s': neither 'any' nor a decimal integer in 0 .. 230\n", value);
} }
DDSRT_WARNING_MSVC_ON(4996);
} }
DDSRT_WARNING_MSVC_ON(4996);
static void pf_domainId(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources) static void pf_domainId(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
{ {

View file

@ -1099,10 +1099,10 @@ static void rebuild_make_locs_nrds(int **locs_nrds, int nreaders, int nlocs, con
if (covered[j * nlocs + i] >= 0) if (covered[j * nlocs + i] >= 0)
n++; n++;
/* The compiler doesn't realize that ln is large enough. */ /* The compiler doesn't realize that ln is large enough. */
DDSRT_WARNING_MSVC_OFF(6386); DDSRT_WARNING_MSVC_OFF(6386);
ln[i] = n; ln[i] = n;
DDSRT_WARNING_MSVC_ON(6386); DDSRT_WARNING_MSVC_ON(6386);
} }
*locs_nrds = ln; *locs_nrds = ln;
} }
@ -3002,7 +3002,7 @@ static void writer_set_state (struct writer *wr, enum writer_state newstate)
wr->state = newstate; wr->state = newstate;
} }
int delete_writer_nolinger_locked (struct writer *wr) dds_return_t delete_writer_nolinger_locked (struct writer *wr)
{ {
DDS_LOG(DDS_LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid)); DDS_LOG(DDS_LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid));
ASSERT_MUTEX_HELD (&wr->e.lock); ASSERT_MUTEX_HELD (&wr->e.lock);
@ -3014,7 +3014,7 @@ int delete_writer_nolinger_locked (struct writer *wr)
return 0; return 0;
} }
int delete_writer_nolinger (const struct nn_guid *guid) dds_return_t delete_writer_nolinger (const struct nn_guid *guid)
{ {
struct writer *wr; struct writer *wr;
/* We take no care to ensure application writers are not deleted /* We take no care to ensure application writers are not deleted
@ -3043,7 +3043,7 @@ void delete_local_orphan_writer (struct local_orphan_writer *lowr)
ddsrt_mutex_unlock (&lowr->wr.e.lock); ddsrt_mutex_unlock (&lowr->wr.e.lock);
} }
int delete_writer (const struct nn_guid *guid) dds_return_t delete_writer (const struct nn_guid *guid)
{ {
struct writer *wr; struct writer *wr;
struct whc_state whcst; struct whc_state whcst;
@ -3409,7 +3409,7 @@ static void gc_delete_reader (struct gcreq *gcreq)
ddsrt_free (rd); ddsrt_free (rd);
} }
int delete_reader (const struct nn_guid *guid) dds_return_t delete_reader (const struct nn_guid *guid)
{ {
struct reader *rd; struct reader *rd;
assert (!is_writer_entityid (guid->entityid)); assert (!is_writer_entityid (guid->entityid));

View file

@ -140,9 +140,9 @@ void nn_freelist_fini (struct nn_freelist *fl, void (*xfree) (void *))
xfree (fl->inner[i].m->x[j]); xfree (fl->inner[i].m->x[j]);
ddsrt_free(fl->inner[i].m); ddsrt_free(fl->inner[i].m);
} }
/* The compiler can't make sense of all these linked lists and doesn't /* The compiler can't make sense of all these linked lists and doesn't
* realize that the next pointers are always initialized here. */ * realize that the next pointers are always initialized here. */
DDSRT_WARNING_MSVC_OFF(6001); DDSRT_WARNING_MSVC_OFF(6001);
while ((m = fl->mlist) != NULL) while ((m = fl->mlist) != NULL)
{ {
fl->mlist = m->next; fl->mlist = m->next;
@ -155,7 +155,7 @@ DDSRT_WARNING_MSVC_OFF(6001);
fl->emlist = m->next; fl->emlist = m->next;
ddsrt_free (m); ddsrt_free (m);
} }
DDSRT_WARNING_MSVC_ON(6001); DDSRT_WARNING_MSVC_ON(6001);
} }
static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0); static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0);

View file

@ -415,9 +415,9 @@ static int check_thread_properties (void)
return ok; return ok;
} }
DDSRT_WARNING_MSVC_OFF(4996);
int rtps_config_open (void) int rtps_config_open (void)
{ {
DDSRT_WARNING_MSVC_OFF(4996);
int status; int status;
if (config.tracingOutputFileName == NULL || *config.tracingOutputFileName == 0 || config.enabled_logcats == 0) if (config.tracingOutputFileName == NULL || *config.tracingOutputFileName == 0 || config.enabled_logcats == 0)
@ -450,8 +450,8 @@ int rtps_config_open (void)
dds_set_trace_file(config.tracingOutputFile); dds_set_trace_file(config.tracingOutputFile);
return status; return status;
DDSRT_WARNING_MSVC_ON(4996);
} }
DDSRT_WARNING_MSVC_ON(4996);
int rtps_config_prep (struct cfgst *cfgst) int rtps_config_prep (struct cfgst *cfgst)
{ {
@ -1654,10 +1654,10 @@ void rtps_fini (void)
while (gv.recvips) while (gv.recvips)
{ {
struct config_in_addr_node *n = gv.recvips; struct config_in_addr_node *n = gv.recvips;
/* The compiler doesn't realize that n->next is always initialized. */ /* The compiler doesn't realize that n->next is always initialized. */
DDSRT_WARNING_MSVC_OFF(6001); DDSRT_WARNING_MSVC_OFF(6001);
gv.recvips = n->next; gv.recvips = n->next;
DDSRT_WARNING_MSVC_ON(6001); DDSRT_WARNING_MSVC_ON(6001);
ddsrt_free (n); ddsrt_free (n);
} }

View file

@ -77,9 +77,9 @@ static const ipv4_hdr_t ipv4_hdr_template = {
#define IPV4_HDR_SIZE 20 #define IPV4_HDR_SIZE 20
#define UDP_HDR_SIZE 8 #define UDP_HDR_SIZE 8
DDSRT_WARNING_MSVC_OFF(4996);
FILE *new_pcap_file (const char *name) FILE *new_pcap_file (const char *name)
{ {
DDSRT_WARNING_MSVC_OFF(4996);
FILE *fp; FILE *fp;
pcap_hdr_t hdr; pcap_hdr_t hdr;
@ -99,8 +99,8 @@ FILE *new_pcap_file (const char *name)
fwrite (&hdr, sizeof (hdr), 1, fp); fwrite (&hdr, sizeof (hdr), 1, fp);
return fp; return fp;
DDSRT_WARNING_MSVC_ON(4996);
} }
DDSRT_WARNING_MSVC_ON(4996);
static void write_data (FILE *fp, const ddsrt_msghdr_t *msghdr, size_t sz) static void write_data (FILE *fp, const ddsrt_msghdr_t *msghdr, size_t sz)
{ {

View file

@ -17,6 +17,7 @@
#include "dds/ddsrt/log.h" #include "dds/ddsrt/log.h"
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/static_assert.h"
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
@ -30,7 +31,6 @@
#include "dds/ddsi/q_globals.h" #include "dds/ddsi/q_globals.h"
#include "dds/ddsi/q_protocol.h" /* for NN_STATUSINFO_... */ #include "dds/ddsi/q_protocol.h" /* for NN_STATUSINFO_... */
#include "dds/ddsi/q_radmin.h" /* for nn_plist_quickscan */ #include "dds/ddsi/q_radmin.h" /* for nn_plist_quickscan */
#include "dds/ddsi/q_static_assert.h"
#include "dds/ddsrt/avl.h" #include "dds/ddsrt/avl.h"
#include "dds/ddsi/q_misc.h" /* for vendor_is_... */ #include "dds/ddsi/q_misc.h" /* for vendor_is_... */
@ -407,8 +407,8 @@ void nn_plist_fini (nn_plist_t *ps)
int i; int i;
nn_xqos_fini (&ps->qos); nn_xqos_fini (&ps->qos);
/* The compiler doesn't understand how offsetof is used in the arrays. */ /* The compiler doesn't understand how offsetof is used in the arrays. */
DDSRT_WARNING_MSVC_OFF(6001); DDSRT_WARNING_MSVC_OFF(6001);
for (i = 0; i < (int) (sizeof (simple) / sizeof (*simple)); i++) for (i = 0; i < (int) (sizeof (simple) / sizeof (*simple)); i++)
{ {
if ((ps->present & simple[i].fl) && !(ps->aliased & simple[i].fl)) if ((ps->present & simple[i].fl) && !(ps->aliased & simple[i].fl))
@ -422,7 +422,7 @@ DDSRT_WARNING_MSVC_OFF(6001);
if ((ps->present & locs[i].fl) && !(ps->aliased & locs[i].fl)) if ((ps->present & locs[i].fl) && !(ps->aliased & locs[i].fl))
free_locators ((nn_locators_t *) ((char *) ps + locs[i].off)); free_locators ((nn_locators_t *) ((char *) ps + locs[i].off));
} }
DDSRT_WARNING_MSVC_ON(6001); DDSRT_WARNING_MSVC_ON(6001);
ps->present = 0; ps->present = 0;
} }
@ -1943,7 +1943,7 @@ static dds_return_t init_one_parameter
if (dd->bufsz >= 2 * sizeof (dest->statusinfo) && vendor_is_eclipse_or_opensplice(dd->vendorid)) if (dd->bufsz >= 2 * sizeof (dest->statusinfo) && vendor_is_eclipse_or_opensplice(dd->vendorid))
{ {
uint32_t statusinfox; uint32_t statusinfox;
Q_STATIC_ASSERT_CODE (sizeof(statusinfox) == sizeof(dest->statusinfo)); DDSRT_STATIC_ASSERT_CODE (sizeof(statusinfox) == sizeof(dest->statusinfo));
memcpy (&statusinfox, dd->buf + sizeof (dest->statusinfo), sizeof (statusinfox)); memcpy (&statusinfox, dd->buf + sizeof (dest->statusinfo), sizeof (statusinfox));
statusinfox = fromBE4u (statusinfox); statusinfox = fromBE4u (statusinfox);
if (statusinfox & NN_STATUSINFOX_OSPL_AUTO) if (statusinfox & NN_STATUSINFOX_OSPL_AUTO)

View file

@ -17,7 +17,7 @@
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
#include "dds/ddsi/q_qosmatch.h" #include "dds/ddsi/q_qosmatch.h"
int is_wildcard_partition (const char *str) static int is_wildcard_partition (const char *str)
{ {
return strchr (str, '*') || strchr (str, '?'); return strchr (str, '*') || strchr (str, '?');
} }
@ -66,46 +66,6 @@ int partitions_match_p (const nn_xqos_t *a, const nn_xqos_t *b)
} }
} }
int partition_match_based_on_wildcard_in_left_operand (const nn_xqos_t *a, const nn_xqos_t *b, const char **realname)
{
assert (partitions_match_p (a, b));
if (!(a->present & QP_PARTITION) || a->partition.n == 0)
{
return 0;
}
else if (!(b->present & QP_PARTITION) || b->partition.n == 0)
{
/* Either A explicitly includes the default partition, or it is a
wildcard that matches it */
unsigned i;
for (i = 0; i < a->partition.n; i++)
if (strcmp (a->partition.strs[i], "") == 0)
return 0;
*realname = "";
return 1;
}
else
{
unsigned i, j;
int maybe_yes = 0;
for (i = 0; i < a->partition.n; i++)
for (j = 0; j < b->partition.n; j++)
{
if (partition_patmatch_p (a->partition.strs[i], b->partition.strs[j]))
{
if (!is_wildcard_partition (a->partition.strs[i]))
return 0;
else
{
*realname = b->partition.strs[j];
maybe_yes = 1;
}
}
}
return maybe_yes;
}
}
static int ddsi_duration_is_lt (nn_duration_t a0, nn_duration_t b0) static int ddsi_duration_is_lt (nn_duration_t a0, nn_duration_t b0)
{ {
/* inf counts as <= inf */ /* inf counts as <= inf */

View file

@ -19,6 +19,7 @@
#include "dds/ddsrt/md5.h" #include "dds/ddsrt/md5.h"
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/string.h" #include "dds/ddsrt/string.h"
#include "dds/ddsrt/static_assert.h"
#include "dds/ddsrt/avl.h" #include "dds/ddsrt/avl.h"
#include "dds__stream.h" #include "dds__stream.h"
@ -46,7 +47,6 @@
#include "dds/ddsi/q_transmit.h" #include "dds/ddsi/q_transmit.h"
#include "dds/ddsi/q_globals.h" #include "dds/ddsi/q_globals.h"
#include "dds/ddsi/q_static_assert.h"
#include "dds/ddsi/q_init.h" #include "dds/ddsi/q_init.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/ddsi_mcgroup.h" #include "dds/ddsi/ddsi_mcgroup.h"
@ -1613,7 +1613,7 @@ static int handle_one_gap (struct proxy_writer *pwr, struct pwr_rd_match *wn, se
anything useful, or there was insufficient memory to store it. anything useful, or there was insufficient memory to store it.
When the result is either ACCEPT or a sample chain, it clearly When the result is either ACCEPT or a sample chain, it clearly
meant something. */ meant something. */
Q_STATIC_ASSERT_CODE (NN_REORDER_ACCEPT == 0); DDSRT_STATIC_ASSERT_CODE (NN_REORDER_ACCEPT == 0);
if (res >= 0) if (res >= 0)
gap_was_valuable = 1; gap_was_valuable = 1;
@ -1877,7 +1877,7 @@ unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr)
case SMID_DATA_FRAG: case SMID_DATA_FRAG:
{ {
unsigned char common = smhdr->flags & DATA_FLAG_INLINE_QOS; unsigned char common = smhdr->flags & DATA_FLAG_INLINE_QOS;
Q_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS); DDSRT_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS);
if (smhdr->flags & DATAFRAG_FLAG_KEYFLAG) if (smhdr->flags & DATAFRAG_FLAG_KEYFLAG)
return common | DATA_FLAG_KEYFLAG; return common | DATA_FLAG_KEYFLAG;
else else

View file

@ -89,15 +89,15 @@ void thread_states_init (unsigned maxthreads)
thread_states.ts = thread_states.ts =
ddsrt_malloc_aligned_cacheline (maxthreads * sizeof (*thread_states.ts)); ddsrt_malloc_aligned_cacheline (maxthreads * sizeof (*thread_states.ts));
memset (thread_states.ts, 0, maxthreads * sizeof (*thread_states.ts)); memset (thread_states.ts, 0, maxthreads * sizeof (*thread_states.ts));
/* The compiler doesn't realize that ts is large enough. */ /* The compiler doesn't realize that ts is large enough. */
DDSRT_WARNING_MSVC_OFF(6386); DDSRT_WARNING_MSVC_OFF(6386);
for (i = 0; i < thread_states.nthreads; i++) for (i = 0; i < thread_states.nthreads; i++)
{ {
thread_states.ts[i].state = THREAD_STATE_ZERO; thread_states.ts[i].state = THREAD_STATE_ZERO;
thread_states.ts[i].vtime = 0u; thread_states.ts[i].vtime = 0u;
thread_states.ts[i].name = NULL; thread_states.ts[i].name = NULL;
} }
DDSRT_WARNING_MSVC_ON(6386); DDSRT_WARNING_MSVC_ON(6386);
} }
void thread_states_fini (void) void thread_states_fini (void)

View file

@ -14,6 +14,7 @@
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/static_assert.h"
#include "dds/ddsrt/avl.h" #include "dds/ddsrt/avl.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
@ -30,7 +31,6 @@
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_unused.h" #include "dds/ddsi/q_unused.h"
#include "dds/ddsi/q_hbcontrol.h" #include "dds/ddsi/q_hbcontrol.h"
#include "dds/ddsi/q_static_assert.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_serdata.h"
#include "dds/ddsi/ddsi_sertopic.h" #include "dds/ddsi/ddsi_sertopic.h"
@ -598,7 +598,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
if (xmsg_kind == NN_XMSG_KIND_DATA_REXMIT) if (xmsg_kind == NN_XMSG_KIND_DATA_REXMIT)
nn_xmsg_set_data_readerId (*pmsg, &ddcmn->readerId); nn_xmsg_set_data_readerId (*pmsg, &ddcmn->readerId);
Q_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS); DDSRT_STATIC_ASSERT_CODE (DATA_FLAG_INLINE_QOS == DATAFRAG_FLAG_INLINE_QOS);
assert (!(ddcmn->smhdr.flags & DATAFRAG_FLAG_INLINE_QOS)); assert (!(ddcmn->smhdr.flags & DATAFRAG_FLAG_INLINE_QOS));
if (fragnum == 0) if (fragnum == 0)

View file

@ -111,7 +111,9 @@ list(APPEND headers
"${include_path}/dds/ddsrt/process.h" "${include_path}/dds/ddsrt/process.h"
"${include_path}/dds/ddsrt/strtod.h" "${include_path}/dds/ddsrt/strtod.h"
"${include_path}/dds/ddsrt/strtol.h" "${include_path}/dds/ddsrt/strtol.h"
"${include_path}/dds/ddsrt/types.h") "${include_path}/dds/ddsrt/types.h"
"${include_path}/dds/ddsrt/countargs.h"
"${include_path}/dds/ddsrt/static_assert.h")
list(APPEND sources list(APPEND sources
"${source_path}/io.c" "${source_path}/io.c"

View file

@ -157,46 +157,46 @@ inline void *ddsrt_atomic_addvoidp_nv (volatile ddsrt_atomic_voidp_t *x, ptrdiff
inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { inline void ddsrt_atomic_sub32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */ /* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146) DDSRT_WARNING_MSVC_OFF(4146)
InterlockedExchangeAdd (&x->v, -v); InterlockedExchangeAdd (&x->v, -v);
DDSRT_WARNING_MSVC_ON(4146) DDSRT_WARNING_MSVC_ON(4146)
} }
#if DDSRT_HAVE_ATOMIC64 #if DDSRT_HAVE_ATOMIC64
inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) { inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */ /* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146) DDSRT_WARNING_MSVC_OFF(4146)
InterlockedExchangeAdd64 (&x->v, -v); InterlockedExchangeAdd64 (&x->v, -v);
DDSRT_WARNING_MSVC_ON(4146) DDSRT_WARNING_MSVC_ON(4146)
} }
#endif #endif
inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */ /* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146) DDSRT_WARNING_MSVC_OFF(4146)
DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v); DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v);
DDSRT_WARNING_MSVC_ON(4146) DDSRT_WARNING_MSVC_ON(4146)
} }
inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) {
ddsrt_atomic_subptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v); ddsrt_atomic_subptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v);
} }
inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */ /* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146) DDSRT_WARNING_MSVC_OFF(4146)
return InterlockedExchangeAdd (&x->v, -v) - v; return InterlockedExchangeAdd (&x->v, -v) - v;
DDSRT_WARNING_MSVC_ON(4146) DDSRT_WARNING_MSVC_ON(4146)
} }
#if DDSRT_HAVE_ATOMIC64 #if DDSRT_HAVE_ATOMIC64
inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) { inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */ /* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146) DDSRT_WARNING_MSVC_OFF(4146)
return InterlockedExchangeAdd64 (&x->v, -v) - v; return InterlockedExchangeAdd64 (&x->v, -v) - v;
DDSRT_WARNING_MSVC_ON(4146) DDSRT_WARNING_MSVC_ON(4146)
} }
#endif #endif
inline uintptr_t ddsrt_atomic_subptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { inline uintptr_t ddsrt_atomic_subptr_nv (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) {
/* disable unary minus applied to unsigned type, result still unsigned */ /* disable unary minus applied to unsigned type, result still unsigned */
DDSRT_WARNING_MSVC_OFF(4146) DDSRT_WARNING_MSVC_OFF(4146)
return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v) - v; return DDSRT_ATOMIC_PTROP (InterlockedExchangeAdd) (&x->v, -v) - v;
DDSRT_WARNING_MSVC_ON(4146) DDSRT_WARNING_MSVC_ON(4146)
} }
inline void *ddsrt_atomic_subvoidp_nv (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { inline void *ddsrt_atomic_subvoidp_nv (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) {
return (void *) ddsrt_atomic_subptr_nv ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v); return (void *) ddsrt_atomic_subptr_nv ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v);
@ -280,10 +280,10 @@ inline void ddsrt_atomic_fence (void) {
/* 28113: accessing a local variable tmp via an Interlocked /* 28113: accessing a local variable tmp via an Interlocked
function: This is an unusual usage which could be reconsidered. function: This is an unusual usage which could be reconsidered.
It is too heavyweight, true, but it does the trick. */ It is too heavyweight, true, but it does the trick. */
DDSRT_WARNING_MSVC_OFF(28113) DDSRT_WARNING_MSVC_OFF(28113)
volatile LONG tmp = 0; volatile LONG tmp = 0;
InterlockedExchange (&tmp, 0); InterlockedExchange (&tmp, 0);
DDSRT_WARNING_MSVC_ON(28113) DDSRT_WARNING_MSVC_ON(28113)
} }
inline void ddsrt_atomic_fence_ldld (void) { inline void ddsrt_atomic_fence_ldld (void) {
#if !(defined _M_IX86 || defined _M_X64) #if !(defined _M_IX86 || defined _M_X64)

View 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

View file

@ -24,11 +24,7 @@ extern "C" {
* @brief Get value for environment variable. * @brief Get value for environment variable.
* *
* @param[in] name Environment variable name. * @param[in] name Environment variable name.
* @param[in] buf Buffer to write value to. * @param[out] value Alias to value of environment variable - must not be modified
* @param[in] sz Size of buffer.
* @param[out] reqsz Number of bytes written (excluding the terminating null
* byte), or would have been written would @buf have been
* sufficiently large enough.
* *
* @returns A dds_return_t indicating success or failure. * @returns A dds_return_t indicating success or failure.
* *

View file

@ -106,7 +106,7 @@ ddsrt_proc_create(
* See ddsrt_proc_waitpids() for waiting on all child processes. * See ddsrt_proc_waitpids() for waiting on all child processes.
* *
* @param[in] pid Process ID (PID) to get the exit code from. * @param[in] pid Process ID (PID) to get the exit code from.
* @param[in] timemout Time within the process is expected to finish. * @param[in] timeout Time within the process is expected to finish.
* @param[out] code The exit code of the process. * @param[out] code The exit code of the process.
* *
* @returns A dds_return_t indicating success or failure. * @returns A dds_return_t indicating success or failure.
@ -145,7 +145,7 @@ ddsrt_proc_waitpid(
* *
* See ddsrt_proc_waitpid() for waiting on a specific child process. * See ddsrt_proc_waitpid() for waiting on a specific child process.
* *
* @param[in] timemout Time within a process is expected to finish. * @param[in] timeout Time within a process is expected to finish.
* @param[out] pid Process ID (PID) of the finished process. * @param[out] pid Process ID (PID) of the finished process.
* @param[out] code The exit code of the process. * @param[out] code The exit code of the process.
* *

View file

@ -84,7 +84,7 @@ typedef int32_t dds_return_t;
/** /**
* @brief Takes the error value and outputs a string corresponding to it. * @brief Takes the error value and outputs a string corresponding to it.
* *
* @param[in] err Error value to be converted to a string * @param[in] ret Error value to be converted to a string
* *
* @returns String corresponding to the error value * @returns String corresponding to the error value
*/ */

View file

@ -247,7 +247,7 @@ typedef struct {
* *
* @param[in] name Host name to resolve. * @param[in] name Host name to resolve.
* @param[in] af Address family, either AF_INET, AF_INET6 or AF_UNSPEC. * @param[in] af Address family, either AF_INET, AF_INET6 or AF_UNSPEC.
* @param[out] hent Structure of type ddsrt_hostent_t. * @param[out] hentp Structure of type ddsrt_hostent_t.
* *
* @returns A dds_return_t indicating success or failure. * @returns A dds_return_t indicating success or failure.
* *

View file

@ -1,5 +1,5 @@
/* /*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others * Copyright(c) 2019 ADLINK Technology Limited and others
* *
* This program and the accompanying materials are made available under the * This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at * terms of the Eclipse Public License v. 2.0 which is available at
@ -9,29 +9,34 @@
* *
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/ */
#ifndef Q_STATIC_ASSERT_H #ifndef DDSRT_STATIC_ASSERT_H
#define Q_STATIC_ASSERT_H #define DDSRT_STATIC_ASSERT_H
/* There are many tricks to use a constant expression to yield an /* There are many tricks to use a constant expression to yield an
illegal type or expression at compile time, such as zero-sized illegal type or expression at compile time, such as zero-sized
arrays and duplicate case or enum labels. So this is but one of the arrays and duplicate case or enum labels. So this is but one of the
many tricks. */ many tricks. */
#define DDSRT_STATIC_ASSERT2(line, pred) \
struct static_assert_##line { \
char cond[(pred) ? 1 : -1]; \
}
#define DDSRT_STATIC_ASSERT1(line, pred) \
DDSRT_STATIC_ASSERT2 (line, pred)
#define DDSRT_STATIC_ASSERT(pred) \
DDSRT_STATIC_ASSERT1 (__LINE__, pred)
#ifndef _MSC_VER #ifndef _MSC_VER
#define DDSRT_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case (pred): ; } } while (0)
#define Q_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case pred: ; } } while (0)
#else #else
/* Temporarily disabling warning C6326: Potential comparison of a /* Temporarily disabling warning C6326: Potential comparison of a
constant with another constant. */ constant with another constant. */
#define Q_STATIC_ASSERT_CODE(pred) do { \ #define DDSRT_STATIC_ASSERT_CODE(pred) do { \
__pragma (warning (push)) \ __pragma (warning (push)) \
__pragma (warning (disable : 6326)) \ __pragma (warning (disable : 6326)) \
switch(0) { case 0: case pred: ; } \ switch(0) { case 0: case (pred): ; } \
__pragma (warning (pop)) \ __pragma (warning (pop)) \
} while (0) } while (0)
#endif #endif
#endif /* Q_STATIC_ASSERT_H */ #endif

View file

@ -57,7 +57,7 @@ ddsrt_nonnull((1,2));
* *
* @param[in] str String to split into tokens. * @param[in] str String to split into tokens.
* @param[in] delim Characters that delimit a token. * @param[in] delim Characters that delimit a token.
* @param[inout] saveptr Pointer to a char * used internally. * @param[in,out] saveptr Pointer to a char * used internally.
* *
* @returns The next token or NULL if there are no more tokens. * @returns The next token or NULL if there are no more tokens.
*/ */
@ -74,7 +74,7 @@ ddsrt_strtok_r(
* @delim. The delimiter is overwritten with a null byte, terminating the * @delim. The delimiter is overwritten with a null byte, terminating the
* token and @stringp is updated to point past the delimiter. * token and @stringp is updated to point past the delimiter.
* *
* @param[inout] stringp String to extract token from. * @param[in,out] stringp String to extract token from.
* @param[in] delim Characters that delimit a token. * @param[in] delim Characters that delimit a token.
* *
* @returns The original value of @stringp. * @returns The original value of @stringp.
@ -153,7 +153,7 @@ ddsrt_nonnull((1,2));
* string is truncated if there is not enough space. The resulting string * string is truncated if there is not enough space. The resulting string
* guaranteed to be null terminated if there is space. * guaranteed to be null terminated if there is space.
* *
* @param[inout] dest Destination buffer. * @param[in,out] dest Destination buffer.
* @param[in] src Null terminated string to append to dest. * @param[in] src Null terminated string to append to dest.
* @param[in] size Number of bytes available in dest. * @param[in] size Number of bytes available in dest.
* *

View file

@ -61,6 +61,7 @@
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/time.h" #include "dds/ddsrt/time.h"
#include "dds/ddsrt/process.h" #include "dds/ddsrt/process.h"
#include "dds/ddsrt/static_assert.h"
#define N DDSRT_MT19937_N #define N DDSRT_MT19937_N
#define M 397 #define M 397
@ -186,9 +187,7 @@ void ddsrt_random_init (void)
if (!ddsrt_prng_makeseed (&seed)) if (!ddsrt_prng_makeseed (&seed))
{ {
/* Poor man's initialisation */ /* Poor man's initialisation */
struct lengthof_seed_large_enough { DDSRT_STATIC_ASSERT (sizeof (seed.key) / sizeof (seed.key[0]) >= 3);
char ok[sizeof (seed.key) / sizeof (seed.key[0]) >= 3 ? 1 : -1];
};
memset (&seed, 0, sizeof (seed)); memset (&seed, 0, sizeof (seed));
dds_time_t now = dds_time (); dds_time_t now = dds_time ();
seed.key[0] = (uint32_t) ddsrt_getpid (); seed.key[0] = (uint32_t) ddsrt_getpid ();

View file

@ -305,9 +305,9 @@ static char *unescape_into_utf8 (char *dst, unsigned cp)
return dst; return dst;
} }
DDSRT_WARNING_MSVC_OFF(4996);
static int unescape_insitu (char *buffer, size_t *n) static int unescape_insitu (char *buffer, size_t *n)
{ {
DDSRT_WARNING_MSVC_OFF(4996);
const char *src = buffer; const char *src = buffer;
char const * const srcend = buffer + *n; char const * const srcend = buffer + *n;
char *dst = buffer; char *dst = buffer;
@ -361,8 +361,8 @@ static int unescape_insitu (char *buffer, size_t *n)
} }
*n = (size_t) (dst - buffer); *n = (size_t) (dst - buffer);
return 0; return 0;
DDSRT_WARNING_MSVC_ON(4996);
} }
DDSRT_WARNING_MSVC_ON(4996);
static void discard_payload (struct ddsrt_xmlp_state *st) static void discard_payload (struct ddsrt_xmlp_state *st)
{ {