qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject qpid-proton git commit: PROTON-865: Simplify container impl and memory management.
Date Mon, 31 Aug 2015 22:22:26 GMT
Repository: qpid-proton
Updated Branches:
  refs/heads/cjansen-cpp-client 9bb9c442c -> e2310f823


PROTON-865: Simplify container impl and memory management.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/e2310f82
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/e2310f82
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/e2310f82

Branch: refs/heads/cjansen-cpp-client
Commit: e2310f82341745318850e161efaa5ca2d6f90fbc
Parents: 9bb9c44
Author: Alan Conway <aconway@redhat.com>
Authored: Mon Aug 31 15:22:40 2015 -0400
Committer: Alan Conway <aconway@redhat.com>
Committed: Mon Aug 31 18:21:27 2015 -0400

----------------------------------------------------------------------
 examples/cpp/client.cpp                         |   4 +-
 examples/cpp/direct_recv.cpp                    |   4 +-
 examples/cpp/direct_send.cpp                    |   8 +-
 examples/cpp/helloworld_direct.cpp              |   3 +-
 examples/cpp/simple_recv.cpp                    |   3 -
 examples/cpp/simple_send.cpp                    |   5 -
 proton-c/bindings/cpp/CMakeLists.txt            |   1 +
 .../bindings/cpp/include/proton/container.hpp   |  31 +--
 .../bindings/cpp/include/proton/handler.hpp     |   3 +-
 proton-c/bindings/cpp/include/proton/link.hpp   |   5 +-
 .../cpp/include/proton/messaging_event.hpp      |   2 +-
 .../cpp/include/proton/proton_event.hpp         |   4 +-
 .../bindings/cpp/include/proton/reactor.hpp     |  74 +++++
 .../bindings/cpp/include/proton/session.hpp     |   2 +-
 proton-c/bindings/cpp/src/connection.cpp        |  11 +-
 proton-c/bindings/cpp/src/container.cpp         |  30 +-
 proton-c/bindings/cpp/src/container_impl.cpp    | 276 +++++--------------
 proton-c/bindings/cpp/src/container_impl.hpp    |  37 +--
 proton-c/bindings/cpp/src/contexts.cpp          |  31 ++-
 proton-c/bindings/cpp/src/contexts.hpp          |  14 +-
 proton-c/bindings/cpp/src/link.cpp              |   8 +
 proton-c/bindings/cpp/src/messaging_event.cpp   |   2 +-
 proton-c/bindings/cpp/src/proton_event.cpp      |   4 +-
 proton-c/bindings/cpp/src/reactor.cpp           |  57 ++++
 24 files changed, 281 insertions(+), 338 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index e58311a..13e3b87 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -23,11 +23,9 @@
 #include "proton/container.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/connection.hpp"
