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_VALUE YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DOCUMENTATION_COMMENTS YES)
endif()
# Make it easy to enable one of Clang's/gcc's analyzers, and default to using

View file

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

View file

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

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.
*
* @param[in,out] dst - Pointer to the destination qos structure
* @param[in] src - Pointer to the source qos structure
* @param[in,out] a - Pointer to the destination qos structure
* @param[in] b - Pointer to the source qos structure
*/
DDS_EXPORT bool
dds_qos_equal (const dds_qos_t * __restrict a, const dds_qos_t * __restrict b);
@ -448,7 +448,7 @@ dds_qset_destination_order (
* @brief Set the writer data-lifecycle policy of a qos structure
*
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
* @param[in] autodispose_unregistered_instances - Automatic disposal of unregistered instances
* @param[in] autodispose - Automatic disposal of unregistered instances
*/
DDS_EXPORT void
dds_qset_writer_data_lifecycle (dds_qos_t * __restrict qos, bool autodispose);
@ -738,7 +738,7 @@ dds_qget_destination_order (
* @brief Get the writer data-lifecycle qos policy
*
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
* @param[in,out] autodispose_unregistered_instances - Pointer that will store the autodispose unregistered instances enable value
* @param[in,out] autodispose - Pointer that will store the autodispose unregistered instances enable value
*
* @returns - false iff any of the arguments is invalid or the qos is not present in the qos object
*/

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__create_subscriber_l(
struct dds_entity *participant, /* entity-lock must be held */
struct dds_participant *participant, /* entity-lock must be held */
const dds_qos_t *qos,
const dds_listener_t *listener);

View file

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

View file

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

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_entity_t sub = dds__create_subscriber_l (participant, qos, NULL);
@ -153,7 +153,7 @@ dds_entity_t dds__get_builtin_subscriber (dds_entity_t e)
return ret;
if (p->m_builtin_subscriber <= 0) {
p->m_builtin_subscriber = dds__create_builtin_subscriber (&p->m_entity);
p->m_builtin_subscriber = dds__create_builtin_subscriber (p);
}
sub = p->m_builtin_subscriber;
dds_participant_unlock(p);

View file

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

View file

@ -12,18 +12,15 @@
#include "dds__domain.h"
#include "dds/ddsi/ddsi_tkmap.h"
static int dds_domain_compare (const int32_t * a, const int32_t * b)
static int dds_domain_compare (const void *va, const void *vb)
{
const int32_t *a = va;
const int32_t *b = vb;
return (*a == *b) ? 0 : (*a < *b) ? -1 : 1;
}
const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALIZER
(
offsetof (dds_domain, m_node),
offsetof (dds_domain, m_id),
(int (*) (const void *, const void *)) dds_domain_compare,
0
);
const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALIZER (
offsetof (dds_domain, m_node), offsetof (dds_domain, m_id), dds_domain_compare, 0);
dds_domain *dds_domain_find_locked (dds_domainid_t id)
{

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

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)
{
dds_entity_unlock (entity);
DDS_ERROR ("Given entity is not a reader\n");
return DDS_RETCODE_ILLEGAL_OPERATION;
}
else if (dds_entity_kind (entity) != DDS_KIND_COND_READ && dds_entity_kind (entity) != DDS_KIND_COND_QUERY)
{
dds_entity_unlock (entity);
DDS_ERROR ("Given entity is a reader nor a condition\n");
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)
{
dds_entity_unlock (entity);
DDS_ERROR ("Failed to lock condition's reader\n");
return rc;
}
else
@ -75,18 +72,7 @@ static void dds_read_unlock (dds_reader *reader, dds_readcond *condition)
has been locked. This is used to support C++ API reading length unlimited
which is interpreted as "all relevant samples in cache".
*/
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)
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)
{
struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret = DDS_RETCODE_OK;
@ -97,63 +83,46 @@ dds_read_impl(
#define NC_FREE_BUF 2u
#define NC_RESET_BUF 4u
if (buf == NULL) {
DDS_ERROR("The provided buffer is NULL\n");
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;
}
if (buf == NULL || si == NULL || maxs == 0 || bufsz == 0 || bufsz < maxs)
return DDS_RETCODE_BAD_PARAMETER;
thread_state_awake (ts1);
ret = dds_read_lock(reader_or_condition, &rd, &cond, only_reader);
if (ret != DDS_RETCODE_OK) {
if ((ret = dds_read_lock (reader_or_condition, &rd, &cond, only_reader)) != DDS_RETCODE_OK)
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");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
dds_read_unlock(rd, cond);
goto fail_awake;
goto fail_awake_lock;
}
}
/* 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 */
if (rd->m_loan_out) {
if (rd->m_loan_out)
{
ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs);
nodata_cleanups = NC_FREE_BUF | NC_RESET_BUF;
} else {
if (rd->m_loan) {
if (rd->m_loan_size < maxs) {
}
else
{
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);
rd->m_loan = buf[0];
rd->m_loan_size = maxs;
nodata_cleanups = NC_RESET_BUF;
} else {
buf[0] = rd->m_loan;
}
nodata_cleanups = NC_RESET_BUF;
}
} else {
else
{
ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs);
rd->m_loan = buf[0];
rd->m_loan_size = maxs;
@ -168,49 +137,43 @@ dds_read_impl(
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
dds_entity_status_reset (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
/* 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);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
if (take) {
ret = (dds_return_t) dds_rhc_take (rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
} else {
ret = (dds_return_t) dds_rhc_read (rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
}
if (take)
ret = dds_rhc_take (rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
else
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
exception of holding on to a buffer we just allocated and that is pointed to by
rd->m_loan */
if (ret <= 0 && nodata_cleanups) {
if (nodata_cleanups & NC_CLEAR_LOAN_OUT) {
if (ret <= 0 && nodata_cleanups)
{
if (nodata_cleanups & NC_CLEAR_LOAN_OUT)
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);
}
if (nodata_cleanups & NC_RESET_BUF) {
if (nodata_cleanups & NC_RESET_BUF)
buf[0] = NULL;
}
}
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:
thread_state_asleep (ts1);
fail:
return ret;
}
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)
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)
{
struct thread_state1 * const ts1 = lookup_thread_state ();
dds_return_t ret = DDS_RETCODE_OK;
@ -225,227 +188,143 @@ dds_readcdr_impl(
(void)take;
thread_state_awake (ts1);
ret = dds_read_lock(reader_or_condition, &rd, &cond, false);
if (ret == DDS_RETCODE_OK) {
if ((ret = dds_read_lock (reader_or_condition, &rd, &cond, false)) == DDS_RETCODE_OK)
{
/* 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 */
ddsrt_mutex_lock (&rd->m_entity.m_observers_lock);
dds_entity_status_reset (&rd->m_entity, DDS_DATA_AVAILABLE_STATUS);
/* 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);
}
ddsrt_mutex_unlock (&rd->m_entity.m_observers_lock);
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
);
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);
}
thread_state_asleep (ts1);
return ret;
}
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_return_t dds_read (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs, so use bufsz instead.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
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);
}
dds_return_t
dds_read_wl(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
uint32_t maxs)
dds_return_t dds_read_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, uint32_t maxs)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
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_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_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)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs, so use bufsz instead.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = (uint32_t)bufsz;
}
return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
}
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_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)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(false, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
fail:
return ret;
return dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(false, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
fail:
return ret;
return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
}
dds_return_t
dds_read_next(
dds_return_t dds_read_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;
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,
void **buf,
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);
}
dds_return_t
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)
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;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs, so use bufsz instead.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
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);
}
dds_return_t
dds_take_wl(
dds_entity_t rd_or_cnd,
void ** buf,
dds_sample_info_t * si,
uint32_t maxs)
dds_return_t dds_take_wl (dds_entity_t rd_or_cnd, void ** buf, dds_sample_info_t * si, uint32_t maxs)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
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_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_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)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs, so use bufsz instead.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = (uint32_t) bufsz;
}
return dds_read_impl (true, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
}
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_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)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
return dds_read_impl (true, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
}
int
dds_takecdr(
dds_entity_t rd_or_cnd,
struct ddsi_serdata **buf,
uint32_t maxs,
dds_sample_info_t *si,
uint32_t mask)
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)
{
bool lock = true;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
return dds_readcdr_impl (true, rd_or_cnd, buf, maxs, si, mask, DDS_HANDLE_NIL, lock);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
return dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
fail:
return ret;
return dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
fail:
return ret;
return dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
}
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_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_return_t ret = DDS_RETCODE_OK;
bool lock = true;
if (handle == DDS_HANDLE_NIL) {
DDS_ERROR("DDS_HANDLE_NIL was provided\n");
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail;
}
if (maxs == DDS_READ_WITHOUT_LOCK) {
if (handle == DDS_HANDLE_NIL)
return DDS_RETCODE_PRECONDITION_NOT_MET;
if (maxs == DDS_READ_WITHOUT_LOCK)
{
lock = false;
/* Use a more sensible maxs. Just an arbitrarily number.
* CHAM-306 will remove this ugly piece of code. */
/* FIXME: Fix the interface. */
maxs = 100;
}
ret = dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
fail:
return ret;
return dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
}
dds_return_t
dds_take_next(
dds_entity_t reader,
void **buf,
dds_sample_info_t *si)
dds_return_t 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;
return dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
}
dds_return_t
dds_take_next_wl(
dds_entity_t reader,
void **buf,
dds_sample_info_t *si)
dds_return_t 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;
return dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
}
dds_return_t
dds_return_loan(
dds_entity_t reader_or_condition,
void **buf,
int32_t bufsz)
dds_return_t dds_return_loan (dds_entity_t reader_or_condition, void **buf, int32_t bufsz)
{
const struct ddsi_sertopic *st;
dds_reader *rd;
dds_readcond *cond;
dds_return_t ret = DDS_RETCODE_OK;
if (!buf) {
DDS_ERROR("Argument buf is NULL\n");
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
if (*buf == NULL && bufsz > 0) {
ret = DDS_RETCODE_BAD_PARAMETER;
goto fail;
}
if (buf == NULL || (*buf == NULL && bufsz > 0))
return DDS_RETCODE_BAD_PARAMETER;
if ((ret = dds_read_lock(reader_or_condition, &rd, &cond, false)) != DDS_RETCODE_OK)
return ret;
ret = dds_read_lock(reader_or_condition, &rd, &cond, false);
if (ret != DDS_RETCODE_OK) {
goto fail;
}
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);
}
/* 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;
ddsi_sertopic_zero_samples (st, rd->m_loan, rd->m_loan_size);
buf[0] = NULL;
}
dds_read_unlock(rd, cond);
fail:
return ret;
return DDS_RETCODE_OK;
}

View file

@ -18,35 +18,32 @@
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_thread.h"
static dds_return_t
dds_readcond_delete(
dds_entity *e)
static dds_return_t dds_readcond_delete (dds_entity *e) ddsrt_nonnull_all;
static dds_return_t dds_readcond_delete (dds_entity *e)
{
dds_rhc_remove_readcondition ((dds_readcond *) e);
return DDS_RETCODE_OK;
}
dds_readcond*
dds_create_readcond(
dds_reader *rd,
dds_entity_kind_t kind,
uint32_t mask,
dds_querycondition_filter_fn filter)
dds_readcond *dds_create_readcond (dds_reader *rd, dds_entity_kind_t kind, uint32_t mask, dds_querycondition_filter_fn filter)
{
dds_readcond *cond = dds_alloc (sizeof (*cond));
assert ((kind == DDS_KIND_COND_READ && filter == 0) || (kind == DDS_KIND_COND_QUERY && filter != 0));
(void) dds_entity_init(&cond->m_entity, (dds_entity*)rd, kind, NULL, NULL, 0);
(void) dds_entity_init (&cond->m_entity, &rd->m_entity, kind, NULL, NULL, 0);
cond->m_entity.m_deriver.delete = dds_readcond_delete;
cond->m_rhc = rd->m_rd->rhc;
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
cond->m_rd_guid = rd->m_entity.m_guid;
if (kind == DDS_KIND_COND_QUERY) {
if (kind == DDS_KIND_COND_QUERY)
{
cond->m_query.m_filter = filter;
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
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. */
@ -55,29 +52,23 @@ dds_create_readcond(
return cond;
}
dds_entity_t
dds_create_readcondition(
dds_entity_t reader,
uint32_t mask)
dds_entity_t dds_create_readcondition (dds_entity_t reader, uint32_t mask)
{
dds_entity_t hdl;
dds_reader *rd;
dds_return_t rc;
rc = dds_reader_lock(reader, &rd);
if (rc == DDS_RETCODE_OK) {
if ((rc = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK)
return rc;
else
{
dds_entity_t hdl;
dds_readcond *cond = dds_create_readcond(rd, DDS_KIND_COND_READ, mask, 0);
assert (cond);
assert (cond->m_entity.m_deriver.delete);
hdl = cond->m_entity.m_hdllink.hdl;
dds_reader_unlock (rd);
} else {
DDS_ERROR("Error occurred on locking reader\n");
hdl = rc;
}
return hdl;
}
}
dds_entity_t dds_get_datareader (dds_entity_t condition)
{

View file

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

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)
{
struct check {
char x[(DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4) ? 1 : -1];
};
DDSRT_STATIC_ASSERT (DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4);
assert (type == DDS_OP_VAL_1BY || type == DDS_OP_VAL_2BY || type == DDS_OP_VAL_4BY || type == DDS_OP_VAL_8BY);
return (uint32_t)1 << ((uint32_t) type - 1);
}

View file

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

View file

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

View file

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

View file

@ -35,7 +35,7 @@ struct whc_node {
struct whc_node *next_seq; /* next in this interval */
struct whc_node *prev_seq; /* prev in this interval */
struct whc_idxnode *idxnode; /* NULL if not in index */
unsigned idxnode_pos; /* index in idxnode.hist */
uint32_t idxnode_pos; /* index in idxnode.hist */
seqno_t seq;
uint64_t total_bytes; /* cumulative number of bytes up to and including this node */
size_t size;
@ -43,7 +43,7 @@ struct whc_node {
unsigned unacked: 1; /* counted in whc::unacked_bytes iff 1 */
unsigned borrowed: 1; /* at most one can borrow it at any time */
nn_mtime_t last_rexmit_ts;
unsigned rexmit_count;
uint32_t rexmit_count;
struct ddsi_serdata *serdata;
};
@ -59,7 +59,7 @@ struct whc_idxnode {
uint64_t iid;
seqno_t prune_seq;
struct ddsi_tkmap_instance *tk;
unsigned headidx;
uint32_t headidx;
#if __STDC_VERSION__ >= 199901L
struct whc_node *hist[];
#else
@ -77,14 +77,14 @@ struct whc_seq_entry {
struct whc_impl {
struct whc common;
ddsrt_mutex_t lock;
unsigned seq_size;
uint32_t seq_size;
size_t unacked_bytes;
size_t sample_overhead;
uint64_t total_bytes; /* total number of bytes pushed in */
unsigned is_transient_local: 1;
unsigned hdepth; /* 0 = unlimited */
unsigned tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
unsigned idxdepth; /* = max(hdepth, tldepth) */
uint32_t hdepth; /* 0 = unlimited */
uint32_t tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
uint32_t idxdepth; /* = max (hdepth, tldepth) */
seqno_t max_drop_seq; /* samples in whc with seq <= max_drop_seq => transient-local */
struct whc_intvnode *open_intv; /* interval where next sample will go (usually) */
struct whc_node *maxseq_node; /* NULL if empty; if not in open_intv, open_intv is empty */
@ -103,9 +103,7 @@ struct whc_sample_iter_impl {
};
/* check that our definition of whc_sample_iter fits in the type that callers allocate */
struct whc_sample_iter_sizecheck {
char fits_in_generic_type[sizeof(struct whc_sample_iter_impl) <= sizeof(struct whc_sample_iter) ? 1 : -1];
};
DDSRT_STATIC_ASSERT (sizeof (struct whc_sample_iter_impl) <= sizeof (struct whc_sample_iter));
/* Hash + interval tree adminitration of samples-by-sequence number
* - by definition contains all samples in WHC (unchanged from older versions)
@ -126,8 +124,8 @@ static int compare_seq (const void *va, const void *vb);
static void free_deferred_free_list (struct whc_node *deferred_free_list);
static void get_state_locked (const struct whc_impl *whc, struct whc_state *st);
static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list);
static unsigned whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list);
static uint32_t whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);
static void whc_default_get_state (const struct whc *whc, struct whc_state *st);
static 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);
@ -135,7 +133,7 @@ static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq);
static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample);
static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample);
static void whc_default_return_sample (struct whc *whc, struct whc_borrowed_sample *sample, bool update_retransmit_info);
static unsigned whc_default_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
static uint32_t whc_default_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
static void whc_default_sample_iter_init (const struct whc *whc, struct whc_sample_iter *opaque_it);
static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, struct whc_borrowed_sample *sample);
static void whc_default_free (struct whc *whc);
@ -177,7 +175,7 @@ static uint32_t whc_seq_entry_hash (const void *vn)
samples in between there won't be significant correlation */
const uint64_t c = UINT64_C (16292676669999574021);
const uint32_t x = (uint32_t) n->seq;
return (unsigned) ((x * c) >> 32);
return (uint32_t) ((x * c) >> 32);
}
static int whc_seq_entry_eq (const void *va, const void *vb)
@ -194,7 +192,7 @@ static uint32_t whc_node_hash (const void *vn)
samples in between there won't be significant correlation */
const uint64_t c = UINT64_C (16292676669999574021);
const uint32_t x = (uint32_t) n->seq;
return (unsigned) ((x * c) >> 32);
return (uint32_t) ((x * c) >> 32);
}
static int whc_node_eq (const void *va, const void *vb)
@ -349,7 +347,7 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
}
}
struct whc *whc_new (int is_transient_local, unsigned hdepth, unsigned tldepth)
struct whc *whc_new (int is_transient_local, uint32_t hdepth, uint32_t tldepth)
{
size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */
struct whc_impl *whc;
@ -551,8 +549,7 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w
else
{
#ifndef NDEBUG
unsigned i;
for (i = 0; i < whc->idxdepth; i++)
for (uint32_t i = 0; i < whc->idxdepth; i++)
assert (i == idxn->headidx || idxn->hist[i] == NULL);
#endif
if (!ddsrt_hh_remove (whc->idx_hash, idxn))
@ -565,8 +562,7 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w
static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_idxnode *idxn)
{
unsigned i;
for (i = 0; i < whc->idxdepth; i++)
for (uint32_t i = 0; i < whc->idxdepth; i++)
{
if (idxn->hist[i])
{
@ -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);
}
static int whcn_in_tlidx (const struct whc_impl *whc, const struct whc_idxnode *idxn, unsigned pos)
static int whcn_in_tlidx (const struct whc_impl *whc, const struct whc_idxnode *idxn, uint32_t pos)
{
if (idxn == NULL)
return 0;
else
{
unsigned d = (idxn->headidx + (pos > idxn->headidx ? whc->idxdepth : 0)) - pos;
uint32_t d = (idxn->headidx + (pos > idxn->headidx ? whc->idxdepth : 0)) - pos;
assert (d < whc->idxdepth);
return d < whc->tldepth;
}
}
static unsigned whc_default_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st)
static uint32_t whc_default_downgrade_to_volatile (struct whc *whc_generic, struct whc_state *st)
{
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
seqno_t old_max_drop_seq;
struct whc_node *deferred_free_list;
unsigned cnt;
uint32_t cnt;
/* We only remove them from whc->tlidx: we don't remove them from
whc->seq yet. That'll happen eventually. */
@ -801,11 +797,11 @@ static void whc_default_free_deferred_free_list (struct whc *whc_generic, struct
free_deferred_free_list (deferred_free_list);
}
static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
static uint32_t whc_default_remove_acked_messages_noidx (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
{
struct whc_intvnode *intv;
struct whc_node *whcn;
unsigned ndropped = 0;
uint32_t ndropped = 0;
/* In the trivial case of an empty WHC, get out quickly */
if (max_drop_seq <= whc->max_drop_seq || whc->maxseq_node == NULL)
@ -847,7 +843,7 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
}
*deferred_free_list = intv->first;
ndropped = (unsigned) (whcn->seq - intv->min + 1);
ndropped = (uint32_t) (whcn->seq - intv->min + 1);
intv->first = whcn->next_seq;
intv->min = max_drop_seq + 1;
@ -877,13 +873,13 @@ static unsigned whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
return ndropped;
}
static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, seqno_t max_drop_seq, struct whc_node **deferred_free_list)
{
struct whc_intvnode *intv;
struct whc_node *whcn;
struct whc_node *prev_seq;
struct whc_node deferred_list_head, *last_to_free = &deferred_list_head;
unsigned ndropped = 0;
uint32_t ndropped = 0;
if (whc->is_transient_local && whc->tldepth == 0)
{
@ -943,7 +939,7 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
if (whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
{
assert (whc->hdepth == whc->idxdepth);
DDS_LOG(DDS_LC_WHC, " idxdepth %u > tldepth %u > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
DDS_LOG (DDS_LC_WHC, " idxdepth %"PRIu32" > tldepth %"PRIu32" > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
/* Do a second pass over the sequence number range we just processed: this time we only
encounter samples that were retained because of the transient-local durability setting
@ -952,7 +948,7 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
while (whcn && whcn->seq <= max_drop_seq)
{
struct whc_idxnode * const idxn = whcn->idxnode;
unsigned cnt, idx;
uint32_t cnt, idx;
DDS_LOG (DDS_LC_WHC, " whcn %p %"PRId64" idxn %p prune_seq %"PRId64":", (void *) whcn, whcn->seq, (void *) idxn, idxn->prune_seq);
@ -1011,10 +1007,10 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se
return ndropped;
}
static unsigned whc_default_remove_acked_messages (struct whc *whc_generic, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list)
static uint32_t whc_default_remove_acked_messages (struct whc *whc_generic, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list)
{
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
unsigned cnt;
uint32_t cnt;
ddsrt_mutex_lock (&whc->lock);
assert (max_drop_seq < MAX_SEQ_NUMBER);
@ -1025,7 +1021,7 @@ static unsigned whc_default_remove_acked_messages (struct whc *whc_generic, seqn
struct whc_state tmp;
get_state_locked (whc, &tmp);
DDS_LOG (DDS_LC_WHC, "whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq);
DDS_LOG(DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n",
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);
}
@ -1118,8 +1114,9 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
{
struct whc_state whcst;
get_state_locked (whc, &whcst);
DDS_LOG(DDS_LC_WHC, "whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n", (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash);
DDS_LOG(DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %u tl %u\n",
DDS_LOG (DDS_LC_WHC, "whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n",
(void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash);
DDS_LOG (DDS_LC_WHC, " whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
}
@ -1188,7 +1185,7 @@ 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). */
if (seq <= max_drop_seq && whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
{
unsigned pos = idxn->headidx + whc->idxdepth - whc->tldepth;
uint32_t pos = idxn->headidx + whc->idxdepth - whc->tldepth;
if (pos >= whc->idxdepth)
pos -= whc->idxdepth;
if ((oldn = idxn->hist[pos]) != NULL)
@ -1207,7 +1204,6 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
/* Ignore unregisters, but insert everything else */
if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER))
{
unsigned i;
idxn = ddsrt_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0]));
DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
ddsi_tkmap_instance_ref (tk);
@ -1216,7 +1212,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
idxn->prune_seq = 0;
idxn->headidx = 0;
idxn->hist[0] = newn;
for (i = 1; i < whc->idxdepth; i++)
for (uint32_t i = 1; i < whc->idxdepth; i++)
idxn->hist[i] = NULL;
newn->idxnode = idxn;
newn->idxnode_pos = 0;
@ -1293,7 +1289,8 @@ static void return_sample_locked (struct whc_impl *whc, struct whc_borrowed_samp
{
/* data no longer present in WHC - that means ownership for serdata, plist shifted to the borrowed copy and "returning" it really becomes "destroying" it */
ddsi_serdata_unref (sample->serdata);
if (sample->plist) {
if (sample->plist)
{
nn_plist_fini (sample->plist);
ddsrt_free (sample->plist);
}

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

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));
while (i < 6 && *str != 0)
{
int o, p;
if (sscanf (str, "%x%n", &o, &p) != 1 || o < 0 || o > 255)
unsigned o;
int p;
if (sscanf (str, "%x%n", &o, &p) != 1 || o > 255)
return AFSR_INVALID;
loc->address[10 + i++] = (unsigned char) o;
str += p;

View file

@ -127,12 +127,12 @@ static int add_addresses_to_addrset_1 (struct addrset *as, const char *ip, int p
return 0;
}
DDSRT_WARNING_MSVC_OFF(4996);
int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc)
{
/* port_mode: -1 => take from string, if 0 & unicast, add for a range of participant indices;
port_mode >= 0 => always set port to port_mode
*/
DDSRT_WARNING_MSVC_OFF(4996);
char *addrs_copy, *ip, *cursor, *a;
int retval = -1;
addrs_copy = ddsrt_strdup (addrs);
@ -179,8 +179,8 @@ int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mo
ddsrt_free (ip);
ddsrt_free (addrs_copy);
return retval;
}
DDSRT_WARNING_MSVC_ON(4996);
}
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);
}
DDSRT_WARNING_MSVC_OFF(4996);
static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *value, const struct unit *unittab, int64_t def_mult, int64_t min, int64_t max)
{
DDSRT_WARNING_MSVC_OFF(4996);
int pos;
double v_dbl;
int64_t v_int;
@ -1364,8 +1364,8 @@ static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *valu
*elem = 0; /* some static analyzers don't "get it" */
return cfg_error (cfgst, "%s: invalid value", value);
}
}
DDSRT_WARNING_MSVC_ON(4996);
}
static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources, const struct unit *unittab, const char *zero_unit)
{
@ -1393,10 +1393,8 @@ static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources,
}
#define GENERIC_ENUM_CTYPE_UF(type_, c_type_) \
struct en_##type_##_vs_ms_check { \
char length_eq[(sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)) ? 1 : -1]; \
}; \
DDSRT_STATIC_ASSERT (sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)); \
\
static int uf_##type_ (struct cfgst *cfgst, void *parent, UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) \
{ \
@ -1773,9 +1771,9 @@ static void pf_allow_multicast(struct cfgst *cfgst, void *parent, struct cfgelem
do_print_uint32_bitset (cfgst, *p, sizeof (allow_multicast_codes) / sizeof (*allow_multicast_codes), allow_multicast_names, allow_multicast_codes, sources, "");
}
DDSRT_WARNING_MSVC_OFF(4996);
static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
DDSRT_WARNING_MSVC_OFF(4996);
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
int pos;
if (ddsrt_strcasecmp (value, "default") == 0) {
@ -1788,8 +1786,8 @@ static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem con
} else {
return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value);
}
}
DDSRT_WARNING_MSVC_ON(4996);
}
static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
{
@ -1940,9 +1938,9 @@ static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const
pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s");
}
DDSRT_WARNING_MSVC_OFF(4996);
static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
DDSRT_WARNING_MSVC_OFF(4996);
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
int pos;
if (ddsrt_strcasecmp (value, "any") == 0) {
@ -1955,8 +1953,8 @@ static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const
} else {
return cfg_error (cfgst, "'%s': neither 'any' nor a decimal integer in 0 .. 230\n", value);
}
}
DDSRT_WARNING_MSVC_ON(4996);
}
static void pf_domainId(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
{

View file

@ -3002,7 +3002,7 @@ static void writer_set_state (struct writer *wr, enum writer_state newstate)
wr->state = newstate;
}
int delete_writer_nolinger_locked (struct writer *wr)
dds_return_t delete_writer_nolinger_locked (struct writer *wr)
{
DDS_LOG(DDS_LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid));
ASSERT_MUTEX_HELD (&wr->e.lock);
@ -3014,7 +3014,7 @@ int delete_writer_nolinger_locked (struct writer *wr)
return 0;
}
int delete_writer_nolinger (const struct nn_guid *guid)
dds_return_t delete_writer_nolinger (const struct nn_guid *guid)
{
struct writer *wr;
/* We take no care to ensure application writers are not deleted
@ -3043,7 +3043,7 @@ void delete_local_orphan_writer (struct local_orphan_writer *lowr)
ddsrt_mutex_unlock (&lowr->wr.e.lock);
}
int delete_writer (const struct nn_guid *guid)
dds_return_t delete_writer (const struct nn_guid *guid)
{
struct writer *wr;
struct whc_state whcst;
@ -3409,7 +3409,7 @@ static void gc_delete_reader (struct gcreq *gcreq)
ddsrt_free (rd);
}
int delete_reader (const struct nn_guid *guid)
dds_return_t delete_reader (const struct nn_guid *guid)
{
struct reader *rd;
assert (!is_writer_entityid (guid->entityid));

View file

@ -415,9 +415,9 @@ static int check_thread_properties (void)
return ok;
}
DDSRT_WARNING_MSVC_OFF(4996);
int rtps_config_open (void)
{
DDSRT_WARNING_MSVC_OFF(4996);
int status;
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);
return status;
}
DDSRT_WARNING_MSVC_ON(4996);
}
int rtps_config_prep (struct cfgst *cfgst)
{

View file

@ -77,9 +77,9 @@ static const ipv4_hdr_t ipv4_hdr_template = {
#define IPV4_HDR_SIZE 20
#define UDP_HDR_SIZE 8
DDSRT_WARNING_MSVC_OFF(4996);
FILE *new_pcap_file (const char *name)
{
DDSRT_WARNING_MSVC_OFF(4996);
FILE *fp;
pcap_hdr_t hdr;
@ -99,8 +99,8 @@ FILE *new_pcap_file (const char *name)
fwrite (&hdr, sizeof (hdr), 1, fp);
return fp;
}
DDSRT_WARNING_MSVC_ON(4996);
}
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/heap.h"
#include "dds/ddsrt/static_assert.h"
#include "dds/ddsi/q_log.h"
@ -30,7 +31,6 @@
#include "dds/ddsi/q_globals.h"
#include "dds/ddsi/q_protocol.h" /* for NN_STATUSINFO_... */
#include "dds/ddsi/q_radmin.h" /* for nn_plist_quickscan */
#include "dds/ddsi/q_static_assert.h"
#include "dds/ddsrt/avl.h"
#include "dds/ddsi/q_misc.h" /* for vendor_is_... */
@ -1943,7 +1943,7 @@ static dds_return_t init_one_parameter
if (dd->bufsz >= 2 * sizeof (dest->statusinfo) && vendor_is_eclipse_or_opensplice(dd->vendorid))
{
uint32_t statusinfox;
Q_STATIC_ASSERT_CODE (sizeof(statusinfox) == sizeof(dest->statusinfo));
DDSRT_STATIC_ASSERT_CODE (sizeof(statusinfox) == sizeof(dest->statusinfo));
memcpy (&statusinfox, dd->buf + sizeof (dest->statusinfo), sizeof (statusinfox));
statusinfox = fromBE4u (statusinfox);
if (statusinfox & NN_STATUSINFOX_OSPL_AUTO)

View file

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

View file

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

View file

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

View file

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

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.
*
* @param[in] name Environment variable name.
* @param[in] buf Buffer to write value to.
* @param[in] sz Size of buffer.
* @param[out] reqsz Number of bytes written (excluding the terminating null
* byte), or would have been written would @buf have been
* sufficiently large enough.
* @param[out] value Alias to value of environment variable - must not be modified
*
* @returns A dds_return_t indicating success or failure.
*

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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