SlideShare a Scribd company logo
1 of 59
Download to read offline
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
3/21/2013   © 2013 RTI • COMPANY PROPRIETARY   2
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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

More Related Content

What's hot

DDS Tutorial -- Part I
DDS Tutorial -- Part IDDS Tutorial -- Part I
DDS Tutorial -- Part IAngelo Corsaro
 
Cloud security and security architecture
Cloud security and security architectureCloud security and security architecture
Cloud security and security architectureVladimir Jirasek
 
S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)Prafull Johri
 
The Data Distribution Service Tutorial
The Data Distribution Service TutorialThe Data Distribution Service Tutorial
The Data Distribution Service TutorialAngelo Corsaro
 
Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...
Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...
Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...Majid Hajibaba
 
Introduction to New CloudWatch Agent
Introduction to New CloudWatch AgentIntroduction to New CloudWatch Agent
Introduction to New CloudWatch AgentNoritaka Sekiyama
 
DDS in Action -- Part I
DDS in Action -- Part IDDS in Action -- Part I
DDS in Action -- Part IAngelo Corsaro
 
Cloud Application Development – The Future is now
Cloud Application Development – The Future is nowCloud Application Development – The Future is now
Cloud Application Development – The Future is nowSPEC INDIA
 
The Data Distribution Service
The Data Distribution ServiceThe Data Distribution Service
The Data Distribution ServiceAngelo Corsaro
 
Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018
Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018
Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018Amazon Web Services Korea
 
Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...
Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...
Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...Amazon Web Services Korea
 
Transport Layer Security (TLS)
Transport Layer Security (TLS)Transport Layer Security (TLS)
Transport Layer Security (TLS)Arun Shukla
 
Introduction to DDS
Introduction to DDSIntroduction to DDS
Introduction to DDSRick Warren
 
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 ThingsComparison of MQTT and DDS as M2M Protocols for the Internet of Things
Comparison of MQTT and DDS as M2M Protocols for the Internet of ThingsReal-Time Innovations (RTI)
 
202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...
202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...
202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...Amazon Web Services Japan
 
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeCommunication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeSumant Tambe
 

What's hot (20)

DDS Tutorial -- Part I
DDS Tutorial -- Part IDDS Tutorial -- Part I
DDS Tutorial -- Part I
 
Cloud security and security architecture
Cloud security and security architectureCloud security and security architecture
Cloud security and security architecture
 
DHCP basics
DHCP basicsDHCP basics
DHCP basics
 
S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)
 
The Data Distribution Service Tutorial
The Data Distribution Service TutorialThe Data Distribution Service Tutorial
The Data Distribution Service Tutorial
 
Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...
Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...
Cloud Computing Principles and Paradigms: 4 the enterprise cloud computing pa...
 
Introduction to New CloudWatch Agent
Introduction to New CloudWatch AgentIntroduction to New CloudWatch Agent
Introduction to New CloudWatch Agent
 
CRYPTOGRAPHY AND NETWORK SECURITY- Transport-level Security
CRYPTOGRAPHY AND NETWORK SECURITY- Transport-level SecurityCRYPTOGRAPHY AND NETWORK SECURITY- Transport-level Security
CRYPTOGRAPHY AND NETWORK SECURITY- Transport-level Security
 
DDS in Action -- Part I
DDS in Action -- Part IDDS in Action -- Part I
DDS in Action -- Part I
 
Cloud Application Development – The Future is now
Cloud Application Development – The Future is nowCloud Application Development – The Future is now
Cloud Application Development – The Future is now
 
The Data Distribution Service
The Data Distribution ServiceThe Data Distribution Service
The Data Distribution Service
 
