Enviar pesquisa
Carregar
Standardizing the Data Distribution Service (DDS) API for Modern C++
•
4 gostaram
•
8,853 visualizações
Sumant Tambe
Seguir
Denunciar
Compartilhar
Denunciar
Compartilhar
1 de 59
Baixar agora
Baixar para ler offline
Recomendados
Introduction to DDS
Introduction to DDS
Rick Warren
DDS QoS Unleashed
DDS QoS Unleashed
Angelo Corsaro
Fast RTPS: Programming with the Default Middleware for Robotics Adopted in ROS2
Fast RTPS: Programming with the Default Middleware for Robotics Adopted in ROS2
Jaime Martin Losa
Cyclone DDS: Sharing Data in the IoT Age
Cyclone DDS: Sharing Data in the IoT Age
Angelo Corsaro
Getting Started in DDS with C++ and Java
Getting Started in DDS with C++ and Java
Angelo Corsaro
Introduction to RTI DDS
Introduction to RTI DDS
Real-Time Innovations (RTI)
DDS Over Low Bandwidth Data Links
DDS Over Low Bandwidth Data Links
Real-Time Innovations (RTI)
OMG DDS: The Data Distribution Service for Real-Time Systems
OMG DDS: The Data Distribution Service for Real-Time Systems
Angelo Corsaro
Recomendados
Introduction to DDS
Introduction to DDS
Rick Warren
DDS QoS Unleashed
DDS QoS Unleashed
Angelo Corsaro
Fast RTPS: Programming with the Default Middleware for Robotics Adopted in ROS2
Fast RTPS: Programming with the Default Middleware for Robotics Adopted in ROS2
Jaime Martin Losa
Cyclone DDS: Sharing Data in the IoT Age
Cyclone DDS: Sharing Data in the IoT Age
Angelo Corsaro
Getting Started in DDS with C++ and Java
Getting Started in DDS with C++ and Java
Angelo Corsaro
Introduction to RTI DDS
Introduction to RTI DDS
Real-Time Innovations (RTI)
DDS Over Low Bandwidth Data Links
DDS Over Low Bandwidth Data Links
Real-Time Innovations (RTI)
OMG DDS: The Data Distribution Service for Real-Time Systems
OMG DDS: The Data Distribution Service for Real-Time Systems
Angelo Corsaro
OpenSplice DDS Tutorial -- Part II
OpenSplice DDS Tutorial -- Part II
Angelo Corsaro
zenoh -- the ZEro Network OverHead protocol
zenoh -- the ZEro Network OverHead protocol
Angelo Corsaro
DDS: The IoT Data Sharing Standard
DDS: The IoT Data Sharing Standard
Angelo Corsaro
OMG Data-Distribution Service (DDS) Tutorial - 2009
OMG Data-Distribution Service (DDS) Tutorial - 2009
Gerardo Pardo-Castellote
DDS Tutorial -- Part I
DDS Tutorial -- Part I
Angelo Corsaro
The Data Distribution Service Tutorial
The Data Distribution Service Tutorial
Angelo Corsaro
The Data Distribution Service
The Data Distribution Service
Angelo Corsaro
Comparison of MQTT and DDS as M2M Protocols for the Internet of Things
Comparison of MQTT and DDS as M2M Protocols for the Internet of Things
Real-Time Innovations (RTI)
The DDS Tutorial - Part I
The DDS Tutorial - Part I
Angelo Corsaro
ROS 2 Foxy with Eclipse Cyclone DDS | Philly ROS Meetup July 20th 2020
ROS 2 Foxy with Eclipse Cyclone DDS | Philly ROS Meetup July 20th 2020
Joe Speed
Introduction to RTI DDS
Introduction to RTI DDS
John Breitenbach
DDS in Action -- Part I
DDS in Action -- Part I
Angelo Corsaro
RTI Data-Distribution Service (DDS) Master Class - 2010
RTI Data-Distribution Service (DDS) Master Class - 2010
Gerardo Pardo-Castellote
Zenoh Tutorial
Zenoh Tutorial
Angelo Corsaro
Best Practices in MDM with Dan Power
Best Practices in MDM with Dan Power
Hub Solution Designs, Inc.
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
Real-Time Innovations (RTI)
zenoh: The Edge Data Fabric
zenoh: The Edge Data Fabric
Angelo Corsaro
The Data Distribution Service Tutorial
The Data Distribution Service Tutorial
Angelo Corsaro
Distributed Algorithms with DDS
Distributed Algorithms with DDS
Angelo Corsaro
RPC Over DDS
RPC Over DDS
Real-Time Innovations (RTI)
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
Sumant Tambe
Introduction to OMG DDS (1 hour, 45 slides)
Introduction to OMG DDS (1 hour, 45 slides)
Gerardo Pardo-Castellote
Mais conteúdo relacionado
Mais procurados
OpenSplice DDS Tutorial -- Part II
OpenSplice DDS Tutorial -- Part II
Angelo Corsaro
zenoh -- the ZEro Network OverHead protocol
zenoh -- the ZEro Network OverHead protocol
Angelo Corsaro
DDS: The IoT Data Sharing Standard
DDS: The IoT Data Sharing Standard
Angelo Corsaro
OMG Data-Distribution Service (DDS) Tutorial - 2009
OMG Data-Distribution Service (DDS) Tutorial - 2009
Gerardo Pardo-Castellote
DDS Tutorial -- Part I
DDS Tutorial -- Part I
Angelo Corsaro
The Data Distribution Service Tutorial
The Data Distribution Service Tutorial
Angelo Corsaro
The Data Distribution Service
The Data Distribution Service
Angelo Corsaro
Comparison of MQTT and DDS as M2M Protocols for the Internet of Things
Comparison of MQTT and DDS as M2M Protocols for the Internet of Things
Real-Time Innovations (RTI)
The DDS Tutorial - Part I
The DDS Tutorial - Part I
Angelo Corsaro
ROS 2 Foxy with Eclipse Cyclone DDS | Philly ROS Meetup July 20th 2020
ROS 2 Foxy with Eclipse Cyclone DDS | Philly ROS Meetup July 20th 2020
Joe Speed
Introduction to RTI DDS
Introduction to RTI DDS
John Breitenbach
DDS in Action -- Part I
DDS in Action -- Part I
Angelo Corsaro
RTI Data-Distribution Service (DDS) Master Class - 2010
RTI Data-Distribution Service (DDS) Master Class - 2010
Gerardo Pardo-Castellote
Zenoh Tutorial
Zenoh Tutorial
Angelo Corsaro
Best Practices in MDM with Dan Power
Best Practices in MDM with Dan Power
Hub Solution Designs, Inc.
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
Real-Time Innovations (RTI)
zenoh: The Edge Data Fabric
zenoh: The Edge Data Fabric
Angelo Corsaro
The Data Distribution Service Tutorial
The Data Distribution Service Tutorial
Angelo Corsaro
Distributed Algorithms with DDS
Distributed Algorithms with DDS
Angelo Corsaro
RPC Over DDS
RPC Over DDS
Real-Time Innovations (RTI)
Mais procurados
(20)
OpenSplice DDS Tutorial -- Part II
OpenSplice DDS Tutorial -- Part II
zenoh -- the ZEro Network OverHead protocol
zenoh -- the ZEro Network OverHead protocol
DDS: The IoT Data Sharing Standard
DDS: The IoT Data Sharing Standard
OMG Data-Distribution Service (DDS) Tutorial - 2009
OMG Data-Distribution Service (DDS) Tutorial - 2009
DDS Tutorial -- Part I
DDS Tutorial -- Part I
The Data Distribution Service Tutorial
The Data Distribution Service Tutorial
The Data Distribution Service
The Data Distribution Service
Comparison of MQTT and DDS as M2M Protocols for the Internet of Things
Comparison of MQTT and DDS as M2M Protocols for the Internet of Things
The DDS Tutorial - Part I
The DDS Tutorial - Part I
ROS 2 Foxy with Eclipse Cyclone DDS | Philly ROS Meetup July 20th 2020
ROS 2 Foxy with Eclipse Cyclone DDS | Philly ROS Meetup July 20th 2020
Introduction to RTI DDS
Introduction to RTI DDS
DDS in Action -- Part I
DDS in Action -- Part I
RTI Data-Distribution Service (DDS) Master Class - 2010
RTI Data-Distribution Service (DDS) Master Class - 2010
Zenoh Tutorial
Zenoh Tutorial
Best Practices in MDM with Dan Power
Best Practices in MDM with Dan Power
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
zenoh: The Edge Data Fabric
zenoh: The Edge Data Fabric
The Data Distribution Service Tutorial
The Data Distribution Service Tutorial
Distributed Algorithms with DDS
Distributed Algorithms with DDS
RPC Over DDS
RPC Over DDS
Semelhante a Standardizing the Data Distribution Service (DDS) API for Modern C++
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
Sumant Tambe
Introduction to OMG DDS (1 hour, 45 slides)
Introduction to OMG DDS (1 hour, 45 slides)
Gerardo Pardo-Castellote
DDS Enabling Open Architecture
DDS Enabling Open Architecture
Real-Time Innovations (RTI)
RTI Technical Road Show SPAWAR SD
RTI Technical Road Show SPAWAR SD
Real-Time Innovations (RTI)
A Gentle Introduction to OpenSplice DDS
A Gentle Introduction to OpenSplice DDS
Angelo Corsaro
Dds the ideal_bus_for_event_processing_engines
Dds the ideal_bus_for_event_processing_engines
Gerardo Pardo-Castellote
Advanced OpenSplice Programming - Part II
Advanced OpenSplice Programming - Part II
Angelo Corsaro
Cyclone DDS Unleashed: The Origins
Cyclone DDS Unleashed: The Origins
ZettaScaleTechnology
Getting Started with OpenSplice DDS Community Ed.
Getting Started with OpenSplice DDS Community Ed.
Angelo Corsaro
Easing Integration of Large-Scale Real-Time Systems with DDS
Easing Integration of Large-Scale Real-Time Systems with DDS
Rick Warren
DDS: The data-centric future beyond message-based integration
DDS: The data-centric future beyond message-based integration
Gerardo Pardo-Castellote
MBSE meets Industrial IoT: Introducing the New MagicDraw Plug-in for RTI Co...
MBSE meets Industrial IoT: Introducing the New MagicDraw Plug-in for RTI Co...
Istvan Rath
Optimizing Lustre and GPFS with DDN
Optimizing Lustre and GPFS with DDN
inside-BigData.com
Interoperability for Intelligence Applications using Data-Centric Middleware
Interoperability for Intelligence Applications using Data-Centric Middleware
Gerardo Pardo-Castellote
DDS for JMS Programmers
DDS for JMS Programmers
Angelo Corsaro
10 Reasons for Choosing OpenSplice DDS
10 Reasons for Choosing OpenSplice DDS
Angelo Corsaro
Fiware - communicating with ROS robots using Fast RTPS
Fiware - communicating with ROS robots using Fast RTPS
Jaime Martin Losa
DDS Interoperability Demo
DDS Interoperability Demo
Angelo Corsaro
UML Profile for DDS
UML Profile for DDS
Angelo Corsaro
Introduction to DDS: Context, Information Model, Security, and Applications.
Introduction to DDS: Context, Information Model, Security, and Applications.
Gerardo Pardo-Castellote
Semelhante a Standardizing the Data Distribution Service (DDS) API for Modern C++
(20)
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
Introduction to OMG DDS (1 hour, 45 slides)
Introduction to OMG DDS (1 hour, 45 slides)
DDS Enabling Open Architecture
DDS Enabling Open Architecture
RTI Technical Road Show SPAWAR SD
RTI Technical Road Show SPAWAR SD
A Gentle Introduction to OpenSplice DDS
A Gentle Introduction to OpenSplice DDS
Dds the ideal_bus_for_event_processing_engines
Dds the ideal_bus_for_event_processing_engines
Advanced OpenSplice Programming - Part II
Advanced OpenSplice Programming - Part II
Cyclone DDS Unleashed: The Origins
Cyclone DDS Unleashed: The Origins
Getting Started with OpenSplice DDS Community Ed.
Getting Started with OpenSplice DDS Community Ed.
Easing Integration of Large-Scale Real-Time Systems with DDS
Easing Integration of Large-Scale Real-Time Systems with DDS
DDS: The data-centric future beyond message-based integration
DDS: The data-centric future beyond message-based integration
MBSE meets Industrial IoT: Introducing the New MagicDraw Plug-in for RTI Co...
MBSE meets Industrial IoT: Introducing the New MagicDraw Plug-in for RTI Co...
Optimizing Lustre and GPFS with DDN
Optimizing Lustre and GPFS with DDN
Interoperability for Intelligence Applications using Data-Centric Middleware
Interoperability for Intelligence Applications using Data-Centric Middleware
DDS for JMS Programmers
DDS for JMS Programmers
10 Reasons for Choosing OpenSplice DDS
10 Reasons for Choosing OpenSplice DDS
Fiware - communicating with ROS robots using Fast RTPS
Fiware - communicating with ROS robots using Fast RTPS
DDS Interoperability Demo
DDS Interoperability Demo
UML Profile for DDS
UML Profile for DDS
Introduction to DDS: Context, Information Model, Security, and Applications.
Introduction to DDS: Context, Information Model, Security, and Applications.
Mais de Sumant Tambe
Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presented
Sumant Tambe
Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++
Sumant Tambe
Tuning kafka pipelines
Tuning kafka pipelines
Sumant Tambe
New Tools for a More Functional C++
New Tools for a More Functional C++
Sumant Tambe
C++ Coroutines
C++ Coroutines
Sumant Tambe
C++ Generators and Property-based Testing
C++ Generators and Property-based Testing
Sumant Tambe
Reactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and Rx
Sumant Tambe
RPC over DDS Beta 1
RPC over DDS Beta 1
Sumant Tambe
Remote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJS
Sumant Tambe
Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)
Sumant Tambe
Reactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing for Data-centric Publish/Subscribe
Sumant Tambe
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and Rx
Sumant Tambe
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
Sumant Tambe
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
Sumant Tambe
An Extensible Architecture for Avionics Sensor Health Assessment Using DDS
An Extensible Architecture for Avionics Sensor Health Assessment Using DDS
Sumant Tambe
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Sumant Tambe
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012
Sumant Tambe
Retargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core Systems
Sumant Tambe
Ph.D. Dissertation
Ph.D. Dissertation
Sumant Tambe
Native XML processing in C++ (BoostCon'11)
Native XML processing in C++ (BoostCon'11)
Sumant Tambe
Mais de Sumant Tambe
(20)
Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presented
Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++
Tuning kafka pipelines
Tuning kafka pipelines
New Tools for a More Functional C++
New Tools for a More Functional C++
C++ Coroutines
C++ Coroutines
C++ Generators and Property-based Testing
C++ Generators and Property-based Testing
Reactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and Rx
RPC over DDS Beta 1
RPC over DDS Beta 1
Remote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJS
Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)
Reactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and Rx
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
An Extensible Architecture for Avionics Sensor Health Assessment Using DDS
An Extensible Architecture for Avionics Sensor Health Assessment Using DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012
Retargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core Systems
Ph.D. Dissertation
Ph.D. Dissertation
Native XML processing in C++ (BoostCon'11)
Native XML processing in C++ (BoostCon'11)
Standardizing the Data Distribution Service (DDS) API for Modern C++
1.
Association of C/C++
Users (ACCU) San Francisco Bay Area March 13, 2013 Your systems. Working as one. Sumant Tambe, Ph.D. Senior Software Research Engineer Real-Time Innovations, Inc. www.rti.com © 2013 RTI • COMPANY PROPRIETARY
2.
3/21/2013
© 2013 RTI • COMPANY PROPRIETARY 2
3.
The Rise of
Smart Systems • DDS is for the systems that interact with the real world – Must adapt to changing environment – Cannot stop processing the information – Live within world-imposed timing 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 3 © 2010 Real-Time Innovations, Inc.
4.
DDS: Standards-based Integration
Infrastructure for Critical Applications Streaming Sensors Events Data Real-Time Enterprise Actuators Applications Applications 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 4
5.
DDS
A Family of Standards 2008 2009 2010 2012 2012 2013 UML Profile DDS for DDS DDS-STD-C++ DDS Security RPC over DDS for DDS Lw CCM X-Types DDS-JAVA5 App 2004 App App DDS Spec DDS 2006 DDS DDS Implementation DDS Implementation Implementation Interoperablity Network / TCP / UDP / IP 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 5
6.
Pub/Sub Vs. Data
Distribution • Pub-Sub – Only messages no concept of data – Each message is interpreted without context – Messages must be delivered FIFO or according to some “priority” attribute – No Caching of data – Simple QoS: filters, durability, lifespan • Data-Distribution – Full-fledged data model on wire – Messages represent update to data-objects Data Bus – Data-Objects identify by a key – Middleware maintains state of each object – Objects are cached. Applications can read at leisure – Smart QoS (Ownership, History per key, Deadline) – Subsumes Pub-Sub 3/21/2013 © 2012 RTI • COMPANY CONFIDENTIAL 6
7.
DDS Entities
Domain Participant 1 Domain Participant 2 Data Publisher Writer Data (Foo) Subscriber Reader (Foo) Offered Requested Listener QoS Listener QoS Topics • Participants scope the global data space (domain) • Topics define the data-objects (collections of subjects) • DataWriters publish data on Topics • DataReaders subscribe to data on Topics • A Subscriber may have many DataReaders • A Publisher may have many DataWriters • QoS Policies are used configure the system • Listeners are used to notify the application of events 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 7
8.
DDS Programming (the
classic model) Standard Java IDL Mapping C/C++ DDS API in Interface Definition UML Model of DDS Language (IDL) (Platform-specific) C# (Platform Independent) • IDL cannot capture programming language idioms – E.g., overloaded operators, static functions, new, templates, iterators, STL, meta- programming, exception-safety • IDL-derived language mapping has limited C++ standard library integration – E.g., char * instead of std:string, Sequence instead of std::vector • Awkward memory management for efficiency reasons – The “bucket” pattern: Provide the lower layer a place to put the result. Pollutes API • Not 100% portable – Some DDS types left to implementers to decide – int and struct initialization syntax is different prior to C++11 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 8
9.
C++ Language DDS
PSM Motivations • Intuitive API – Provide better integration with the C++ programming language and the standard library – An API that is efficient, expressive, easy-to-use, easy-to- learn, and exception-safe – Works well with “intellisense” editors • Ensure 100% portability – Drop in replacement of vendor implementations; ideally just a recompile and relink – Standard OMG-managed header files can be used to test compliance and portability • Extensible – Implementers can extend the API • New quality-of-service (QoS) policies, new members in the standard policies, etc. – The extensions are syntactically distinct • Forward-looking – Make special provisions for C++11 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 9
10.
Track DataWriter Example dds::domain::DomainParticipant
dp(0); dds::topic::Topic<Track> topic(dp, “track-topic”); dds::pub::Publisher pub(dp); dds::pub::qos::DataWriterQos dwqos = pub.default_writer_qos() << Reliability::Reliable() << History::KeepLast(10) << Durability::Transient(); dds::pub::DataWriter<Track> dw (pub, topic, dwqos); Track t = { 0xDEAD, “tank” }; // track id and vehicle-type for(;;) { dw.write(t); } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 10
11.
Track DataReader Example try
{ dds::domain::DomainParticipant dp(0); dds::topic::Topic<Track> topic(dp, “track-topic”); dds::sub::Subscriber sub(dp); dds::sub::qos::DataReaderQos drqos = sub.default_reader_qos() << Reliability::BestEffort() << History::KeepLast(5); dds::sub::DataReader<Track> dr (sub, topic, drqos); LoanedSamples<Track> data = dr.read(); std::for_each(data.begin(), data.begin(), printTanks); } catch (const dds::core::PreconditionNotMetError&) { ... } catch (const dds::core::Exception& ex) { ... } catch (const std::exception& ex) { ... } catch (...) { ... } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 11
12.
ISO/IEC C++ 2003
Language DDS PSM • Organization – C++ namespaces group relevant classes – Fine grain #includes also possible dds core domain topic pub sub detail detail detail detail detail xtypes qos qos qos qos detail detail detail detail detail cond cond detail detail status detail status Standard namespaces policy detail detail detail Implementation namespace 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 12
13.
Exceptions for Error
Handling std::exception dds::core::Exception std::runtime_error std::logic_error dds::core::Error std::invalid_argument OutOfResourcesError InvalidArgumentError InvalidDataError TimeoutError AlreadyClosedError InvalidDowncastError IllegalOperationError NullReferenceError ImmutablePolicyError InconsistentPolicyError NotEnabledError PreconditionNotMetError UnsupportedError 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 13
14.
Instantiating the Standard
API • The standard uses DELEGATEs—provided by vendors–to instantiate the concrete types – Compliant implementations must not change the standard API – Vendor-specific extensions are possible but accessible only through the DELEGATEs – The standard provides a well-defined syntax to access the extensions – Vendor-specific types appear only in the detail namespace namespace rti { class InstanceHandleImpl; // vendor-specific } namespace dds { namespace core { template <typename DELEGATE> class TInstanceHandle { ... }; // standard } } namespace dds { namespace core { namespace { detail typedef dds::core::TInstanceHandle<rti::InstanceHandleImpl> InstanceHandle; // vendor-specific } } } namespace dds { namespace core { typedef dds::core::detail::InstanceHandle InstanceHandle; // bring name in the standard namespace. } } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 14
15.
Accessing Vendor-specific Extensions •
Vendor-specific extensions are possible but accessible only through the DELEGATEs • The standard provides a well-defined syntax to access the extensions • Dot: obj.method() for standard API • Arrow: obj->extension_method() for extensions namespace rti { class InstanceHandleImpl { bool is_nil() const; // standard void rti_extension(); // extension }; // vendor-specific } namespace dds { namespace core { template <typename DELEGATE> class TInstanceHandle // standard { DELEGATE * operator -> (); const DELEGATE * operator -> () const; bool is_nil() const; }; // standard } } namespace dds { namespace core { namespace { detail typedef dds::core::TInstanceHandle<rti::InstanceHandleImpl> InstanceHandle; // vendor-specific } } } namespace dds { namespace core { typedef dds::core::detail::InstanceHandle InstanceHandle; // bring name in the standard namespace. } } int main(void) { dds:core::InstanceHandle handle = ...; handle.is_nil(); // standard handle->rti_extension(); // extension } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 15
16.
Instantiating the Standard
API (templates) • Some DELEGATEs are themselves templates • The type parameter is provided by the user – The standard must forward the vendor-specific templates to the standard namespaces namespace rti { template <class T> class DataReader { ... }; // vendor-specific } C++11 template aliases would namespace dds { namespace sub { namespace detail { using rti::DataReader; allow different names template<class T> } } } using DataReader = rti::DataReaderImpl<T>; namespace dds { namespace sub Can’t change! template <typename T, template <typename Q> class DELEGATE = dds::sub::detail::DataReader> class DataReader { ... }; // standard } } int main(void) { dds::sub::DataReader<Foo> dr; // user-code } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 16
17.
DDS C++ PSM
Object Model • Reference Types – E.g., DomainParticipant, Subscriber, Publisher, RefType DataReader, DataWriter, etc. Delegate Objects – Shallow copy semantics; Identical if the pointers match – Inherit from core::Reference<DELEGATE> • Manage memory for DDS entities automatically • Reference counted—similar to boost::shared_ptr Impl. • Works with core::WeakReferenceReference<DELEGATE> – Similar to boost::weak_ptr – Can be constructed from strong references only – You can either check if the weak reference is valid or get the strong reference from it • Value Types – E.g., Policies (History, Reliabiliy, Durability, etc.), QoS objects, InstanceHandle – Deep copy semantics; Identical if the contents match – Inherit from core::Value<DELEGATE> 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 17
18.
DDS Real-Time QoS
Policies QoS Policy QoS Policy DURABILITY USER DATA User QoS HISTORY TOPIC DATA Volatility READER DATA LIFECYCLE GROUP DATA WRITER DATA LIFECYCLE PARTITION Presentation LIFESPAN PRESENTATION Infrastructure ENTITY FACTORY DESTINATION ORDER RESOURCE LIMITS OWNERSHIP Redundancy RELIABILITY OWNERSHIP STRENGTH Delivery TIME BASED FILTER LIVELINESS Transport DEADLINE LATENCY BUDGET CONTENT FILTERS TRANSPORT PRIORITY 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 18
19.
Supporting QoS Extensibility •
Vendors provide many additional QoS policies or additional attributes for the standard QoS policies – For example, RTI Connext™ DDS provides extension attributes to standard QoS policies • Reliability::max_blocking_time • Reliability::acknowledgement_kind • History::refilter_qos – Also, RTI Connext™ DDS provides many extension QoS • Control receiver thread pool • Batching of data samples • Various transports, and more… • The standard wants to provide a consistent, extensible API that accommodates the standard as well as extension QoS policies. 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 19
20.
Extensible Qos via
EntityQos namespace dds { namespace core { • An EntityQos object represents a collection of policies template <typename DELEGATE> class dds::core::EntityQos – typedef EntityQos<rti::DataReaderQos> : public dds::core::Value<DELEGATE> DataReaderQos { – typedef EntityQos<rti::DataWriterQos> public: DataWriterQos template <typename POLICY> • Provides a DSL using the overloaded << and EntityQos& policy(const POLICY& p); >> operators in C++. For example, template <typename POLICY> datawriter_qos << History::KeepAll(); const POLICY& policy() const; datawriter_qos.policy(History::KeepAll()); History h = datawriter_qos.policy<History>(); template <typename POLICY> POLICY& policy(); • Extensible naturally to vendor-specific Qos template <typename POLICY> policies EntityQos& operator << (const POLICY& p); template <typename POLICY> const EntityQos& operator >> (POLICY& p) const; }; } } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 20
21.
Is EntityQos too
Generic? Qos Policy Applicability • An EntityQos object represents a collection of DURABILITY T, DR, DW policies DURABILITY_SERVICE T, DW – typedef EntityQos<rti::DataReaderQos> DataReaderQos LIFESPAN T, DW – typedef EntityQos<rti::DataWriterQos> DataWriterQos HISTORY T, DR, DW • Not all policies can be combined with all Qos PRESENTATION P, S objects (see table) RELIABILITY T, DR, DW • How to prevent setting policies that do not make PARTITION P, S sense for a qos? DESTINATION_ORDER T, DR, DW – For example, prevent assignment of partition to DWQos at OWNERSHIP T, DR, DW compile-time OWNERSHIP_STRENGTH DW – datawriter_qos << Partition(“A-stocks”); DEADLINE T, DR, DW LATENCY_BUDGET T, DR, DW TRANSPORT_PRIORITY T, DW TIME_BASED_FILTER DR RESOUCE_LIMITS T, DR, DW USER_DATA DP, DR, DW TOPIC_DATA T GROUP_DATA P, S T=Topic, DR=DataReader, DW=DataWriter, P=Publisher, S=Subscriber, DP=DomainParticipant 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 21
22.
Constraining EntityQos
• Define “marker” interfaces ForDataReader, ForDataWriter, ForTopic etc. • Have policies inherit from appropriate marker interfaces – class Reliability : public ForDataReader, ForDataWriter, ForTopic { ... } – class Partition : public ForPublisher, ForSubscriber { ... } • Use SFINAE or static_assert to disallow invalid combinations template <typename DELEGATE> template <typename DELEGATE> class dds::core::EntityQos class dds::core::DataReaderQos : public dds::core::Value<DELEGATE> : public dds::core::EntityQos<DELEGATE> { { public: public: template <typename POLICY> template <typename POLICY> typename enable_if<is_base_of<ForDataReader, POLICY>, EntityQos& DataReaderQos &>::type operator << (const POLICY& p); operator << (const POLICY& p) { ... } // ... // alternatively }; template <typename POLICY> DataReaderQos & operator << (const POLICY& p) { OMG_STATIC_ASSERT(is_base_of<ForDataReader, POLICY>::Value); } }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 22
23.
Choice of Error:
SFINAE • SFINAE (Substitution Failure Is Not An Error) – Remove the function out of the overload set – Pros: The error is shown in the user code as opposed to the library code – Con: Error: “Failed to specialize” – not very informative 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 23
24.
Choice of Error:
static_assert • Insert a static_assert with a descriptive message. – Pros: Clear message. However, can’t be customized. It would be nice to do printf-style static_assert. – Con: The error is shown in the library implementation – Con: C++11 only 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 24
25.
Reading/Taking Data • The
API provides “data-centric” access – DDS provides built-in caching for future use – read—means access data but keep it in the middleware buffer • Internal queue does not grow unbounded because QoS policies limit resource usage – take—means access data and remove it from the middleware buffer – Query/Filter data based on • Sample state (read or not read) – “Have I read this sample before or not?” • View state (viewed or not viewed) – “Is this a new tank or I’ve read something about it?” – based on key • Instance state (alive, not alive_disposed, not_alive_no_writers) – “Is there anyone out there talking about that specific tank?” • A specific instance (instance_handle) – “What’s latest on this specific tank?” • Next instance (analogous to an iterator of instances) – “Get me data on each tank in the convoy.” – based on some total ordering of the key • Samples that match an expression (query condition) – “Tell me about the tanks where x < 25 and y > 10”. 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 25
26.
Reading/Taking Data •
6 basic functions template <typename T, template <typename Q> class DELEGATE> class dds::sub::DataReader { LoanedSamples<T> read(); // LoanedSamples<T> provides begin/end LoanedSamples<T> take(); template <typename SamplesFWIterator> uint32_t read(SamplesFWIterator sfit, uint32_t max_samples); // forward iterator template <typename SamplesFWIterator> uint32_t take(SamplesFWIterator sfit, uint32_t max_samples); // forward iterator template <typename SamplesBIIterator> uint32_t read(SamplesBIIterator sbit); // back-insert iterator template <typename SamplesBIIterator> uint32_t read(SamplesBIIterator sbit); // back-insert iterator }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 26
27.
Reading/Taking/Querying Data • Fluent
interface in C++ – Method chaining std::vector<Track> tracks = ... DataReader<Track> dr = ... InstanceHandle handle = dr.lookup_instance(Track(id)); dr.select() .instance(handle) All 6 basic forms .content(Query(dr, “x < 25 AND y > 10”)) are applicable .state(DataState::new_data()) .max_samples(100) .take(std::back_inserter(tracks)); 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 27
28.
Abstracting Queries using
Selector • The Selector separates how to read from what to read – N+M instead of N*M – How: LoanedSamples, Forward iterators, back-insert iterators – What: specified using the query object template <typename T, template <typename Q> class DELEGATE> class dds::sub::DataReader { class Selector { public: Selector(DataReader& dr); Selector& instance(const dds::core::InstanceHandle& h); Selector& next_instance(const dds::core::InstanceHandle& h); Selector& state(const dds::sub::status::DataState& s); Selector& content(const dds::sub::Query& query); Selector& max_samples(uint32_t n); // Selector also has the basic read/take functions // which delegate to the DataReader. }; }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 28
29.
Reading Data using
Conditions and WaitSets Condition GuardCondition StatusCondition ReadCondition Provides a way for an Wakes up the application Wakes up the application application to signal based on status m/w based on the status of the conditions to other entities. E.g., sample data. E.g., threads DATA_AVAILABLE NOT_VIEWED_SAMPLE LIVELINESS_LOST NEW_VIEW_STATE SAMPLE_LOST ALIVE_INSTANCE_STATE DEADLINE_MISSED • WaitSets and conditions work together – Multiple conditions can be attached to a WaitSet – WaitSet unblocks when one or more conditions become active 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 29
30.
Managing DDS Entities
Polymorphically Entity T T Domain Publisher TopicDescription DataReader Participant T Subscriber DataWriter T T ContentFilterTopic Topic template <typename DELEGATE> class dds::core::TEntity : public dds::core::Reference<DELEGATE> { public: void enable(); const dds::core::status::StatusMask status_changes(); const dds::core::InstanceHandle instance_handle() const; Not virtual void close(); void retain(); }; • Polymorphism is an implementation detail! – Managed internally by the DELEGATEs using an analogous hierarchy of EntityImpl objects 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 30
31.
DDS Entities and
Listeners Entity T T T Domain Publisher Subscriber Topic DataWriter DataReader Participant T T T Domain Publisher Subscriber Topic DataWriter DataReader Participant Listener Listener Listener Listener Listener Listener • Listeners allow asynchronous notification of entity status changes • DataReader – Data available, requested deadline missed, liveliness changed, requested incompatible QoS, sample rejected, sample lost, subscription matched • DataWriter – Offered deadline missed, liveliness lost, offered incompatible qos, publication matched 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 31
32.
Typed Listeners template <typename
T> template <typename T> class dds::sub::DataReaderListener { class dds::pub::DataWriterListener { public: public: virtual ~DataReaderListener() {} virtual ~DataWriterListener() { } virtual void on_requested_deadline_missed( virtual void on_offered_deadline_missed( DataReader<T>& the_reader, const RequestedDeadlineMissedStatus& status) = 0; DataWriter<T>& writer, const OfferedDeadlineMissedStatus& status) = 0; virtual void on_requested_incompatible_qos( DataReader<T>& the_reader, virtual void on_offered_incompatible_qos( const RequestedIncompatibleQosStatus& status) = 0; DataWriter<T> writer, const OfferedIncompatibleQosStatus& status) = 0; virtual void on_sample_rejected( DataReader<T>& the_reader, virtual void on_liveliness_lost( const SampleRejectedStatus& status) = 0; DataWriter<T>& writer, const LivelinessLostStatus& status) = 0; virtual void on_liveliness_changed( DataReader<T>& the_reader, const LivelinessChangedStatus& status) = 0; virtual void on_publication_matched( DataWriter<T>& writer, virtual void on_data_available( const PublicationMatchedStatus& status) = 0; DataReader<T>& the_reader) = 0; }; virtual void on_subscription_matched( DataReader<T>& the_reader, const SubscriptionMatchedStatus& status) = 0; virtual void on_sample_lost( DataReader<T>& the_reader, const SampleLostStatus& status) = 0; }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 32
33.
DDS Entities and
Listeners T T T Specific Typed Less Specific Untyped Untyped “catch-all” Least listener Specific 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 33
34.
Inheritance Dilemma • Untyped
“catch-all” listeners inherit from typed listeners – E.g., DomainParticipantListener serves like “catch-all” – One place to handle status changes for all the constituent Publishers, Subscribers, DataReaders, DataWriters. • However, untyped listeners have no knowledge of type T – Type T is a purely DataReader/DataWriter concern – Publishers, Subscribers, and DomainPartcipant don’t have much to do with the type • Except that the type must be registered with the DomainParticipant • C++ Issue – How to pass a typed DataReader/DataWriter to the untyped listener which has no knowledge of type T? – How to “erase” type information superficially? 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 34
35.
Type Erasure for
DataReader, DataWriters, and Topics • DataReaders, DataWriters, Topics, and TopicDescriptions are parameterized over types (E.g., DataReader<Foo>) • std::vector<DataReader> cannot be created but would be useful • Welcome type erased entities – AnyDataReader, AnyDataWriter, AnyTopic, AnyTopicDescription • Access type independent API Type Erased • Create std::vector<AnyDataWriter> (but not forgotten!) class dds::pub::AnyDataWriter { public: const dds::pub::qos::DataWriterQos& qos() const; void qos(const ::dds::pub::qos::DataWriterQos& q); const std::string& topic_name() const; const std::string& type_name() const; void wait_for_acknowledgments(const dds::core::Duration& timeout); void close(); void retain(bool b); // ... }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 35
36.
Type-Erased Listeners
AnyDataWriterListener AnyTopicListener AnyDataReaderListener Specific Erased Type Less Specific Untyped Untyped “catch-all” Least listener Specific 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 36
37.
Inside AnyDataWriter (Type
Erasure) • AnyDataWriter constructor accepts any typed DataWriter • Internally it is stored without type information • AnyDataWriter::get<T> retrieves the typed DataWriter namespace dds { namespace pub { namespace detail { class DWHolderBase; template <typename T> class DWHolder; } } } class dds::pub::AnyDataWriter { public: template <typename T> AnyDataWriter(const dds::pub::DataWriter<T>& dw) : holder_(new detail::DWHolder<T>(dw)) {} template <typename T> dds::pub::DataWriter<T> get() { return dynamic_cast<DWHolder<T> *>(holder_)->get(); } private: detail::DWHolderBase* holder_; // ... }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 38
38.
Inside AnyDataWriter class dds::pub::detail::DWHolderBase
{ public: virtual ~DWHolderBase() = 0; virtual const dds::pub::qos::DataWriterQos& qos() const = 0; virtual void qos(const ::dds::pub::qos::DataWriterQos& qos) = 0; virtual const std::string& topic_name() const = 0; virtual const std::string& type_name() const = 0; }; template <typename T> class dds::pub::detail::DWHolder : public DWHolderBase { public: DWHolder(const dds::pub::DataWriter<T>& dw) : dw_(dw) { } virtual ~DWHolder() { } dds::pub::DataWriter<T> get() const { return dw_; } // Implement the rest of the DWHolderBase abstract base class private: dds::pub::DataWriter<T> dw_; }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 39
39.
Mapping Types
DDS Type Boolean C++ Type Bool Char8 Char Char32 wchar_t • DDS-PSM-Cxx maps the Byte uint8_t DDS PIM types to C++ Int16 int16_t types UInt16 uint16_t Int32 int32_t UInt32 uint32_t Int64 int64_t UInt64 uint64_t Float32 float Float64 Double Float128 long double String<Char8> std::string String<Char32> std::wstring sequence<T> std::vector<T> map<K,V> std::map<K,V> T[N] dds::core::array<T, N> 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 40
40.
Mapping Enumerations • Classic
DDS API uses C++ enumerations to model entity status kinds, QoS policy kinds, sample states, view states, instance states. For example, enum StatusKind { DDS_INCONSISTENT_TOPIC_STATUS , DDS_SAMPLE_LOST_STATS, DDS_SAMPLE_REJECTED_STATUS, … }; enum DurabilityKind { VOLATILE, TRANSIENT, TRANSIENT_LOCAL, PERSISTENT }; • C++ enumerations are convenient because bitwise-OR allows masking – E.g., StatusMask for listeners and status conditions • C++ enumerations, however, suffer from two major problems – Implicit conversion to integer, long, etc. – Scoping issues StatusKind status = INCONSISTENT_TOPIC; bool flag = (status > PERSISTENT); // oops! DataReader<Foo> dr(sub, topic,qos,listener, DDS_SAMPLE_LOST_STATUS | TRANSIENT); // oops! 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 41
41.
Improving Type-Safety • DDS-PSM-Cxx
improves type-safety – SampleState, ViewState, InstanceState are classes with named constructors – DataState and StatusMask are classes with named constructors (and possibly fluid interfaces) – Policy kinds are represented using the type-safe enumeration idiom class dds::sub::status::SampleState class StatusMask : public std::bitset<BIT_COUNT> : public std::bitset<STATUS_COUNT> { { static const SampleState read(); static const StatusMask inconsistent_topic(); static const SampleState not_read(); static const StatusMask sample_lost(); static const SampleState any(); static const StatusMask sample_rejected(); } // many more }; // For example DataReader<Track> datareader (sub, topic, qos, listener, StatusMask::sample_lost().inconsistent_topic().sample_rejected()); datareader.Select().state(DataState(SampleState::not_read(), ViewState::new_view(), InstanceState::alive())).take(); 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 42
42.
Safer Enumerations int main
(void) { DurabilityKind status = DurabilityKind::VOLATILE; bool flag = (status > PERSISTENT); // Compiler error } int main (void) { DurabilityKind status = DurabilityKind::VOLATILE; bool flag = (status > DurabilityKind::PERSISTENT); // fine! } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 43
43.
PolicyKinds using the
Type-safe Enumerations template <typename def, namespace dds { typename inner = typename def::type> namespace core { class dds::core::safe_enum : public def { namespace policy { typedef typename def::type type; inner val; template <class DELEGATE> public: class History : public Value<DELEGATE> { safe_enum(type v) : val(v) {} public: inner underlying() const { return val; } History(); bool operator == (const safe_enum & s) const; History(HistoryKind kind, int32_t depth); bool operator != (const safe_enum & s) const; // other operators }; HistoryKind kind() const; History & kind(HistoryKind kind); namespace dds { namespace core { namespace policy { // ... struct History_def { }; enum type { KEEP_LAST, KEEP_ALL }; }; } typedef dds::core::safe_enum<History_def> HistoryKind; } } struct Durability_def { enum type { VOLATILE, TRANSIENT_LOCAL, TRANSIENT, PERSISTENT }; }; typedef dds::core::safe_enum<Durability_def> DurabilityKind; } } } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 44
44.
Managing The Entity
Lifecycle • Entity Survival rules! – Any entity to which the application has a direct reference (but not a WeakReference) is still in use. – Any entity with a non-null listener is still in use. – Any entity that has been explicitly retained is still in use. Application can retrive the entity anytime using dds::pub::find, dds::sub::find, etc. – If a child object is in use, the parent is also in use. (E.g., All DataReaders keep the corresponding Subscribers and the DomainParticipant alive) – Regardless of references/listeners/retain, close terminates the entity. • DDS PSM C++ relies on the shared pointer idiom for entity lifecycle – dds::core::Reference uses shared_ptr internally App calls Keeping the hierarchy alive With App level References With App-level Listener retain() Participant R R R R DR L R Subscriber DR DR R R Delegate Application space Application space Delegate Delegate DR 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 45
45.
Mapping User-Defined Data
Types User-Defined IDL C++ Representation (possibly generated) typedef sequence<octet> plot_t; typedef std::vector<uint8_t> plot_t; struct RadarTrack { class RadarTrack { string id; private: long lat; // state representation is implementation dependent long lon; long alt; //@optional public: plot_t plot; typedef smart_ptr_traits<plot_t>::ref_type plot_ref_t; }; RadarTrack(); RadarTrack(const std::string & id, int32_t lat, int32_t lon, int32_t alt, std::vector<uint8_t> * plot); std::string & id(); const std::string & id() const; void id(const std::string &); int32_t lat() const; void lat(int32_t); int32_t lon() const; void lon(int32_t); dds::core::optional<int32_t> alt() const; void alt(int32_t); void alt(const dds::core::optional<int32_t> &); plot_ref_t & plot(); const plot_ref_r & plot() const; void plot(const plot_ref_t &); }; 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 46
46.
Exception-Safety: Read/Take API
• 6 basic functions template <typename T, template <typename Q> class DELEGATE> class dds::sub::DataReader { LoanedSamples<T> read(); // LoanedSamples<T> provides begin/end LoanedSamples<T> take(); template <typename SamplesFWIterator> uint32_t read(SamplesFWIterator sfit, uint32_t max_samples); // forward iterator template <typename SamplesFWIterator> uint32_t take(SamplesFWIterator sfit, uint32_t max_samples); // forward iterator template <typename SamplesBIIterator> uint32_t read(SamplesBIIterator sbit); // back-insert iterator template <typename SamplesBIIterator> uint32_t read(SamplesBIIterator sbit); // back-insert iterator }; Is this API Exception-Safe? 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 47
47.
Exception Safety: Read/Take
API • Exception-Safety Recap – Basic: No resource leaks – Strong: Object state remains unaltered. Roll-back semantics – No-throw: The operation will not throw—ever – Exception Neutrality: Propagate the (potentially unknown) exception as it is while maintaining basic or strong guarantee • Consider the following function that may throw template <typename SamplesBIIterator> uint32_t DataReader<T>::read(SamplesBIIterator sbit); // back-insert iterator – The sample copy assignment operator may throw – The std::vector<Foo>::push_back may throw • Only basic guarantee – The application-level std::vector and sample data might have change arbitrarily in the case of exception – What about the middleware? • What is the state of the middleware? • Can I get the lost samples (those I could not read) again? – The sample that causes an exception is important for debugging • Exception-Safety has two sides – Application-perspective – Middleware perspective 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 48
48.
Exception-Safety Dual Perspective
Application level App layer std::vector Read data from the lower layer (just pointers) Exception! Cannot undo DDS-PSM-C++ read! API layer All side-effects of Copy data to the app layer read/take are complete Native Middleware Queued Samples DataReader Layer (in C) Metadata about samples Metadata changes from not-read to read when m/w layer read completes • An exception in the middle C++ layer leaves data stranded – In practice it means data that caused exception is lost • Lower layer API does not provide roll-back semantics—undo read as if nothing happened – Undo semantics will limit concurrency substantially – DDS-PSM-C++ layer and all the layers below become a critical section—No new samples can be queued, no other thread can read data, etc. 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 49
49.
Exception-Safety: Read/Take API •
Towards a better solution – Do not copy data in the app-level vector • Consequence: Iterator-based API, although convenient, is not exception-safe – Simply return a container of pointers to the middleware buffers Samples<T> DataReader<T>::read(); Samples<T> DataReader<T>::take(); • However, the object must manage the responsibility of the m/w buffers – Use RAII in Samples<T> to manage the resources – However, copy-assign and copy-ctor of Sample<T> must now perform deep copies » Making deep copies during return may itself throw! » Remember: Exception-safe stack has stack::pop and stack::top. » Consequence: RAII-based solution is too expensive and not exception safe 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 50
50.
Exception-Safety: Read/Take API •
Towards a better solution – How about the shared pointer idiom? Memory allocation! May throw SharedSamples<T> DataReader<T>::read() { T * data = mw_read(); std::shared_ptr sp(data, mw_custom_release); return SharedSamples<T>(sp); } – Creation of shared_ptr may itself throw • shared_ptr allocates a reference count – Allocate memory before mw_read() Unconditional memory allocation (slow) SharedSamples<T> DataReader<T>::read() { std::shared_ptr sp(new placeholder(), mw_custom_release); T * data = mw_read(); sp->set(data); return sp; } – Preallocating the ref-count forces dynamic memory allocation on each read call • Expensive • There may be no data available to read/take 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 51
51.
Exception-Safety Read/Take API •
Welcome move-semantics! • LoanedSamples<T> LoanedSamples<T> DataReader::read(); LoanedSamples<T> DataReader::take(); • LoanedSamples<T> moves data from within the function to outside – Exactly one LoanedSamples<T> object owns the data at a time • No copy-assign, copy-ctor. Only move-assign and move-ctor – Contains just a pointer to the data. Moving a pointer never throws – RAII still applicable: The last LoanedSamples<T> returns the buffers to the m/w – Can be implemented in C++03—very easy in C++11 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 52
52.
The Move-Constructor idiom
for LoanedSamples template <class T> class LoanedSamples { template <class U> struct proxy { U *resource_; }; Private T * resource_; LoanedSamples(LoanedSamples &) throw (); LoanedSamples & operator = (LoanedSamples &) throw (); public: explicit LoanedSamples (T * r = 0) : resource_(r) { } ~LoanedSamples () throw() { delete resource_; } // Assuming std:::auto_ptr like behavior. LoanedSamples(proxy<T> p) throw () // The proxy move constructor : resource_(p.resource_) { } LoanedSamples & operator = (proxy<T> p) { if(this->resource_) delete resource_; this->resource_= p.resource_; return *this; } operator proxy<T> () throw () { // A helper conversion function. Note that it is non-const proxy<T> p; p.resource_ = this->resource_; this->resource_ = 0; return p; // Resource moved to the temporary proxy object. } }; template <class T> LoanedSamples<T> move(LoanedSamples <T> & ls) throw() { // Convert explicitly to a non-const reference to rvalue return LoanedSamples<T>(detail::proxy<T>(ls)); } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 53
53.
Using LoanedSamples<T> LoanedSamples<Track> source() {
LoanedSamples<Track> local(new Track()); return move(local); } void sink (LoanedSamples<Track> ls) { // Do something useful with ls. ls is deleted automatically at the end. } int main(void) { LoanedSamples<Track> ls(source()); // OK LoanedSamples<Track> ls2; ls2 = ls; // Compiler error ls2 = move(ls); // OK sink(ls2); // Compiler error sink(move(ls2)); // OK } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 54
54.
LoanedSamples<T> and SharedSamples<T> •
LoanedSamples<T> is a move-only type – C++03 standard library does not play nicely with move-only types – E.g., std::vector<std::auto_ptr<T>> fails to compile – LoanedSamples<T> move-constructor and move-assign operators are private – LoanedSamples<T> resists sharing • SharedSamples<T> – References counted container of Ts – Buffers returned to the m/w when all reference cease to exist – Works fine with STL because copy-assign and copy-ctor are public – Created from LoanedSamples<T> only – Extra cost of allocating the reference-count is now explicit (pay only if you use it) 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 55
55.
DDS API for
C++11 • DDS-PSM-Cxx makes special provisions for C++11 environment – LoanedSamples<T> is a first-class move-only type – Namespace-level begin, end, cbegin, and cend functions to facilitate C++11 range-based for loop LoanedSamples<Foo> ls = datareader.read(); for(auto & sample : ls) { /* use sample */ } – dds::core::array is a template alias for std::array namespace dds { namespace core { template <class T> using array = std::array<T>; } } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 56
56.
Type-safe Enumerations in
C++11 namespace dds { namespace core { namespace policy { struct History_def { enum type { KEEP_LAST, KEEP_ALL }; }; typedef dds::core::safe_enum<History_def> HistoryKind; struct Durability_def { C++03 enum type { VOLATILE, TRANSIENT_LOCAL, TRANSIENT, PERSISTENT }; }; typedef dds::core::safe_enum<Durability_def> DurabilityKind; Syntactically compatible } } } E.g., HistoryKind::KEEP_ALL namespace dds { namespace core { namespace policy { enum class HistoryKind { KEEP_LAST, KEEP_ALL }; C++11 enum class DurabilityKind { VOLATILE, TRANSIENT_LOCAL, TRANSIENT, PERSISTENT }; } } } 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 57
57.
C++11 Language Binding
for User-Defined Types • IDL to C++11 language mapping in a slide – OMG standard – http://www.omg.org/spec/CPP11/1.0/ – DDS-PSM-Cxx uses the IDL to C++11 mapping with some minor tweaks • No CORBA::TypeCode, Any, Fixed types, etc. • Mapping of struct is the most relevant – Uses many C++11 features and libraries • nullptr, strongly typed enums, constexpr, move-semantics, uniform initialization, final, etc. • std::shared_ptr, std::weak_ptr, std::array, type traits, exceptions, etc. 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 58
58.
Pass-by-value idiom in
the IDL2C++11 Specification IDL C++11 class Book { typedef sequence<string> Authors; Book(); Book(const Book &); struct Book { Book(Book &&); string title; Book & operator = (const Book &); Authors authors; Book & operator = (Book &&); string publisher; Book (std::string title, long pub_year; std::vector<string> authors, }; std::string publisher, int32_t pub_year); // ... }; • Mapping for IDL struct types uses the pass-by-value idiom – The constructor take parameters by value – A typical implementation will std::move the parameters – The spec uses move-friendly types only – See C++11 Idioms talk @ Silicon Valley Code Camp 2012 for more details 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 59
59.
Thank You! •
More Information – DDS PSM C++ • http://www.omg.org/spec/DDS-PSM-Cxx/ – Real-Time Innovations • www.rti.com 3/21/2013 © 2013 RTI • COMPANY PROPRIETARY 60
Baixar agora