Repository: qpid-proton Updated Branches: refs/heads/master acfe8a3b3 -> e07d4fe73
PROTON-1543: c++ doc improvements - container.hpp and mt.md: more explanation of recommended "handler-per-connection" approach - minor clarifications Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/e07d4fe7 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/e07d4fe7 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/e07d4fe7 Branch: refs/heads/master Commit: e07d4fe73a8151d23c5d17eb986013e65d7fb435 Parents: acfe8a3 Author: Alan Conway <acon...@redhat.com> Authored: Thu Sep 14 14:16:10 2017 -0400 Committer: Alan Conway <acon...@redhat.com> Committed: Thu Sep 14 14:17:31 2017 -0400 ---------------------------------------------------------------------- proton-c/bindings/cpp/docs/main.md | 5 ++- proton-c/bindings/cpp/docs/mt.md | 34 +++++++++++------ .../bindings/cpp/include/proton/container.hpp | 40 +++++++++++++------- .../bindings/cpp/include/proton/thread_safe.hpp | 5 +-- 4 files changed, 54 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e07d4fe7/proton-c/bindings/cpp/docs/main.md ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/docs/main.md b/proton-c/bindings/cpp/docs/main.md index e7eb212..798ac4b 100644 --- a/proton-c/bindings/cpp/docs/main.md +++ b/proton-c/bindings/cpp/docs/main.md @@ -64,5 +64,6 @@ Address URLs (`addr_url`) extend the connection URL to reference an AMQP node such as a queue or topic. The path of the URL, minus the leading slash, is treated as the AMQP address of the node. -Listener URLs (`listen_url`) specify a local network address and port -for accepting incoming TCP connections. +Listener URLs (`listen_url`) specify a local network address and port for +accepting incoming TCP connections. The path part of the URL is ignored. +The host part may be empty, meaning "listen on all available interfaces". http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e07d4fe7/proton-c/bindings/cpp/docs/mt.md ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/docs/mt.md b/proton-c/bindings/cpp/docs/mt.md index 5b60278..293290c 100644 --- a/proton-c/bindings/cpp/docs/mt.md +++ b/proton-c/bindings/cpp/docs/mt.md @@ -4,22 +4,31 @@ Full multithreading support is available with C++11 and later. Limited multithreading is possible with older versions of C++. See the last section of this page for more information. -## Thread-safety rules +The `proton::container` handles multiple connections concurrently in a thread +pool, created using `proton::container::run()`. As AMQP events occur on a +connection the container calls `proton::messaging_handler` event callbacks. The +calls for each connection are *serialized* - callbacks for the same connection +are never made concurrently. -`proton::message` is a value type with the same threading constraints -as a standard C++ built-in type. It cannot be concurrently modified. -The `proton::container` is thread-safe *with C++11 or greater*. It has -the following capabilities. +You assign a handler to a connection in `proton::container::connect()` or +`proton::listen_handler::on_accept()` with +`proton::connection_options::handler()`. We recommend you create a separate +handler for each connection. That means the handler doesn't need locks or other +synchronization to protect it against concurrent use by proton threads. +(If you use the handler concurrently from non-proton threads then you will need +synchronization.) - * Application threads can open (or listen for) new connections at any - time. +The examples @ref multithreaded_client.cpp and @ref +multithreaded_client_flow_control.cpp illustrate these points. - * It manages worker threads to process connections. - * It handles network IO and calls the relevant - `proton::messaging_handler` event callbacks to execute application - code. +## Thread-safety rules + +The `proton::container` is thread-safe *with C++11 or greater*. An application +thread can open (or listen for) new connections at any time. The container uses +threads that call proton::container::run() to handle network IO, and call +user-defined `proton::messaging_handler` callbacks. The `proton::container` ensures that calls to event callbacks for each connection instance are *serialized* (not called concurrently), but @@ -41,6 +50,9 @@ thread-safe and are subject to the following rules. 3. You can store Proton objects in member variables for use in a later callback, provided you respect rule two. +`proton::message` is a value type with the same threading constraints +as a standard C++ built-in type. It cannot be concurrently modified. + ## Work queues `proton::work_queue` provides a safe way to communicate between http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e07d4fe7/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 b37bfd8..64caa15 100644 --- a/proton-c/bindings/cpp/include/proton/container.hpp +++ b/proton-c/bindings/cpp/include/proton/container.hpp @@ -54,25 +54,31 @@ namespace proton { /// messages. class PN_CPP_CLASS_EXTERN container { public: - /// Create a container with a handler for messaging events. + /// Create a container with a global handler for messaging events. /// - /// The optional `id` parameter sets the container's unique - /// identity. + /// **Thread safety** - in a multi-threaded container this handler will be + /// called concurrently. You can use locks to make that safe, or use a + /// separate handler for each connection. See @ref mt_page. + /// + /// @param handler global handler, called for events on all connections + /// managed by the container. + /// + /// @param id sets the container's unique identity. PN_CPP_EXTERN container(messaging_handler& handler, const std::string& id=""); /// Create a container. - /// - /// @copydetails container() + /// @param id sets the container's unique identity. PN_CPP_EXTERN container(const std::string& id=""); /// Destroy a container. /// - /// **Thread safety** - It is unsafe to delete a container from - /// within any of the threads running a `messaging_handler`. - /// Deleting the container from within a handler will cause a - /// deadlock or crash. The only safe place to delete a container - /// is after all of the threads running a container have finished - /// and all of the `run()` functions have returned. + /// A container must not be destroyed while a call to run() is in progress, + /// in particular it must not be destroyed from a @ref messaging_handler + /// callback. + /// + /// **Thread safety** - in a multi-threaded application, run() must return + /// in all threads that call it before destroying the container. + /// PN_CPP_EXTERN ~container(); /// Connect to `conn_url` and send an open request to the remote @@ -99,6 +105,9 @@ class PN_CPP_CLASS_EXTERN container { /// Listen for new connections on `listen_url`. /// + /// listen_handler::on_accept is called for each incoming connection to determine + /// the @ref connection_options to use, including the @ref messaging_handler. + /// /// **Thread safety** - Calls to `listen_handler` methods /// are serialized for this listener, but handlers attached to /// separate listeners can be safely called concurrently. @@ -109,13 +118,18 @@ class PN_CPP_CLASS_EXTERN container { /// /// Use a fixed set of options for all accepted connections. See /// listen(const std::string&, listen_handler&). + /// + /// **Thread safety** - for multi-threaded applications we recommend using a + /// @ref listen_handler to create a new @ref messaging_handler for each connection. + /// See listen(const std::string&, listen_handler&) and @ref mt_page PN_CPP_EXTERN listener listen(const std::string& listen_url, const connection_options& conn_opts); /// @copybrief listen /// /// New connections will use the handler from - /// `server_connection_options()`. + /// `server_connection_options()`. See listen(const std::string&, const + /// connection_options&); PN_CPP_EXTERN listener listen(const std::string& listen_url); /// Run the container in the current thread. @@ -129,7 +143,7 @@ class PN_CPP_CLASS_EXTERN container { PN_CPP_EXTERN void run(); #if PN_CPP_SUPPORTS_THREADS - /// Run the container with a pool of `count` threads. + /// Run the container with a pool of `count` threads, including the current thread. /// /// **C++ versions** - Available with C++11 or later. /// http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e07d4fe7/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 index e0d1789..81b10b1 100644 --- a/proton-c/bindings/cpp/include/proton/thread_safe.hpp +++ b/proton-c/bindings/cpp/include/proton/thread_safe.hpp @@ -20,9 +20,6 @@ * under the License. */ -/// @file -/// -/// **Deprecated** - Container method return values are safe to -/// use only inside handlers. +// Removed. Place-holder for for #include compatibility. #endif // PROTON_THREAD_SAFE_HPP --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org