PROTON-1554: Remove thread-safe template, simplify returned<> Removed the thread-safe template.
Simplified and documented returned<>: It can *only* be converted to proton object, and only in a single-threaded application. Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/f1ee2681 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/f1ee2681 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/f1ee2681 Branch: refs/heads/go1 Commit: f1ee268163ce80c2b9dc3dcb7ec00151f5c6b486 Parents: ed756d8 Author: Alan Conway <acon...@redhat.com> Authored: Thu Aug 24 16:49:08 2017 -0400 Committer: Alan Conway <acon...@redhat.com> Committed: Sat Aug 26 13:16:50 2017 -0400 ---------------------------------------------------------------------- examples/cpp/broker.cpp | 2 +- examples/cpp/client.cpp | 1 - examples/cpp/connection_options.cpp | 1 - examples/cpp/flow_control.cpp | 1 - examples/cpp/helloworld.cpp | 1 - examples/cpp/helloworld_direct.cpp | 1 - examples/cpp/queue_browser.cpp | 1 - examples/cpp/scheduled_send.cpp | 2 +- examples/cpp/scheduled_send_03.cpp | 1 - examples/cpp/selected_recv.cpp | 1 - examples/cpp/server.cpp | 1 - examples/cpp/service_bus.cpp | 2 +- examples/cpp/simple_recv.cpp | 1 - examples/cpp/simple_send.cpp | 1 - examples/cpp/ssl.cpp | 1 - examples/cpp/ssl_client_cert.cpp | 1 - proton-c/bindings/cpp/CMakeLists.txt | 2 +- proton-c/bindings/cpp/docs/headers.dox | 2 - .../bindings/cpp/include/proton/connection.hpp | 5 +- .../bindings/cpp/include/proton/container.hpp | 28 +++- .../bindings/cpp/include/proton/delivery.hpp | 2 +- proton-c/bindings/cpp/include/proton/fwd.hpp | 2 - .../cpp/include/proton/internal/object.hpp | 5 +- .../cpp/include/proton/io/connection_driver.hpp | 1 - .../bindings/cpp/include/proton/receiver.hpp | 3 +- .../bindings/cpp/include/proton/returned.hpp | 62 +++++++ proton-c/bindings/cpp/include/proton/sender.hpp | 1 - .../bindings/cpp/include/proton/session.hpp | 1 - .../bindings/cpp/include/proton/thread_safe.hpp | 165 ------------------- .../bindings/cpp/include/proton/work_queue.hpp | 6 +- .../bindings/cpp/src/connection_driver_test.cpp | 2 +- proton-c/bindings/cpp/src/container.cpp | 1 - proton-c/bindings/cpp/src/container_test.cpp | 1 - .../bindings/cpp/src/include/proton_bits.hpp | 6 + .../cpp/src/proactor_container_impl.cpp | 9 +- proton-c/bindings/cpp/src/returned.cpp | 41 +++++ proton-c/bindings/cpp/src/thread_safe_test.cpp | 108 ------------ tests/tools/apps/cpp/reactor_send.cpp | 1 - 38 files changed, 155 insertions(+), 318 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/broker.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp index 198b449..a236bb1 100644 --- a/examples/cpp/broker.cpp +++ b/examples/cpp/broker.cpp @@ -35,9 +35,9 @@ #include <proton/source_options.hpp> #include <proton/target.hpp> #include <proton/target_options.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/transport.hpp> +#include <proton/work_queue.hpp> #include <deque> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/client.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp index 7139155..81a9a32 100644 --- a/examples/cpp/client.cpp +++ b/examples/cpp/client.cpp @@ -28,7 +28,6 @@ #include <proton/messaging_handler.hpp> #include <proton/receiver_options.hpp> #include <proton/source_options.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/connection_options.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/connection_options.cpp b/examples/cpp/connection_options.cpp index f718060..a696c6d 100644 --- a/examples/cpp/connection_options.cpp +++ b/examples/cpp/connection_options.cpp @@ -24,7 +24,6 @@ #include <proton/container.hpp> #include <proton/default_container.hpp> #include <proton/messaging_handler.hpp> -#include <proton/thread_safe.hpp> #include <proton/transport.hpp> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/flow_control.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/flow_control.cpp b/examples/cpp/flow_control.cpp index c0b8739..7b1474e 100644 --- a/examples/cpp/flow_control.cpp +++ b/examples/cpp/flow_control.cpp @@ -31,7 +31,6 @@ #include <proton/messaging_handler.hpp> #include <proton/receiver_options.hpp> #include <proton/sender.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/helloworld.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp index 4aa5cdd..404d822 100644 --- a/examples/cpp/helloworld.cpp +++ b/examples/cpp/helloworld.cpp @@ -25,7 +25,6 @@ #include <proton/delivery.hpp> #include <proton/message.hpp> #include <proton/messaging_handler.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/url.hpp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/helloworld_direct.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp index 9331587..f879edd 100644 --- a/examples/cpp/helloworld_direct.cpp +++ b/examples/cpp/helloworld_direct.cpp @@ -26,7 +26,6 @@ #include <proton/message.hpp> #include <proton/messaging_handler.hpp> #include <proton/sender.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/queue_browser.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/queue_browser.cpp b/examples/cpp/queue_browser.cpp index 583277e..ef158b5 100644 --- a/examples/cpp/queue_browser.cpp +++ b/examples/cpp/queue_browser.cpp @@ -27,7 +27,6 @@ #include <proton/messaging_handler.hpp> #include <proton/receiver_options.hpp> #include <proton/source_options.hpp> -#include <proton/thread_safe.hpp> #include <proton/url.hpp> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/scheduled_send.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/scheduled_send.cpp b/examples/cpp/scheduled_send.cpp index 2914c44..4c71482 100644 --- a/examples/cpp/scheduled_send.cpp +++ b/examples/cpp/scheduled_send.cpp @@ -22,11 +22,11 @@ #include "options.hpp" #include <proton/container.hpp> +#include <proton/connection.hpp> #include <proton/default_container.hpp> #include <proton/message.hpp> #include <proton/messaging_handler.hpp> #include <proton/sender.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/work_queue.hpp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/scheduled_send_03.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/scheduled_send_03.cpp b/examples/cpp/scheduled_send_03.cpp index 008853c..20972e4 100644 --- a/examples/cpp/scheduled_send_03.cpp +++ b/examples/cpp/scheduled_send_03.cpp @@ -29,7 +29,6 @@ #include <proton/message.hpp> #include <proton/messaging_handler.hpp> #include <proton/sender.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/work_queue.hpp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/selected_recv.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/selected_recv.cpp b/examples/cpp/selected_recv.cpp index a48ef0e..771fb29 100644 --- a/examples/cpp/selected_recv.cpp +++ b/examples/cpp/selected_recv.cpp @@ -26,7 +26,6 @@ #include <proton/messaging_handler.hpp> #include <proton/receiver_options.hpp> #include <proton/source_options.hpp> -#include <proton/thread_safe.hpp> #include <proton/url.hpp> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/server.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp index 449ce6e..573b3a0 100644 --- a/examples/cpp/server.cpp +++ b/examples/cpp/server.cpp @@ -27,7 +27,6 @@ #include <proton/message.hpp> #include <proton/message_id.hpp> #include <proton/messaging_handler.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/url.hpp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/service_bus.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/service_bus.cpp b/examples/cpp/service_bus.cpp index 6b57f8d..2c7a682 100644 --- a/examples/cpp/service_bus.cpp +++ b/examples/cpp/service_bus.cpp @@ -94,9 +94,9 @@ Done. No more messages. #include <proton/sender.hpp> #include <proton/sender_options.hpp> #include <proton/source_options.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/url.hpp> +#include <proton/work_queue.hpp> #include <iostream> #include <sstream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/simple_recv.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp index 145eef9..93b4868 100644 --- a/examples/cpp/simple_recv.cpp +++ b/examples/cpp/simple_recv.cpp @@ -30,7 +30,6 @@ #include <proton/message.hpp> #include <proton/message_id.hpp> #include <proton/messaging_handler.hpp> -#include <proton/thread_safe.hpp> #include <proton/value.hpp> #include <iostream> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/simple_send.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp index 358bbec..ebc02cb 100644 --- a/examples/cpp/simple_send.cpp +++ b/examples/cpp/simple_send.cpp @@ -28,7 +28,6 @@ #include <proton/message.hpp> #include <proton/message_id.hpp> #include <proton/messaging_handler.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/types.hpp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/ssl.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/ssl.cpp b/examples/cpp/ssl.cpp index 166bd61..e24961f 100644 --- a/examples/cpp/ssl.cpp +++ b/examples/cpp/ssl.cpp @@ -30,7 +30,6 @@ #include <proton/message.hpp> #include <proton/messaging_handler.hpp> #include <proton/ssl.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/transport.hpp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/ssl_client_cert.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/ssl_client_cert.cpp b/examples/cpp/ssl_client_cert.cpp index 8ca2dc2..c6c7666 100644 --- a/examples/cpp/ssl_client_cert.cpp +++ b/examples/cpp/ssl_client_cert.cpp @@ -28,7 +28,6 @@ #include <proton/messaging_handler.hpp> #include <proton/sasl.hpp> #include <proton/ssl.hpp> -#include <proton/thread_safe.hpp> #include <proton/tracker.hpp> #include <proton/transport.hpp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt index 21ff26c..472105a 100644 --- a/proton-c/bindings/cpp/CMakeLists.txt +++ b/proton-c/bindings/cpp/CMakeLists.txt @@ -57,6 +57,7 @@ set(qpid-proton-cpp-source src/receiver.cpp src/receiver_options.cpp src/reconnect_timer.cpp + src/returned.cpp src/sasl.cpp src/scalar_base.cpp src/sender.cpp @@ -169,7 +170,6 @@ endmacro(add_cpp_test) add_cpp_test(codec_test) add_cpp_test(connection_driver_test) -add_cpp_test(thread_safe_test) add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) add_cpp_test(message_test) add_cpp_test(map_test) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/docs/headers.dox ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/docs/headers.dox b/proton-c/bindings/cpp/docs/headers.dox index 0ff7220..7e9d79c 100644 --- a/proton-c/bindings/cpp/docs/headers.dox +++ b/proton-c/bindings/cpp/docs/headers.dox @@ -14,7 +14,6 @@ /// @file proton/duration.hpp Time duration data type /// @file proton/error_condition.hpp AMQP error condition /// @file proton/error.hpp Base exception type thrown by proton functions -/// @file proton/event_loop.hpp /// @file proton/function.hpp /// @file proton/fwd.hpp /// @file proton/link.hpp @@ -42,7 +41,6 @@ /// @file proton/target.hpp /// @file proton/target_options.hpp /// @file proton/terminus.hpp -/// @file proton/thread_safe.hpp /// @file proton/timestamp.hpp /// @file proton/tracker.hpp /// @file proton/transfer.hpp http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/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 ef75a4e..10ea61b 100644 --- a/proton-c/bindings/cpp/include/proton/connection.hpp +++ b/proton-c/bindings/cpp/include/proton/connection.hpp @@ -109,10 +109,10 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi PN_CPP_EXTERN receiver open_receiver(const std::string &addr, const receiver_options &); - /// @copydoc container::sender_options + /// @see proton::container::sender_options() PN_CPP_EXTERN class sender_options sender_options() const; - /// @copydoc container::receiver_options + /// @see container::receiver_options() PN_CPP_EXTERN class receiver_options receiver_options() const; /// Return all sessions on this connection. @@ -142,7 +142,6 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi /// @cond INTERNAL friend class internal::factory<connection>; friend class container; - friend class proton::thread_safe<connection>; /// @endcond }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/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 859d70c..64e52ad 100644 --- a/proton-c/bindings/cpp/include/proton/container.hpp +++ b/proton-c/bindings/cpp/include/proton/container.hpp @@ -23,7 +23,7 @@ */ #include "./fwd.hpp" -#include "./thread_safe.hpp" +#include "./returned.hpp" #include "./types_fwd.hpp" #include "./internal/config.hpp" @@ -76,9 +76,14 @@ class PN_CPP_CLASS_EXTERN container { /// The handler in the composed options is used to call /// proton::messaging_handler::on_connection_open() when the remote peer's /// open response is received. + /// + /// @return A returned<connection> + /// @copydetails returned PN_CPP_EXTERN returned<connection> connect(const std::string& url, const connection_options &); /// Connect to `url` and send an open request to the remote peer. + /// @return A returned<connection> + /// @copydetails returned PN_CPP_EXTERN returned<connection> connect(const std::string& url); /// Start listening on url. @@ -135,12 +140,16 @@ class PN_CPP_CLASS_EXTERN container { PN_CPP_EXTERN void stop(); /// Open a connection and sender for `url`. + /// @return A returned<sender> + /// @copydetails returned PN_CPP_EXTERN returned<sender> open_sender(const std::string &url); /// Open a connection and sender for `url`. /// /// Supplied sender options will override the container's /// template options. + /// @return A returned<sender> + /// @copydetails returned PN_CPP_EXTERN returned<sender> open_sender(const std::string &url, const proton::sender_options &o); @@ -148,6 +157,8 @@ class PN_CPP_CLASS_EXTERN container { /// /// Supplied connection options will override the /// container's template options. + /// @return A returned<sender> + /// @copydetails returned PN_CPP_EXTERN returned<sender> open_sender(const std::string &url, const connection_options &c); @@ -155,11 +166,17 @@ class PN_CPP_CLASS_EXTERN container { /// /// Supplied sender or connection options will override the /// container's template options. + /// + /// @return A returned<sender> + /// @copydetails returned PN_CPP_EXTERN returned<sender> open_sender(const std::string &url, const proton::sender_options &o, const connection_options &c); /// Open a connection and receiver for `url`. + /// + /// @return A returned<receiver> + /// @copydetails returned PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url); @@ -167,6 +184,9 @@ class PN_CPP_CLASS_EXTERN container { /// /// Supplied receiver options will override the container's /// template options. + /// + /// @return A returned<receiver> + /// @copydetails returned PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url, const proton::receiver_options &o); @@ -174,6 +194,9 @@ class PN_CPP_CLASS_EXTERN container { /// /// Supplied receiver or connection options will override the /// container's template options. + /// + /// @return A returned<receiver> + /// @copydetails returned PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url, const connection_options &c); @@ -181,6 +204,9 @@ class PN_CPP_CLASS_EXTERN container { /// /// Supplied receiver or connection options will override the /// container's template options. + /// + /// @return A returned<receiver> + /// @copydetails returned PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url, const proton::receiver_options &o, const connection_options &c); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/delivery.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/delivery.hpp b/proton-c/bindings/cpp/include/proton/delivery.hpp index 7c89f0c..7a38bca 100644 --- a/proton-c/bindings/cpp/include/proton/delivery.hpp +++ b/proton-c/bindings/cpp/include/proton/delivery.hpp @@ -46,7 +46,7 @@ class delivery : public transfer { // XXX ATM the following don't reflect the differing behaviors we // get from the different delivery modes. - Deferred - + /// Settle with ACCEPTED state. PN_CPP_EXTERN void accept(); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/fwd.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/fwd.hpp b/proton-c/bindings/cpp/include/proton/fwd.hpp index 5ade5fd..efbb91b 100644 --- a/proton-c/bindings/cpp/include/proton/fwd.hpp +++ b/proton-c/bindings/cpp/include/proton/fwd.hpp @@ -64,8 +64,6 @@ class connection_driver; } template <class T> class returned; -template <class T> class thread_safe; - } #endif // PROTON_FWD_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/internal/object.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/internal/object.hpp b/proton-c/bindings/cpp/include/proton/internal/object.hpp index d492b80..442b09d 100644 --- a/proton-c/bindings/cpp/include/proton/internal/object.hpp +++ b/proton-c/bindings/cpp/include/proton/internal/object.hpp @@ -31,7 +31,7 @@ namespace proton { -template <class T> class thread_safe; +template <class T> class returned; namespace internal { @@ -101,7 +101,8 @@ template <class T> class object : private comparable<object<T> > { 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_; } friend std::ostream& operator<<(std::ostream& o, const object& a) { o << a.object_.inspect(); return o; } - template <class U> friend class proton::thread_safe; + + template <class U> friend class proton::returned; }; /// Factory class used internally to make wrappers and extract proton objects http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp index 44275bc..f9774ac 100644 --- a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp +++ b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp @@ -179,7 +179,6 @@ PN_CPP_CLASS_EXTERN connection_driver { PN_CPP_EXTERN bool dispatch(); /// Get the AMQP connection associated with this connection_driver. - /// The event_loop is availabe via proton::thread_safe<connection>(connection()) PN_CPP_EXTERN proton::connection connection() const; /// Get the transport associated with this connection_driver. http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/receiver.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/receiver.hpp b/proton-c/bindings/cpp/include/proton/receiver.hpp index f92ac96..b995e6f 100644 --- a/proton-c/bindings/cpp/include/proton/receiver.hpp +++ b/proton-c/bindings/cpp/include/proton/receiver.hpp @@ -76,12 +76,11 @@ PN_CPP_CLASS_EXTERN receiver : public link { /// @cond INTERNAL friend class internal::factory<receiver>; friend class receiver_iterator; - friend class thread_safe<receiver>; /// @endcond }; /// @cond INTERNAL - + /// An iterator of receivers. class receiver_iterator : public internal::iter_base<receiver, receiver_iterator> { explicit receiver_iterator(receiver r, pn_session_t* s = 0) : http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/returned.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/returned.hpp b/proton-c/bindings/cpp/include/proton/returned.hpp new file mode 100644 index 0000000..25b5c91 --- /dev/null +++ b/proton-c/bindings/cpp/include/proton/returned.hpp @@ -0,0 +1,62 @@ +#ifndef PROTON_RETURNED_HPP +#define PROTON_RETURNED_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 "./internal/object.hpp" +#include "./connection.hpp" +#include "./receiver.hpp" +#include "./sender.hpp" + +/// @file +/// Return type for container functions + +namespace proton { + +namespace internal { +template <class T> class factory; +} + +/// Return type for container functions +/// +/// @note returned value is *thread-unsafe*. +/// A single-threaded application can assign the returned<T> value to a plain T. +/// A multi-threaded application *must* ignore the returned value, as it may already +/// be invalid by the time the function returns. Multi-threaded applications +/// can access the value in @ref messaging_handler functions. +/// +template <class T> +class returned +{ + public: + operator T() const; + + private: + typename T::pn_type* ptr_; + returned(const T&); + returned& operator=(const returned&); + template <class U> friend class internal::factory; +}; + +} // proton + +#endif /*!PROTON_RETURNED_HPP*/ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/sender.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/sender.hpp b/proton-c/bindings/cpp/include/proton/sender.hpp index f8c1e66..b01f21c 100644 --- a/proton-c/bindings/cpp/include/proton/sender.hpp +++ b/proton-c/bindings/cpp/include/proton/sender.hpp @@ -71,7 +71,6 @@ PN_CPP_CLASS_EXTERN sender : public link { /// @cond INTERNAL friend class internal::factory<sender>; friend class sender_iterator; - friend class thread_safe<sender>; /// @endcond }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/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 8d4184b..c66aa05 100644 --- a/proton-c/bindings/cpp/include/proton/session.hpp +++ b/proton-c/bindings/cpp/include/proton/session.hpp @@ -99,7 +99,6 @@ PN_CPP_CLASS_EXTERN session : public internal::object<pn_session_t>, public endp /// @cond INTERNAL friend class internal::factory<session>; friend class session_iterator; - friend class thread_safe<session>; /// @endcond }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/thread_safe.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/thread_safe.hpp b/proton-c/bindings/cpp/include/proton/thread_safe.hpp deleted file mode 100644 index 0b38883..0000000 --- a/proton-c/bindings/cpp/include/proton/thread_safe.hpp +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef PROTON_THREAD_SAFE_HPP -#define PROTON_THREAD_SAFE_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 "./fwd.hpp" -#include "./internal/config.hpp" -#include "./connection.hpp" -#include "./function.hpp" -#include "./internal/object.hpp" -#include "./internal/type_traits.hpp" -#include "./work_queue.hpp" - -#include <functional> - -namespace proton { - -namespace internal { -template <class T> struct endpoint_traits; -template<> struct endpoint_traits<connection> {}; -template<> struct endpoint_traits<session> {}; -template<> struct endpoint_traits<link> {}; -template<> struct endpoint_traits<sender> {}; -template<> struct endpoint_traits<receiver> {}; -} - -/// **Experimental** - A thread-safe object wrapper. -/// -/// The proton::object subclasses (proton::connection, proton::sender etc.) are -/// reference-counted wrappers for C structs. They are not safe for concurrent use, -/// not even to copy or assign. -/// -/// A pointer to thread_safe<> can be used from any thread to get the -/// proton::event_loop for the object's connection. The object will not be -/// destroyed until the thread_safe<> is deleted. You can use std::shared_ptr, -/// std::unique_ptr or any other memory management technique to manage the -/// thread_safe<>. -/// -/// Use make_thread_safe(), make_shared_thread_safe(), make_unique_thread_safe() to -/// create a thread_safe<> -/// -/// @see @ref mt_page -template <class T> -class thread_safe : private internal::pn_ptr_base, private internal::endpoint_traits<T> { - typedef typename T::pn_type pn_type; - - public: - /// @cond INTERNAL - static void operator delete(void*) {} - /// @endcond - - ~thread_safe() { - if (ptr()) { - if (!!work_queue().impl_) schedule_work(&work_queue(), &decref, (void*)ptr()); - else decref(ptr()); - } - } - - /// Get the work queue for this object. - class work_queue& work_queue() { return work_queue::get(ptr()); } - - /// Get the thread-unsafe proton object wrapped by this thread_safe<T> - T unsafe() { return T(ptr()); } - - private: - static thread_safe* create(const T& obj) { return new (obj.pn_object()) thread_safe(); } - static void* operator new(size_t, pn_type* p) { return p; } - static void operator delete(void*, pn_type*) {} - thread_safe() { incref(ptr()); } - pn_type* ptr() { return reinterpret_cast<pn_type*>(this); } - - - // Non-copyable. - thread_safe(const thread_safe&); - thread_safe& operator=(const thread_safe&); - - /// @cond INTERNAL - friend class returned<T>; - /// @endcond -}; - -// A return value for functions returning a thread_safe<> object. -// -// Temporary return value only, you should release() to get a plain pointer or -// assign to a smart pointer type. -template <class T> -class returned : private internal::endpoint_traits<T> -{ - public: - /// Take ownership - explicit returned(thread_safe<T>* p) : ptr_(p) {} - /// Create an owned thread_safe<T> - explicit returned(const T& obj) : ptr_(thread_safe<T>::create(obj)) {} - /// Transfer ownership. - /// Use the same "cheat" as std::auto_ptr, calls x.release() even though x is const. - returned(const returned& x) : ptr_(const_cast<returned&>(x).release()) {} - /// Delete if still owned. - ~returned() { if (ptr_) delete ptr_; } - - /// Release ownership. - thread_safe<T>* release() const { thread_safe<T>* p = ptr_; ptr_ = 0; return p; } - - /// Get the raw pointer, caller must not delete. - thread_safe<T>* get() const { return ptr_; } - - /// Implicit conversion to target, usable only in a safe context. - operator T() { return ptr_->unsafe(); } - -#if PN_CPP_HAS_SHARED_PTR - /// Release to a std::shared_ptr - operator std::shared_ptr<thread_safe<T> >() { - return std::shared_ptr<thread_safe<T> >(release()); - } -#endif -#if PN_CPP_HAS_UNIQUE_PTR - /// Release to a std::unique_ptr - operator std::unique_ptr<thread_safe<T> >() { - return std::unique_ptr<thread_safe<T> >(release()); - } -#endif - - private: - void operator=(const returned&); - mutable thread_safe<T>* ptr_; -}; - -/// Make a thread-safe wrapper for `obj`. -template <class T> returned<T> make_thread_safe(const T& obj) { return returned<T>(obj); } - -#if PN_CPP_HAS_SHARED_PTR -/// Create a thread-safe shared_ptr to `obj`. -template <class T> std::shared_ptr<thread_safe<T> > make_shared_thread_safe(const T& obj) { - return make_thread_safe(obj); -} -#endif -#if PN_CPP_HAS_UNIQUE_PTR -/// Create a thread-safe unique_ptr to `obj`. -template <class T> std::unique_ptr<thread_safe<T> > make_unique_thread_safe(const T& obj) { - return make_thread_safe(obj); -} - -#endif - -} // proton - -#endif // PROTON_THREAD_SAFE_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/work_queue.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/work_queue.hpp b/proton-c/bindings/cpp/include/proton/work_queue.hpp index 844680b..30d8395 100644 --- a/proton-c/bindings/cpp/include/proton/work_queue.hpp +++ b/proton-c/bindings/cpp/include/proton/work_queue.hpp @@ -40,10 +40,10 @@ namespace proton { /// **Experimental** - A work queue for serial execution. /// /// Event handler functions associated with a single proton::connection are called in sequence. -/// The connection's @ref work_queue allows you to "inject" extra @ref work from any thread, +/// The connection's proton::work_queue allows you to "inject" extra @ref work from any thread, /// and have it executed in the same sequence. /// -/// You may also create arbitrary @ref work_queue objects backed by a @ref container that allow +/// You may also create arbitrary proton::work_queue objects backed by a @ref container that allow /// other objects to have their own serialised work queues that can have work injected safely /// from other threads. The @ref container ensures that the work is correctly serialised. /// @@ -113,7 +113,6 @@ class PN_CPP_CLASS_EXTERN work_queue { /// @cond INTERNAL friend class container; friend class io::connection_driver; - template <class T> friend class thread_safe; /// @endcond }; @@ -347,6 +346,7 @@ void schedule_work(WQ wq, duration dn, F f, A a, B b, C c, D d) { #else // The C++11 version is *much* simpler and even so more general! // These definitions encompass everything in the C++03 section + template <class WQ, class... Rest> bool schedule_work(WQ wq, Rest&&... r) { return wq->add(std::bind(std::forward<Rest>(r)...)); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/connection_driver_test.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/connection_driver_test.cpp b/proton-c/bindings/cpp/src/connection_driver_test.cpp index 7fcde46..d174454 100644 --- a/proton-c/bindings/cpp/src/connection_driver_test.cpp +++ b/proton-c/bindings/cpp/src/connection_driver_test.cpp @@ -22,6 +22,7 @@ #include "proton_bits.hpp" #include "proton/container.hpp" +#include "proton/connection.hpp" #include "proton/io/connection_driver.hpp" #include "proton/io/link_namer.hpp" #include "proton/link.hpp" @@ -31,7 +32,6 @@ #include "proton/sender.hpp" #include "proton/sender_options.hpp" #include "proton/source_options.hpp" -#include "proton/thread_safe.hpp" #include "proton/transport.hpp" #include "proton/types_fwd.hpp" #include "proton/uuid.hpp" http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/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 35f645c..c82e1a8 100644 --- a/proton-c/bindings/cpp/src/container.cpp +++ b/proton-c/bindings/cpp/src/container.cpp @@ -25,7 +25,6 @@ #include "proton/error_condition.hpp" #include "proton/listen_handler.hpp" #include "proton/listener.hpp" -#include "proton/thread_safe.hpp" #include "proactor_container_impl.hpp" http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/container_test.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/container_test.cpp b/proton-c/bindings/cpp/src/container_test.cpp index d210268..498b217 100644 --- a/proton-c/bindings/cpp/src/container_test.cpp +++ b/proton-c/bindings/cpp/src/container_test.cpp @@ -26,7 +26,6 @@ #include "proton/messaging_handler.hpp" #include "proton/listener.hpp" #include "proton/listen_handler.hpp" -#include "proton/thread_safe.hpp" #include <cstdlib> #include <ctime> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/include/proton_bits.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/include/proton_bits.hpp b/proton-c/bindings/cpp/src/include/proton_bits.hpp index fdd79b5..035ffb7 100644 --- a/proton-c/bindings/cpp/src/include/proton_bits.hpp +++ b/proton-c/bindings/cpp/src/include/proton_bits.hpp @@ -124,6 +124,7 @@ class factory { public: static T wrap(typename wrapped<T>::type* t) { return t; } static typename wrapped<T>::type* unwrap(const T& t) { return t.pn_object(); } + static returned<T> make_returned(const T& t) { return returned<T>(t); } }; template <class T> struct context {}; @@ -150,6 +151,11 @@ U make_wrapper(typename internal::wrapped<U>::type* t) { return internal::factor template <class T> typename internal::wrapped<T>::type* unwrap(const T& t) { return internal::factory<T>::unwrap(t); } +template <class T> +returned<T> make_returned(const T& t) { + return internal::factory<T>::make_returned(t); +} + } #endif // PROTON_BITS_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/proactor_container_impl.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp index b900d6f..1389306 100644 --- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp +++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp @@ -24,7 +24,6 @@ #include "proton/function.hpp" #include "proton/listener.hpp" #include "proton/listen_handler.hpp" -#include "proton/thread_safe.hpp" #include "proton/url.hpp" #include "proton/connection.h" @@ -188,13 +187,13 @@ proton::connection container::impl::connect_common( return conn; } -proton::returned<proton::connection> container::impl::connect( +returned<proton::connection> container::impl::connect( const std::string& addr, const proton::connection_options& user_opts) { connection conn = connect_common(addr, user_opts); GUARD(lock_); - return make_thread_safe(conn); + return make_returned(conn); } returned<sender> container::impl::open_sender(const std::string &url, const proton::sender_options &o1, const connection_options &o2) { @@ -203,7 +202,7 @@ returned<sender> container::impl::open_sender(const std::string &url, const prot connection conn = connect_common(url, o2); GUARD(lock_); - return make_thread_safe(conn.default_session().open_sender(proton::url(url).path(), lopts)); + return make_returned(conn.default_session().open_sender(proton::url(url).path(), lopts)); } returned<receiver> container::impl::open_receiver(const std::string &url, const proton::receiver_options &o1, const connection_options &o2) { @@ -212,7 +211,7 @@ returned<receiver> container::impl::open_receiver(const std::string &url, const connection conn = connect_common(url, o2); GUARD(lock_); - return make_thread_safe( + return make_returned( conn.default_session().open_receiver(proton::url(url).path(), lopts)); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/returned.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/returned.cpp b/proton-c/bindings/cpp/src/returned.cpp new file mode 100644 index 0000000..2e1a4b2 --- /dev/null +++ b/proton-c/bindings/cpp/src/returned.cpp @@ -0,0 +1,41 @@ +/* + * 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_bits.hpp" + +#include <proton/returned.hpp> +#include <proton/connection.hpp> +#include <proton/sender.hpp> +#include <proton/receiver.hpp> + +namespace proton { + +template <class T> returned<T>::returned(const T& t) : ptr_(unwrap(t)) {} + +template <class T> returned<T>::operator T() const { + return internal::factory<T>::wrap(ptr_); +} + +// Explicit instantiations for allowed types + +template class PN_CPP_CLASS_EXTERN returned<connection>; +template class PN_CPP_CLASS_EXTERN returned<sender>; +template class PN_CPP_CLASS_EXTERN returned<receiver>; + +} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/thread_safe_test.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/thread_safe_test.cpp b/proton-c/bindings/cpp/src/thread_safe_test.cpp deleted file mode 100644 index 3a72f7f..0000000 --- a/proton-c/bindings/cpp/src/thread_safe_test.cpp +++ /dev/null @@ -1,108 +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. - */ - -/// Test reference counting for object wrappers, threads_safe<> wrappers and returned<> wrappers. -/// - -#include "test_bits.hpp" -#include "proton_bits.hpp" - -#include "proton/thread_safe.hpp" -#include "proton/io/connection_driver.hpp" - -#include <proton/connection.h> - -namespace { - -using namespace std; -using namespace proton; - -void test_new() { - pn_connection_t* c = 0; - thread_safe<connection>* p = 0; - { - io::connection_driver e; - c = unwrap(e.connection()); - int r = pn_refcount(c); - ASSERT(r >= 1); // engine may have internal refs (transport, collector). - p = make_thread_safe(e.connection()).release(); - ASSERT_EQUAL(r+1, pn_refcount(c)); - delete p; - ASSERT_EQUAL(r, pn_refcount(c)); - p = make_thread_safe(e.connection()).release(); - } - ASSERT_EQUAL(1, pn_refcount(c)); // Engine gone, thread_safe keeping c alive. - delete p; - -#if PN_CPP_HAS_SHARED_PTR - { - std::shared_ptr<thread_safe<connection> > sp; - { - io::connection_driver e; - c = unwrap(e.connection()); - sp = make_shared_thread_safe(e.connection()); - } - ASSERT_EQUAL(1, pn_refcount(c)); // Engine gone, sp keeping c alive. - } -#endif -#if PN_CPP_HAS_UNIQUE_PTR - { - std::unique_ptr<thread_safe<connection> > up; - { - io::connection_driver e; - c = unwrap(e.connection()); - up = make_unique_thread_safe(e.connection()); - } - ASSERT_EQUAL(1, pn_refcount(c)); // Engine gone, sp keeping c alive. - } -#endif -} - -void test_convert() { - // Verify refcounts as expected with conversion between proton::object - // and thread_safe. - connection c; - pn_connection_t* pc = 0; - { - io::connection_driver eng; - c = eng.connection(); - pc = unwrap(c); // Unwrap in separate scope to avoid confusion from temp values. - } - { - ASSERT_EQUAL(1, pn_refcount(pc)); - returned<connection> pptr = make_thread_safe(c); - ASSERT_EQUAL(2, pn_refcount(pc)); - returned<connection> pp2 = pptr; - ASSERT(!pptr.release()); // Transferred to pp2 - ASSERT_EQUAL(2, pn_refcount(pc)); - connection c2 = pp2; // Transfer and convert to target - ASSERT_EQUAL(3, pn_refcount(pc)); // c, c2, thread_safe. - ASSERT(c == c2); - } - ASSERT_EQUAL(1, pn_refcount(pc)); // only c is left -} - -} - -int main(int, char**) { - int failed = 0; - RUN_TEST(failed, test_new()); - RUN_TEST(failed, test_convert()); - return failed; -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/tests/tools/apps/cpp/reactor_send.cpp ---------------------------------------------------------------------- diff --git a/tests/tools/apps/cpp/reactor_send.cpp b/tests/tools/apps/cpp/reactor_send.cpp index 7841a5e..62ac4ce 100644 --- a/tests/tools/apps/cpp/reactor_send.cpp +++ b/tests/tools/apps/cpp/reactor_send.cpp @@ -32,7 +32,6 @@ #include "proton/messaging_handler.hpp" #include "proton/receiver_options.hpp" #include "proton/sender.hpp" -#include "proton/thread_safe.hpp" #include "proton/tracker.hpp" #include "proton/value.hpp" --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org