Adds immediate migration results

This commit is contained in:
torsten committed 2026-08-18 22:12:24 +02:00
1 parent ba4121728b
commit 6a2a0667ab
2395 files changed
+357322 -2524

No files matched your search

@@ -0,0 +1,110 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_ADAPTER_FORWARDER_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_ADAPTER_FORWARDER_HPP_
#include <rti/core/Exception.hpp>
#include <routingservice/routingservice_adapter_new.h>
#include <rti/routing/adapter/detail/ConnectionForwarder.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
class AdapterForwarder {
public:
static RTI_RoutingServiceAdapterPluginExt * create_plugin(
AdapterPlugin *adapter_plugin)
{
RTI_RoutingServiceAdapterPluginExt *native_adapter = NULL;
RTIOsapiHeap_allocateStructure(
&native_adapter,
struct RTI_RoutingServiceAdapterPluginExt);
rti::core::check_create_entity(
native_adapter,
"RTI_RoutingServiceAdapterPluginExt");
RTI_RoutingServiceAdapterPluginExt_initialize(native_adapter);
// Set adapter version
rti::config::LibraryVersion version = adapter_plugin->get_version();
native_adapter->plugin_version.major = version.major_version();
native_adapter->plugin_version.minor = version.minor_version();
native_adapter->plugin_version.release = version.release_version();
// Initialize adapter methods
native_adapter->adapter_plugin_data =
static_cast<void *>(adapter_plugin);
native_adapter->plugin_delete =
AdapterForwarder::delete_plugin;
native_adapter->create_connection =
AdapterForwarder::create_connection;
native_adapter->delete_connection =
AdapterForwarder::delete_connection;
return native_adapter;
}
static void delete_plugin(
void *native_adapter_data,
RTI_RoutingServiceEnvironment *)
{
RTI_RoutingServiceAdapterPluginExt *native_adapter =
static_cast<RTI_RoutingServiceAdapterPluginExt *>(
native_adapter_data);
AdapterPlugin *adapter = static_cast<AdapterPlugin *>(
native_adapter->adapter_plugin_data);
// Plug-in is destructor not allowed to throw
delete adapter;
RTIOsapiHeap_freeStructure(native_adapter);
}
static RTI_RoutingServiceConnectionExt* create_connection(
void *native_adapter_data,
const char *routing_service_name,
const char *routing_service_group_name,
const RTI_RoutingServiceStreamReaderListenerExt *native_output_stream_listener,
const RTI_RoutingServiceStreamReaderListenerExt *native_input_stream_listener,
const RTI_RoutingServiceTypeInfo **registered_types,
int registered_type_count,
const RTI_RoutingServiceProperties *native_properties,
RTI_RoutingServiceEnvironment *environment)
{
return ConnectionForwarder::create_native(
static_cast<AdapterPlugin *>(native_adapter_data),
routing_service_name,
routing_service_group_name,
native_output_stream_listener,
native_input_stream_listener,
registered_types,
registered_type_count,
native_properties,
environment);
}
static void delete_connection(
void *native_adapter_data,
RTI_RoutingServiceConnectionExt *native_connection,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder::delete_native(
static_cast<AdapterPlugin *>(native_adapter_data),
native_connection,
environment);
}
};
}}}}
#endif // RTI_ROUTING_ADAPTER_DETAIL_ADAPTER_FORWARDER_HPP_
@@ -0,0 +1,335 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_CONNECTION_FORWARDER_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_CONNECTION_FORWARDER_HPP_
#include <rti/core/Exception.hpp>
#include <rti/apputils/ServiceException.hpp>
#include <osapi/osapi_heap.h>
#include <routingservice/routingservice_adapter_new.h>
#include <rti/routing/adapter/detail/SessionForwarder.hpp>
#include <rti/routing/adapter/detail/StreamReaderForwarder.hpp>
#include <rti/routing/adapter/detail/StreamWriterForwarder.hpp>
#include <rti/routing/adapter/detail/DiscoveryStreamReaderForwarder.hpp>
#include <rti/routing/detail/UpdatableEntityForwarder.hpp>
#include <rti/routing/detail/ForwarderUtils.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
class ConnectionForwarder {
public:
static RTI_RoutingServiceConnectionExt * create_native(
AdapterPlugin *adapter,
const char *,
const char *,
const RTI_RoutingServiceStreamReaderListenerExt *native_output_stream_listener,
const RTI_RoutingServiceStreamReaderListenerExt *native_input_stream_listener,
const RTI_RoutingServiceTypeInfo **,
int,
const RTI_RoutingServiceProperties *native_properties,
RTI_RoutingServiceEnvironment *environment)
{
try {
using rti::routing::detail::ScopedForwarder;
// Set properties
std::map<std::string, std::string> properties;
rti::routing::PropertyAdapter::add_properties_from_native(
properties,
native_properties);
ConnectionForwarder *forwarder = new ConnectionForwarder(
native_output_stream_listener,
native_input_stream_listener);
ScopedForwarder<AdapterPlugin, ConnectionForwarder> scoped(
adapter,
forwarder,
environment);
// Create connection
forwarder->connection_ = adapter->create_connection(
&forwarder->input_discovery_listener_,
&forwarder->output_discovery_listener_,
properties);
RTI_ROUTING_THROW_ON_NULL(forwarder->connection_);
// Create built-in SRs
forwarder->input_stream_discovery_forwarder_ =
new DiscoveryStreamReaderForwarder(
forwarder->connection_
->input_stream_discovery_reader());
forwarder->output_stream_discovery_forwarder_ =
new DiscoveryStreamReaderForwarder(
forwarder->connection_
->output_stream_discovery_reader());
scoped.release();
// TRUST-134: the forwarder is not leaked here. It might be leaked
// if delete_native() were not to be called, but Routing Service
// will make sure that is not the case
/* coverity[leaked_storage : FALSE] */
return forwarder->native();
} catch (const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
return NULL;
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
return NULL;
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
return NULL;
}
}
static void delete_native(
AdapterPlugin *adapter,
RTI_RoutingServiceConnectionExt *native_connection,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection->connection_data);
try {
// delete built-in SRs
delete forwarder->input_stream_discovery_forwarder_;
delete forwarder->output_stream_discovery_forwarder_;
// delete connection
if (forwarder->connection_ != NULL) {
adapter->delete_connection(forwarder->connection_);
forwarder->connection_ = NULL;
}
} catch(const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch(const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
}
delete forwarder;
}
static RTI_RoutingServiceStreamReaderExt *
get_input_stream_discovery_reader(
void *native_connection_data,
RTI_RoutingServiceEnvironment *)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection_data);
return forwarder->input_stream_discovery_forwarder_->native();
}
static RTI_RoutingServiceStreamReaderExt *
get_output_stream_discovery_reader(
void *native_connection_data,
RTI_RoutingServiceEnvironment *)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection_data);
return forwarder->output_stream_discovery_forwarder_->native();
}
static RTI_RoutingServiceSessionExt * create_session(
void *native_connection_data,
const struct RTI_RoutingServiceProperties * native_properties,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection_data);
return SessionForwarder::create_native(
forwarder->connection_,
native_properties,
environment);
}
static void delete_session(
void *native_connection_data,
RTI_RoutingServiceSessionExt *native_session,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*> (
native_connection_data);
SessionForwarder::delete_native(
forwarder->connection_,
native_session,
environment);
}
static RTI_RoutingServiceStreamReaderExt* create_stream_reader(
void *native_connection_data,
void *native_session_data,
const struct RTI_RoutingServiceStreamInfo *native_stream_info,
const struct RTI_RoutingServiceProperties *native_properties,
const struct RTI_RoutingServiceStreamReaderListenerExt *native_listener,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection_data);
SessionForwarder *session_forwarder = static_cast<SessionForwarder*>(
native_session_data);
return StreamReaderForwarder::create_native(
forwarder->connection_,
session_forwarder->session(),
native_stream_info,
native_properties,
native_listener,
environment);
}
static void delete_stream_reader(
void *native_connection_data,
RTI_RoutingServiceStreamReaderExt *native_reader,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection_data);
StreamReaderForwarder::delete_native(
forwarder->connection_,
native_reader,
environment);
}
static RTI_RoutingServiceStreamWriterExt* create_stream_writer(
void *native_connection_data,
void *native_session_data,
const struct RTI_RoutingServiceStreamInfo *native_stream_info,
const struct RTI_RoutingServiceProperties *native_properties,
const struct RTI_RoutingServiceStreamWriterListenerExt *,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection_data);
SessionForwarder *session_forwarder = static_cast<SessionForwarder*>(
native_session_data);
return StreamWriterForwarder::create_native(
forwarder->connection_,
session_forwarder->session(),
native_stream_info,
native_properties,
environment);
}
static void delete_stream_writer(
void *native_connection_data,
RTI_RoutingServiceStreamWriterExt *native_writer,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder = static_cast<ConnectionForwarder*>(
native_connection_data);
StreamWriterForwarder::delete_native(
forwarder->connection_,
native_writer,
environment);
}
static void update(
void *native_connection_data,
const struct RTI_RoutingServiceProperties *native_properties,
RTI_RoutingServiceEnvironment *environment)
{
ConnectionForwarder *forwarder =
static_cast<ConnectionForwarder*> (native_connection_data);
rti::routing::detail::UpdatableEntityForwarder::update(
forwarder->connection_,
native_properties,
environment);
}
Connection * connection()
{
return connection_;
}
RTI_RoutingServiceConnectionExt* native()
{
return &this->native_;
}
RTI_RoutingServiceStreamReaderExt* native_input_discovery_reader()
{
return input_stream_discovery_forwarder_->native();
}
RTI_RoutingServiceStreamReaderExt* native_output_discovery_reader()
{
return output_stream_discovery_forwarder_->native();
}
private:
ConnectionForwarder(
const RTI_RoutingServiceStreamReaderListenerExt *native_output_stream_listener,
const RTI_RoutingServiceStreamReaderListenerExt *native_input_stream_listener) :
connection_(NULL),
output_stream_discovery_forwarder_(NULL),
output_discovery_listener_(native_output_stream_listener),
input_stream_discovery_forwarder_(NULL),
input_discovery_listener_(native_input_stream_listener)
{
RTIOsapiMemory_zero(&native_, sizeof(native_));
native_.connection_data = static_cast<void*>(this);
native_.create_session = ConnectionForwarder::create_session;
native_.delete_session = ConnectionForwarder::delete_session;
native_.create_stream_reader =
ConnectionForwarder::create_stream_reader;
native_.delete_stream_reader =
ConnectionForwarder::delete_stream_reader;
native_.create_stream_writer =
ConnectionForwarder::create_stream_writer;
native_.delete_stream_writer =
ConnectionForwarder::delete_stream_writer;
native_.get_input_stream_discovery_reader =
ConnectionForwarder::get_input_stream_discovery_reader;
native_.get_output_stream_discovery_reader =
ConnectionForwarder::get_output_stream_discovery_reader;
native_.update = ConnectionForwarder::update;
}
~ConnectionForwarder()
{
}
private:
RTI_RoutingServiceConnectionExt native_;
Connection *connection_;
DiscoveryStreamReaderForwarder *output_stream_discovery_forwarder_;
StreamReaderListener output_discovery_listener_;
DiscoveryStreamReaderForwarder *input_stream_discovery_forwarder_;
StreamReaderListener input_discovery_listener_;
};
}}}}
#endif // RTI_ROUTING_ADAPTER_DETAIL_CONNECTION_FORWARDER_HPP_
@@ -0,0 +1,134 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_DISCOVERY_STREAM_READER_FORWARDER_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_DISCOVERY_STREAM_READER_FORWARDER_HPP_
#include <rti/core/Exception.hpp>
#include <rti/apputils/ServiceException.hpp>
#include <routingservice/routingservice_adapter_new.h>
#include <rti/routing/adapter/DiscoveryStreamReader.hpp>
#include <rti/routing/detail/ForwarderUtils.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
class DiscoveryStreamReaderForwarder {
public:
static void take(
void *native_stream_reader_data,
RTI_RoutingServiceSample **sample_array,
RTI_RoutingServiceSampleInfo **sample_info_array,
int *array_length,
RTI_RoutingServiceEnvironment *environment)
{
DiscoveryStreamReaderForwarder *forwarder =
static_cast<DiscoveryStreamReaderForwarder*>(
native_stream_reader_data);
*sample_info_array = NULL;
*array_length = 0;
try {
forwarder->stream_reader_->take(forwarder->sample_seq_);
*array_length = static_cast<int>(forwarder->sample_seq_.size());
if (*array_length > 0) {
*sample_array = reinterpret_cast<RTI_RoutingServiceSample*> (
&forwarder->sample_seq_[0]);
}
} catch (const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
}
}
static void return_loan(
void *native_stream_reader_data,
RTI_RoutingServiceSample *,
RTI_RoutingServiceSampleInfo *,
int,
RTI_RoutingServiceEnvironment *environment)
{
DiscoveryStreamReaderForwarder *forwarder =
static_cast<DiscoveryStreamReaderForwarder*>(
native_stream_reader_data);
try {
forwarder->stream_reader_->return_loan(forwarder->sample_seq_);
} catch (const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
return;
}
forwarder->sample_seq_.clear();
}
DiscoveryStreamReaderForwarder(
DiscoveryStreamReader *stream_reader) :
stream_reader_(stream_reader)
{
RTIOsapiMemory_zero(&native_, sizeof(native_));
native_.stream_reader_data =
static_cast<void *>(this);
native_.take =
DiscoveryStreamReaderForwarder::take;
native_.return_loan =
DiscoveryStreamReaderForwarder::return_loan;
}
~DiscoveryStreamReaderForwarder()
{
}
static DiscoveryStreamReaderForwarder* from_native(
RTI_RoutingServiceStreamReaderExt *native)
{
return static_cast<DiscoveryStreamReaderForwarder*>(
native->stream_reader_data);
}
RTI_RoutingServiceStreamReaderExt * native()
{
return &native_;
}
private:
RTI_RoutingServiceStreamReaderExt native_;
DiscoveryStreamReader *stream_reader_;
std::vector<StreamInfo*> sample_seq_;
};
}}}}
#endif // RTI_ROUTING_ADAPTER_DETAIL_DISCOVERY_STREAM_READER_FORWARDER_HPP_
@@ -0,0 +1,106 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_READ_PROXY_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_READ_PROXY_HPP_
#include <rti/routing/adapter/StreamReader.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
struct TakeProxy {
TakeProxy (StreamReader& stream_reader)
: stream_reader_(stream_reader)
{
}
void operator() (
std::vector<rti::routing::adapter::StreamReader::SamplePtr>& sample_seq,
std::vector<rti::routing::adapter::StreamReader::InfoPtr>& info_seq)
{
stream_reader_.take(sample_seq, info_seq);
}
private:
StreamReader& stream_reader_;
};
struct ReadProxy {
ReadProxy (StreamReader& stream_reader)
: stream_reader_(stream_reader)
{
}
void operator() (
std::vector<rti::routing::adapter::StreamReader::SamplePtr>& sample_seq,
std::vector<rti::routing::adapter::StreamReader::InfoPtr>& info_seq)
{
stream_reader_.read(sample_seq, info_seq);
}
private:
StreamReader& stream_reader_;
};
struct TakeSelectorProxy {
TakeSelectorProxy(
StreamReader& stream_reader,
const rti::routing::adapter::SelectorState& state)
: stream_reader_(stream_reader), state_(state)
{
}
void operator() (
std::vector<rti::routing::adapter::StreamReader::SamplePtr>& sample_seq,
std::vector<rti::routing::adapter::StreamReader::InfoPtr>& info_seq)
{
stream_reader_.take(sample_seq, info_seq, state_);
}
private:
StreamReader& stream_reader_;
const rti::routing::adapter::SelectorState& state_;
};
struct ReadSelectorProxy {
ReadSelectorProxy (
StreamReader& stream_reader,
const rti::routing::adapter::SelectorState& state)
: stream_reader_(stream_reader), state_(state)
{
}
void operator() (
std::vector<rti::routing::adapter::StreamReader::SamplePtr>& sample_seq,
std::vector<rti::routing::adapter::StreamReader::InfoPtr>& info_seq)
{
stream_reader_.read(sample_seq, info_seq, state_);
}
private:
StreamReader& stream_reader_;
const rti::routing::adapter::SelectorState& state_;
};
} } } }
#endif /* RTI_ROUTING_ADAPTER_DETAIL_READ_PROXY_HPP_ */
@@ -0,0 +1,151 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_SESSION_FORWARDER_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_SESSION_FORWARDER_HPP_
#include <rti/core/Exception.hpp>
#include <rti/apputils/ServiceException.hpp>
#include <rti/routing/adapter/Connection.hpp>
#include <rti/routing/detail/UpdatableEntityForwarder.hpp>
#include <rti/routing/detail/ForwarderUtils.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
class SessionForwarder {
public:
static RTI_RoutingServiceSessionExt* create_native(
Connection *connection,
const RTI_RoutingServiceProperties *native_properties,
RTI_RoutingServiceEnvironment *environment)
{
try {
using rti::routing::detail::ScopedForwarder;
// Set properties
std::map<std::string, std::string> properties;
rti::routing::PropertyAdapter::add_properties_from_native(
properties,
native_properties);
SessionForwarder *forwarder = new SessionForwarder();
ScopedForwarder<Connection, SessionForwarder> scoped(
connection,
forwarder,
environment);
// Create session: Note we don't check for NULL because a Session
// is not required
forwarder->session_ = connection->create_session(properties);
scoped.release();
// TRUST-134: the forwarder is not leaked here. It might be leaked
// if delete_native() were not to be called, but Routing Service
// will make sure that is not the case
/* coverity[leaked_storage : FALSE] */
return forwarder->native();
} catch(const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
return NULL;
} catch(const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
return NULL;
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
return NULL;
}
}
static void delete_native(
Connection *connection,
RTI_RoutingServiceSessionExt *native_session,
RTI_RoutingServiceEnvironment *environment)
{
SessionForwarder *forwarder = static_cast<SessionForwarder*>(
native_session->session_data);
try {
// delete session
if (forwarder->session_ != NULL) {
connection->delete_session(forwarder->session_);
forwarder->session_ = NULL;
}
} catch(const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch(const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
}
delete forwarder;
}
Session * session()
{
return session_;
}
RTI_RoutingServiceSessionExt* native()
{
return &this->native_;
}
static void update(
void *native_session_data,
const struct RTI_RoutingServiceProperties * native_properties,
RTI_RoutingServiceEnvironment * environment)
{
SessionForwarder *forwarder =
static_cast<SessionForwarder*> (native_session_data);
rti::routing::detail::UpdatableEntityForwarder::update(
forwarder->session_,
native_properties,
environment);
}
private:
SessionForwarder() : session_(NULL)
{
RTIOsapiMemory_zero(&native_, sizeof(native_));
native_.session_data =
static_cast<void*>(this);
native_.update =
SessionForwarder::update;
}
~SessionForwarder()
{
}
private:
RTI_RoutingServiceSessionExt native_;
Session *session_;
};
}}}}
#endif // RTI_ROUTING_ADAPTER_DETAIL_SESSION_FORWARDER_HPP_
@@ -0,0 +1,524 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_FORWARDER_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_FORWARDER_HPP_
#include <assert.h>
#include <list>
#include <rti/core/Exception.hpp>
#include <rti/apputils/ServiceException.hpp>
#include <rti/routing/adapter/StreamReader.hpp>
#include <rti/routing/StreamInfo.hpp>
#include <rti/routing/detail/UpdatableEntityForwarder.hpp>
#include <rti/routing/detail/ForwarderUtils.hpp>
#include <rti/routing/adapter/detail/DiscoveryStreamReaderForwarder.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
template <bool ReadOrTake, bool HasSelector> struct read_or_take;
template<>
struct read_or_take<false, false> {
static void read(
rti::routing::adapter::StreamReader& stream_reader,
std::vector<StreamReader::SamplePtr>& sample_seq,
std::vector<StreamReader::InfoPtr>& info_seq,
const struct RTI_RoutingServiceSelectorState *)
{
stream_reader.take(sample_seq, info_seq);
}
};
template<>
struct read_or_take<true, false> {
static void read(
rti::routing::adapter::StreamReader& stream_reader,
std::vector<StreamReader::SamplePtr>& sample_seq,
std::vector<StreamReader::InfoPtr>& info_seq,
const struct RTI_RoutingServiceSelectorState *)
{
stream_reader.read(sample_seq, info_seq);
}
};
template<>
struct read_or_take<false, true> {
static void read(
rti::routing::adapter::StreamReader& stream_reader,
std::vector<StreamReader::SamplePtr>& sample_seq,
std::vector<StreamReader::InfoPtr>& info_seq,
const struct RTI_RoutingServiceSelectorState *native_selector)
{
stream_reader.take(
sample_seq,
info_seq,
SelectorState(*native_selector));
}
};
template<>
struct read_or_take<true, true> {
static void read(
rti::routing::adapter::StreamReader& stream_reader,
std::vector<StreamReader::SamplePtr>& sample_seq,
std::vector<StreamReader::InfoPtr>& info_seq,
const struct RTI_RoutingServiceSelectorState *native_selector)
{
stream_reader.read(
sample_seq,
info_seq,
SelectorState(*native_selector));
}
};
struct SamplesHolder {
public:
SamplesHolder()
{
}
std::vector<StreamReader::SamplePtr> sample_seq_;
std::vector<StreamReader::InfoPtr> info_seq_;
};
class StreamReaderForwarder {
public:
static RTI_RoutingServiceStreamReaderExt* create_native(
Connection *connection,
Session *session,
const struct RTI_RoutingServiceStreamInfo *native_stream_info,
const struct RTI_RoutingServiceProperties *native_properties,
const struct RTI_RoutingServiceStreamReaderListenerExt *native_listener,
RTI_RoutingServiceEnvironment *environment)
{
try {
using rti::routing::detail::ScopedForwarder;
StreamInfo stream_info(*native_stream_info);
std::map<std::string, std::string> properties;
rti::routing::PropertyAdapter::add_properties_from_native(
properties,
native_properties);
StreamReaderForwarder *forwarder = new StreamReaderForwarder(
native_listener);
ScopedForwarder<Connection, StreamReaderForwarder> scoped(
connection,
forwarder,
environment);
forwarder->stream_reader_ = connection->create_stream_reader(
session,
stream_info,
properties,
&forwarder->listener_);
RTI_ROUTING_THROW_ON_NULL(forwarder->stream_reader_);
scoped.release();
// TRUST-134: the forwarder is not leaked here. It might be leaked
// if delete_native() were not to be called, but Routing Service
// will make sure that is not the case
/* coverity[leaked_storage : FALSE] */
return forwarder->native();
} catch(const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
return NULL;
} catch(const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
return NULL;
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
return NULL;
}
}
static void delete_native(
Connection *connection,
RTI_RoutingServiceStreamReaderExt *native_stream_reader,
RTI_RoutingServiceEnvironment *environment)
{
StreamReaderForwarder *stream_reader_forwarder =
from_native(native_stream_reader);
try {
if (stream_reader_forwarder->stream_reader_ != NULL) {
connection->delete_stream_reader(
stream_reader_forwarder->stream_reader_);
stream_reader_forwarder->stream_reader_ = NULL;
}
} catch(const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch(const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
}
delete stream_reader_forwarder;
}
RTI_RoutingServiceStreamReaderExt* native()
{
return &this->native_;
}
private:
StreamReaderForwarder(
const RTI_RoutingServiceStreamReaderListenerExt *native_listener) :
stream_reader_(NULL),
listener_(native_listener)
{
RTIOsapiMemory_zero(&native_, sizeof(native_));
native_.stream_reader_data =
static_cast<void *>(this);
native_.take =
StreamReaderForwarder::take;
native_.read =
StreamReaderForwarder::read;
native_.take_w_selector =
StreamReaderForwarder::take_with_selector;
native_.read_w_selector =
StreamReaderForwarder::read_with_selector;
native_.return_loan =
StreamReaderForwarder::return_loan;
native_.create_content_query =
StreamReaderForwarder::create_content_query;
native_.delete_content_query =
StreamReaderForwarder::delete_content_query;
native_.update =
StreamReaderForwarder::update;
}
~StreamReaderForwarder()
{
// delete holders
for (std::list<SamplesHolder*>::iterator it = holder_pool_.begin();
it != holder_pool_.end();
++it) {
delete (*it);
}
}
static void take(
void *native_stream_reader_data,
RTI_RoutingServiceSample **sample_array,
RTI_RoutingServiceSampleInfo **sample_info_array,
int *array_length,
RTI_RoutingServiceEnvironment *environment)
{
proxy_read<false, false>(
native_stream_reader_data,
sample_array,
sample_info_array,
array_length,
NULL,
environment);
}
static void read(
void *native_stream_reader_data,
RTI_RoutingServiceSample **sample_array,
RTI_RoutingServiceSampleInfo **sample_info_array,
int *array_length,
RTI_RoutingServiceEnvironment *environment)
{
proxy_read<true, false>(
native_stream_reader_data,
sample_array,
sample_info_array,
array_length,
NULL,
environment);
}
static void take_with_selector(
void *native_stream_reader_data,
RTI_RoutingServiceSample **sample_array,
RTI_RoutingServiceSampleInfo **sample_info_array,
int *array_length,
const struct RTI_RoutingServiceSelectorState *native_selector,
RTI_RoutingServiceEnvironment *environment)
{
proxy_read<false, true>(
native_stream_reader_data,
sample_array,
sample_info_array,
array_length,
native_selector,
environment);
}
static void read_with_selector(
void *native_stream_reader_data,
RTI_RoutingServiceSample **sample_array,
RTI_RoutingServiceSampleInfo **sample_info_array,
int *array_length,
const struct RTI_RoutingServiceSelectorState *native_selector,
RTI_RoutingServiceEnvironment *environment)
{
proxy_read<true, true>(
native_stream_reader_data,
sample_array,
sample_info_array,
array_length,
native_selector,
environment);
}
static void return_loan(
void *native_stream_reader_data,
RTI_RoutingServiceSample *native_samples,
RTI_RoutingServiceSampleInfo *,
int count,
RTI_RoutingServiceEnvironment *environment)
{
StreamReaderForwarder *forwarder =
static_cast<StreamReaderForwarder*>(native_stream_reader_data);
assert(forwarder != NULL);
SamplesHolder *holder = static_cast<SamplesHolder*>(
native_samples[count]);
assert(holder != NULL);
try {
forwarder->stream_reader_->return_loan(
holder->sample_seq_,
holder->info_seq_);
} catch (const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
}
forwarder->return_holder(holder);
}
static void update(
void *native_stream_reader_data,
const struct RTI_RoutingServiceProperties * native_properties,
RTI_RoutingServiceEnvironment * environment)
{
StreamReaderForwarder *stream_reader_forwarder =
static_cast<StreamReaderForwarder*>(native_stream_reader_data);
rti::routing::detail::UpdatableEntityForwarder::update(
stream_reader_forwarder->stream_reader_,
native_properties,
environment);
}
static void* create_content_query(
void *native_stream_reader_data,
RTI_RoutingServiceSelectorStateQueryData old_query_data,
const struct RTI_RoutingServiceSelectorContent *content,
RTI_RoutingServiceEnvironment *environment)
{
StreamReaderForwarder *forwarder =
static_cast<StreamReaderForwarder*>(native_stream_reader_data);
void *query_data = NULL;
try {
dds::topic::Filter filter(
content->expression == NULL ? "" : content->expression,
rti::core::native_conversions::from_native<std::string>(
content->expression_parameters));
query_data = forwarder->stream_reader_->create_content_query(
old_query_data,
filter);
} catch (const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
}
return query_data;
}
static void delete_content_query(
void *native_stream_reader_data,
RTI_RoutingServiceSelectorStateQueryData query_data,
RTI_RoutingServiceEnvironment *environment)
{
StreamReaderForwarder *forwarder =
static_cast<StreamReaderForwarder*>(native_stream_reader_data);
try {
forwarder->stream_reader_->delete_content_query(query_data);
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"%s",
ex.what());
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
}
}
static StreamReaderForwarder* from_native(
RTI_RoutingServiceStreamReaderExt *native)
{
return static_cast<StreamReaderForwarder*>(native->stream_reader_data);
}
template <bool ReadOrTake, bool HasSelector>
static void proxy_read(
void *native_stream_reader_data,
RTI_RoutingServiceSample **sample_array,
RTI_RoutingServiceSampleInfo **sample_info_array,
int *array_length,
const struct RTI_RoutingServiceSelectorState *native_selector,
RTI_RoutingServiceEnvironment *environment)
{
StreamReaderForwarder *forwarder =
static_cast<StreamReaderForwarder*>(native_stream_reader_data);
assert(forwarder != NULL);
SamplesHolder *holder = forwarder->get_holder();
*array_length = 0;
try {
read_or_take<ReadOrTake, HasSelector>::read(
*forwarder->stream_reader_,
holder->sample_seq_,
holder->info_seq_,
native_selector);
if (!holder->info_seq_.empty()
&& (holder->info_seq_.size() != holder->sample_seq_.size())) {
throw dds::core::PreconditionNotMetError(
"sample and info sequences length mismatch");
}
/*
* We reserve a hidden slot in the sample_seq to keep the original
* loaned returned from the native StreamReader. This allows us
* to quickly access it on return_loan(), instead of having to search
* in a list.
*
* TRUST-1466: reserving just 1 more memory spot can be inefficient,
* and we're doing this for every read/take operation called in C++.
*/
if (holder->sample_seq_.size() + 1
>= holder->sample_seq_.capacity()) {
holder->sample_seq_.reserve(
holder->sample_seq_.capacity() == 0
? 1
: 2 * holder->sample_seq_.capacity());
}
*(holder->sample_seq_.data() + holder->sample_seq_.size()) = holder;
} catch (const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
forwarder->return_holder(holder);
return;
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
forwarder->return_holder(holder);
return;
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
forwarder->return_holder(holder);
return;
}
// direct mapping
*array_length = static_cast<int>(holder->sample_seq_.size());
*sample_array = holder->sample_seq_.data();
if (holder->info_seq_.empty()) {
*sample_info_array = NULL;
} else {
*sample_info_array = &holder->info_seq_[0];
}
}
SamplesHolder* get_holder()
{
if (holder_pool_.size() == 0) {
return new SamplesHolder();
}
SamplesHolder *holder = holder_pool_.front();
holder_pool_.pop_front();
return holder;
}
void return_holder(SamplesHolder *holder)
{
holder->sample_seq_.clear();
holder->info_seq_.clear();
holder_pool_.push_front(holder);
}
private:
RTI_RoutingServiceStreamReaderExt native_;
StreamReader *stream_reader_;
StreamReaderListener listener_;
std::list<SamplesHolder*> holder_pool_;
};
}}}}
#endif // RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_FORWARDER_HPP_
@@ -0,0 +1,75 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_LISTENER_FORWARDER_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_LISTENER_FORWARDER_HPP_
#include <rti/core/Exception.hpp>
#include <routingservice/routingservice_adapter_new.h>
#include <rti/routing/adapter/StreamReader.hpp>
#include <rti/routing/adapter/DiscoveryStreamReader.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
/** @ingroup RTI_RoutingServiceAdapterModule
*
* @class rti::routing::adapter::StreamReaderListener
*
* @brief Listener representation used by StreamReader to notify @product
* when new data is available.
*
* When a StreamReader receives new data, it shall call
* StreamReaderListener::on_data_available to wake up the associated Session.
* After that, the Session will invoke any of the StreamReader operations to
* read the new data.
*
*/
class StreamReaderListener {
public:
public:
/**
* @brief Operation to notify @product about data available on the
* a StreamReader.
*
* @param stream_reader
* @rs_st_in Stream reader for which new data is available.
*
*/
void on_data_available(
rti::routing::adapter::StreamReader *stream_reader)
{
native_listener_.on_data_available(
static_cast<void*>(stream_reader),
native_listener_.listener_data);
}
StreamReaderListener(
const RTI_RoutingServiceStreamReaderListenerExt *native_listener) :
native_listener_(*native_listener)
{
}
~StreamReaderListener()
{
}
private:
RTI_RoutingServiceStreamReaderListenerExt native_listener_;
};
}}}}
#endif // RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_LISTENER_FORWARDER_HPP_
@@ -0,0 +1,207 @@
/*
* (c) Copyright, Real-Time Innovations, 2017.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_ROUTING_ADAPTER_DETAIL_STREAM_WRITER_FORWARDER_HPP_
#define RTI_ROUTING_ADAPTER_DETAIL_STREAM_WRITER_FORWARDER_HPP_
#include <rti/core/Exception.hpp>
#include <rti/apputils/ServiceException.hpp>
#include <rti/routing/adapter/StreamWriter.hpp>
#include <rti/routing/detail/UpdatableEntityForwarder.hpp>
#include <rti/routing/detail/ForwarderUtils.hpp>
namespace rti { namespace routing { namespace adapter { namespace detail {
class StreamWriterForwarder {
public:
static RTI_RoutingServiceStreamWriterExt* create_native(
Connection *connection,
Session *session,
const struct RTI_RoutingServiceStreamInfo *native_stream_info,
const struct RTI_RoutingServiceProperties *native_properties,
RTI_RoutingServiceEnvironment *environment)
{
try {
using rti::routing::detail::ScopedForwarder;
StreamInfo stream_info(*native_stream_info);
std::map<std::string, std::string> properties;
rti::routing::PropertyAdapter::add_properties_from_native(
properties,
native_properties);
StreamWriterForwarder *forwarder = new StreamWriterForwarder(
NULL);
ScopedForwarder<Connection, StreamWriterForwarder> scoped(
connection,
forwarder,
environment);
forwarder->stream_writer_ = connection->create_stream_writer(
session,
stream_info,
properties);
RTI_ROUTING_THROW_ON_NULL(forwarder->stream_writer_);
scoped.release();
// TRUST-134: the forwarder is not leaked here. It might be leaked
// if delete_native() were not to be called, but Routing Service
// will make sure that is not the case
/* coverity[leaked_storage : FALSE] */
return forwarder->native();
} catch(const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
return NULL;
} catch(const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
return NULL;
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
return NULL;
}
}
static void delete_native(
Connection *connection,
RTI_RoutingServiceStreamWriterExt *native_stream_writer,
RTI_RoutingServiceEnvironment *environment)
{
StreamWriterForwarder *stream_writer_forwarder =
static_cast<StreamWriterForwarder*>(
native_stream_writer->stream_writer_data);
try {
if (stream_writer_forwarder->stream_writer_ != NULL) {
connection->delete_stream_writer(
stream_writer_forwarder->stream_writer_);
stream_writer_forwarder->stream_writer_ = NULL;
}
} catch(const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch(const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
}
delete stream_writer_forwarder;
}
static int write(
void *native_stream_writer_data,
const RTI_RoutingServiceSample *sample_array,
const RTI_RoutingServiceSampleInfo *sample_info_array,
int array_length,
RTI_RoutingServiceEnvironment *environment)
{
StreamWriterForwarder *forwarder =
static_cast<StreamWriterForwarder*>(native_stream_writer_data);
try {
RTI_ROUTING_SAMPLE_VECTOR_COPY_FROM_NATIVE(
forwarder->sample_seq_,
sample_array,
array_length);
if (sample_info_array != NULL) {
RTI_ROUTING_SAMPLE_VECTOR_COPY_FROM_NATIVE(
forwarder->info_seq_,
sample_info_array,
array_length);
} else {
forwarder->info_seq_.clear();
}
return forwarder->stream_writer_->write(
forwarder->sample_seq_,
forwarder->info_seq_);
} catch (const rti::apputils::FatalServiceException& ex) {
RTI_RoutingServiceEnvironment_fatal_error(
environment,
ex.what());
} catch (const std::exception& ex) {
RTI_RoutingServiceEnvironment_set_error(
environment,
ex.what());
} catch (...) {
RTI_RoutingServiceEnvironment_set_error(
environment,
"unexpected exception");
}
return 0;
}
static void update(
void *native_stream_writer_data,
const struct RTI_RoutingServiceProperties * native_properties,
RTI_RoutingServiceEnvironment * environment)
{
StreamWriterForwarder *stream_writer_forwarder =
static_cast<StreamWriterForwarder*> (native_stream_writer_data);
rti::routing::detail::UpdatableEntityForwarder::update(
stream_writer_forwarder->stream_writer_,
native_properties,
environment);
}
RTI_RoutingServiceStreamWriterExt* native()
{
return &this->native_;
}
private:
StreamWriterForwarder(
StreamWriter *stream_writer) :
stream_writer_(stream_writer)
{
RTIOsapiMemory_zero(&native_, sizeof(native_));
native_.stream_writer_data =
static_cast<void*>(this);
native_.write =
StreamWriterForwarder::write;
native_.update =
StreamWriterForwarder::update;
}
~StreamWriterForwarder()
{
}
private:
RTI_RoutingServiceStreamWriterExt native_;
StreamWriter *stream_writer_;
std::vector<StreamWriter::SamplePtr> sample_seq_;
std::vector<StreamWriter::InfoPtr> info_seq_;
};
}}}}
#endif // RTI_ROUTING_ADAPTER_DETAIL_STREAM_WRITER_FORWARDER_HPP_