+
 #include <iostream>
 #include <vector>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
 
 class client : public proton::messaging_handler {
   private:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/examples/cpp/direct_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp
index 94cc943..4bb9d62 100644
--- a/examples/cpp/direct_recv.cpp
+++ b/examples/cpp/direct_recv.cpp
@@ -22,15 +22,13 @@
 #include "options.hpp"
 
 #include "proton/container.hpp"
+#include "proton/acceptor.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/link.hpp"
 #include "proton/url.hpp"
 
 #include <iostream>
 #include <map>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
 
 class direct_recv : public proton::messaging_handler {
   private:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/examples/cpp/direct_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_send.cpp b/examples/cpp/direct_send.cpp
index 1302ac7..1fd4529 100644
--- a/examples/cpp/direct_send.cpp
+++ b/examples/cpp/direct_send.cpp
@@ -21,17 +21,13 @@
 
 #include "options.hpp"
 
+#include "proton/acceptor.hpp"
+#include "proton/connection.hpp"
 #include "proton/container.hpp"
 #include "proton/messaging_handler.hpp"
-#include "proton/connection.hpp"
 
 #include <iostream>
 #include <map>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-
 
 class simple_send : public proton::messaging_handler {
   private:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index 3240586..c1ff1ea 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -19,8 +19,9 @@
  *
  */
 
-#include "proton/messaging_handler.hpp"
+#include "proton/acceptor.hpp"
 #include "proton/container.hpp"
+#include "proton/messaging_handler.hpp"
 
 //#include "proton/acceptor.hpp"
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index 88eb48c..4806c4c 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -27,9 +27,6 @@
 
 #include <iostream>
 #include <map>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
 
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 1db94af..8303358 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -27,11 +27,6 @@
 
 #include <iostream>
 #include <map>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-
 
 class simple_send : public proton::messaging_handler {
   private:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 5e116da..eb2f903 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -69,6 +69,7 @@ set(qpid-proton-cpp-source
   src/proton_bits.cpp
   src/proton_event.cpp
   src/proton_handler.cpp
+  src/reactor.cpp
   src/receiver.cpp
   src/sender.cpp
   src/session.cpp

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/include/proton/container.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/container.hpp b/proton-c/bindings/cpp/include/proton/container.hpp
index 014d2c0..ce23939 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -21,22 +21,15 @@
  * under the License.
  *
  */
-#include "proton/acceptor.hpp"
 #include "proton/duration.hpp"
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/reactor.hpp"
 #include "proton/url.hpp"
 
-#include <proton/reactor.h>
-#include <string>
-
 namespace proton {
 
-class dispatch_helper;
 class connection;
-class connector;
 class acceptor;
-class container_impl;
 class messaging_handler;
 class sender;
 class receiver;
@@ -57,18 +50,12 @@ class container
     /** Locally open a connection @see connection::open  */
     PN_CPP_EXTERN connection& connect(const proton::url&, handler *h=0);
 
+    /** Open a connection to url and create a receiver with source=url.path() */
+    PN_CPP_EXTERN acceptor& listen(const proton::url &);
+
     /** Run the event loop, return when all connections and acceptors are closed. */
     PN_CPP_EXTERN void run();
 
-    /** Start the reactor, you must call process() to process events */
-    PN_CPP_EXTERN void start();
-
-    /** Process events, return true if there are more events to process. */
-    PN_CPP_EXTERN bool process();
-
-    /** Stop the reactor, causes run() to return and process() to return false. */
-    PN_CPP_EXTERN void stop();
-
     /** Create a sender on connection with target=addr and optional handler h */
     PN_CPP_EXTERN sender& create_sender(connection &connection, const std::string
&addr, handler *h=0);
 
@@ -81,9 +68,6 @@ class container
     /** Create a receiver on connection with source=url.path() */
     PN_CPP_EXTERN receiver& create_receiver(const url &);
 
-    /** Open a connection to url and create a receiver with source=url.path() */
-    PN_CPP_EXTERN acceptor& listen(const proton::url &);
-
     /// Identifier for the container
     PN_CPP_EXTERN std::string container_id();
 
@@ -93,12 +77,7 @@ class container
     /// Set timeout, process() will return if there is no activity within the timeout.
     PN_CPP_EXTERN void timeout(duration timeout);
 
-    /// Get the reactor
-    PN_CPP_EXTERN pn_reactor_t *reactor();
-
-    PN_CPP_EXTERN void wakeup();
-    PN_CPP_EXTERN bool is_quiesced();
-    PN_CPP_EXTERN void yield();
+    PN_CPP_EXTERN class reactor& reactor();
 
   private:
     PN_UNIQUE_OR_AUTO_PTR<container_impl> impl_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/include/proton/handler.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/handler.hpp b/proton-c/bindings/cpp/include/proton/handler.hpp
index f5f40c1..c1d4f49 100644
--- a/proton-c/bindings/cpp/include/proton/handler.hpp
+++ b/proton-c/bindings/cpp/include/proton/handler.hpp
@@ -32,9 +32,10 @@ namespace proton {
  *
  * A handler can have child handlers which are called in order, after the parent handler.
  *
- * Note: Event handlers are not deleted by the proton library, they must not be
+ * Note: Event handlers are not deleted by the proton library, and they must not be
  * deleted while they are still in use. You can allocate a handler with `new` and
  * call `delete this` in the appropriate `on_*_closed` or `on_*_final` event if you wish.
+ *
  */
 class handler : public std::vector<handler*> {
   public:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/include/proton/link.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/link.hpp b/proton-c/bindings/cpp/include/proton/link.hpp
index 77d88ae..1ff8a4d 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -44,7 +44,7 @@ class link : public counted_facade<pn_link_t, link>, public endpoint
      */
     PN_CPP_EXTERN void open();
 
-    /** Locally close the link, not complete till messaging_handler::on_link_closeed or
+    /** Locally close the link, not complete till messaging_handler::on_link_closed or
      * proton_handler::link_remote_close
      */
     PN_CPP_EXTERN void close();
@@ -88,6 +88,9 @@ class link : public counted_facade<pn_link_t, link>, public endpoint
 
     /** Connection that owns this link */
     PN_CPP_EXTERN class connection &connection();
+
+    /** Set a custom handler for this link */
+    PN_CPP_EXTERN void handler(class handler&);
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/include/proton/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_event.hpp b/proton-c/bindings/cpp/include/proton/messaging_event.hpp
index 0dbe7e4..af22b41 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_event.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_event.hpp
@@ -80,7 +80,7 @@ class messaging_event : public proton_event
         TRANSPORT_CLOSED
     };
 
-    messaging_event(pn_event_t *ce, pn_event_type_t t, class container &c);
+    messaging_event(pn_event_t *ce, proton_event::event_type t, class container &c);
     messaging_event(event_type t, proton_event &parent);
     ~messaging_event();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/include/proton/proton_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/proton_event.hpp b/proton-c/bindings/cpp/include/proton/proton_event.hpp
index 00413d4..c809e55 100644
--- a/proton-c/bindings/cpp/include/proton/proton_event.hpp
+++ b/proton-c/bindings/cpp/include/proton/proton_event.hpp
@@ -24,6 +24,8 @@
 #include "proton/event.hpp"
 #include "proton/link.hpp"
 
+struct pn_event_t;
+
 namespace proton {
 
 class handler;
@@ -282,7 +284,7 @@ class proton_event : public event
     PN_CPP_EXTERN pn_event_t* pn_event();
 
   protected:
-    PN_CPP_EXTERN proton_event(pn_event_t *ce, pn_event_type_t t, class container &c);
+    PN_CPP_EXTERN proton_event(pn_event_t *ce, proton_event::event_type t, class container
&c);
   private:
     pn_event_t *pn_event_;
     event_type type_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/include/proton/reactor.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/reactor.hpp b/proton-c/bindings/cpp/include/proton/reactor.hpp
new file mode 100644
index 0000000..3c3bc51
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/reactor.hpp
@@ -0,0 +1,74 @@
+#ifndef REACTOR_HPP
+#define REACTOR_HPP
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "proton/facade.hpp"
+#include "proton/duration.hpp"
+
+struct pn_reactor_t;
+
+namespace proton {
+
+class connection;
+class acceptor;
+class url;
+class handler;
+
+class reactor : public facade<pn_reactor_t, reactor> {
+ public:
+    /** Create a new reactor. */
+    PN_CPP_EXTERN static PN_UNIQUE_OR_AUTO_PTR<reactor> create();
+
+    /** Open a connection @see connection::open  */
+    PN_CPP_EXTERN connection& connect(const proton::url&, handler *h=0);
+
+    /** Open a connection to url and create a receiver with source=url.path() */
+    PN_CPP_EXTERN acceptor& listen(const proton::url &);
+
+    /** Run the event loop, return when all connections and acceptors are closed. */
+    PN_CPP_EXTERN void run();
+
+    /** Start the reactor, you must call process() to process events */
+    PN_CPP_EXTERN void start();
+
+    /** Process events, return true if there are more events to process. */
+    PN_CPP_EXTERN bool process();
+
+    /** Stop the reactor, causes run() to return and process() to return false. */
+    PN_CPP_EXTERN void stop();
+
+    /// Identifier for the container
+    PN_CPP_EXTERN std::string container_id();
+
+    /// Get timeout, process() will return if there is no activity within the timeout.
+    PN_CPP_EXTERN duration timeout();
+
+    /// Set timeout, process() will return if there is no activity within the timeout.
+    PN_CPP_EXTERN void timeout(duration timeout);
+
+    PN_CPP_EXTERN void wakeup();
+    PN_CPP_EXTERN bool quiesced();
+    PN_CPP_EXTERN void yield();
+
+    void operator delete(void*);
+};
+
+}
+#endif // REACTOR_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/include/proton/session.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/session.hpp b/proton-c/bindings/cpp/include/proton/session.hpp
index 561b90b..e94a75b 100644
--- a/proton-c/bindings/cpp/include/proton/session.hpp
+++ b/proton-c/bindings/cpp/include/proton/session.hpp
@@ -54,7 +54,7 @@ class session : public counted_facade<pn_session_t, session>, public
endpoint
     /// Get connection
     PN_CPP_EXTERN class connection &connection();
 
-    // FIXME aconway 2015-08-31: default generate unique name.
+    // TODO aconway 2015-08-31: default generate unique name. Container args?
     /// Create a receiver link
     PN_CPP_EXTERN receiver& create_receiver(const std::string& name);
     /// Create a sender link

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection.cpp b/proton-c/bindings/cpp/src/connection.cpp
index f3781a8..d5d8d06 100644
--- a/proton-c/bindings/cpp/src/connection.cpp
+++ b/proton-c/bindings/cpp/src/connection.cpp
@@ -37,14 +37,6 @@
 
 namespace proton {
 
-namespace {
-struct override_holder : counted {
-    override_holder(class handler* h) : handler(h) {}
-    ~override_holder() { delete handler; }
-    class handler* handler;
-};
-}
-
 transport &connection::transport() {
     return *transport::cast(pn_connection_transport(pn_cast(this)));
 }
@@ -58,8 +50,7 @@ std::string connection::hostname() {
 }
 
 container& connection::container() {
-    container_impl* impl = container_context(pn_object_reactor(pn_cast(this)));
-    return impl->container_;
+    return container_context(pn_object_reactor(pn_cast(this)));
 }
 
 link* connection::link_head(endpoint::state mask) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/container.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container.cpp b/proton-c/bindings/cpp/src/container.cpp
index d5ad890..30ae88b 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -38,23 +38,24 @@
 
 namespace proton {
 
+//// Public container class.
+
 container::container() : impl_(new container_impl(*this, 0)) {}
 
-container::container(messaging_handler &mhandler) :
-    impl_(new container_impl(*this, &mhandler)) {}
+container::container(messaging_handler &mhandler) : impl_(new container_impl(*this, &mhandler))
{}
 
 container::~container() {}
 
-connection& container::connect(const url &host, handler *h) {
-    return impl_->connect(host, h);
-}
+connection& container::connect(const url &host, handler *h) { return impl_->connect(host,
h); }
+
+reactor &container::reactor() { return *impl_->reactor_; }
 
-pn_reactor_t *container::reactor() { return impl_->reactor(); }
+std::string container::container_id() { return impl_->container_id_; }
 
-std::string container::container_id() { return impl_->container_id(); }
+duration container::timeout() { return impl_->reactor_->timeout(); }
+void container::timeout(duration timeout) { impl_->reactor_->timeout(timeout); }
 
-duration container::timeout() { return impl_->timeout(); }
-void container::timeout(duration timeout) { impl_->timeout(timeout); }
+void container::run() { impl_->reactor_->run(); }
 
 
 sender& container::create_sender(connection &connection, const std::string &addr,
handler *h) {
@@ -77,13 +78,4 @@ acceptor& container::listen(const proton::url &url) {
     return impl_->listen(url);
 }
 
-
-void container::run() { impl_->run(); }
-void container::start() { impl_->start(); }
-bool container::process() { return impl_->process(); }
-void container::stop() { impl_->stop(); }
-void container::wakeup() { impl_->wakeup(); }
-bool container::is_quiesced() { return impl_->is_quiesced(); }
-void container::yield() { impl_->yield(); }
-
-}
+} // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp b/proton-c/bindings/cpp/src/container_impl.cpp
index 9750b18..ab4379c 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -19,6 +19,7 @@
  *
  */
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_event.hpp"
 #include "proton/connection.hpp"
 #include "proton/session.hpp"
@@ -38,30 +39,28 @@
 #include "proton/connection.h"
 #include "proton/session.h"
 #include "proton/handlers.h"
+#include "proton/reactor.h"
 
 namespace proton {
 
-class CHandler : public handler
-{
-  public:
-    CHandler(pn_handler_t *h) : pn_handler_(h) {
-        pn_incref(pn_handler_);
-    }
-    ~CHandler() {
-        pn_decref(pn_handler_);
-    }
-    pn_handler_t *pn_handler() { return pn_handler_; }
+namespace {
 
-    virtual void on_unhandled(event &e) {
-        proton_event *pne = dynamic_cast<proton_event *>(&e);
-        if (!pne) return;
-        int type = pne->type();
-        if (!type) return;  // Not from the reactor
-        pn_handler_dispatch(pn_handler_, pne->pn_event(), (pn_event_type_t) type);
+struct handler_context {
+    static handler_context& get(pn_handler_t* h) {
+        return *reinterpret_cast<handler_context*>(pn_handler_mem(h));
+    }
+    static void cleanup(pn_handler_t*) {}
+
+    static void dispatch(pn_handler_t *c_handler, pn_event_t *c_event, pn_event_type_t type)
+    {
+        handler_context& hc(handler_context::get(c_handler));
+        messaging_event mevent(c_event, type, *hc.container_);
+        mevent.dispatch(*hc.handler_);
+        return;
     }
 
-  private:
-    pn_handler_t *pn_handler_;
+    container *container_;
+    handler *handler_;
 };
 
 
@@ -69,15 +68,9 @@ class CHandler : public handler
 class override_handler : public handler
 {
   public:
-    pn_handler_t *base_handler;
-
-    override_handler(pn_handler_t *h) : base_handler(h) {
-        pn_incref(base_handler);
-    }
-    ~override_handler() {
-        pn_decref(base_handler);
-    }
+    counted_ptr<pn_handler_t> base_handler;
 
+    override_handler(pn_handler_t *h) : base_handler(h) {}
 
     virtual void on_unhandled(event &e) {
         proton_event *pne = dynamic_cast<proton_event *>(&e);
@@ -92,151 +85,89 @@ class override_handler : public handler
             handler *override = connection_context::get(conn).handler;
             if (override) e.dispatch(*override);
         }
-
-        pn_handler_dispatch(base_handler, cevent, (pn_event_type_t) type);
+        pn_handler_dispatch(base_handler.get(), cevent, (pn_event_type_t) type);
     }
 };
 
+} // namespace
 
-namespace {
-
-struct inbound_context {
-    static inbound_context* get(pn_handler_t* h) {
-        return reinterpret_cast<inbound_context*>(pn_handler_mem(h));
-    }
-    container_impl *container_impl_;
-    handler *cpp_handler_;
-};
-
-void cpp_handler_dispatch(pn_handler_t *c_handler, pn_event_t *cevent, pn_event_type_t type)
-{
-    container& c(inbound_context::get(c_handler)->container_impl_->container_);
-    messaging_event mevent(cevent, type, c);
-    mevent.dispatch(*inbound_context::get(c_handler)->cpp_handler_);
-    return;
-}
-
-void cpp_handler_cleanup(pn_handler_t *c_handler)
-{
-}
-
-pn_handler_t *cpp_handler(container_impl *c, handler *h)
+counted_ptr<pn_handler_t> container_impl::cpp_handler(handler *h)
 {
-    pn_handler_t *handler = pn_handler_new(cpp_handler_dispatch, sizeof(struct inbound_context),
cpp_handler_cleanup);
-    inbound_context *ctxt = inbound_context::get(handler);
-    ctxt->container_impl_ = c;
-    ctxt->cpp_handler_ = h;
+    counted_ptr<pn_handler_t> handler(
+        pn_handler_new(&handler_context::dispatch, sizeof(struct handler_context),
+                       &handler_context::cleanup),
+        false);
+    handler_context &hc = handler_context::get(handler.get());
+    hc.container_ = &container_;
+    hc.handler_ = h;
     return handler;
 }
 
+container_impl::container_impl(container& c, handler *h) :
+    container_(c), reactor_(reactor::create()), handler_(h)
+{
+    container_context(pn_cast(reactor_.get()), container_);
 
-} // namespace
+    // Set our own global handler that "subclasses" the existing one
+    pn_handler_t *global_handler = pn_reactor_get_global_handler(pn_cast(reactor_.get()));
+    override_handler_.reset(new override_handler(global_handler));
+    counted_ptr<pn_handler_t> cpp_global_handler(cpp_handler(override_handler_.get()));
+    pn_reactor_set_global_handler(pn_cast(reactor_.get()), cpp_global_handler.get());
+    if (handler_) {
+        counted_ptr<pn_handler_t> pn_handler(cpp_handler(handler_));
+        pn_reactor_set_handler(pn_cast(reactor_.get()), pn_handler.get());
+    }
 
 
-void container_impl::incref(container_impl *impl_) {
-    impl_->refcount_++;
-}
-
-void container_impl::decref(container_impl *impl_) {
-    impl_->refcount_--;
-    if (impl_->refcount_ == 0)
-        delete impl_;
+    // Note: we have just set up the following handlers that see events in this order:
+    // messaging_handler (Proton C events), pn_flowcontroller (optional), messaging_adapter,
+    // messaging_handler (Messaging events from the messaging_adapter, i.e. the delegate),
+    // connector override, the reactor's default globalhandler (pn_iohandler)
 }
 
-container_impl::container_impl(container& c, handler *h) :
-    container_(c),
-    reactor_(0), handler_(h), messaging_adapter_(0),
-    override_handler_(0), flow_controller_(0), container_id_(),
-    refcount_(0)
-{}
-
-container_impl::~container_impl() {
-    delete override_handler_;
-    delete flow_controller_;
-    delete messaging_adapter_;
-    pn_reactor_free(reactor_);
-}
+container_impl::~container_impl() {}
 
 connection& container_impl::connect(const proton::url &url, handler *h) {
-    if (!reactor_) throw error(MSG("container not started"));
-
-    pn_handler_t *chandler = h ? wrap_handler(h) : 0;
-    connection* conn = connection::cast(pn_reactor_connection(reactor_, chandler));
-    if (chandler) pn_decref(chandler);
+    counted_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : counted_ptr<pn_handler_t>();
+    connection* conn =
+        connection::cast(pn_reactor_connection(pn_cast(reactor_.get()), chandler.get()));
     connector *ctor = new connector(*conn); // Will be deleted by connection_context
     ctor->address(url);  // TODO: url vector
-    connection_context::get(pn_cast(conn)).handler = ctor;
+    connection_context& cc(connection_context::get(pn_cast(conn)));
+    cc.container_impl = this;
+    cc.handler = ctor;
     conn->open();
     return *conn;
 }
 
-pn_reactor_t *container_impl::reactor() { return reactor_; }
-
-
-std::string container_impl::container_id() { return container_id_; }
-
-duration container_impl::timeout() {
-    pn_millis_t tmo = pn_reactor_get_timeout(reactor_);
-    if (tmo == PN_MILLIS_MAX)
-        return duration::FOREVER;
-    return duration(tmo);
-}
-
-void container_impl::timeout(duration timeout) {
-    if (timeout == duration::FOREVER || timeout.milliseconds > PN_MILLIS_MAX)
-        pn_reactor_set_timeout(reactor_, PN_MILLIS_MAX);
-    else {
-        pn_millis_t tmo = timeout.milliseconds;
-        pn_reactor_set_timeout(reactor_, tmo);
-    }
-}
-
-
 sender& container_impl::create_sender(connection &connection, const std::string &addr,
handler *h) {
-    if (!reactor_) throw error(MSG("container not started"));
     sender& snd = connection.default_session().create_sender(container_id_  + '-' + addr);
-    pn_link_t *lnk = pn_cast(&snd);
-    pn_terminus_set_address(pn_link_target(lnk), addr.c_str());
-    if (h) {
-        pn_record_t *record = pn_link_attachments(lnk);
-        pn_handler_t *chandler = wrap_handler(h);
-        pn_record_set_handler(record, chandler);
-        pn_decref(chandler);
-    }
+    snd.target().address(addr);
+    if (h) snd.handler(*h);
     snd.open();
     return snd;
 }
 
 sender& container_impl::create_sender(const proton::url &url) {
-    if (!reactor_) throw error(MSG("container not started"));
     connection& conn = connect(url, 0);
     std::string path = url.path();
     sender& snd = conn.default_session().create_sender(container_id_ + '-' + path);
-    pn_terminus_set_address(pn_link_target(pn_cast(&snd)), path.c_str());
+    snd.target().address(path);
     snd.open();
     return snd;
 }
 
-receiver& container_impl::create_receiver(connection &conn, const std::string &addr,
bool dynamic, handler *h) {
-    if (!reactor_) throw error(MSG("container not started"));
+receiver& container_impl::create_receiver(connection &conn, const std::string &addr,
bool dynamic, handler *h)
+{
     receiver& rcv = conn.default_session().create_receiver(container_id_ + '-' + addr);
-    pn_link_t *lnk = pn_cast(&rcv);
-    pn_terminus_t *src = pn_link_source(lnk);
-    pn_terminus_set_address(src, addr.c_str());
-    if (dynamic)
-        pn_terminus_set_dynamic(src, true);
-    if (h) {
-        pn_record_t *record = pn_link_attachments(lnk);
-        pn_handler_t *chandler = wrap_handler(h);
-        pn_record_set_handler(record, chandler);
-        pn_decref(chandler);
-    }
+    rcv.source().address(addr);
+    if (dynamic) rcv.source().dynamic(true);
+    if (h) rcv.handler(*h);
     rcv.open();
     return rcv;
 }
 
 receiver& container_impl::create_receiver(const proton::url &url) {
-    if (!reactor_) throw error(MSG("container not started"));
     connection& conn = connect(url, 0);
     std::string path = url.path();
     receiver& rcv = conn.default_session().create_receiver(container_id_ + '-' + path);
@@ -245,88 +176,15 @@ receiver& container_impl::create_receiver(const proton::url &url)
{
     return rcv;
 }
 
-acceptor& container_impl::acceptor(const proton::url& url) {
-    pn_acceptor_t *acptr = pn_reactor_acceptor(reactor_, url.host().c_str(), url.port().c_str(),
NULL);
+acceptor& container_impl::listen(const proton::url& url) {
+    pn_acceptor_t *acptr = pn_reactor_acceptor(
+        pn_cast(reactor_.get()), url.host().c_str(), url.port().c_str(), NULL);
     if (acptr)
         return *acceptor::cast(acptr);
     else
-        throw error(MSG("accept fail: " << pn_error_text(pn_io_error(pn_reactor_io(reactor_)))
<< "(" << url << ")"));
-}
-
-acceptor& container_impl::listen(const proton::url &url) {
-    if (!reactor_) throw error(MSG("container not started"));
-    return acceptor(url);
-}
-
-
-pn_handler_t *container_impl::wrap_handler(handler *h) {
-    return cpp_handler(this, h);
-}
-
-
-void container_impl::initialize_reactor() {
-    if (reactor_) throw error(MSG("container already running"));
-    reactor_ = pn_reactor();
-
-    // Set our context on the reactor
-    container_context(reactor_, this);
-
-    if (handler_) {
-        pn_handler_t *pn_handler = cpp_handler(this, handler_);
-        pn_reactor_set_handler(reactor_, pn_handler);
-        pn_decref(pn_handler);
-    }
-
-    // Set our own global handler that "subclasses" the existing one
-    pn_handler_t *global_handler = pn_reactor_get_global_handler(reactor_);
-    override_handler_ = new override_handler(global_handler);
-    pn_handler_t *cpp_global_handler = cpp_handler(this, override_handler_);
-    pn_reactor_set_global_handler(reactor_, cpp_global_handler);
-    pn_decref(cpp_global_handler);
-
-    // Note: we have just set up the following 4/5 handlers that see events in this order:
-    // messaging_handler (Proton C events), pn_flowcontroller (optional), messaging_adapter,
-    // messaging_handler (Messaging events from the messaging_adapter, i.e. the delegate),
-    // connector override, the reactor's default globalhandler (pn_iohandler)
-}
-
-void container_impl::run() {
-    initialize_reactor();
-    pn_reactor_run(reactor_);
-}
-
-void container_impl::start() {
-    initialize_reactor();
-    pn_reactor_start(reactor_);
-}
-
-bool container_impl::process() {
-    if (!reactor_) throw error(MSG("container not started"));
-    bool result = pn_reactor_process(reactor_);
-    // TODO: check errors
-    return result;
-}
-
-void container_impl::stop() {
-    if (!reactor_) throw error(MSG("container not started"));
-    pn_reactor_stop(reactor_);
-    // TODO: check errors
-}
-
-void container_impl::wakeup() {
-    if (!reactor_) throw error(MSG("container not started"));
-    pn_reactor_wakeup(reactor_);
-    // TODO: check errors
-}
-
-bool container_impl::is_quiesced() {
-    if (!reactor_) throw error(MSG("container not started"));
-    return pn_reactor_quiesced(reactor_);
-}
-
-void container_impl::yield() {
-    if (!reactor_) throw error(MSG("container not started"));
-    pn_reactor_yield(reactor_);
+        throw error(MSG("accept fail: " <<
+                        pn_error_text(pn_io_error(pn_reactor_io(pn_cast(reactor_.get()))))
+                        << "(" << url << ")"));
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.hpp b/proton-c/bindings/cpp/src/container_impl.hpp
index 6780bb5..d552cdc 100644
--- a/proton-c/bindings/cpp/src/container_impl.hpp
+++ b/proton-c/bindings/cpp/src/container_impl.hpp
@@ -30,12 +30,14 @@
 #include "proton/reactor.h"
 
 #include <string>
+
 namespace proton {
 
 class dispatch_helper;
 class connection;
 class connector;
 class acceptor;
+class container;
 
 class container_impl
 {
@@ -43,43 +45,34 @@ class container_impl
     PN_CPP_EXTERN container_impl(container&, handler *);
     PN_CPP_EXTERN ~container_impl();
     PN_CPP_EXTERN connection& connect(const url&, handler *h);
-    PN_CPP_EXTERN void run();
-    PN_CPP_EXTERN pn_reactor_t *reactor();
     PN_CPP_EXTERN sender& create_sender(connection &connection, const std::string
&addr, handler *h);
     PN_CPP_EXTERN sender& create_sender(const url&);
     PN_CPP_EXTERN receiver& create_receiver(connection &connection, const std::string
&addr, bool dynamic, handler *h);
     PN_CPP_EXTERN receiver& create_receiver(const url&);
     PN_CPP_EXTERN class acceptor& listen(const url&);
-    PN_CPP_EXTERN std::string container_id();
     PN_CPP_EXTERN duration timeout();
     PN_CPP_EXTERN void timeout(duration timeout);
-    void start();
-    bool process();
-    void stop();
-    void wakeup();
-    bool is_quiesced();
-    void yield();
-    pn_handler_t *wrap_handler(handler *h);
-    static void incref(container_impl *);
-    static void decref(container_impl *);
 
-    container& container_;
+    counted_ptr<pn_handler_t> cpp_handler(handler *h);
 
   private:
-    void dispatch(pn_event_t *event, pn_event_type_t type);
-    class acceptor& acceptor(const url&);
-    void initialize_reactor();
 
-    pn_reactor_t *reactor_;
+    container& container_;
+    PN_UNIQUE_OR_AUTO_PTR<reactor> reactor_;
     handler *handler_;
-    messaging_adapter *messaging_adapter_;
-    handler *override_handler_;
-    handler *flow_controller_;
+    PN_UNIQUE_OR_AUTO_PTR<messaging_adapter> messaging_adapter_;
+    PN_UNIQUE_OR_AUTO_PTR<handler> override_handler_;
+    PN_UNIQUE_OR_AUTO_PTR<handler> flow_controller_;
     std::string container_id_;
-    int refcount_;
-};
 
+  friend class container;
+};
 
 }
 
+// Allow counted_ptr to a pn_handler_t
+inline void incref(const pn_handler_t* h) { pn_incref(const_cast<pn_handler_t*>(h));
}
+inline void decref(const pn_handler_t* h) { pn_decref(const_cast<pn_handler_t*>(h));
}
+
+
 #endif  /*!PROTON_CPP_CONTAINERIMPL_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/contexts.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/contexts.cpp b/proton-c/bindings/cpp/src/contexts.cpp
index 3309214..9e0d4e5 100644
--- a/proton-c/bindings/cpp/src/contexts.cpp
+++ b/proton-c/bindings/cpp/src/contexts.cpp
@@ -36,8 +36,9 @@ namespace proton {
 namespace {
 
 // A proton class for counted c++ objects used as proton attachments
+extern pn_class_t* COUNTED_CONTEXT;
 #define CID_cpp_context CID_pn_void
-static const pn_class_t *cpp_context_reify(void *object) { return CPP_CONTEXT; }
+static const pn_class_t *cpp_context_reify(void *object) { return COUNTED_CONTEXT; }
 #define cpp_context_new NULL
 #define cpp_context_free NULL
 #define cpp_context_initialize NULL
@@ -50,14 +51,14 @@ int cpp_context_refcount(void* p) { return 1; }
 #define cpp_context_compare NULL
 #define cpp_context_inspect NULL
 
-pn_class_t CPP_CONTEXT_ = PN_METACLASS(cpp_context);
+pn_class_t COUNTED_CONTEXT_ = PN_METACLASS(cpp_context);
+pn_class_t *COUNTED_CONTEXT = &COUNTED_CONTEXT_;
 }
 
-pn_class_t *CPP_CONTEXT = &CPP_CONTEXT_;
 
 void set_context(pn_record_t* record, pn_handle_t handle, counted* value)
 {
-    pn_record_def(record, handle, CPP_CONTEXT);
+    pn_record_def(record, handle, COUNTED_CONTEXT);
     pn_record_set(record, handle, value);
 }
 
@@ -69,7 +70,7 @@ counted* get_context(pn_record_t* record, pn_handle_t handle) {
 
 PN_HANDLE(CONNECTION_CONTEXT)
 
-connection_context::connection_context() : handler(0), default_session(0) {}
+connection_context::connection_context() : handler(0), default_session(0), container_impl(0)
{}
 connection_context::~connection_context() { delete handler; }
 
 struct connection_context& connection_context::get(pn_connection_t* c) {
@@ -84,16 +85,17 @@ struct connection_context& connection_context::get(pn_connection_t*
c) {
 
 PN_HANDLE(CONTAINER_CONTEXT)
 
-void container_context(pn_reactor_t *pn_reactor, container_impl *container) {
-    pn_record_t *record = pn_reactor_attachments(pn_reactor);
+void container_context(pn_reactor_t *r, container& c) {
+    pn_record_t *record = pn_reactor_attachments(r);
     pn_record_def(record, CONTAINER_CONTEXT, PN_VOID);
-    pn_record_set(record, CONTAINER_CONTEXT, container);
+    pn_record_set(record, CONTAINER_CONTEXT, &c);
 }
-container_impl *container_context(pn_reactor_t *pn_reactor) {
+
+container &container_context(pn_reactor_t *pn_reactor) {
     pn_record_t *record = pn_reactor_attachments(pn_reactor);
-    container_impl *p = (container_impl *) pn_record_get(record, CONTAINER_CONTEXT);
-    if (!p) throw error(MSG("Reactor has no C++ container context"));
-    return p;
+    container *ctx = reinterpret_cast<container*>(pn_record_get(record, CONTAINER_CONTEXT));
+    if (!ctx) throw error(MSG("Reactor has no C++ container context"));
+    return *ctx;
 }
 
 PN_HANDLE(EVENT_CONTEXT)
@@ -103,11 +105,12 @@ void event_context(pn_event_t *pn_event, pn_message_t *m) {
     pn_record_def(record, EVENT_CONTEXT, PN_OBJECT); // refcount it for life of the event
     pn_record_set(record, EVENT_CONTEXT, m);
 }
+
 pn_message_t *event_context(pn_event_t *pn_event) {
     if (!pn_event) return NULL;
     pn_record_t *record = pn_event_attachments(pn_event);
-    pn_message_t *p = (pn_message_t *) pn_record_get(record, EVENT_CONTEXT);
-    return p;
+    pn_message_t *ctx = (pn_message_t *) pn_record_get(record, EVENT_CONTEXT);
+    return ctx;
 }
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/contexts.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/contexts.hpp b/proton-c/bindings/cpp/src/contexts.hpp
index ed6642b..ba1c4aa 100644
--- a/proton-c/bindings/cpp/src/contexts.hpp
+++ b/proton-c/bindings/cpp/src/contexts.hpp
@@ -25,15 +25,14 @@
 #include "proton/facade.hpp"
 
 #include "proton/reactor.h"
-#include "proton/connection.h"
 #include "proton/message.h"
 
 namespace proton {
 
 class session;
 class handler;
+class container_impl;
 
-extern pn_class_t* CPP_CONTEXT;
 counted* get_context(pn_record_t*, pn_handle_t handle);
 void set_context(pn_record_t*, pn_handle_t, counted* value);
 
@@ -45,15 +44,12 @@ struct connection_context : public counted {
 
     class handler* handler;
     session* default_session;
+    class container_impl* container_impl;
 };
 
-class connection_impl;
-void connection_context(pn_connection_t *pn_connection, connection_impl *connection);
-connection_impl *connection_context(pn_connection_t *pn_connection);
-
-class container_impl;
-void container_context(pn_reactor_t *pn_reactor, container_impl *container);
-container_impl *container_context(pn_reactor_t *pn_reactor);
+class container;
+void container_context(pn_reactor_t *, container&);
+container& container_context(pn_reactor_t *);
 
 void event_context(pn_event_t *pn_event, pn_message_t *m);
 pn_message_t *event_context(pn_event_t *pn_event);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/link.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/link.cpp b/proton-c/bindings/cpp/src/link.cpp
index 25bd3f3..2f309e3 100644
--- a/proton-c/bindings/cpp/src/link.cpp
+++ b/proton-c/bindings/cpp/src/link.cpp
@@ -21,6 +21,7 @@
 #include "proton/link.hpp"
 #include "proton/error.hpp"
 #include "proton/connection.hpp"
+#include "container_impl.hpp"
 #include "msg.hpp"
 #include "contexts.hpp"
 
@@ -75,4 +76,11 @@ link* link::next(endpoint::state mask) {
     return link::cast(pn_link_next(pn_cast(this), (pn_state_t) mask));
 }
 
+void link::handler(class handler& h) {
+    pn_record_t *record = pn_link_attachments(pn_cast(this));
+    connection_context& cc(connection_context::get(pn_cast(&connection())));
+    counted_ptr<pn_handler_t> chandler = cc.container_impl->cpp_handler(&h);
+    pn_record_set_handler(record, chandler.get());
+}
+
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/messaging_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.cpp b/proton-c/bindings/cpp/src/messaging_event.cpp
index 7befc25..ece1c4e 100644
--- a/proton-c/bindings/cpp/src/messaging_event.cpp
+++ b/proton-c/bindings/cpp/src/messaging_event.cpp
@@ -35,7 +35,7 @@
 
 namespace proton {
 
-messaging_event::messaging_event(pn_event_t *ce, pn_event_type_t t, class container &c)
:
+messaging_event::messaging_event(pn_event_t *ce, proton_event::event_type t, class container
&c) :
     proton_event(ce, t, c), type_(messaging_event::PROTON), parent_event_(0)
 {}
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/proton_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.cpp b/proton-c/bindings/cpp/src/proton_event.cpp
index 723fdaa..4b2d3ac 100644
--- a/proton-c/bindings/cpp/src/proton_event.cpp
+++ b/proton-c/bindings/cpp/src/proton_event.cpp
@@ -36,9 +36,9 @@
 
 namespace proton {
 
-proton_event::proton_event(pn_event_t *ce, pn_event_type_t t, class container &c) :
+proton_event::proton_event(pn_event_t *ce, proton_event::event_type t, class container &c)
:
     pn_event_(ce),
-    type_((int) t),
+    type_(t),
     container_(c)
 {}
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2310f82/proton-c/bindings/cpp/src/reactor.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/reactor.cpp b/proton-c/bindings/cpp/src/reactor.cpp
new file mode 100644
index 0000000..e8057fd
--- /dev/null
+++ b/proton-c/bindings/cpp/src/reactor.cpp
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "proton/reactor.hpp"
+
+#include <proton/reactor.h>
+
+namespace proton {
+
+PN_UNIQUE_OR_AUTO_PTR<reactor> reactor::create() {
+    return PN_UNIQUE_OR_AUTO_PTR<reactor>(reactor::cast(pn_reactor()));
+}
+
+void reactor::run() { pn_reactor_run(pn_cast(this)); }
+void reactor::start() { pn_reactor_start(pn_cast(this)); }
+bool reactor::process() { return pn_reactor_process(pn_cast(this)); }
+void reactor::stop() { pn_reactor_stop(pn_cast(this)); }
+void reactor::wakeup() { pn_reactor_wakeup(pn_cast(this)); }
+bool reactor::quiesced() { return pn_reactor_quiesced(pn_cast(this)); }
+void reactor::yield() { pn_reactor_yield(pn_cast(this)); }
+
+duration reactor::timeout() {
+    pn_millis_t tmo = pn_reactor_get_timeout(pn_cast(this));
+    if (tmo == PN_MILLIS_MAX)
+        return duration::FOREVER;
+    return duration(tmo);
+}
+
+void reactor::timeout(duration timeout) {
+    if (timeout == duration::FOREVER || timeout.milliseconds > PN_MILLIS_MAX)
+        pn_reactor_set_timeout(pn_cast(this), PN_MILLIS_MAX);
+    else
+        pn_reactor_set_timeout(pn_cast(this), timeout.milliseconds);
+}
+
+
+void reactor::operator delete(void* p) {
+    pn_reactor_free(reinterpret_cast<pn_reactor_t*>(p));
+}
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message