CoAP - Web Protocol for IoT
CoAP - Web Protocol for IoTCoAP - Web Protocol for IoT
CoAP - Web Protocol for IoT
 
Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018
Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018
Amazon DynamoDB 기반 글로벌 서비스 개발 방법 및 사례::김준형::AWS Summit Seoul 2018
 
Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...
Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...
Amazon Elasticache - Fully managed, Redis & Memcached Compatible Service (Lev...
 
Transport Layer Security (TLS)
Transport Layer Security (TLS)Transport Layer Security (TLS)
Transport Layer Security (TLS)
 
Introduction to DDS
Introduction to DDSIntroduction to DDS
Introduction to DDS
 
DDS QoS Unleashed
DDS QoS UnleashedDDS QoS Unleashed
DDS QoS Unleashed
 
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 ThingsComparison 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
 
202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...
202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...
202201 AWS Black Belt Online Seminar Apache Spark Performnace Tuning for AWS ...
 
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeCommunication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
 

Similar to Standardizing the Data Distribution Service (DDS) API for Modern C++

Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeCommunication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeReal-Time Innovations (RTI)
 
Introduction to OMG DDS (1 hour, 45 slides)
Introduction to OMG DDS (1 hour, 45 slides)Introduction to OMG DDS (1 hour, 45 slides)
Introduction to OMG DDS (1 hour, 45 slides)Gerardo Pardo-Castellote
 
A Gentle Introduction to OpenSplice DDS
A Gentle Introduction to OpenSplice DDSA Gentle Introduction to OpenSplice DDS
A Gentle Introduction to OpenSplice DDSAngelo Corsaro
 
Dds the ideal_bus_for_event_processing_engines
Dds the ideal_bus_for_event_processing_enginesDds the ideal_bus_for_event_processing_engines
Dds the ideal_bus_for_event_processing_enginesGerardo Pardo-Castellote
 
Advanced OpenSplice Programming - Part II
Advanced OpenSplice Programming - Part IIAdvanced OpenSplice Programming - Part II
Advanced OpenSplice Programming - Part IIAngelo Corsaro
 
Cyclone DDS Unleashed: The Origins
Cyclone DDS Unleashed: The OriginsCyclone DDS Unleashed: The Origins
Cyclone DDS Unleashed: The OriginsZettaScaleTechnology
 
Getting Started with OpenSplice DDS Community Ed.
Getting Started with OpenSplice DDS Community Ed.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 DDSEasing Integration of Large-Scale Real-Time Systems with DDS
Easing Integration of Large-Scale Real-Time Systems with DDSRick Warren
 
DDS: The data-centric future beyond message-based integration
DDS: The data-centric future beyond message-based integrationDDS: The data-centric future beyond message-based integration
DDS: The data-centric future beyond message-based integrationGerardo 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...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 DDNOptimizing Lustre and GPFS with DDN
Optimizing Lustre and GPFS with DDNinside-BigData.com
 
Interoperability for Intelligence Applications using Data-Centric Middleware
Interoperability for Intelligence Applications using Data-Centric MiddlewareInteroperability for Intelligence Applications using Data-Centric Middleware
Interoperability for Intelligence Applications using Data-Centric MiddlewareGerardo Pardo-Castellote
 
DDS for JMS Programmers
DDS for JMS ProgrammersDDS for JMS Programmers
DDS for JMS ProgrammersAngelo Corsaro
 
10 Reasons for Choosing OpenSplice DDS
10 Reasons for Choosing OpenSplice DDS10 Reasons for Choosing OpenSplice DDS
10 Reasons for Choosing OpenSplice DDSAngelo Corsaro
 
Fiware - communicating with ROS robots using Fast RTPS
Fiware - communicating with ROS robots using Fast RTPSFiware - communicating with ROS robots using Fast RTPS
Fiware - communicating with ROS robots using Fast RTPSJaime Martin Losa
 
DDS Interoperability Demo
DDS Interoperability DemoDDS Interoperability Demo
DDS Interoperability DemoAngelo Corsaro
 
Introduction to DDS: Context, Information Model, Security, and Applications.
Introduction to DDS: Context, Information Model, Security, and Applications.Introduction to DDS: Context, Information Model, Security, and Applications.
Introduction to DDS: Context, Information Model, Security, and Applications.Gerardo Pardo-Castellote
 

Similar to Standardizing the Data Distribution Service (DDS) API for Modern C++ (20)

Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeCommunication 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)Introduction to OMG DDS (1 hour, 45 slides)
Introduction to OMG DDS (1 hour, 45 slides)
 
DDS Enabling Open Architecture
DDS Enabling Open ArchitectureDDS Enabling Open Architecture
DDS Enabling Open Architecture
 
RTI Technical Road Show SPAWAR SD
RTI Technical Road Show SPAWAR SDRTI Technical Road Show SPAWAR SD
RTI Technical Road Show SPAWAR SD
 
A Gentle Introduction to OpenSplice DDS
A Gentle Introduction to OpenSplice DDSA 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_enginesDds the ideal_bus_for_event_processing_engines
Dds the ideal_bus_for_event_processing_engines
 
