You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by jr...@apache.org on 2016/07/13 09:45:42 UTC

[04/51] [partial] qpid-site git commit: QPID-7350: Restore some missing 0.13.0 examples and the tutorial; avoid some accidental exposure of example classes in API ref

http://git-wip-us.apache.org/repos/asf/qpid-site/blob/59433afd/content/releases/qpid-proton-0.13.0/proton/cpp/api/mt_2broker_8cpp-example.html
----------------------------------------------------------------------
diff --git a/content/releases/qpid-proton-0.13.0/proton/cpp/api/mt_2broker_8cpp-example.html b/content/releases/qpid-proton-0.13.0/proton/cpp/api/mt_2broker_8cpp-example.html
index 3fc73fc..bc3fc19 100755
--- a/content/releases/qpid-proton-0.13.0/proton/cpp/api/mt_2broker_8cpp-example.html
+++ b/content/releases/qpid-proton-0.13.0/proton/cpp/api/mt_2broker_8cpp-example.html
@@ -3,7 +3,7 @@
 <head>
 <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
 <meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.10"/>
+<meta name="generator" content="Doxygen 1.8.11"/>
 <title>Qpid Proton C++ API: mt/broker.cpp</title>
 <link href="tabs.css" rel="stylesheet" type="text/css"/>
 <script type="text/javascript" src="jquery.js"></script>
@@ -55,7 +55,7 @@
 </table>
 </div>
 <!-- end header part -->
-<!-- Generated by Doxygen 1.8.10 -->
+<!-- Generated by Doxygen 1.8.11 -->
 <script type="text/javascript">
 var searchBox = new SearchBox("searchBox", "search",false,'Search');
 </script>
@@ -95,298 +95,14 @@ $(document).ready(function(){initNavTree('mt_2broker_8cpp-example.html','');});
 <div class="contents">
 <p>A multithreaded broker, that will work on any multi-threaded container. See <a class="el" href="mt_2epoll_container_8cpp-example.html">mt/epoll_container.cpp</a> for an example of a multi-threaded container.</p>
 <p><b>Requires C++11</b></p>
