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"> * "License"); 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"> * "AS IS" 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 "../options.hpp"</span></div>
-<div class="line"><span class="preprocessor">#include "mt_container.hpp"</span></div>
-<div class="line"></div>
-<div class="line"><span class="preprocessor">#include <proton/connection.hpp></span></div>
-<div class="line"><span class="preprocessor">#include <proton/default_container.hpp></span></div>
-<div class="line"><span class="preprocessor">#include <proton/delivery.hpp></span></div>
-<div class="line"><span class="preprocessor">#include <proton/messaging_handler.hpp></span></div>
-<div class="line"><span class="preprocessor">#include <proton/listen_handler.hpp></span></div>
-<div class="line"><span class="preprocessor">#include <proton/thread_safe.hpp></span></div>
-<div class="line"></div>
-<div class="line"><span class="preprocessor">#include <atomic></span></div>
-<div class="line"><span class="preprocessor">#include <functional></span></div>
-<div class="line"><span class="preprocessor">#include <iostream></span></div>
-<div class="line"><span class="preprocessor">#include <mutex></span></div>
-<div class="line"><span class="preprocessor">#include <thread></span></div>
-<div class="line"></div>
-<div class="line"><span class="preprocessor">#include "../fake_cpp11.hpp"</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& 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'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> &m) {</div>
-<div class="line"> std::lock_guard<std::mutex> 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's connection.</span></div>
-<div class="line"> <span class="keywordtype">bool</span> pop(<a class="code" href="classproton_1_1message.html">proton::message</a>& m, std::function<<span class="keywordtype">void</span>(<a class="code" href="classqueue.html">queue</a>*)> callback) {</div>
-<div class="line"> std::lock_guard<std::mutex> 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<proton::message> messages_;</div>
-<div class="line"> std::vector<std::function<void(queue*)> > 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& name) {</div>
-<div class="line"> std::lock_guard<std::mutex> 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->second)</div>
-<div class="line"> i->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->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 << <span class="stringliteral">"_dynamic_"</span> << 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<std::string, std::unique_ptr<queue> > 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<uint64_t> 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>& 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>& 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's proton::event_loop will remain valid as a shared_ptr exists.</span></div>
-<div class="line"> std::shared_ptr<proton::thread_safe<proton::connection> > 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->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->event_loop()->inject(</div>
-<div class="line"> std::bind(&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> &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 << <span class="stringliteral">"sending from "</span> << q-><a name="a8"></a>name() << 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> &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> &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">"shutdown"</span>) {</div>
-<div class="line"> std::cout << <span class="stringliteral">"broker shutting down"</span> << std::endl;</div>
-<div class="line"> <span class="comment">// Sending to the special "shutdown" 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">"shutdown"</span>, <span class="stringliteral">"stop broker"</span>));</div>
-<div class="line"> } <span class="keywordflow">else</span> {</div>
-<div class="line"> std::cout << <span class="stringliteral">"receiving to "</span> << qname << 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> &d, <a class="code" href="classproton_1_1message.html">proton::message</a> &m) OVERRIDE {</div>
-<div class="line"> std::string qname = d.receiver().target().address();</div>
-<div class="line"> queues_.get(qname)->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> &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>& 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> &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>& 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>&) 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<queue*, proton::sender> 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>& 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> &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->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'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->second.credit() <= 0 || do_send(q, i->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'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> <<span class="keyword">class</span> Predicate></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->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>& queues_;</div>
-<div class="line"> blocked_map blocked_;</div>
-<div class="line"> std::function<void(queue*)> 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">"mt_broker"</span>)), listener_(queues_)</div>
-<div class="line"> {</div>
-<div class="line"> container_->listen(addr, listener_);</div>
-<div class="line"> std::cout << <span class="stringliteral">"broker listening on "</span> << addr << 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<std::thread> threads(std::thread::hardware_concurrency()-1);</div>
-<div class="line"> <span class="keywordflow">for</span> (<span class="keyword">auto</span>& t : threads)</div>
-<div class="line"> t = std::thread(&<a name="a23"></a><a class="code" href="classproton_1_1container.html#a18954417d3124a8095783ea13dc6d00b">proton::container::run</a>, container_.get());</div>
-<div class="line"> container_->run(); <span class="comment">// Use this thread too.</span></div>
-<div class="line"> <span class="keywordflow">for</span> (<span class="keyword">auto</span>& 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>& 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& s) OVERRIDE {</div>
-<div class="line"> std::cerr << <span class="stringliteral">"listen error: "</span> << s << 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>& 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<proton::container> 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">"0.0.0.0"</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">'a'</span>, <span class="stringliteral">"address"</span>, <span class="stringliteral">"listen on URL"</span>, <span class="stringliteral">"URL"</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>& e) {</div>
-<div class="line"> std::cout << opts << std::endl << e.what() << std::endl;</div>
-<div class="line"> } <span class="keywordflow">catch</span> (<span class="keyword">const</span> std::exception& e) {</div>
-<div class="line"> std::cerr << <span class="stringliteral">"broker shutdown: "</span> << e.what() << 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"> * "License"); 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"> * "AS IS" 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 "../options.hpp"</span></div><div class="line"><span class="preprocessor">#include "mt_container.hpp"</span></
div><div class="line"></div><div class="line"><span class="preprocessor">#include <proton/connection.hpp></span></div><div class="line"><span class="preprocessor">#include <proton/default_container.hpp></span></div><div class="line"><span class="preprocessor">#include <proton/delivery.hpp></span></div><div class="line"><span class="preprocessor">#include <proton/messaging_handler.hpp></span></div><div class="line"><span class="preprocessor">#include <proton/listen_handler.hpp></span></div><div class="line"><span class="preprocessor">#include <proton/thread_safe.hpp></span></div><div class="line"></div><div class="line"><span class="preprocessor">#include <atomic></span></div><div class="line"><span class="preprocessor">#include <functional></span></div><div class="line"><span class="preprocessor">#include <iostream></span></div><div class="line"><span class="preprocessor">#include <mutex></span></div><div class="line"><span
class="preprocessor">#include <thread></span></div><div class="line"></div><div class="line"><span class="preprocessor">#include "../fake_cpp11.hpp"</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& 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'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> &m) {</div><div class="line"> std::lock_guard<std::mutex> 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's connection.</span></div><div class="line"> <span class="keywordtype">bool</span> pop(<a class="code" href="classproton_1_1message.html">proton::message</a>& m, std::function<<span class="keywordtype">void</span>(queue*)> callback) {</div><div class="line"> std::lock_guard<std::mutex> 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<proton::message> messages_;</div><div class="line"> std::vector<std::function<void(queue*)> > 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& name) {</div><div class="line"> std::lock_guard<std::mutex> 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->second)</div><div class="line"> i->second.reset(<span class="keyword">new</span> queue(name));</div><div class="line"> <span class="keywordflow">return</span> i->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 << <span class="stringliteral">"_dynamic_"</span> << 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<std::string, std::unique_ptr<queue> > 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<uint64_t> 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& 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>& 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's proton::event_loop will remain valid as a shared_ptr exists.</span></div><div class="line"> std::shared_ptr<proton::thread_safe<proton::connection> > 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->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->event_loop()->inject(</div><div class="line"> std::bind(&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> &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 << <span class="stringliteral">"sending from "</s
pan> << q->name() << 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> &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> &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">"shutdown"</span>) {</div><div class="line"> std::cout << <span class="stringliteral">"broker shutting down"</span> << std::endl;</div><div class="line"> <span class="comment">// Sending to the special "shutdown" 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">"shutdown"</span>, <span class="stringliteral">"stop broker"</span>));</div><div class="line"> } <span class="keywordflow">else</span> {</div><div class="line"> std::cout << <span class="stringliteral">"receiving to "</span> << qname << 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> &d, <a class="code" href="classproton_1_1message.
html">proton::message</a> &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)->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> &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>& 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> &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>& 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>&) 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<queue*, proton::sender> 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>& 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> &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->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'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->second.credit() <= 0 || do_send(q, i->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'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> <<span class="keyword">class</span> Predicate></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->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& queues_;</div><div class="line"> blocked_map blocked_;</div><div class="line"> std::function<void(queue*)> 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">"mt_broker"</span>)), listener_(queues_)</div><div class="line"> {</div><div class="line"> container_->listen(addr, listener_);</div><div class="line"> std::cout << <span class="stringliteral">"broker listening on "</span> << addr << 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<std::thread> threads(std::thread::hardware_concurrency()-1);</div><div class="line"> <span class="keywordflow">for</span> (<span class="keyword">auto</span>& t : threads)</div><div class="line"> t = std::thread(&<a name="a21"></a><a class="code" href="classproton_1_1container.html#a18954417d3124a8095783ea13dc6d00b">proton::container::run</a>, container_.get());</div><div class="line">
container_->run(); <span class="comment">// Use this thread too.</span></div><div class="line"> <span class="keywordflow">for</span> (<span class="keyword">auto</span>& 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& 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& s) OVERRIDE {</div><div class="line"> std::cerr << <span class="stringliteral">"listen error: "</span> << s << std::endl;</div><div class="line"> <span class="keywordflow">throw</span> std::runtime_error(s);</div><div class="line"> }</div><div class="line"> queues& queues_;</div><div class="line"> };</div><div class="line"></div><div class="line"> queues queues_;</div><div class="line"> std::unique_ptr<proton::container> 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">"0.0.0.0"</span>);</div><div class="line"> example::options opts(argc, argv);</div><div class="line"> opts.add_value(address, <span class="charliteral">'a'</span>, <span class="stringliteral">"address"</span>, <span class="stringliteral">"listen on URL"</span>, <span class="stringliteral">"URL"</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& e) {</div><div class="line"> std::cout << opts << std::endl << e.what() << std::endl;</div><div class="line"> } <span class="keywordflow">catch</span> (<span class="keyword">const</span> std::exception& e) {</div><div class="line"> std::cerr << <span class="stringliteral">"broker shutdown: "</span> << e.what() << 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