Advanced OpenSplice Programming - Part II
Advanced OpenSplice Programming - Part IIAdvanced OpenSplice Programming - Part II
Advanced OpenSplice Programming - Part II
 
Cyclone DDS Unleashed: The Origins
Cyclone DDS Unleashed: The OriginsCyclone DDS Unleashed: The Origins
Cyclone DDS Unleashed: The Origins
 
Getting Started with OpenSplice DDS Community Ed.
Getting Started with OpenSplice DDS Community Ed.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 DDSEasing 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 integrationDDS: 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...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 DDNOptimizing 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 MiddlewareInteroperability for Intelligence Applications using Data-Centric Middleware
Interoperability for Intelligence Applications using Data-Centric Middleware
 
DDS for JMS Programmers
DDS for JMS ProgrammersDDS for JMS Programmers
DDS for JMS Programmers
 
10 Reasons for Choosing OpenSplice DDS
10 Reasons for Choosing OpenSplice DDS10 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 RTPSFiware - communicating with ROS robots using Fast RTPS
Fiware - communicating with ROS robots using Fast RTPS
 
DDS Interoperability Demo
DDS Interoperability DemoDDS Interoperability Demo
DDS Interoperability Demo
 
Introduction to DDS: Context, Information Model, Security, and Applications.
Introduction to DDS: Context, Information Model, Security, and Applications.Introduction to DDS: Context, Information Model, Security, and Applications.
Introduction to DDS: Context, Information Model, Security, and Applications.
 
OMG Data-Distribution Service Security
OMG Data-Distribution Service SecurityOMG Data-Distribution Service Security
OMG Data-Distribution Service Security
 

More from Sumant Tambe

Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedKafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedSumant Tambe
 
Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++Sumant Tambe
 
Tuning kafka pipelines
Tuning kafka pipelinesTuning kafka pipelines
Tuning kafka pipelinesSumant Tambe
 
New Tools for a More Functional C++
New Tools for a More Functional C++New Tools for a More Functional C++
New Tools for a More Functional C++Sumant Tambe
 
C++ Generators and Property-based Testing
C++ Generators and Property-based TestingC++ Generators and Property-based Testing
C++ Generators and Property-based TestingSumant Tambe
 
Reactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and RxReactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and RxSumant Tambe
 
RPC over DDS Beta 1
RPC over DDS Beta 1RPC over DDS Beta 1
RPC over DDS Beta 1Sumant Tambe
 
Remote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJSRemote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJSSumant Tambe
 
Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)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/SubscribeReactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing for Data-centric Publish/SubscribeSumant Tambe
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxReactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxSumant Tambe
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)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)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 DDSAn Extensible Architecture for Avionics Sensor Health Assessment Using DDS
An Extensible Architecture for Avionics Sensor Health Assessment Using DDSSumant Tambe
 
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDSOverloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDSSumant Tambe
 
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 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 SystemsRetargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core SystemsSumant Tambe
 
Ph.D. Dissertation
Ph.D. DissertationPh.D. Dissertation
Ph.D. DissertationSumant Tambe
 
Native XML processing in C++ (BoostCon'11)
Native XML processing in C++ (BoostCon'11)Native XML processing in C++ (BoostCon'11)
Native XML processing in C++ (BoostCon'11)Sumant Tambe
 

More from Sumant Tambe (20)

Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedKafka 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++Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++
 
Tuning kafka pipelines
Tuning kafka pipelinesTuning kafka pipelines
Tuning kafka pipelines
 
New Tools for a More Functional C++
New Tools for a More Functional C++New Tools for a More Functional C++
New Tools for a More Functional C++
 
C++ Coroutines
C++ CoroutinesC++ Coroutines
C++ Coroutines
 
C++ Generators and Property-based Testing
C++ Generators and Property-based TestingC++ 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 RxReactive 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 1RPC over DDS Beta 1
RPC over DDS Beta 1
 
Remote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJSRemote 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)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/SubscribeReactive 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 RxReactive 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 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)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 DDSAn 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 DDSOverloading 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 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 SystemsRetargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core Systems
 
Ph.D. Dissertation
Ph.D. DissertationPh.D. Dissertation
Ph.D. Dissertation
 
Native XML processing in C++ (BoostCon'11)
Native XML processing in C++ (BoostCon'11)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