-<div class="fragment"><div class="line"><span class="comment">/*</span></div>
-<div class="line"><span class="comment"> * Licensed to the Apache Software Foundation (ASF) under one</span></div>
-<div class="line"><span class="comment"> * or more contributor license agreements.  See the NOTICE file</span></div>
-<div class="line"><span class="comment"> * distributed with this work for additional information</span></div>
-<div class="line"><span class="comment"> * regarding copyright ownership.  The ASF licenses this file</span></div>
-<div class="line"><span class="comment"> * to you under the Apache License, Version 2.0 (the</span></div>
-<div class="line"><span class="comment"> * &quot;License&quot;); you may not use this file except in compliance</span></div>
-<div class="line"><span class="comment"> * with the License.  You may obtain a copy of the License at</span></div>
-<div class="line"><span class="comment"> *</span></div>
-<div class="line"><span class="comment"> *   http://www.apache.org/licenses/LICENSE-2.0</span></div>
-<div class="line"><span class="comment"> *</span></div>
-<div class="line"><span class="comment"> * Unless required by applicable law or agreed to in writing,</span></div>
-<div class="line"><span class="comment"> * software distributed under the License is distributed on an</span></div>
-<div class="line"><span class="comment"> * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span></div>
-<div class="line"><span class="comment"> * KIND, either express or implied.  See the License for the</span></div>
-<div class="line"><span class="comment"> * specific language governing permissions and limitations</span></div>
-<div class="line"><span class="comment"> * under the License.</span></div>
-<div class="line"><span class="comment"> */</span></div>
-<div class="line"></div>
-<div class="line"><span class="preprocessor">#include &quot;../options.hpp&quot;</span></div>
-<div class="line"><span class="preprocessor">#include &quot;mt_container.hpp&quot;</span></div>
-<div class="line"></div>
-<div class="line"><span class="preprocessor">#include &lt;proton/connection.hpp&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;proton/default_container.hpp&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;proton/delivery.hpp&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;proton/messaging_handler.hpp&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;proton/listen_handler.hpp&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;proton/thread_safe.hpp&gt;</span></div>
-<div class="line"></div>
-<div class="line"><span class="preprocessor">#include &lt;atomic&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;functional&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;mutex&gt;</span></div>
-<div class="line"><span class="preprocessor">#include &lt;thread&gt;</span></div>
-<div class="line"></div>
-<div class="line"><span class="preprocessor">#include &quot;../fake_cpp11.hpp&quot;</span></div>
-<div class="line"></div>
-<div class="line"><span class="comment">// Thread safe queue.</span></div>
-<div class="line"><span class="comment">// Stores messages, notifies subscribed connections when there is data.</span></div>
-<div class="line"><span class="keyword">class </span><a name="_a0"></a><a class="code" href="classqueue.html">queue</a> {</div>
-<div class="line">  <span class="keyword">public</span>:</div>
-<div class="line">    <a class="code" href="classqueue.html">queue</a>(<span class="keyword">const</span> std::string&amp; name) : name_(name) {}</div>
-<div class="line"></div>
-<div class="line">    std::string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> name_; }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// Push a message onto the queue.</span></div>
-<div class="line">    <span class="comment">// If the queue was previously empty, notify subscribers it has messages.</span></div>
-<div class="line">    <span class="comment">// Called from receiver&#39;s connection.</span></div>
-<div class="line">    <span class="keywordtype">void</span> push(<span class="keyword">const</span> <a name="_a1"></a><a class="code" href="classproton_1_1message.html">proton::message</a> &amp;m) {</div>
-<div class="line">        std::lock_guard&lt;std::mutex&gt; g(lock_);</div>
-<div class="line">        messages_.push_back(m);</div>
-<div class="line">        <span class="keywordflow">if</span> (messages_.size() == 1) { <span class="comment">// Non-empty, notify subscribers</span></div>
-<div class="line">            <span class="keywordflow">for</span> (<span class="keyword">auto</span> cb : callbacks_)</div>
-<div class="line">                cb(<span class="keyword">this</span>);</div>
-<div class="line">            callbacks_.clear();</div>
-<div class="line">        }</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// If the queue is not empty, pop a message into m and return true.</span></div>
-<div class="line">    <span class="comment">// Otherwise save callback to be called when there are messages and return false.</span></div>
-<div class="line">    <span class="comment">// Called from sender&#39;s connection.</span></div>
-<div class="line">    <span class="keywordtype">bool</span> pop(<a class="code" href="classproton_1_1message.html">proton::message</a>&amp; m, std::function&lt;<span class="keywordtype">void</span>(<a class="code" href="classqueue.html">queue</a>*)&gt; callback) {</div>
-<div class="line">        std::lock_guard&lt;std::mutex&gt; g(lock_);</div>
-<div class="line">        <span class="keywordflow">if</span> (messages_.empty()) {</div>
-<div class="line">            callbacks_.push_back(callback);</div>
-<div class="line">            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
-<div class="line">        } <span class="keywordflow">else</span> {</div>
-<div class="line">            m = std::move(messages_.front());</div>
-<div class="line">            messages_.pop_front();</div>
-<div class="line">            <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
-<div class="line">        }</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">  <span class="keyword">private</span>:</div>
-<div class="line">    <span class="keyword">const</span> std::string name_;</div>
-<div class="line">    std::mutex lock_;</div>
-<div class="line">    std::deque&lt;proton::message&gt; messages_;</div>
-<div class="line">    std::vector&lt;std::function&lt;void(queue*)&gt; &gt; callbacks_;</div>
-<div class="line">};</div>
-<div class="line"></div>
-<div class="line"><span class="keyword">class </span><a name="_a2"></a><a class="code" href="classqueues.html">queues</a> {</div>
-<div class="line">  <span class="keyword">public</span>:</div>
-<div class="line">    <a class="code" href="classqueues.html">queues</a>() : next_id_(0) {}</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// Get or create the named queue.</span></div>
-<div class="line">    <a class="code" href="classqueue.html">queue</a>* <span class="keyword">get</span>(<span class="keyword">const</span> std::string&amp; name) {</div>
-<div class="line">        std::lock_guard&lt;std::mutex&gt; g(lock_);</div>
-<div class="line">        <span class="keyword">auto</span> i = queues_.insert(queue_map::value_type(name, <span class="keyword">nullptr</span>)).first;</div>
-<div class="line">        <span class="keywordflow">if</span> (!i-&gt;second)</div>
-<div class="line">            i-&gt;second.reset(<span class="keyword">new</span> <a class="code" href="classqueue.html">queue</a>(name));</div>
-<div class="line">        <span class="keywordflow">return</span> i-&gt;second.get();</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// Create a dynamic queue with a unique name.</span></div>
-<div class="line">    <a class="code" href="classqueue.html">queue</a>* dynamic() {</div>
-<div class="line">        std::ostringstream os;</div>
-<div class="line">        os &lt;&lt; <span class="stringliteral">&quot;_dynamic_&quot;</span> &lt;&lt; next_id_++;</div>
-<div class="line">        <span class="keywordflow">return</span> <span class="keyword">get</span>(os.str());</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">  <span class="keyword">private</span>:</div>
-<div class="line">    <span class="keyword">typedef</span> std::map&lt;std::string, std::unique_ptr&lt;queue&gt; &gt; queue_map;</div>
-<div class="line"></div>
-<div class="line">    std::mutex lock_;</div>
-<div class="line">    queue_map queues_;</div>
-<div class="line">    std::atomic&lt;uint64_t&gt; next_id_; <span class="comment">// Use to generate unique queue IDs.</span></div>
-<div class="line">};</div>
-<div class="line"></div>
-<div class="line"><span class="keyword">class </span>broker_connection_handler : <span class="keyword">public</span> <a name="_a3"></a><a class="code" href="classproton_1_1messaging__handler.html">proton::messaging_handler</a> {</div>
-<div class="line">  <span class="keyword">public</span>:</div>
-<div class="line">    broker_connection_handler(<a class="code" href="classqueues.html">queues</a>&amp; qs) : queues_(qs) {}</div>
-<div class="line"></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a4"></a><a class="code" href="classproton_1_1messaging__handler.html#a16ba022e899957b2e25b9561b1f53968">on_connection_open</a>(<a name="_a5"></a><a class="code" href="classproton_1_1connection.html">proton::connection</a>&amp; c) OVERRIDE {</div>
-<div class="line">        <span class="comment">// Create the has_messages callback for queue subscriptions.</span></div>
-<div class="line">        <span class="comment">//</span></div>
-<div class="line">        <span class="comment">// Make a std::shared_ptr to a thread_safe handle for our proton::connection.</span></div>
-<div class="line">        <span class="comment">// The connection&#39;s proton::event_loop will remain valid as a shared_ptr exists.</span></div>
-<div class="line">        std::shared_ptr&lt;proton::thread_safe&lt;proton::connection&gt; &gt; ts_c = make_shared_thread_safe(c);</div>
-<div class="line"></div>
-<div class="line">        <span class="comment">// Make a lambda function to inject a call to this-&gt;has_messages() via the proton::event_loop.</span></div>
-<div class="line">        <span class="comment">// The function is bound to a shared_ptr so this is safe. If the connection has already closed</span></div>
-<div class="line">        <span class="comment">// proton::event_loop::inject() will drop the callback.</span></div>
-<div class="line">        has_messages_callback_ = [<span class="keyword">this</span>, ts_c](<a class="code" href="classqueue.html">queue</a>* q) <span class="keyword">mutable</span> {</div>
-<div class="line">            ts_c-&gt;event_loop()-&gt;inject(</div>
-<div class="line">                std::bind(&amp;broker_connection_handler::has_messages, <span class="keyword">this</span>, q));</div>
-<div class="line">        };</div>
-<div class="line"></div>
-<div class="line">        c.open();            <span class="comment">// Accept the connection</span></div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// A sender sends messages from a queue to a subscriber.</span></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a6"></a><a class="code" href="classproton_1_1messaging__handler.html#a0b5d066e5463d3365f662c8a7dc52661">on_sender_open</a>(<a name="_a7"></a><a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;sender) OVERRIDE {</div>
-<div class="line">        <a class="code" href="classqueue.html">queue</a> *q = sender.source().dynamic() ?</div>
-<div class="line">            queues_.dynamic() : queues_.get(sender.source().address());</div>
-<div class="line">        std::cout &lt;&lt; <span class="stringliteral">&quot;sending from &quot;</span> &lt;&lt; q-&gt;<a name="a8"></a>name() &lt;&lt; std::endl;</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// We have credit to send a message.</span></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a9"></a><a class="code" href="classproton_1_1messaging__handler.html#aa24f522a68cdf382762702cece7790e7">on_sendable</a>(<a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;s) OVERRIDE {</div>
-<div class="line">        <a class="code" href="classqueue.html">queue</a>* q = sender_queue(s);</div>
-<div class="line">        <span class="keywordflow">if</span> (!do_send(q, s))     <span class="comment">// Queue is empty, save ourselves in the blocked set.</span></div>
-<div class="line">            blocked_.insert(std::make_pair(q, s));</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// A receiver receives messages from a publisher to a queue.</span></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a10"></a><a class="code" href="classproton_1_1messaging__handler.html#a768b0a50669aa1d512d12e9d68af14cd">on_receiver_open</a>(<a name="_a11"></a><a class="code" href="classproton_1_1receiver.html">proton::receiver</a> &amp;r) OVERRIDE {</div>
-<div class="line">        std::string qname = r.target().address();</div>
-<div class="line">        <span class="keywordflow">if</span> (qname == <span class="stringliteral">&quot;shutdown&quot;</span>) {</div>
-<div class="line">            std::cout &lt;&lt; <span class="stringliteral">&quot;broker shutting down&quot;</span> &lt;&lt; std::endl;</div>
-<div class="line">            <span class="comment">// Sending to the special &quot;shutdown&quot; queue stops the broker.</span></div>
-<div class="line">            r.connection().container().stop(</div>
-<div class="line">                <a name="_a12"></a><a class="code" href="classproton_1_1error__condition.html">proton::error_condition</a>(<span class="stringliteral">&quot;shutdown&quot;</span>, <span class="stringliteral">&quot;stop broker&quot;</span>));</div>
-<div class="line">        } <span class="keywordflow">else</span> {</div>
-<div class="line">            std::cout &lt;&lt; <span class="stringliteral">&quot;receiving to &quot;</span> &lt;&lt; qname &lt;&lt; std::endl;</div>
-<div class="line">        }</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// A message is received.</span></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a13"></a><a class="code" href="classproton_1_1messaging__handler.html#a96879b0b0b7ade11f98d3f450abd4c46">on_message</a>(<a name="_a14"></a><a class="code" href="classproton_1_1delivery.html">proton::delivery</a> &amp;d, <a class="code" href="classproton_1_1message.html">proton::message</a> &amp;m) OVERRIDE {</div>
-<div class="line">        std::string qname = d.receiver().target().address();</div>
-<div class="line">        queues_.get(qname)-&gt;push(m);</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a15"></a><a class="code" href="classproton_1_1messaging__handler.html#a54fe4fc5394418f8606f9263f13d2e98">on_session_close</a>(<a name="_a16"></a><a class="code" href="classproton_1_1session.html">proton::session</a> &amp;session) OVERRIDE {</div>
-<div class="line">        <span class="comment">// Erase all blocked senders that belong to session.</span></div>
-<div class="line">        <span class="keyword">auto</span> predicate = [session](<span class="keyword">const</span> <a class="code" href="classproton_1_1sender.html">proton::sender</a>&amp; s) {</div>
-<div class="line">            <span class="keywordflow">return</span> s.session() == session;</div>
-<div class="line">        };</div>
-<div class="line">        erase_sender_if(blocked_.begin(), blocked_.end(), predicate);</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a17"></a><a class="code" href="classproton_1_1messaging__handler.html#a7942b98699bd21e827041626ee1b5c84">on_sender_close</a>(<a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;sender) OVERRIDE {</div>
-<div class="line">        <span class="comment">// Erase sender from the blocked set.</span></div>
-<div class="line">        <span class="keyword">auto</span> range = blocked_.equal_range(sender_queue(sender));</div>
-<div class="line">        <span class="keyword">auto</span> predicate = [sender](<span class="keyword">const</span> <a class="code" href="classproton_1_1sender.html">proton::sender</a>&amp; s) { <span class="keywordflow">return</span> s == sender; };</div>
-<div class="line">        erase_sender_if(range.first, range.second, predicate);</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// The container calls on_transport_close() last.</span></div>
-<div class="line">    <span class="keywordtype">void</span> <a name="a18"></a><a class="code" href="classproton_1_1messaging__handler.html#a47c33c5e6c13d23f1b8a745bf7bdfa8f">on_transport_close</a>(<a name="_a19"></a><a class="code" href="classproton_1_1transport.html">proton::transport</a>&amp;) OVERRIDE {</div>
-<div class="line">        <span class="keyword">delete</span> <span class="keyword">this</span>;            <span class="comment">// All done.</span></div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">  <span class="keyword">private</span>:</div>
-<div class="line">    <span class="keyword">typedef</span> std::multimap&lt;queue*, proton::sender&gt; blocked_map;</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// Get the queue associated with a sender.</span></div>
-<div class="line">    <a class="code" href="classqueue.html">queue</a>* sender_queue(<span class="keyword">const</span> <a class="code" href="classproton_1_1sender.html">proton::sender</a>&amp; s) {</div>
-<div class="line">        <span class="keywordflow">return</span> queues_.get(s.<a name="a20"></a><a class="code" href="classproton_1_1sender.html#a2f1d8ca25f71dff178c462cf984327f9">source</a>().<a name="a21"></a><a class="code" href="classproton_1_1source.html#a977efa04715923ca4fa290a6ec90c830">address</a>()); <span class="comment">// Thread safe.</span></div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// Only called if we have credit. Return true if we sent a message.</span></div>
-<div class="line">    <span class="keywordtype">bool</span> do_send(<a class="code" href="classqueue.html">queue</a>* q, <a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;s) {</div>
-<div class="line">        <a class="code" href="classproton_1_1message.html">proton::message</a> m;</div>
-<div class="line">        <span class="keywordtype">bool</span> popped =  q-&gt;pop(m, has_messages_callback_);</div>
-<div class="line">        <span class="keywordflow">if</span> (popped)</div>
-<div class="line">            s.<a name="a22"></a><a class="code" href="classproton_1_1sender.html#a214eb30b24e6831d016a47b9dddda830">send</a>(m);</div>
-<div class="line">        <span class="keywordflow">return</span> popped;</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// Called via the connection&#39;s proton::event_loop when q has messages.</span></div>
-<div class="line">    <span class="comment">// Try all the blocked senders.</span></div>
-<div class="line">    <span class="keywordtype">void</span> has_messages(<a class="code" href="classqueue.html">queue</a>* q) {</div>
-<div class="line">        <span class="keyword">auto</span> range = blocked_.equal_range(q);</div>
-<div class="line">        <span class="keywordflow">for</span> (<span class="keyword">auto</span> i = range.first; i != range.second;) {</div>
-<div class="line">            <span class="keywordflow">if</span> (i-&gt;second.credit() &lt;= 0 || do_send(q, i-&gt;second))</div>
-<div class="line">                i = blocked_.erase(i); <span class="comment">// No credit or send was successful, stop blocked.</span></div>
-<div class="line">            <span class="keywordflow">else</span></div>
-<div class="line">                ++i;            <span class="comment">// have credit, didn&#39;t send, keep blocked</span></div>
-<div class="line">        }</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="comment">// Use to erase closed senders from blocked_ set.</span></div>
-<div class="line">    <span class="keyword">template</span> &lt;<span class="keyword">class</span> Predicate&gt;</div>
-<div class="line">    <span class="keywordtype">void</span> erase_sender_if(blocked_map::iterator begin, blocked_map::iterator end, Predicate p) {</div>
-<div class="line">        <span class="keywordflow">for</span> (<span class="keyword">auto</span> i = begin; i != end; ) {</div>
-<div class="line">            <span class="keywordflow">if</span> (p(i-&gt;second))</div>
-<div class="line">                i = blocked_.erase(i);</div>
-<div class="line">            <span class="keywordflow">else</span></div>
-<div class="line">                ++i;</div>
-<div class="line">        }</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <a class="code" href="classqueues.html">queues</a>&amp; queues_;</div>
-<div class="line">    blocked_map blocked_;</div>
-<div class="line">    std::function&lt;void(queue*)&gt; has_messages_callback_;</div>
-<div class="line">    <a class="code" href="classproton_1_1connection.html">proton::connection</a> connection_;</div>
-<div class="line">};</div>
-<div class="line"></div>
-<div class="line"></div>
-<div class="line"><span class="keyword">class </span>broker {</div>
-<div class="line">  <span class="keyword">public</span>:</div>
-<div class="line">    broker(<span class="keyword">const</span> std::string addr) :</div>
-<div class="line">        container_(make_mt_container(<span class="stringliteral">&quot;mt_broker&quot;</span>)), listener_(queues_)</div>
-<div class="line">    {</div>
-<div class="line">        container_-&gt;listen(addr, listener_);</div>
-<div class="line">        std::cout &lt;&lt; <span class="stringliteral">&quot;broker listening on &quot;</span> &lt;&lt; addr &lt;&lt; std::endl;</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">    <span class="keywordtype">void</span> run() {</div>
-<div class="line">        std::vector&lt;std::thread&gt; threads(std::thread::hardware_concurrency()-1);</div>
-<div class="line">        <span class="keywordflow">for</span> (<span class="keyword">auto</span>&amp; t : threads)</div>
-<div class="line">            t = std::thread(&amp;<a name="a23"></a><a class="code" href="classproton_1_1container.html#a18954417d3124a8095783ea13dc6d00b">proton::container::run</a>, container_.get());</div>
-<div class="line">        container_-&gt;run();      <span class="comment">// Use this thread too.</span></div>
-<div class="line">        <span class="keywordflow">for</span> (<span class="keyword">auto</span>&amp; t : threads)</div>
-<div class="line">            t.join();</div>
-<div class="line">    }</div>
-<div class="line"></div>
-<div class="line">  <span class="keyword">private</span>:</div>
-<div class="line">    <span class="keyword">struct </span>listener : <span class="keyword">public</span> <a name="_a24"></a><a class="code" href="classproton_1_1listen__handler.html">proton::listen_handler</a> {</div>
-<div class="line">        listener(<a class="code" href="classqueues.html">queues</a>&amp; qs) : queues_(qs) {}</div>
-<div class="line"></div>
-<div class="line">        <a name="_a25"></a><a class="code" href="classproton_1_1connection__options.html">proton::connection_options</a> on_accept() OVERRIDE{</div>
-<div class="line">            <span class="keywordflow">return</span> <a class="code" href="classproton_1_1connection__options.html">proton::connection_options</a>().<a name="a26"></a><a class="code" href="classproton_1_1connection__options.html#a7bca23aeb3455378ef2d35975758e504">handler</a>(*(<span class="keyword">new</span> broker_connection_handler(queues_)));</div>
-<div class="line">        }</div>
-<div class="line"></div>
-<div class="line">        <span class="keywordtype">void</span> on_error(<span class="keyword">const</span> std::string&amp; s) OVERRIDE {</div>
-<div class="line">            std::cerr &lt;&lt; <span class="stringliteral">&quot;listen error: &quot;</span> &lt;&lt; s &lt;&lt; std::endl;</div>
-<div class="line">            <span class="keywordflow">throw</span> std::runtime_error(s);</div>
-<div class="line">        }</div>
-<div class="line">        <a class="code" href="classqueues.html">queues</a>&amp; queues_;</div>
-<div class="line">    };</div>
-<div class="line"></div>
-<div class="line">    <a class="code" href="classqueues.html">queues</a> queues_;</div>
-<div class="line">    std::unique_ptr&lt;proton::container&gt; container_;</div>
-<div class="line">    listener listener_;</div>
-<div class="line">};</div>
-<div class="line"></div>
-<div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv) {</div>
-<div class="line">    <span class="comment">// Command line options</span></div>
-<div class="line">    std::string address(<span class="stringliteral">&quot;0.0.0.0&quot;</span>);</div>
-<div class="line">    <a name="_a27"></a><a class="code" href="classexample_1_1options.html">example::options</a> opts(argc, argv);</div>
-<div class="line">    opts.add_value(address, <span class="charliteral">&#39;a&#39;</span>, <span class="stringliteral">&quot;address&quot;</span>, <span class="stringliteral">&quot;listen on URL&quot;</span>, <span class="stringliteral">&quot;URL&quot;</span>);</div>
-<div class="line">    <span class="keywordflow">try</span> {</div>
-<div class="line">        opts.parse();</div>
-<div class="line">        broker(address).run();</div>
-<div class="line">        <span class="keywordflow">return</span> 0;</div>
-<div class="line">    } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a name="_a28"></a><a class="code" href="structexample_1_1bad__option.html">example::bad_option</a>&amp; e) {</div>
-<div class="line">        std::cout &lt;&lt; opts &lt;&lt; std::endl &lt;&lt; e.what() &lt;&lt; std::endl;</div>
-<div class="line">    } <span class="keywordflow">catch</span> (<span class="keyword">const</span> std::exception&amp; e) {</div>
-<div class="line">        std::cerr &lt;&lt; <span class="stringliteral">&quot;broker shutdown: &quot;</span> &lt;&lt; e.what() &lt;&lt; std::endl;</div>
-<div class="line">    }</div>
-<div class="line">    <span class="keywordflow">return</span> 1;</div>
-<div class="line">}</div>
-</div><!-- fragment --> </div><!-- contents -->
+<div class="fragment"><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Licensed to the Apache Software Foundation (ASF) under one</span></div><div class="line"><span class="comment"> * or more contributor license agreements.  See the NOTICE file</span></div><div class="line"><span class="comment"> * distributed with this work for additional information</span></div><div class="line"><span class="comment"> * regarding copyright ownership.  The ASF licenses this file</span></div><div class="line"><span class="comment"> * to you under the Apache License, Version 2.0 (the</span></div><div class="line"><span class="comment"> * &quot;License&quot;); you may not use this file except in compliance</span></div><div class="line"><span class="comment"> * with the License.  You may obtain a copy of the License at</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> *   http://www.apache.org/li
 censes/LICENSE-2.0</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * Unless required by applicable law or agreed to in writing,</span></div><div class="line"><span class="comment"> * software distributed under the License is distributed on an</span></div><div class="line"><span class="comment"> * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span></div><div class="line"><span class="comment"> * KIND, either express or implied.  See the License for the</span></div><div class="line"><span class="comment"> * specific language governing permissions and limitations</span></div><div class="line"><span class="comment"> * under the License.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;../options.hpp&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;mt_container.hpp&quot;</span></
 div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;proton/connection.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;proton/default_container.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;proton/delivery.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;proton/messaging_handler.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;proton/listen_handler.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;proton/thread_safe.hpp&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;atomic&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;functional&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;mutex&gt;</span></div><div class="line"><span
  class="preprocessor">#include &lt;thread&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;../fake_cpp11.hpp&quot;</span></div><div class="line"></div><div class="line"><span class="comment">// Thread safe queue.</span></div><div class="line"><span class="comment">// Stores messages, notifies subscribed connections when there is data.</span></div><div class="line"><span class="keyword">class </span>queue {</div><div class="line">  <span class="keyword">public</span>:</div><div class="line">    queue(<span class="keyword">const</span> std::string&amp; name) : name_(name) {}</div><div class="line"></div><div class="line">    std::string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> name_; }</div><div class="line"></div><div class="line">    <span class="comment">// Push a message onto the queue.</span></div><div class="line">    <span class="comment">// If the queue was previously empty, notify su
 bscribers it has messages.</span></div><div class="line">    <span class="comment">// Called from receiver&#39;s connection.</span></div><div class="line">    <span class="keywordtype">void</span> push(<span class="keyword">const</span> <a name="_a0"></a><a class="code" href="classproton_1_1message.html">proton::message</a> &amp;m) {</div><div class="line">        std::lock_guard&lt;std::mutex&gt; g(lock_);</div><div class="line">        messages_.push_back(m);</div><div class="line">        <span class="keywordflow">if</span> (messages_.size() == 1) { <span class="comment">// Non-empty, notify subscribers</span></div><div class="line">            <span class="keywordflow">for</span> (<span class="keyword">auto</span> cb : callbacks_)</div><div class="line">                cb(<span class="keyword">this</span>);</div><div class="line">            callbacks_.clear();</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span 
 class="comment">// If the queue is not empty, pop a message into m and return true.</span></div><div class="line">    <span class="comment">// Otherwise save callback to be called when there are messages and return false.</span></div><div class="line">    <span class="comment">// Called from sender&#39;s connection.</span></div><div class="line">    <span class="keywordtype">bool</span> pop(<a class="code" href="classproton_1_1message.html">proton::message</a>&amp; m, std::function&lt;<span class="keywordtype">void</span>(queue*)&gt; callback) {</div><div class="line">        std::lock_guard&lt;std::mutex&gt; g(lock_);</div><div class="line">        <span class="keywordflow">if</span> (messages_.empty()) {</div><div class="line">            callbacks_.push_back(callback);</div><div class="line">            <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">       
      m = std::move(messages_.front());</div><div class="line">            messages_.pop_front();</div><div class="line">            <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">  <span class="keyword">private</span>:</div><div class="line">    <span class="keyword">const</span> std::string name_;</div><div class="line">    std::mutex lock_;</div><div class="line">    std::deque&lt;proton::message&gt; messages_;</div><div class="line">    std::vector&lt;std::function&lt;void(queue*)&gt; &gt; callbacks_;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">class </span>queues {</div><div class="line">  <span class="keyword">public</span>:</div><div class="line">    queues() : next_id_(0) {}</div><div class="line"></div><div class="line">    <span class="comment">// Get or create the named queue.</span></div
 ><div class="line">    queue* <span class="keyword">get</span>(<span class="keyword">const</span> std::string&amp; name) {</div><div class="line">        std::lock_guard&lt;std::mutex&gt; g(lock_);</div><div class="line">        <span class="keyword">auto</span> i = queues_.insert(queue_map::value_type(name, <span class="keyword">nullptr</span>)).first;</div><div class="line">        <span class="keywordflow">if</span> (!i-&gt;second)</div><div class="line">            i-&gt;second.reset(<span class="keyword">new</span> queue(name));</div><div class="line">        <span class="keywordflow">return</span> i-&gt;second.get();</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// Create a dynamic queue with a unique name.</span></div><div class="line">    queue* dynamic() {</div><div class="line">        std::ostringstream os;</div><div class="line">        os &lt;&lt; <span class="stringliteral">&quot;_dynamic_&quot;</span> &lt;&lt; ne
 xt_id_++;</div><div class="line">        <span class="keywordflow">return</span> <span class="keyword">get</span>(os.str());</div><div class="line">    }</div><div class="line"></div><div class="line">  <span class="keyword">private</span>:</div><div class="line">    <span class="keyword">typedef</span> std::map&lt;std::string, std::unique_ptr&lt;queue&gt; &gt; queue_map;</div><div class="line"></div><div class="line">    std::mutex lock_;</div><div class="line">    queue_map queues_;</div><div class="line">    std::atomic&lt;uint64_t&gt; next_id_; <span class="comment">// Use to generate unique queue IDs.</span></div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">class </span>broker_connection_handler : <span class="keyword">public</span> <a name="_a1"></a><a class="code" href="classproton_1_1messaging__handler.html">proton::messaging_handler</a> {</div><div class="line">  <span class="keyword">public</span>:</div><div class="line">    bro
 ker_connection_handler(queues&amp; qs) : queues_(qs) {}</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> on_connection_open(<a name="_a2"></a><a class="code" href="classproton_1_1connection.html">proton::connection</a>&amp; c) OVERRIDE {</div><div class="line">        <span class="comment">// Create the has_messages callback for queue subscriptions.</span></div><div class="line">        <span class="comment">//</span></div><div class="line">        <span class="comment">// Make a std::shared_ptr to a thread_safe handle for our proton::connection.</span></div><div class="line">        <span class="comment">// The connection&#39;s proton::event_loop will remain valid as a shared_ptr exists.</span></div><div class="line">        std::shared_ptr&lt;proton::thread_safe&lt;proton::connection&gt; &gt; ts_c = make_shared_thread_safe(c);</div><div class="line"></div><div class="line">        <span class="comment">// Make a lambda function to inject a c
 all to this-&gt;has_messages() via the proton::event_loop.</span></div><div class="line">        <span class="comment">// The function is bound to a shared_ptr so this is safe. If the connection has already closed</span></div><div class="line">        <span class="comment">// proton::event_loop::inject() will drop the callback.</span></div><div class="line">        has_messages_callback_ = [<span class="keyword">this</span>, ts_c](queue* q) <span class="keyword">mutable</span> {</div><div class="line">            ts_c-&gt;event_loop()-&gt;inject(</div><div class="line">                std::bind(&amp;broker_connection_handler::has_messages, <span class="keyword">this</span>, q));</div><div class="line">        };</div><div class="line"></div><div class="line">        c.<a name="a3"></a><a class="code" href="classproton_1_1connection.html#a9e8555112049fc2b4945120b3c45f8ab">open</a>();            <span class="comment">// Accept the connection</span></div><div class="line">    }</div><d
 iv class="line"></div><div class="line">    <span class="comment">// A sender sends messages from a queue to a subscriber.</span></div><div class="line">    <span class="keywordtype">void</span> on_sender_open(<a name="_a4"></a><a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;sender) OVERRIDE {</div><div class="line">        queue *q = sender.<a name="a5"></a><a class="code" href="classproton_1_1sender.html#a2f1d8ca25f71dff178c462cf984327f9">source</a>().<a name="a6"></a><a class="code" href="classproton_1_1terminus.html#ab6f99d305cf67c3a6c3d786d2b819ca8">dynamic</a>() ?</div><div class="line">            queues_.dynamic() : queues_.get(sender.<a class="code" href="classproton_1_1sender.html#a2f1d8ca25f71dff178c462cf984327f9">source</a>().<a name="a7"></a><a class="code" href="classproton_1_1source.html#a977efa04715923ca4fa290a6ec90c830">address</a>());</div><div class="line">        std::cout &lt;&lt; <span class="stringliteral">&quot;sending from &quot;</s
 pan> &lt;&lt; q-&gt;name() &lt;&lt; std::endl;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// We have credit to send a message.</span></div><div class="line">    <span class="keywordtype">void</span> on_sendable(<a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;s) OVERRIDE {</div><div class="line">        queue* q = sender_queue(s);</div><div class="line">        <span class="keywordflow">if</span> (!do_send(q, s))     <span class="comment">// Queue is empty, save ourselves in the blocked set.</span></div><div class="line">            blocked_.insert(std::make_pair(q, s));</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// A receiver receives messages from a publisher to a queue.</span></div><div class="line">    <span class="keywordtype">void</span> on_receiver_open(<a name="_a8"></a><a class="code" href="classproton_1_1receiver.html">proton::recei
 ver</a> &amp;r) OVERRIDE {</div><div class="line">        std::string qname = r.<a name="a9"></a><a class="code" href="classproton_1_1receiver.html#a68cde95e630ce554bb4a2ba9ef087a17">target</a>().<a name="a10"></a><a class="code" href="classproton_1_1target.html#a977efa04715923ca4fa290a6ec90c830">address</a>();</div><div class="line">        <span class="keywordflow">if</span> (qname == <span class="stringliteral">&quot;shutdown&quot;</span>) {</div><div class="line">            std::cout &lt;&lt; <span class="stringliteral">&quot;broker shutting down&quot;</span> &lt;&lt; std::endl;</div><div class="line">            <span class="comment">// Sending to the special &quot;shutdown&quot; queue stops the broker.</span></div><div class="line">            r.<a name="a11"></a><a class="code" href="classproton_1_1link.html#af13d10fc3d843719af9ff4c456330a73">connection</a>().<a name="a12"></a><a class="code" href="classproton_1_1connection.html#a604ee46e04955a2323f305b4a81017a0">container</
 a>().<a name="a13"></a><a class="code" href="classproton_1_1container.html#a40a47814c7196a4c796015fd5c16b542">stop</a>(</div><div class="line">                <a name="_a14"></a><a class="code" href="classproton_1_1error__condition.html">proton::error_condition</a>(<span class="stringliteral">&quot;shutdown&quot;</span>, <span class="stringliteral">&quot;stop broker&quot;</span>));</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            std::cout &lt;&lt; <span class="stringliteral">&quot;receiving to &quot;</span> &lt;&lt; qname &lt;&lt; std::endl;</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// A message is received.</span></div><div class="line">    <span class="keywordtype">void</span> on_message(<a name="_a15"></a><a class="code" href="classproton_1_1delivery.html">proton::delivery</a> &amp;d, <a class="code" href="classproton_1_1message.
 html">proton::message</a> &amp;m) OVERRIDE {</div><div class="line">        std::string qname = d.<a name="a16"></a><a class="code" href="classproton_1_1delivery.html#ad94696eb7d2907efd72e021c2513ed48">receiver</a>().<a class="code" href="classproton_1_1receiver.html#a68cde95e630ce554bb4a2ba9ef087a17">target</a>().<a class="code" href="classproton_1_1target.html#a977efa04715923ca4fa290a6ec90c830">address</a>();</div><div class="line">        queues_.get(qname)-&gt;push(m);</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> on_session_close(<a name="_a17"></a><a class="code" href="classproton_1_1session.html">proton::session</a> &amp;session) OVERRIDE {</div><div class="line">        <span class="comment">// Erase all blocked senders that belong to session.</span></div><div class="line">        <span class="keyword">auto</span> predicate = [session](<span class="keyword">const</span> <a class="code" href="classproton_
 1_1sender.html">proton::sender</a>&amp; s) {</div><div class="line">            <span class="keywordflow">return</span> s.<a name="a18"></a><a class="code" href="classproton_1_1link.html#aa33faff52aea9845efaf184f86676cc5">session</a>() == session;</div><div class="line">        };</div><div class="line">        erase_sender_if(blocked_.begin(), blocked_.end(), predicate);</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> on_sender_close(<a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;sender) OVERRIDE {</div><div class="line">        <span class="comment">// Erase sender from the blocked set.</span></div><div class="line">        <span class="keyword">auto</span> range = blocked_.equal_range(sender_queue(sender));</div><div class="line">        <span class="keyword">auto</span> predicate = [sender](<span class="keyword">const</span> <a class="code" href="classproton_1_1sender.html">proton::s
 ender</a>&amp; s) { <span class="keywordflow">return</span> s == sender; };</div><div class="line">        erase_sender_if(range.first, range.second, predicate);</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// The container calls on_transport_close() last.</span></div><div class="line">    <span class="keywordtype">void</span> on_transport_close(<a name="_a19"></a><a class="code" href="classproton_1_1transport.html">proton::transport</a>&amp;) OVERRIDE {</div><div class="line">        <span class="keyword">delete</span> <span class="keyword">this</span>;            <span class="comment">// All done.</span></div><div class="line">    }</div><div class="line"></div><div class="line">  <span class="keyword">private</span>:</div><div class="line">    <span class="keyword">typedef</span> std::multimap&lt;queue*, proton::sender&gt; blocked_map;</div><div class="line"></div><div class="line">    <span class="comment">// Get the queue
  associated with a sender.</span></div><div class="line">    queue* sender_queue(<span class="keyword">const</span> <a class="code" href="classproton_1_1sender.html">proton::sender</a>&amp; s) {</div><div class="line">        <span class="keywordflow">return</span> queues_.get(s.<a class="code" href="classproton_1_1sender.html#a2f1d8ca25f71dff178c462cf984327f9">source</a>().<a class="code" href="classproton_1_1source.html#a977efa04715923ca4fa290a6ec90c830">address</a>()); <span class="comment">// Thread safe.</span></div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// Only called if we have credit. Return true if we sent a message.</span></div><div class="line">    <span class="keywordtype">bool</span> do_send(queue* q, <a class="code" href="classproton_1_1sender.html">proton::sender</a> &amp;s) {</div><div class="line">        <a class="code" href="classproton_1_1message.html">proton::message</a> m;</div><div class="line">        
 <span class="keywordtype">bool</span> popped =  q-&gt;pop(m, has_messages_callback_);</div><div class="line">        <span class="keywordflow">if</span> (popped)</div><div class="line">            s.<a name="a20"></a><a class="code" href="classproton_1_1sender.html#a214eb30b24e6831d016a47b9dddda830">send</a>(m);</div><div class="line">        <span class="keywordflow">return</span> popped;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// Called via the connection&#39;s proton::event_loop when q has messages.</span></div><div class="line">    <span class="comment">// Try all the blocked senders.</span></div><div class="line">    <span class="keywordtype">void</span> has_messages(queue* q) {</div><div class="line">        <span class="keyword">auto</span> range = blocked_.equal_range(q);</div><div class="line">        <span class="keywordflow">for</span> (<span class="keyword">auto</span> i = range.first; i != range.second;) {</d
 iv><div class="line">            <span class="keywordflow">if</span> (i-&gt;second.credit() &lt;= 0 || do_send(q, i-&gt;second))</div><div class="line">                i = blocked_.erase(i); <span class="comment">// No credit or send was successful, stop blocked.</span></div><div class="line">            <span class="keywordflow">else</span></div><div class="line">                ++i;            <span class="comment">// have credit, didn&#39;t send, keep blocked</span></div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">// Use to erase closed senders from blocked_ set.</span></div><div class="line">    <span class="keyword">template</span> &lt;<span class="keyword">class</span> Predicate&gt;</div><div class="line">    <span class="keywordtype">void</span> erase_sender_if(blocked_map::iterator begin, blocked_map::iterator end, Predicate p) {</div><div class="line">        <span class="keywordflow">for<
 /span> (<span class="keyword">auto</span> i = begin; i != end; ) {</div><div class="line">            <span class="keywordflow">if</span> (p(i-&gt;second))</div><div class="line">                i = blocked_.erase(i);</div><div class="line">            <span class="keywordflow">else</span></div><div class="line">                ++i;</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    queues&amp; queues_;</div><div class="line">    blocked_map blocked_;</div><div class="line">    std::function&lt;void(queue*)&gt; has_messages_callback_;</div><div class="line">    <a class="code" href="classproton_1_1connection.html">proton::connection</a> connection_;</div><div class="line">};</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">class </span>broker {</div><div class="line">  <span class="keyword">public</span>:</div><div class="line">    broker(<span class="keyword">const</span> std::
 string addr) :</div><div class="line">        container_(make_mt_container(<span class="stringliteral">&quot;mt_broker&quot;</span>)), listener_(queues_)</div><div class="line">    {</div><div class="line">        container_-&gt;listen(addr, listener_);</div><div class="line">        std::cout &lt;&lt; <span class="stringliteral">&quot;broker listening on &quot;</span> &lt;&lt; addr &lt;&lt; std::endl;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">void</span> run() {</div><div class="line">        std::vector&lt;std::thread&gt; threads(std::thread::hardware_concurrency()-1);</div><div class="line">        <span class="keywordflow">for</span> (<span class="keyword">auto</span>&amp; t : threads)</div><div class="line">            t = std::thread(&amp;<a name="a21"></a><a class="code" href="classproton_1_1container.html#a18954417d3124a8095783ea13dc6d00b">proton::container::run</a>, container_.get());</div><div class="line">   
      container_-&gt;run();      <span class="comment">// Use this thread too.</span></div><div class="line">        <span class="keywordflow">for</span> (<span class="keyword">auto</span>&amp; t : threads)</div><div class="line">            t.join();</div><div class="line">    }</div><div class="line"></div><div class="line">  <span class="keyword">private</span>:</div><div class="line">    <span class="keyword">struct </span>listener : <span class="keyword">public</span> <a name="_a22"></a><a class="code" href="classproton_1_1listen__handler.html">proton::listen_handler</a> {</div><div class="line">        listener(queues&amp; qs) : queues_(qs) {}</div><div class="line"></div><div class="line">        <a name="_a23"></a><a class="code" href="classproton_1_1connection__options.html">proton::connection_options</a> on_accept() OVERRIDE{</div><div class="line">            <span class="keywordflow">return</span> <a class="code" href="classproton_1_1connection__options.html">proton::conn
 ection_options</a>().<a name="a24"></a><a class="code" href="classproton_1_1connection__options.html#a7bca23aeb3455378ef2d35975758e504">handler</a>(*(<span class="keyword">new</span> broker_connection_handler(queues_)));</div><div class="line">        }</div><div class="line"></div><div class="line">        <span class="keywordtype">void</span> on_error(<span class="keyword">const</span> std::string&amp; s) OVERRIDE {</div><div class="line">            std::cerr &lt;&lt; <span class="stringliteral">&quot;listen error: &quot;</span> &lt;&lt; s &lt;&lt; std::endl;</div><div class="line">            <span class="keywordflow">throw</span> std::runtime_error(s);</div><div class="line">        }</div><div class="line">        queues&amp; queues_;</div><div class="line">    };</div><div class="line"></div><div class="line">    queues queues_;</div><div class="line">    std::unique_ptr&lt;proton::container&gt; container_;</div><div class="line">    listener listener_;</div><div class="line"
 >};</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv) {</div><div class="line">    <span class="comment">// Command line options</span></div><div class="line">    std::string address(<span class="stringliteral">&quot;0.0.0.0&quot;</span>);</div><div class="line">    example::options opts(argc, argv);</div><div class="line">    opts.add_value(address, <span class="charliteral">&#39;a&#39;</span>, <span class="stringliteral">&quot;address&quot;</span>, <span class="stringliteral">&quot;listen on URL&quot;</span>, <span class="stringliteral">&quot;URL&quot;</span>);</div><div class="line">    <span class="keywordflow">try</span> {</div><div class="line">        opts.parse();</div><div class="line">        broker(address).run();</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    } <span class="keywordflow">catch
 </span> (<span class="keyword">const</span> example::bad_option&amp; e) {</div><div class="line">        std::cout &lt;&lt; opts &lt;&lt; std::endl &lt;&lt; e.what() &lt;&lt; std::endl;</div><div class="line">    } <span class="keywordflow">catch</span> (<span class="keyword">const</span> std::exception&amp; e) {</div><div class="line">        std::cerr &lt;&lt; <span class="stringliteral">&quot;broker shutdown: &quot;</span> &lt;&lt; e.what() &lt;&lt; std::endl;</div><div class="line">    }</div><div class="line">    <span class="keywordflow">return</span> 1;</div><div class="line">}</div></div><!-- fragment --> </div><!-- contents -->
 </div><!-- doc-content -->
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
     <li class="footer">Generated by
     <a href="http://www.doxygen.org/index.html">
-    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.10 </li>
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
 </div>
 </body>


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