PROTON-1068: c++ remove counted_ptr and context types from public API - got rid of proton::counted base class - remove mention of internal context types and functions from public headers. - c++ rename data::op==, = and < to avoid clashes with object<> ops. - replace complex exteranl counted_ptr with simple, internal-only pn_ptr - simpler pn_class for C++ contexts, holds C++ value without an extra allocation. - removed operator bool, made op == and < operators friends - removed owned_object<>: equivalent to "take_ownership" constructor and move operator.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/5045ec03 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/5045ec03 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/5045ec03 Branch: refs/heads/go1 Commit: 5045ec0320441089fe61d4b338d3b89da77da45a Parents: 8501509 Author: Alan Conway <[email protected]> Authored: Fri Nov 27 12:43:49 2015 -0500 Committer: Alan Conway <[email protected]> Committed: Fri Dec 4 11:43:14 2015 -0500 ---------------------------------------------------------------------- proton-c/bindings/cpp/CMakeLists.txt | 1 - .../cpp/include/proton/blocking_link.hpp | 1 - .../bindings/cpp/include/proton/connection.hpp | 12 +- .../bindings/cpp/include/proton/counted.hpp | 48 -------- .../bindings/cpp/include/proton/counted_ptr.hpp | 117 ------------------- proton-c/bindings/cpp/include/proton/data.hpp | 17 +-- .../bindings/cpp/include/proton/handler.hpp | 3 +- proton-c/bindings/cpp/include/proton/object.hpp | 105 ++++++----------- .../bindings/cpp/include/proton/reactor.hpp | 7 +- proton-c/bindings/cpp/include/proton/value.hpp | 4 +- proton-c/bindings/cpp/src/connection.cpp | 9 +- .../bindings/cpp/src/connection_options.cpp | 3 +- proton-c/bindings/cpp/src/container_impl.cpp | 41 +++---- proton-c/bindings/cpp/src/container_impl.hpp | 2 +- proton-c/bindings/cpp/src/contexts.cpp | 82 +++++-------- proton-c/bindings/cpp/src/contexts.hpp | 51 +++++--- proton-c/bindings/cpp/src/counted_ptr.cpp | 32 ----- proton-c/bindings/cpp/src/data.cpp | 8 +- proton-c/bindings/cpp/src/decoder.cpp | 2 +- proton-c/bindings/cpp/src/encoder.cpp | 2 +- proton-c/bindings/cpp/src/link.cpp | 4 +- proton-c/bindings/cpp/src/message.cpp | 8 +- proton-c/bindings/cpp/src/messaging_adapter.cpp | 2 +- proton-c/bindings/cpp/src/object.cpp | 8 +- proton-c/bindings/cpp/src/reactor.cpp | 9 +- proton-c/bindings/cpp/src/session.cpp | 2 +- proton-c/bindings/cpp/src/value.cpp | 8 +- 27 files changed, 170 insertions(+), 418 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt index bcdc61b..6352f66 100644 --- a/proton-c/bindings/cpp/CMakeLists.txt +++ b/proton-c/bindings/cpp/CMakeLists.txt @@ -37,7 +37,6 @@ set(qpid-proton-cpp-source src/connector.cpp src/container.cpp src/container_impl.cpp - src/counted_ptr.cpp src/contexts.cpp src/data.cpp src/decoder.cpp http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/include/proton/blocking_link.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/blocking_link.hpp b/proton-c/bindings/cpp/include/proton/blocking_link.hpp index 2b0a089..ba584af 100644 --- a/proton-c/bindings/cpp/include/proton/blocking_link.hpp +++ b/proton-c/bindings/cpp/include/proton/blocking_link.hpp @@ -22,7 +22,6 @@ * */ #include "proton/export.hpp" -#include "proton/counted_ptr.hpp" #include "proton/duration.hpp" #include "proton/link.hpp" http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/include/proton/connection.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp b/proton-c/bindings/cpp/include/proton/connection.hpp index 338e542..7a9cf74 100644 --- a/proton-c/bindings/cpp/include/proton/connection.hpp +++ b/proton-c/bindings/cpp/include/proton/connection.hpp @@ -34,7 +34,6 @@ struct pn_connection_t; namespace proton { -struct connection_context; class handler; class engine; @@ -44,9 +43,6 @@ class connection : public object<pn_connection_t>, endpoint public: connection(pn_connection_t* c=0) : object<pn_connection_t>(c) {} - /// Get the connection context object from the connection - PN_CPP_EXTERN connection_context& context() const; - /// Get the event_loop, can be a container or an engine. PN_CPP_EXTERN class event_loop &event_loop() const; @@ -111,10 +107,10 @@ class connection : public object<pn_connection_t>, endpoint PN_CPP_EXTERN void user(const std::string &); PN_CPP_EXTERN void password(const std::string &); - - friend class connection_options; - friend class connector; - friend class transport; + friend class connection_context; + friend class connection_options; + friend class connector; + friend class transport; }; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/include/proton/counted.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/counted.hpp b/proton-c/bindings/cpp/include/proton/counted.hpp deleted file mode 100644 index 2195d93..0000000 --- a/proton-c/bindings/cpp/include/proton/counted.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef COUNTED_HPP -#define COUNTED_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. - */ - -namespace proton { - -/// Base class for reference counted objects other than proton struct facade types. -class counted { - protected: - counted() : refcount_(0) {} - virtual ~counted() {} - - private: - counted(const counted&); - counted& operator=(const counted&); - mutable int refcount_; - - // TODO aconway 2015-08-27: atomic operations. - void incref() const { ++refcount_; } - void decref() const { if (--refcount_ == 0) delete this; } - - friend void incref(const counted*); - friend void decref(const counted*); - template <class T> friend class counted_ptr; -}; - -inline void incref(const counted* p) { if (p) p->incref(); } -inline void decref(const counted* p) { if (p) p->decref(); } - -} -#endif // COUNTED_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/include/proton/counted_ptr.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp b/proton-c/bindings/cpp/include/proton/counted_ptr.hpp deleted file mode 100644 index 0865e4a..0000000 --- a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef COUNTED_PTR_HPP -#define COUNTED_PTR_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/config.hpp" -#include "proton/comparable.hpp" - -#if PN_HAS_BOOST -#include <boost/shared_ptr.hpp> -#include <boost/intrusive_ptr.hpp> -#endif - -#include <memory> - -namespace proton { - -///@cond INTERNAL - -// Default refcounting uses pn_incref, pn_decref. Other types must define -// their own incref/decref overloads. -PN_CPP_EXTERN void incref(const void*); -PN_CPP_EXTERN void decref(const void*); - -///@endcond - -/** - * Smart pointer for reference counted objects derived from `proton::counted` - * or `proton::pn_counted` - */ -template <class T> class counted_ptr : public proton::comparable<counted_ptr<T> > { - public: - typedef T element_type; - - explicit counted_ptr(T *p = 0, bool add_ref = true) : ptr_(p) { - if (add_ref) incref(ptr_); - } - - counted_ptr(const counted_ptr<T>& p) : ptr_(p.ptr_) { incref(ptr_); } - - // TODO aconway 2015-08-20: C++11 move constructor - - ~counted_ptr() { decref(ptr_); } - - void swap(counted_ptr& x) { std::swap(ptr_, x.ptr_); } - - counted_ptr<T>& operator=(const counted_ptr<T>& p) { - counted_ptr<T>(p.get()).swap(*this); - return *this; - } - - void reset(T* p=0, bool add_ref = true) { - counted_ptr<T>(p, add_ref).swap(*this); - } - - T* release() { - T* ret = ptr_; - ptr_ = 0; - return ret; - } - - T* get() const { return ptr_; } - T* operator->() const { return ptr_; } - T& operator*() const { return *ptr_; } - operator bool() const { return !!ptr_; } - bool operator!() const { return !ptr_; } - - template <class U> operator counted_ptr<U>() const { return counted_ptr<U>(get()); } - template <class U> bool operator==(const counted_ptr<U>& x) { return get() == x.get(); } - template <class U> bool operator<(const counted_ptr<U>& x) { return get() < x.get(); } - -#if PN_HAS_STD_PTR - // TODO aconway 2015-08-21: need weak pointer context for efficient shared_ptr - operator std::shared_ptr<T>() { return std::shared_ptr<T>(dup()); } - operator std::shared_ptr<const T>() const { return std::shared_ptr<const T>(dup()); } - operator std::unique_ptr<T>() { return std::unique_ptr<T>(dup()); } - operator std::unique_ptr<const T>() const { return std::unique_ptr<const T>(dup()); } -#endif -#if PN_HAS_BOOST - // TODO aconway 2015-08-21: need weak pointer context for efficient shared_ptr - operator boost::shared_ptr<T>() { return boost::shared_ptr<T>(dup()); } - operator boost::shared_ptr<const T>() const { return boost::shared_ptr<const T>(dup()); } - operator boost::intrusive_ptr<T>() { return boost::intrusive_ptr<T>(ptr_); } - operator boost::intrusive_ptr<const T>() const { return boost::intrusive_ptr<const T>(ptr_); } -#endif - - private: - T* dup() { incref(ptr_); return ptr_; } - const T* dup() const { incref(ptr_); return ptr_; } - - T* ptr_; -}; - -#if PN_HAS_BOOST -template <class T> inline void intrusive_ptr_add_ref(const T* p) { if (p) incref(p); } -template <class T> inline void intrusive_ptr_release(const T* p) { if (p) decref(p); } -#endif - -} - -#endif // COUNTED_PTR_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/include/proton/data.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/data.hpp b/proton-c/bindings/cpp/include/proton/data.hpp index e74b77b..c2ffd3c 100644 --- a/proton-c/bindings/cpp/include/proton/data.hpp +++ b/proton-c/bindings/cpp/include/proton/data.hpp @@ -40,15 +40,15 @@ class data; class data : public object<pn_data_t> { public: data(pn_data_t* d) : object<pn_data_t>(d) {} - data(owned_object<pn_data_t> d) : object<pn_data_t>(d) {} - PN_CPP_EXTERN static owned_object<pn_data_t> create(); + data& operator=(const data&); // FIXME aconway 2015-12-01: - PN_CPP_EXTERN data& operator=(const data&); + PN_CPP_EXTERN static data create(); - template<class T> data& operator=(const T &t) { - clear(); encoder() << t; return *this; - } + // Copy the contents of another data object t this one. + PN_CPP_EXTERN data& copy(const data&); + + template<class T> data& copy(T &t) { clear(); encoder() << t; return *this; } /** Clear the data. */ PN_CPP_EXTERN void clear(); @@ -86,13 +86,14 @@ class data : public object<pn_data_t> { template<class T> T get() const { T t; get(t); return t; } - PN_CPP_EXTERN bool operator==(const data& x) const; - PN_CPP_EXTERN bool operator<(const data& x) const; + PN_CPP_EXTERN bool equal(const data& x) const; + PN_CPP_EXTERN bool less(const data& x) const; /** Human readable representation of data. */ friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const data&); friend class value; private: + data(pn_ptr<pn_data_t> d) : object<pn_data_t>(d) {} class decoder decoder() const { return const_cast<data*>(this)->decoder(); } }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 70da48b..6680d70 100644 --- a/proton-c/bindings/cpp/include/proton/handler.hpp +++ b/proton-c/bindings/cpp/include/proton/handler.hpp @@ -22,7 +22,6 @@ * */ #include "proton/export.hpp" -#include "proton/counted_ptr.hpp" #include "proton/event.hpp" #include "proton/event.h" #include "proton/reactor.h" @@ -58,7 +57,7 @@ class handler : public std::vector<handler*> { PN_CPP_EXTERN virtual void add_child_handler(handler &h); private: - counted_ptr<pn_handler_t> pn_handler_; + pn_ptr<pn_handler_t> pn_handler_; friend class container_impl; }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/include/proton/object.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/object.hpp b/proton-c/bindings/cpp/include/proton/object.hpp index 118f40d..0da20ae 100644 --- a/proton-c/bindings/cpp/include/proton/object.hpp +++ b/proton-c/bindings/cpp/include/proton/object.hpp @@ -21,93 +21,64 @@ #include "proton/config.hpp" #include "proton/export.hpp" +#include "proton/comparable.hpp" #include <memory> namespace proton { -/** - * Base class for proton object types - * - * Automatically perform memory management for pn_object based types. - * - * Note that for the memory management to work correctly no class - * inheriting from this should define any data members of its own. - * - * This is ok because the entire purpose of this class is to provide - * and manage the underlying pointer to the proton-c object. - * - * So any class using this one needs to be merely a thin wrapping of - * the proton-c object with no data members of it's own. Anything that internally - * needs extra data members and a proton-c object must use an inheritor of - * object<> as a data member - it must not inherit and add data members. - * - */ -class object_base { - public: - object_base() : object_(0) {} - object_base(void* o) : object_(o) {} - object_base(const object_base& o) : object_(o.object_) { incref(); } - - #ifdef PN_HAS_CPP11 - object_base(object_base&& o) : object_base() { *this = o; } - #endif +///@cond INTERNAL +class pn_ptr_base { + protected: + static void incref(void* p); + static void decref(void* p); +}; - ~object_base() { decref(); }; +template <class T> class pn_ptr : public comparable<pn_ptr<T> >, private pn_ptr_base { + public: + pn_ptr() : ptr_(0) {} + pn_ptr(T* p) : ptr_(p) { incref(ptr_); } + pn_ptr(const pn_ptr& o) : ptr_(o.ptr_) { incref(ptr_); } - object_base& operator=(object_base o) - { std::swap(object_, o.object_); return *this; } +#ifdef PN_HAS_CPP11 + pn_ptr(pn_ptr&& o) : ptr_(0) { std::swap(ptr_, o.ptr_); } +#endif - bool operator!() const { return !object_; } + ~pn_ptr() { decref(ptr_); }; - private: - PN_CPP_EXTERN void incref() const; - PN_CPP_EXTERN void decref() const; + static pn_ptr<T> take(T* p) { return pn_ptr<T>(p, true); } - void* object_; + pn_ptr& operator=(pn_ptr o) { std::swap(ptr_, o.ptr_); return *this; } - template <class T> - friend class object; - template <class T> - friend class owned_object; - friend bool operator==(const object_base&, const object_base&); -}; + T* get() const { return ptr_; } + bool operator!() const { return !ptr_; } -template <class T> -class owned_object : public object_base { - public: - owned_object(T* o) : object_base(o) {}; + friend bool operator==(const pn_ptr& a, const pn_ptr& b) { return a.ptr_ == b.ptr_; } + friend bool operator<(const pn_ptr& a, const pn_ptr& b) { return a.ptr_ < b.ptr_; } - protected: - T* pn_object() const { return static_cast<T*>(object_); } - - template <class U> - friend class object; + private: + pn_ptr(T* p, bool) : ptr_(p) {} + T *ptr_; }; +///@endcond INTERNAL -template <class T> -class object : public object_base { +/** + * Base class for proton object types + */ +template <class T> class object : public comparable<object<T> > { public: - object(T* o, bool take_own=false) : object_base(o) { if (!take_own) incref(); }; - object(owned_object<T> o) : object_base(o.object_) { o.object_=0; }; + bool operator!() const { return !object_; } - object& operator=(owned_object<T> o) - { object_ = o.object_; o = 0; return *this; } + friend bool operator==(const object& a, const object& b) { return a.object_ == b.object_; } + friend bool operator<(const object& a, const object& b) { return a.object_ < b.object_; } protected: - static const bool take_ownership = true; - T* pn_object() const { return static_cast<T*>(object_); } -}; - -inline -bool operator==(const object_base& o1, const object_base& o2) { - return o1.object_==o2.object_; -} + object(pn_ptr<T> o) : object_(o) {} + T* pn_object() const { return object_.get(); } -inline -bool operator!=(const object_base& o1, const object_base& o2) { - return !(o1==o2); -} + private: + pn_ptr<T> object_; +}; } #endif // OBJECT_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 index fa7d633..7592a14 100644 --- a/proton-c/bindings/cpp/include/proton/reactor.hpp +++ b/proton-c/bindings/cpp/include/proton/reactor.hpp @@ -67,7 +67,7 @@ class reactor : public object<pn_reactor_t> { PN_CPP_EXTERN amqp_timestamp mark(); PN_CPP_EXTERN amqp_timestamp now(); - + PN_CPP_EXTERN task schedule(int, pn_handler_t*); class connection connection(pn_handler_t*) const; @@ -86,9 +86,8 @@ class reactor : public object<pn_reactor_t> { PN_CPP_EXTERN bool quiesced(); PN_CPP_EXTERN void yield(); - void container_context(container&); - - friend class container_impl; + friend class container_impl; + friend class container_context; }; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/include/proton/value.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/value.hpp b/proton-c/bindings/cpp/include/proton/value.hpp index 661de51..c33eea1 100644 --- a/proton-c/bindings/cpp/include/proton/value.hpp +++ b/proton-c/bindings/cpp/include/proton/value.hpp @@ -46,10 +46,10 @@ class value : public comparable<value> { PN_CPP_EXTERN value(const value& x); // TODO: Should enumerate specifically all the pointer types that can convert to value // to avoid accidental conversions to bool this will require enable_if<> or the like - template <class T> value(const T& x) : data_(data::create()) { data_ = x; } + template <class T> value(const T& x) : data_(data::create()) { data_.copy(x); } PN_CPP_EXTERN value& operator=(const value& x); - template <class T> value& operator=(const T& x) { data_ = x; return *this; } + template <class T> value& operator=(const T& x) { data_.copy(x); return *this; } PN_CPP_EXTERN void clear(); PN_CPP_EXTERN bool empty() const; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 508a013..41c56f6 100644 --- a/proton-c/bindings/cpp/src/connection.cpp +++ b/proton-c/bindings/cpp/src/connection.cpp @@ -38,14 +38,13 @@ namespace proton { -connection_context& connection::context() const { return connection_context::get(pn_object()); } - transport connection::transport() const { return pn_connection_transport(pn_object()); } void connection::open() { - connector *connector = dynamic_cast<class connector*>(context().handler.get()); + connector *connector = dynamic_cast<class connector*>( + connection_context::get(pn_object()).handler.get()); if (connector) connector->apply_options(); // Inbound connections should already be configured. @@ -74,7 +73,7 @@ void connection::container_id(const std::string& id) { } container& connection::container() const { - return container_context(pn_object_reactor(pn_object())); + return container_context::get(pn_object_reactor(pn_object())); } link_range connection::find_links(endpoint::state mask) const { @@ -88,7 +87,7 @@ session_range connection::find_sessions(endpoint::state mask) const { session connection::open_session() { return pn_session(pn_object()); } session connection::default_session() { - struct connection_context& ctx = connection_context::get(pn_object()); + connection_context& ctx = connection_context::get(pn_object()); if (!ctx.default_session) { // Note we can't use a proton::session here because we don't want to own // a session reference. The connection owns the session, owning it here as well http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/connection_options.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/connection_options.cpp b/proton-c/bindings/cpp/src/connection_options.cpp index 141ffc9..6b72c9c 100644 --- a/proton-c/bindings/cpp/src/connection_options.cpp +++ b/proton-c/bindings/cpp/src/connection_options.cpp @@ -62,7 +62,8 @@ class connection_options::impl { void apply(connection& c) { pn_connection_t *pnc = connection_options::pn_connection(c); pn_transport_t *pnt = pn_connection_transport(pnc); - connector *outbound = dynamic_cast<connector*>(c.context().handler.get()); + connector *outbound = dynamic_cast<connector*>( + connection_context::get(c).handler.get()); bool uninit = (c.state() & endpoint::LOCAL_UNINIT); // pnt is NULL between reconnect attempts. http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 7d64ebc..f83e0a6 100644 --- a/proton-c/bindings/cpp/src/container_impl.cpp +++ b/proton-c/bindings/cpp/src/container_impl.cpp @@ -81,7 +81,7 @@ struct handler_context { class override_handler : public handler { public: - counted_ptr<pn_handler_t> base_handler; + pn_ptr<pn_handler_t> base_handler; container_impl &container_impl_; override_handler(pn_handler_t *h, container_impl &c) : base_handler(h), container_impl_(c) {} @@ -113,19 +113,17 @@ class override_handler : public handler } // namespace -counted_ptr<pn_handler_t> container_impl::cpp_handler(handler *h) -{ - if (h->pn_handler_) - return h->pn_handler_; - 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; - h->pn_handler_ = handler; - return handler; +pn_ptr<pn_handler_t> container_impl::cpp_handler(handler *h) { + if (!h->pn_handler_) { + h->pn_handler_ = pn_ptr<pn_handler_t>::take( + pn_handler_new(&handler_context::dispatch, + sizeof(struct handler_context), + &handler_context::cleanup)); + handler_context &hc = handler_context::get(h->pn_handler_.get()); + hc.container_ = &container_; + hc.handler_ = h; + } + return h->pn_handler_; } container_impl::container_impl(container& c, handler *h, const std::string& id) : @@ -133,16 +131,15 @@ container_impl::container_impl(container& c, handler *h, const std::string& id) link_id_(0) { if (id_.empty()) id_ = uuid().str(); - reactor_.container_context(container_); + container_context::set(reactor_, container_); // Set our own global handler that "subclasses" the existing one pn_handler_t *global_handler = reactor_.pn_global_handler(); override_handler_.reset(new override_handler(global_handler, *this)); - counted_ptr<pn_handler_t> cpp_global_handler(cpp_handler(override_handler_.get())); + pn_ptr<pn_handler_t> cpp_global_handler(cpp_handler(override_handler_.get())); reactor_.pn_global_handler(cpp_global_handler.get()); if (handler_) { - counted_ptr<pn_handler_t> pn_handler(cpp_handler(handler_)); - reactor_.pn_handler(pn_handler.get()); + reactor_.pn_handler(cpp_handler(handler_).get()); } @@ -159,11 +156,11 @@ connection container_impl::connect(const proton::url &url, const connection_opti opts.override(user_opts); handler *h = opts.handler(); - counted_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : counted_ptr<pn_handler_t>(); + pn_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : pn_ptr<pn_handler_t>(); connection conn(reactor_.connection(chandler.get())); pn_unique_ptr<connector> ctor(new connector(conn, opts)); ctor->address(url); // TODO: url vector - connection_context& cc(conn.context()); + connection_context& cc(connection_context::get(conn)); cc.container_impl = this; cc.handler.reset(ctor.release()); conn.open(); @@ -194,7 +191,7 @@ acceptor container_impl::listen(const proton::url& url) { opts.override(user_opts); #endif handler *h = opts.handler(); - counted_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : counted_ptr<pn_handler_t>(); + pn_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : pn_ptr<pn_handler_t>(); pn_acceptor_t *acptr = pn_reactor_acceptor(reactor_.pn_object(), url.host().c_str(), url.port().c_str(), chandler.get()); if (!acptr) throw error(MSG("accept fail: " << @@ -221,7 +218,7 @@ std::string container_impl::next_link_name() { } task container_impl::schedule(int delay, handler *h) { - counted_ptr<pn_handler_t> task_handler; + pn_ptr<pn_handler_t> task_handler; if (h) task_handler = cpp_handler(h); return reactor_.schedule(delay, task_handler.get()); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 d9401d0..4a89ab3 100644 --- a/proton-c/bindings/cpp/src/container_impl.hpp +++ b/proton-c/bindings/cpp/src/container_impl.hpp @@ -62,7 +62,7 @@ class container_impl void configure_server_connection(connection &c); task schedule(int delay, handler *h); - counted_ptr<pn_handler_t> cpp_handler(handler *h); + pn_ptr<pn_handler_t> cpp_handler(handler *h); std::string next_link_name(); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 4d17e54..0ea4262 100644 --- a/proton-c/bindings/cpp/src/contexts.cpp +++ b/proton-c/bindings/cpp/src/contexts.cpp @@ -30,87 +30,63 @@ #include "proton/session.h" #include "proton/link.h" +#include <typeinfo> + 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 COUNTED_CONTEXT; } -#define cpp_context_new NULL -#define cpp_context_free NULL +void cpp_context_finalize(void* v) { reinterpret_cast<context*>(v)->~context(); } +#define CID_cpp_context CID_pn_object +#define cpp_context_reify pn_object_reify #define cpp_context_initialize NULL -void cpp_context_incref(void* p) { proton::incref(reinterpret_cast<counted*>(p)); } -void cpp_context_decref(void* p) { proton::decref(reinterpret_cast<counted*>(p)); } -// Always return 1 to prevent the class finalizer logic running after we are deleted. -int cpp_context_refcount(void* p) { return 1; } -#define cpp_context_finalize NULL +#define cpp_context_finalize cpp_context_finalize #define cpp_context_hashcode NULL #define cpp_context_compare NULL #define cpp_context_inspect NULL +pn_class_t cpp_context_class = PN_CLASS(cpp_context); -pn_class_t COUNTED_CONTEXT_ = PN_METACLASS(cpp_context); -pn_class_t *COUNTED_CONTEXT = &COUNTED_CONTEXT_; +// Handles +PN_HANDLE(CONNECTION_CONTEXT) +PN_HANDLE(CONTAINER_CONTEXT) } +context::~context() {} +void *context::alloc(size_t n) { return pn_object_new(&cpp_context_class, n); } +pn_class_t* context::pn_class() { return &cpp_context_class; } -void set_context(pn_record_t* record, pn_handle_t handle, counted* value) +void set_context(pn_record_t* record, pn_handle_t handle, const pn_class_t *clazz, void* value) { - pn_record_def(record, handle, COUNTED_CONTEXT); + pn_record_def(record, handle, clazz); pn_record_set(record, handle, value); } -counted* get_context(pn_record_t* record, pn_handle_t handle) { - return reinterpret_cast<counted*>(pn_record_get(record, handle)); +template <class T> +T* get_context(pn_record_t* record, pn_handle_t handle) { + return reinterpret_cast<T*>(pn_record_get(record, handle)); } -// Connection context - -PN_HANDLE(CONNECTION_CONTEXT) - -connection_context::connection_context() : default_session(), container_impl() {} -connection_context::~connection_context() {} -struct connection_context& connection_context::get(pn_connection_t* c) { - connection_context* ctx = reinterpret_cast<connection_context*>( - get_context(pn_connection_attachments(c), CONNECTION_CONTEXT)); +connection_context& connection_context::get(pn_connection_t* c) { + connection_context* ctx = + get_context<connection_context>(pn_connection_attachments(c), CONNECTION_CONTEXT); if (!ctx) { - ctx = new connection_context(); - set_context(pn_connection_attachments(c), CONNECTION_CONTEXT, ctx); + ctx = context::create<connection_context>(); + set_context(pn_connection_attachments(c), CONNECTION_CONTEXT, context::pn_class(), ctx); + pn_decref(ctx); } return *ctx; } -PN_HANDLE(CONTAINER_CONTEXT) +connection_context& connection_context::get(const connection& c) { return get(c.pn_object()); } -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, &c); +void container_context::set(const reactor& r, container& c) { + set_context(pn_reactor_attachments(r.pn_object()), CONTAINER_CONTEXT, PN_VOID, &c); } -container &container_context(pn_reactor_t *pn_reactor) { - pn_record_t *record = pn_reactor_attachments(pn_reactor); - container *ctx = reinterpret_cast<container*>(pn_record_get(record, CONTAINER_CONTEXT)); +container &container_context::get(pn_reactor_t *pn_reactor) { + container *ctx = get_context<container>(pn_reactor_attachments(pn_reactor), CONTAINER_CONTEXT); if (!ctx) throw error(MSG("Reactor has no C++ container context")); return *ctx; } -PN_HANDLE(EVENT_CONTEXT) - -void event_context(pn_event_t *pn_event, pn_message_t *m) { - pn_record_t *record = pn_event_attachments(pn_event); - 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 *ctx = (pn_message_t *) pn_record_get(record, EVENT_CONTEXT); - return ctx; -} - - } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 a0e6cf6..c12d8bd 100644 --- a/proton-c/bindings/cpp/src/contexts.hpp +++ b/proton-c/bindings/cpp/src/contexts.hpp @@ -22,27 +22,45 @@ * */ -#include "proton/counted.hpp" #include "proton/pn_unique_ptr.hpp" -#include "proton/reactor.h" -#include "proton/session.hpp" +#include "proton/message.hpp" +#include "proton/connection.hpp" +#include "proton/container.hpp" +#include "proton/handler.hpp" -#include <proton/message.h> +struct pn_session_t; +struct pn_event_t; +struct pn_record_t; namespace proton { -class session; class handler; class container_impl; -counted* get_context(pn_record_t*, pn_handle_t handle); -void set_context(pn_record_t*, pn_handle_t, counted* value); +// Base class for C++ classes that are used as proton contexts. +// contexts are pn_objects managed by pn reference counts. +class context { + public: + // Allocate a default-constructed T as a proton object. T must be a subclass of context. + template <class T> static T *create() { return new(alloc(sizeof(T))) T(); } -struct connection_context : public counted { - static connection_context& get(pn_connection_t* c); + // Allocate a copy-constructed T as a proton object. T must be a subclass of context. + template <class T> static T *create(const T& x) { return new(alloc(sizeof(T))) T(x); } - connection_context(); - ~connection_context(); + virtual ~context(); + + static pn_class_t* pn_class(); + + private: + static void *alloc(size_t n); +}; + +class connection_context : public context { + public: + static connection_context& get(pn_connection_t*); + static connection_context& get(const connection&); + + connection_context() : default_session(0), container_impl(0) {} pn_unique_ptr<class handler> handler; pn_session_t *default_session; // Owned by connection @@ -50,12 +68,13 @@ struct connection_context : public counted { message event_message; // re-used by messaging_adapter for performance }; -class container; -void container_context(pn_reactor_t *, container&); -container& container_context(pn_reactor_t *); +void container_context(const reactor&, container&); -void event_context(pn_event_t *pn_event, pn_message_t *m); -pn_message_t *event_context(pn_event_t *pn_event); +class container_context { + public: + static void set(const reactor& r, container& c); + static container& get(pn_reactor_t*); +}; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/counted_ptr.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/counted_ptr.cpp b/proton-c/bindings/cpp/src/counted_ptr.cpp deleted file mode 100644 index 261d5ec..0000000 --- a/proton-c/bindings/cpp/src/counted_ptr.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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/object.h> - -namespace proton { - -void incref(const void* p) { - if (p) ::pn_incref(const_cast<void*>(p)); -} - -void decref(const void* p) { - if (p) ::pn_decref(const_cast<void*>(p)); -} - -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/data.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/data.cpp b/proton-c/bindings/cpp/src/data.cpp index 8a45d6b..1eb6ab8 100644 --- a/proton-c/bindings/cpp/src/data.cpp +++ b/proton-c/bindings/cpp/src/data.cpp @@ -26,7 +26,7 @@ namespace proton { -data& data::operator=(const data& x) { ::pn_data_copy(pn_object(), x.pn_object()); return *this; } +data& data::copy(const data& x) { ::pn_data_copy(pn_object(), x.pn_object()); return *this; } void data::clear() { ::pn_data_clear(pn_object()); } @@ -62,7 +62,7 @@ std::ostream& operator<<(std::ostream& o, const data& d) { return o << inspectable(d.pn_object()); } -owned_object<pn_data_t> data::create() { return pn_data(0); } +data data::create() { return pn_ptr<pn_data_t>::take(pn_data(0)); } encoder data::encoder() { return proton::encoder(pn_object()); } decoder data::decoder() { return proton::decoder(pn_object()); } @@ -156,10 +156,10 @@ int compare(data& a, data& b) { } } // namespace -bool data::operator==(const data& x) const { +bool data::equal(const data& x) const { return compare(const_cast<data&>(*this), const_cast<data&>(x)) == 0; } -bool data::operator<(const data& x) const { +bool data::less(const data& x) const { return compare(const_cast<data&>(*this), const_cast<data&>(x)) < 0; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/decoder.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/decoder.cpp b/proton-c/bindings/cpp/src/decoder.cpp index f14345d..611d275 100644 --- a/proton-c/bindings/cpp/src/decoder.cpp +++ b/proton-c/bindings/cpp/src/decoder.cpp @@ -156,7 +156,7 @@ decoder operator>>(decoder d, rewind) { d.rewind(); return d; } decoder operator>>(decoder d, value& v) { data ddata = d.data(); - if (object_base(ddata) == v.data_) throw decode_error("extract into self"); + if (ddata == v.data_) throw decode_error("extract into self"); data vdata = v.encoder().data(); { narrow n(ddata); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/encoder.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/encoder.cpp b/proton-c/bindings/cpp/src/encoder.cpp index a0b10c0..3624821 100644 --- a/proton-c/bindings/cpp/src/encoder.cpp +++ b/proton-c/bindings/cpp/src/encoder.cpp @@ -132,7 +132,7 @@ encoder operator<<(encoder e, amqp_binary value) { return insert(e, e.pn_object( encoder operator<<(encoder e, const value& v) { data edata = e.data(); - if (object_base(edata) == v.data_) throw encode_error("cannot insert into self"); + if (edata == v.data_) throw encode_error("cannot insert into self"); data vdata = v.decoder().data(); check(edata.append(vdata), e.pn_object()); return e; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 587dec9..cb66933 100644 --- a/proton-c/bindings/cpp/src/link.cpp +++ b/proton-c/bindings/cpp/src/link.cpp @@ -80,8 +80,8 @@ class session link::session() const { void link::handler(class handler &h) { pn_record_t *record = pn_link_attachments(pn_object()); - connection_context& cc(connection().context()); - counted_ptr<pn_handler_t> chandler = cc.container_impl->cpp_handler(&h); + connection_context& cc(connection_context::get(connection())); + pn_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/5045ec03/proton-c/bindings/cpp/src/message.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/message.cpp b/proton-c/bindings/cpp/src/message.cpp index 7c032f0..dd57606 100644 --- a/proton-c/bindings/cpp/src/message.cpp +++ b/proton-c/bindings/cpp/src/message.cpp @@ -66,7 +66,7 @@ void check(int err) { } } // namespace -void message::id(const message_id& id) { data(pn_message_id(message_)) = id.value_; } +void message::id(const message_id& id) { data(pn_message_id(message_)).copy(id.value_); } namespace { inline message_id from_pn_atom(const pn_atom_t& v) { @@ -125,7 +125,7 @@ std::string message::reply_to() const { } void message::correlation_id(const message_id& id) { - data(pn_message_correlation_id(message_)) = id.value_; + data(pn_message_correlation_id(message_)).copy(id.value_); } message_id message::correlation_id() const { @@ -186,7 +186,7 @@ bool message::inferred() const { return pn_message_is_inferred(message_); } void message::inferred(bool b) { pn_message_set_inferred(message_, b); } -void message::body(const value& v) { body() = v; } +void message::body(const value& v) { body().copy(v); } const data message::body() const { return pn_message_body(message_); @@ -197,7 +197,7 @@ data message::body() { } void message::properties(const value& v) { - properties() = v; + properties().copy(v); } const data message::properties() const { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/messaging_adapter.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/messaging_adapter.cpp b/proton-c/bindings/cpp/src/messaging_adapter.cpp index e3bced8..d551018 100644 --- a/proton-c/bindings/cpp/src/messaging_adapter.cpp +++ b/proton-c/bindings/cpp/src/messaging_adapter.cpp @@ -75,7 +75,7 @@ void messaging_adapter::on_delivery(event &e) { // generate on_message messaging_event mevent(messaging_event::MESSAGE, *pe); pn_connection_t *pnc = pn_session_connection(pn_link_session(lnk)); - struct connection_context& ctx = connection_context::get(pnc); + connection_context& ctx = connection_context::get(pnc); // Reusable per-connection message. // Avoid expensive heap malloc/free overhead. // See PROTON-998 http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/object.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/object.cpp b/proton-c/bindings/cpp/src/object.cpp index d5fb7ef..9fde50f 100644 --- a/proton-c/bindings/cpp/src/object.cpp +++ b/proton-c/bindings/cpp/src/object.cpp @@ -22,12 +22,12 @@ namespace proton { -void object_base::incref() const { - if (object_) ::pn_incref(const_cast<void*>(object_)); +void pn_ptr_base::incref(void *p) { + if (p) ::pn_incref(const_cast<void*>(p)); } -void object_base::decref() const { - if (object_) ::pn_decref(const_cast<void*>(object_)); +void pn_ptr_base::decref(void *p) { + if (p) ::pn_decref(const_cast<void*>(p)); } } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/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 index 9a52d99..2a740e8 100644 --- a/proton-c/bindings/cpp/src/reactor.cpp +++ b/proton-c/bindings/cpp/src/reactor.cpp @@ -30,10 +30,7 @@ namespace proton { reactor reactor::create() { - pn_reactor_t *p = pn_reactor(); - reactor r(p); - pn_decref(p); // FIXME aconway 2015-11-26: take ownership - return r; + return pn_ptr<pn_reactor_t>::take(pn_reactor()).get(); } void reactor::run() { pn_reactor_run(pn_object()); } @@ -92,8 +89,4 @@ void reactor::timeout(duration timeout) { pn_reactor_set_timeout(pn_object(), timeout.milliseconds); } -void reactor::container_context(container& c) { - proton::container_context(pn_object(), c); -} - } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/session.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/session.cpp b/proton-c/bindings/cpp/src/session.cpp index e903080..c6c2233 100644 --- a/proton-c/bindings/cpp/src/session.cpp +++ b/proton-c/bindings/cpp/src/session.cpp @@ -40,7 +40,7 @@ connection session::connection() const { namespace { std::string set_name(const std::string& name, session* s) { if (name.empty()) - return s->connection().context().container_impl->next_link_name(); + return connection_context::get(s->connection()).container_impl->next_link_name(); return name; } } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5045ec03/proton-c/bindings/cpp/src/value.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/value.cpp b/proton-c/bindings/cpp/src/value.cpp index be5ca5e..b603bf9 100644 --- a/proton-c/bindings/cpp/src/value.cpp +++ b/proton-c/bindings/cpp/src/value.cpp @@ -28,9 +28,9 @@ namespace proton { value::value() : data_(data::create()) {} -value::value(const value& x) : data_(data::create()) { data_ = x.data_; } +value::value(const value& x) : data_(data::create()) { data_.copy(x.data_); } -value& value::operator=(const value& x) { data_ = x.data_; return *this; } +value& value::operator=(const value& x) { data_.copy(x.data_); return *this; } void value::clear() { data_.clear(); } @@ -42,9 +42,9 @@ class decoder value::decoder() const { data_.decoder().rewind(); return data_.de type_id value::type() const { return decoder().type(); } -bool value::operator==(const value& x) const { return data_ == x.data_; } +bool value::operator==(const value& x) const { return data_.equal(x.data_); } -bool value::operator<(const value& x) const { return data_ < x.data_; } +bool value::operator<(const value& x) const { return data_.less(x.data_); } std::ostream& operator<<(std::ostream& o, const value& v) { // pn_inspect prints strings with quotes which is not normal in C++. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
