[mingw-qpid-cpp: 19/28] Rebased to Qpid 0.12
Kalev Lember
kalev at fedoraproject.org
Wed Mar 7 17:18:24 UTC 2012
commit 49a2019d845ff01ce4be8fa39a29505e98d51dba
Author: Ted Ross <tross at redhat.com>
Date: Thu Sep 22 14:45:43 2011 -0400
Rebased to Qpid 0.12
.gitignore | 1 +
QPID-3159.patch | 16 -
boost_filesystem_v2.patch | 13 -
fedora.patch | 2497 +++++++
mingw32-qpid-cpp.spec | 19 +-
qpid-fedora-patch.patch |16808 ---------------------------------------------
qpid-gcc46.patch | 188 -
qpid-mingw.patch | 1701 -----
qpid-mingw32.patch | 2778 --------
qpid-mutable.patch | 22 -
sources | 2 +-
11 files changed, 2507 insertions(+), 21538 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 55f7d9c..f09518c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/qpid-0.8.tar.gz
/qpid-0.10.tar.gz
+/qpid-0.12.tar.gz
diff --git a/fedora.patch b/fedora.patch
new file mode 100644
index 0000000..8172f66
--- /dev/null
+++ b/fedora.patch
@@ -0,0 +1,2497 @@
+From 00d9b16761b7f237c6b1418995cc9367aebac0f5 Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at apache.org>
+Date: Tue, 12 Jul 2011 11:49:32 +0000
+Subject: [PATCH 01/14] QPID-3275 - QMF Console asynchronous correlation-id
+ should be scoped to the session, not the specific
+ agent
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1145557 13f79535-47bb-0310-9956-ffa450edef68
+---
+ qpid/cpp/src/qmf/Agent.cpp | 29 ++++++-----------------------
+ qpid/cpp/src/qmf/AgentImpl.h | 1 -
+ qpid/cpp/src/qmf/ConsoleSession.cpp | 2 +-
+ qpid/cpp/src/qmf/ConsoleSessionImpl.h | 3 +++
+ 4 files changed, 10 insertions(+), 25 deletions(-)
+
+diff --git a/qpid/cpp/src/qmf/Agent.cpp b/qpid/cpp/src/qmf/Agent.cpp
+index 915f2a1..684f8e4 100644
+--- a/qpid/cpp/src/qmf/Agent.cpp
++++ b/qpid/cpp/src/qmf/Agent.cpp
+@@ -72,7 +72,7 @@ Schema Agent::getSchema(const SchemaId& s, Duration t) { return impl->getSchema(
+
+ AgentImpl::AgentImpl(const std::string& n, uint32_t e, ConsoleSessionImpl& s) :
+ name(n), directSubject(n), epoch(e), session(s), touched(true), untouchedCount(0), capability(0),
+- sender(session.directSender), nextCorrelator(1), schemaCache(s.schemaCache)
++ sender(session.directSender), schemaCache(s.schemaCache)
+ {
+ }
+
+@@ -102,12 +102,11 @@ const Variant& AgentImpl::getAttribute(const string& k) const
+ ConsoleEvent AgentImpl::query(const Query& query, Duration timeout)
+ {
+ boost::shared_ptr<SyncContext> context(new SyncContext());
+- uint32_t correlator;
++ uint32_t correlator(session.correlator());
+ ConsoleEvent result;
+
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+- correlator = nextCorrelator++;
+ contextMap[correlator] = context;
+ }
+ try {
+@@ -151,12 +150,7 @@ ConsoleEvent AgentImpl::query(const string& text, Duration timeout)
+
+ uint32_t AgentImpl::queryAsync(const Query& query)
+ {
+- uint32_t correlator;
+-
+- {
+- qpid::sys::Mutex::ScopedLock l(lock);
+- correlator = nextCorrelator++;
+- }
++ uint32_t correlator(session.correlator());
+
+ sendQuery(query, correlator);
+ return correlator;
+@@ -172,12 +166,11 @@ uint32_t AgentImpl::queryAsync(const string& text)
+ ConsoleEvent AgentImpl::callMethod(const string& method, const Variant::Map& args, const DataAddr& addr, Duration timeout)
+ {
+ boost::shared_ptr<SyncContext> context(new SyncContext());
+- uint32_t correlator;
++ uint32_t correlator(session.correlator());
+ ConsoleEvent result;
+
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+- correlator = nextCorrelator++;
+ contextMap[correlator] = context;
+ }
+ try {
+@@ -213,12 +206,7 @@ ConsoleEvent AgentImpl::callMethod(const string& method, const Variant::Map& arg
+
+ uint32_t AgentImpl::callMethodAsync(const string& method, const Variant::Map& args, const DataAddr& addr)
+ {
+- uint32_t correlator;
+-
+- {
+- qpid::sys::Mutex::ScopedLock l(lock);
+- correlator = nextCorrelator++;
+- }
++ uint32_t correlator(session.correlator());
+
+ sendMethod(method, args, addr, correlator);
+ return correlator;
+@@ -596,12 +584,7 @@ void AgentImpl::sendMethod(const string& method, const Variant::Map& args, const
+
+ void AgentImpl::sendSchemaRequest(const SchemaId& id)
+ {
+- uint32_t correlator;
+-
+- {
+- qpid::sys::Mutex::ScopedLock l(lock);
+- correlator = nextCorrelator++;
+- }
++ uint32_t correlator(session.correlator());
+
+ if (capability >= AGENT_CAPABILITY_V2_SCHEMA) {
+ Query query(QUERY_SCHEMA, id);
+diff --git a/qpid/cpp/src/qmf/AgentImpl.h b/qpid/cpp/src/qmf/AgentImpl.h
+index 7fa4f43..09754a3 100644
+--- a/qpid/cpp/src/qmf/AgentImpl.h
++++ b/qpid/cpp/src/qmf/AgentImpl.h
+@@ -99,7 +99,6 @@ namespace qmf {
+ uint32_t capability;
+ qpid::messaging::Sender sender;
+ qpid::types::Variant::Map attributes;
+- uint32_t nextCorrelator;
+ std::map<uint32_t, boost::shared_ptr<SyncContext> > contextMap;
+ boost::shared_ptr<SchemaCache> schemaCache;
+ mutable std::set<std::string> packageSet;
+diff --git a/qpid/cpp/src/qmf/ConsoleSession.cpp b/qpid/cpp/src/qmf/ConsoleSession.cpp
+index 5df0d83..7b51d80 100644
+--- a/qpid/cpp/src/qmf/ConsoleSession.cpp
++++ b/qpid/cpp/src/qmf/ConsoleSession.cpp
+@@ -68,7 +68,7 @@ Subscription ConsoleSession::subscribe(const string& q, const string& f, const s
+ ConsoleSessionImpl::ConsoleSessionImpl(Connection& c, const string& options) :
+ connection(c), domain("default"), maxAgentAgeMinutes(5), listenOnDirect(true), strictSecurity(false),
+ opened(false), thread(0), threadCanceled(false), lastVisit(0), lastAgePass(0),
+- connectedBrokerInAgentList(false), schemaCache(new SchemaCache())
++ connectedBrokerInAgentList(false), schemaCache(new SchemaCache()), nextCorrelator(1)
+ {
+ if (!options.empty()) {
+ qpid::messaging::AddressParser parser(options);
+diff --git a/qpid/cpp/src/qmf/ConsoleSessionImpl.h b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+index 411b3f0..429dfc4 100644
+--- a/qpid/cpp/src/qmf/ConsoleSessionImpl.h
++++ b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+@@ -90,6 +90,8 @@ namespace qmf {
+ std::string directBase;
+ std::string topicBase;
+ boost::shared_ptr<SchemaCache> schemaCache;
++ qpid::sys::Mutex corrlock;
++ uint32_t nextCorrelator;
+
+ void enqueueEvent(const ConsoleEvent&);
+ void enqueueEventLH(const ConsoleEvent&);
+@@ -100,6 +102,7 @@ namespace qmf {
+ void handleV1SchemaResponse(qpid::management::Buffer&, uint32_t, const qpid::messaging::Message&);
+ void periodicProcessing(uint64_t);
+ void run();
++ uint32_t correlator() { qpid::sys::Mutex::ScopedLock l(corrlock); return nextCorrelator++; }
+
+ friend class AgentImpl;
+ };
+--
+1.7.4.4
+
+From 40738a2501f8bfe2f85e1d26790584ce034bd930 Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at apache.org>
+Date: Tue, 12 Jul 2011 16:11:34 +0000
+Subject: [PATCH 02/14] QPID-3344 - Comparisons of const DataAddr objects are
+ incorrect Applied patch from Zane Bitter
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1145644 13f79535-47bb-0310-9956-ffa450edef68
+---
+ qpid/cpp/include/qmf/DataAddr.h | 3 +++
+ qpid/cpp/src/qmf/DataAddr.cpp | 6 ++++--
+ qpid/cpp/src/qmf/DataAddrImpl.h | 4 ++--
+ qpid/cpp/src/qpid/store/StorageProvider.h | 2 +-
+ 4 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/qpid/cpp/include/qmf/DataAddr.h b/qpid/cpp/include/qmf/DataAddr.h
+index 63d309c..20c4690 100644
+--- a/qpid/cpp/include/qmf/DataAddr.h
++++ b/qpid/cpp/include/qmf/DataAddr.h
+@@ -51,6 +51,9 @@ namespace qmf {
+ QMF_EXTERN uint32_t getAgentEpoch() const;
+ QMF_EXTERN qpid::types::Variant::Map asMap() const;
+
++ QMF_EXTERN bool operator==(const DataAddr&) const;
++ QMF_EXTERN bool operator<(const DataAddr&) const;
++
+ #ifndef SWIG
+ private:
+ friend class qmf::PrivateImplRef<DataAddr>;
+diff --git a/qpid/cpp/src/qmf/DataAddr.cpp b/qpid/cpp/src/qmf/DataAddr.cpp
+index fb51d57..d16e120 100644
+--- a/qpid/cpp/src/qmf/DataAddr.cpp
++++ b/qpid/cpp/src/qmf/DataAddr.cpp
+@@ -36,7 +36,9 @@ DataAddr::~DataAddr() { PI::dtor(*this); }
+ DataAddr& DataAddr::operator=(const DataAddr& s) { return PI::assign(*this, s); }
+
+ bool DataAddr::operator==(const DataAddr& o) { return *impl == *o.impl; }
++bool DataAddr::operator==(const DataAddr& o) const { return *impl == *o.impl; }
+ bool DataAddr::operator<(const DataAddr& o) { return *impl < *o.impl; }
++bool DataAddr::operator<(const DataAddr& o) const { return *impl < *o.impl; }
+
+ DataAddr::DataAddr(const qpid::types::Variant::Map& m) { PI::ctor(*this, new DataAddrImpl(m)); }
+ DataAddr::DataAddr(const string& n, const string& a, uint32_t e) { PI::ctor(*this, new DataAddrImpl(n, a, e)); }
+@@ -45,7 +47,7 @@ const string& DataAddr::getAgentName() const { return impl->getAgentName(); }
+ uint32_t DataAddr::getAgentEpoch() const { return impl->getAgentEpoch(); }
+ Variant::Map DataAddr::asMap() const { return impl->asMap(); }
+
+-bool DataAddrImpl::operator==(const DataAddrImpl& other)
++bool DataAddrImpl::operator==(const DataAddrImpl& other) const
+ {
+ return
+ agentName == other.agentName &&
+@@ -54,7 +56,7 @@ bool DataAddrImpl::operator==(const DataAddrImpl& other)
+ }
+
+
+-bool DataAddrImpl::operator<(const DataAddrImpl& other)
++bool DataAddrImpl::operator<(const DataAddrImpl& other) const
+ {
+ if (agentName < other.agentName) return true;
+ if (agentName > other.agentName) return false;
+diff --git a/qpid/cpp/src/qmf/DataAddrImpl.h b/qpid/cpp/src/qmf/DataAddrImpl.h
+index 3f9cae9..11d512f 100644
+--- a/qpid/cpp/src/qmf/DataAddrImpl.h
++++ b/qpid/cpp/src/qmf/DataAddrImpl.h
+@@ -38,8 +38,8 @@ namespace qmf {
+ //
+ // Methods from API handle
+ //
+- bool operator==(const DataAddrImpl&);
+- bool operator<(const DataAddrImpl&);
++ bool operator==(const DataAddrImpl&) const;
++ bool operator<(const DataAddrImpl&) const;
+ DataAddrImpl(const qpid::types::Variant::Map&);
+ DataAddrImpl(const std::string& _name, const std::string& _agentName, uint32_t _agentEpoch=0) :
+ agentName(_agentName), name(_name), agentEpoch(_agentEpoch) {}
+diff --git a/qpid/cpp/src/qpid/store/StorageProvider.h b/qpid/cpp/src/qpid/store/StorageProvider.h
+index bc8d187..d162cc5 100644
+--- a/qpid/cpp/src/qpid/store/StorageProvider.h
++++ b/qpid/cpp/src/qpid/store/StorageProvider.h
+@@ -54,7 +54,7 @@ struct QueueEntry {
+ QueueEntry(uint64_t id, TplStatus tpl = NONE, const std::string& x = "")
+ : queueId(id), tplStatus(tpl), xid(x) {}
+
+- bool operator==(const QueueEntry& rhs) {
++ bool operator==(const QueueEntry& rhs) const {
+ if (queueId != rhs.queueId) return false;
+ if (tplStatus == NONE && rhs.tplStatus == NONE) return true;
+ return xid == rhs.xid;
+--
+1.7.4.4
+
+From e2257aece703af5d775b087440958e19702b92a0 Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at apache.org>
+Date: Fri, 5 Aug 2011 15:24:16 +0000
+Subject: [PATCH 03/14] NO-JIRA - Added missing template file in distribution.
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1154264 13f79535-47bb-0310-9956-ffa450edef68
+---
+ qpid/cpp/managementgen/Makefile.am | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am
+index e10dd63..4fc5edc 100644
+--- a/qpid/cpp/managementgen/Makefile.am
++++ b/qpid/cpp/managementgen/Makefile.am
+@@ -32,6 +32,7 @@ pkgpyexec_qmfgentmpl_PYTHON = \
+ qmfgen/templates/Args.h \
+ qmfgen/templates/Class.cpp \
+ qmfgen/templates/Class.h \
++ qmfgen/templates/CMakeLists.cmake \
+ qmfgen/templates/Event.cpp \
+ qmfgen/templates/Event.h \
+ qmfgen/templates/Makefile.mk \
+--
+1.7.4.4
+
+From f654585bacf244e33cdb5a8a1ece6c15b18ecdc1 Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at apache.org>
+Date: Mon, 15 Aug 2011 16:47:56 +0000
+Subject: [PATCH 04/14] QPID-3423 - Timing and Performance Improvements in QMF
+ Libraries
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1157907 13f79535-47bb-0310-9956-ffa450edef68
+---
+ qpid/cpp/include/qmf/AgentSession.h | 5 +++
+ qpid/cpp/include/qmf/ConsoleSession.h | 4 ++
+ qpid/cpp/src/qmf/AgentSession.cpp | 41 ++++++++++++++++------
+ qpid/cpp/src/qmf/ConsoleSession.cpp | 43 ++++++++++++++++-------
+ qpid/cpp/src/qmf/ConsoleSessionImpl.h | 1 +
+ qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp | 19 ++++++++--
+ 6 files changed, 86 insertions(+), 27 deletions(-)
+
+diff --git a/qpid/cpp/include/qmf/AgentSession.h b/qpid/cpp/include/qmf/AgentSession.h
+index 1eeb252..5ecfb04 100644
+--- a/qpid/cpp/include/qmf/AgentSession.h
++++ b/qpid/cpp/include/qmf/AgentSession.h
+@@ -71,6 +71,11 @@ namespace qmf {
+ * If False: Listen only on the routable direct address
+ * strict-security:{True,False} - If True: Cooperate with the broker to enforce strict access control to the network
+ * - If False: Operate more flexibly with regard to use of messaging facilities [default]
++ * max-thread-wait-time:N - Time (in seconds) the session thread will wait for messages from the network between
++ * periodic background processing passes. [default: 5]
++ * Must not be greater than 'interval'. Larger numbers will cause fewer wake-ups but will
++ * increase the time it takes to shut down the process. This setting will not affect the
++ * agent's response time for queries or method invocation.
+ */
+ QMF_EXTERN AgentSession(qpid::messaging::Connection& conn, const std::string& options="");
+
+diff --git a/qpid/cpp/include/qmf/ConsoleSession.h b/qpid/cpp/include/qmf/ConsoleSession.h
+index 6008036..5e3a091 100644
+--- a/qpid/cpp/include/qmf/ConsoleSession.h
++++ b/qpid/cpp/include/qmf/ConsoleSession.h
+@@ -61,6 +61,10 @@ namespace qmf {
+ * If False: Listen only on the routable direct address
+ * strict-security:{True,False} - If True: Cooperate with the broker to enforce strict access control to the network
+ * - If False: Operate more flexibly with regard to use of messaging facilities [default]
++ * max-thread-wait-time:N - Time (in seconds) the session thread will wait for messages from the network between
++ * periodic background processing passes.
++ * Must not be greater than 60. Larger numbers will cause fewer wake-ups but will
++ * increase the time it takes to shut down the process. [default: 5]
+ */
+ QMF_EXTERN ConsoleSession(qpid::messaging::Connection& conn, const std::string& options="");
+
+diff --git a/qpid/cpp/src/qmf/AgentSession.cpp b/qpid/cpp/src/qmf/AgentSession.cpp
+index 71d3693..a88782d 100644
+--- a/qpid/cpp/src/qmf/AgentSession.cpp
++++ b/qpid/cpp/src/qmf/AgentSession.cpp
+@@ -120,6 +120,7 @@ namespace qmf {
+ bool publicEvents;
+ bool listenOnDirect;
+ bool strictSecurity;
++ uint32_t maxThreadWaitTime;
+ uint64_t schemaUpdateTime;
+ string directBase;
+ string topicBase;
+@@ -185,7 +186,7 @@ AgentSessionImpl::AgentSessionImpl(Connection& c, const string& options) :
+ bootSequence(1), interval(60), lastHeartbeat(0), lastVisit(0), forceHeartbeat(false),
+ externalStorage(false), autoAllowQueries(true), autoAllowMethods(true),
+ maxSubscriptions(64), minSubInterval(3000), subLifetime(300), publicEvents(true),
+- listenOnDirect(true), strictSecurity(false),
++ listenOnDirect(true), strictSecurity(false), maxThreadWaitTime(5),
+ schemaUpdateTime(uint64_t(qpid::sys::Duration(qpid::sys::EPOCH, qpid::sys::now())))
+ {
+ //
+@@ -246,7 +247,14 @@ AgentSessionImpl::AgentSessionImpl(Connection& c, const string& options) :
+ iter = optMap.find("strict-security");
+ if (iter != optMap.end())
+ strictSecurity = iter->second.asBool();
++
++ iter = optMap.find("max-thread-wait-time");
++ if (iter != optMap.end())
++ maxThreadWaitTime = iter->second.asUint32();
+ }
++
++ if (maxThreadWaitTime > interval)
++ maxThreadWaitTime = interval;
+ }
+
+
+@@ -254,6 +262,11 @@ AgentSessionImpl::~AgentSessionImpl()
+ {
+ if (opened)
+ close();
++
++ if (thread) {
++ thread->join();
++ delete thread;
++ }
+ }
+
+
+@@ -262,6 +275,12 @@ void AgentSessionImpl::open()
+ if (opened)
+ throw QmfException("The session is already open");
+
++ // If the thread exists, join and delete it before creating a new one.
++ if (thread) {
++ thread->join();
++ delete thread;
++ }
++
+ const string addrArgs(";{create:never,node:{type:topic}}");
+ const string routableAddr("direct-agent.route." + qpid::types::Uuid(true).str());
+ attributes["_direct_subject"] = routableAddr;
+@@ -304,13 +323,8 @@ void AgentSessionImpl::close()
+ if (!opened)
+ return;
+
+- // Stop and join the receiver thread
++ // Stop the receiver thread. Don't join it until the destructor is called or open() is called.
+ threadCanceled = true;
+- thread->join();
+- delete thread;
+-
+- // Close the AMQP session
+- session.close();
+ opened = false;
+ }
+
+@@ -320,9 +334,13 @@ bool AgentSessionImpl::nextEvent(AgentEvent& event, Duration timeout)
+ uint64_t milliseconds = timeout.getMilliseconds();
+ qpid::sys::Mutex::ScopedLock l(lock);
+
+- if (eventQueue.empty() && milliseconds > 0)
+- cond.wait(lock, qpid::sys::AbsTime(qpid::sys::now(),
+- qpid::sys::Duration(milliseconds * qpid::sys::TIME_MSEC)));
++ if (eventQueue.empty() && milliseconds > 0) {
++ int64_t nsecs(qpid::sys::TIME_INFINITE);
++ if ((uint64_t)(nsecs / 1000000) > milliseconds)
++ nsecs = (int64_t) milliseconds * 1000000;
++ qpid::sys::Duration then(nsecs);
++ cond.wait(lock, qpid::sys::AbsTime(qpid::sys::now(), then));
++ }
+
+ if (!eventQueue.empty()) {
+ event = eventQueue.front();
+@@ -1050,7 +1068,7 @@ void AgentSessionImpl::run()
+ periodicProcessing((uint64_t) qpid::sys::Duration(qpid::sys::EPOCH, qpid::sys::now()) / qpid::sys::TIME_SEC);
+
+ Receiver rx;
+- bool valid = session.nextReceiver(rx, Duration::SECOND);
++ bool valid = session.nextReceiver(rx, Duration::SECOND * maxThreadWaitTime);
+ if (threadCanceled)
+ break;
+ if (valid) {
+@@ -1067,6 +1085,7 @@ void AgentSessionImpl::run()
+ enqueueEvent(AgentEvent(new AgentEventImpl(AGENT_THREAD_FAILED)));
+ }
+
++ session.close();
+ QPID_LOG(debug, "AgentSession thread exiting for agent " << agentName);
+ }
+
+diff --git a/qpid/cpp/src/qmf/ConsoleSession.cpp b/qpid/cpp/src/qmf/ConsoleSession.cpp
+index 7b51d80..af83595 100644
+--- a/qpid/cpp/src/qmf/ConsoleSession.cpp
++++ b/qpid/cpp/src/qmf/ConsoleSession.cpp
+@@ -66,7 +66,7 @@ Subscription ConsoleSession::subscribe(const string& q, const string& f, const s
+ //========================================================================================
+
+ ConsoleSessionImpl::ConsoleSessionImpl(Connection& c, const string& options) :
+- connection(c), domain("default"), maxAgentAgeMinutes(5), listenOnDirect(true), strictSecurity(false),
++ connection(c), domain("default"), maxAgentAgeMinutes(5), listenOnDirect(true), strictSecurity(false), maxThreadWaitTime(5),
+ opened(false), thread(0), threadCanceled(false), lastVisit(0), lastAgePass(0),
+ connectedBrokerInAgentList(false), schemaCache(new SchemaCache()), nextCorrelator(1)
+ {
+@@ -92,7 +92,14 @@ ConsoleSessionImpl::ConsoleSessionImpl(Connection& c, const string& options) :
+ iter = optMap.find("strict-security");
+ if (iter != optMap.end())
+ strictSecurity = iter->second.asBool();
++
++ iter = optMap.find("max-thread-wait-time");
++ if (iter != optMap.end())
++ maxThreadWaitTime = iter->second.asUint32();
+ }
++
++ if (maxThreadWaitTime > 60)
++ maxThreadWaitTime = 60;
+ }
+
+
+@@ -100,6 +107,11 @@ ConsoleSessionImpl::~ConsoleSessionImpl()
+ {
+ if (opened)
+ close();
++
++ if (thread) {
++ thread->join();
++ delete thread;
++ }
+ }
+
+
+@@ -154,6 +166,12 @@ void ConsoleSessionImpl::open()
+ if (opened)
+ throw QmfException("The session is already open");
+
++ // If the thread exists, join and delete it before creating a new one.
++ if (thread) {
++ thread->join();
++ delete thread;
++ }
++
+ // Establish messaging addresses
+ directBase = "qmf." + domain + ".direct";
+ topicBase = "qmf." + domain + ".topic";
+@@ -182,14 +200,13 @@ void ConsoleSessionImpl::open()
+
+ // Start the receiver thread
+ threadCanceled = false;
++ opened = true;
+ thread = new qpid::sys::Thread(*this);
+
+ // Send an agent_locate to direct address 'broker' to identify the connected-broker-agent.
+ sendBrokerLocate();
+ if (agentQuery)
+ sendAgentLocate();
+-
+- opened = true;
+ }
+
+
+@@ -198,13 +215,8 @@ void ConsoleSessionImpl::close()
+ if (!opened)
+ throw QmfException("The session is already closed");
+
+- // Stop and join the receiver thread
++ // Stop the receiver thread. Don't join it until the destructor is called or open() is called.
+ threadCanceled = true;
+- thread->join();
+- delete thread;
+-
+- // Close the AMQP session
+- session.close();
+ opened = false;
+ }
+
+@@ -214,9 +226,13 @@ bool ConsoleSessionImpl::nextEvent(ConsoleEvent& event, Duration timeout)
+ uint64_t milliseconds = timeout.getMilliseconds();
+ qpid::sys::Mutex::ScopedLock l(lock);
+
+- if (eventQueue.empty() && milliseconds > 0)
+- cond.wait(lock, qpid::sys::AbsTime(qpid::sys::now(),
+- qpid::sys::Duration(milliseconds * qpid::sys::TIME_MSEC)));
++ if (eventQueue.empty() && milliseconds > 0) {
++ int64_t nsecs(qpid::sys::TIME_INFINITE);
++ if ((uint64_t)(nsecs / 1000000) > milliseconds)
++ nsecs = (int64_t) milliseconds * 1000000;
++ qpid::sys::Duration then(nsecs);
++ cond.wait(lock, qpid::sys::AbsTime(qpid::sys::now(), then));
++ }
+
+ if (!eventQueue.empty()) {
+ event = eventQueue.front();
+@@ -596,7 +612,7 @@ void ConsoleSessionImpl::run()
+ qpid::sys::TIME_SEC);
+
+ Receiver rx;
+- bool valid = session.nextReceiver(rx, Duration::SECOND);
++ bool valid = session.nextReceiver(rx, Duration::SECOND * maxThreadWaitTime);
+ if (threadCanceled)
+ break;
+ if (valid) {
+@@ -613,6 +629,7 @@ void ConsoleSessionImpl::run()
+ enqueueEvent(ConsoleEvent(new ConsoleEventImpl(CONSOLE_THREAD_FAILED)));
+ }
+
++ session.close();
+ QPID_LOG(debug, "ConsoleSession thread exiting");
+ }
+
+diff --git a/qpid/cpp/src/qmf/ConsoleSessionImpl.h b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+index 429dfc4..478d24e 100644
+--- a/qpid/cpp/src/qmf/ConsoleSessionImpl.h
++++ b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+@@ -76,6 +76,7 @@ namespace qmf {
+ uint32_t maxAgentAgeMinutes;
+ bool listenOnDirect;
+ bool strictSecurity;
++ uint32_t maxThreadWaitTime;
+ Query agentQuery;
+ bool opened;
+ std::queue<ConsoleEvent> eventQueue;
+diff --git a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
+index 633401e..f183ff8 100644
+--- a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
++++ b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
+@@ -1378,13 +1378,26 @@ bool ManagementAgentImpl::ConnectionThread::isSleeping() const
+
+ void ManagementAgentImpl::PublishThread::run()
+ {
+- uint16_t totalSleep;
++ uint16_t totalSleep;
++ uint16_t sleepTime;
+
+ while (!shutdown) {
+ agent.periodicProcessing();
+ totalSleep = 0;
+- while (totalSleep++ < agent.getInterval() && !shutdown) {
+- ::sleep(1);
++
++ //
++ // Calculate a sleep time that is no greater than 5 seconds and
++ // no less than 1 second.
++ //
++ sleepTime = agent.getInterval();
++ if (sleepTime > 5)
++ sleepTime = 5;
++ else if (sleepTime == 0)
++ sleepTime = 1;
++
++ while (totalSleep < agent.getInterval() && !shutdown) {
++ ::sleep(sleepTime);
++ totalSleep += sleepTime;
+ }
+ }
+ }
+--
+1.7.4.4
+
+From 6ca9eda32ed8c809524b913dd169afa4a35eb58d Mon Sep 17 00:00:00 2001
+From: Ted Ross <ross at localhost.localdomain>
+Date: Mon, 15 Aug 2011 16:25:52 -0400
+Subject: [PATCH 05/14] Fixed EXTERN definitions
+
+---
+ qpid/cpp/include/qpid/framing/FieldTable.h | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/qpid/cpp/include/qpid/framing/FieldTable.h b/qpid/cpp/include/qpid/framing/FieldTable.h
+index e8ec524..bdcef6d 100644
+--- a/qpid/cpp/include/qpid/framing/FieldTable.h
++++ b/qpid/cpp/include/qpid/framing/FieldTable.h
+@@ -65,8 +65,8 @@ class FieldTable
+ QPID_COMMON_EXTERN void decode(Buffer& buffer);
+
+ QPID_COMMON_EXTERN int count() const;
+- QPID_COMMON_EXTERN size_t size() const { return values.size(); }
+- QPID_COMMON_EXTERN bool empty() { return size() == 0; }
++ QPID_COMMON_INLINE_EXTERN size_t size() const { return values.size(); }
++ QPID_COMMON_INLINE_EXTERN bool empty() { return size() == 0; }
+ QPID_COMMON_EXTERN void set(const std::string& name, const ValuePtr& value);
+ QPID_COMMON_EXTERN ValuePtr get(const std::string& name) const;
+ QPID_COMMON_INLINE_EXTERN bool isSet(const std::string& name) const { return get(name).get() != 0; }
+--
+1.7.4.4
+
+From 1f68475caffaa3c36ad921684bbaea35c68ce375 Mon Sep 17 00:00:00 2001
+From: Ted Ross <ross at localhost.localdomain>
+Date: Mon, 15 Aug 2011 17:10:15 -0400
+Subject: [PATCH 06/14] Enable qmf2 for mingw32
+
+---
+ qpid/cpp/src/CMakeLists.txt | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/qpid/cpp/src/CMakeLists.txt b/qpid/cpp/src/CMakeLists.txt
+index 80315b9..978d962 100644
+--- a/qpid/cpp/src/CMakeLists.txt
++++ b/qpid/cpp/src/CMakeLists.txt
+@@ -1081,7 +1081,7 @@ install (TARGETS qmf OPTIONAL
+ COMPONENT ${QPID_COMPONENT_QMF})
+ install_pdb (qmf ${QPID_COMPONENT_QMF})
+
+-if(NOT WIN32)
++#if(NOT WIN32)
+ set (qmf2_HEADERS
+ ../include/qmf/AgentEvent.h
+ ../include/qmf/Agent.h
+@@ -1156,7 +1156,7 @@ if(NOT WIN32)
+ DESTINATION ${QPID_INSTALL_INCLUDEDIR}/qmf
+ COMPONENT ${QPID_COMPONENT_QMF})
+ install_pdb (qmf2 ${QPID_COMPONENT_QMF})
+-endif (NOT WIN32)
++#endif (NOT WIN32)
+
+ set (qmfengine_SOURCES
+ qmf/engine/Agent.cpp
+--
+1.7.4.4
+
+From 337286e57705835975acd215aa1990f3597abc6a Mon Sep 17 00:00:00 2001
+From: Ted Ross <ross at localhost.localdomain>
+Date: Mon, 15 Aug 2011 17:36:24 -0400
+Subject: [PATCH 07/14] Fixed externs in AddressParser
+
+---
+ qpid/cpp/src/qpid/messaging/AddressParser.h | 10 +++++-----
+ 1 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/qpid/cpp/src/qpid/messaging/AddressParser.h b/qpid/cpp/src/qpid/messaging/AddressParser.h
+index 1635331..c51200c 100644
+--- a/qpid/cpp/src/qpid/messaging/AddressParser.h
++++ b/qpid/cpp/src/qpid/messaging/AddressParser.h
+@@ -26,13 +26,13 @@
+ namespace qpid {
+ namespace messaging {
+
+-class AddressParser
++class QPID_MESSAGING_CLASS_EXTERN AddressParser
+ {
+ public:
+- AddressParser(const std::string&);
+- bool parse(Address& address);
+- bool parseMap(qpid::types::Variant::Map& map);
+- bool parseList(qpid::types::Variant::List& list);
++ QPID_MESSAGING_EXTERN AddressParser(const std::string&);
++ QPID_MESSAGING_EXTERN bool parse(Address& address);
++ QPID_MESSAGING_EXTERN bool parseMap(qpid::types::Variant::Map& map);
++ QPID_MESSAGING_EXTERN bool parseList(qpid::types::Variant::List& list);
+ private:
+ const std::string& input;
+ std::string::size_type current;
+--
+1.7.4.4
+
+From 666f43e30629559d97a71bd737d36ab14d3eeb86 Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at apache.org>
+Date: Tue, 13 Sep 2011 19:34:38 +0000
+Subject: [PATCH 08/14] QPID-3484 - QMF Main-Loop Integration Applied patch
+ from Darryl Pierce.
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1170314 13f79535-47bb-0310-9956-ffa450edef68
+---
+ qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am | 5 +-
+ .../qmf2/examples/cpp/event_driven_list_agents.cpp | 107 ++++++++++++
+ qpid/cpp/include/qmf/AgentSession.h | 1 +
+ qpid/cpp/include/qmf/ConsoleSession.h | 1 +
+ qpid/cpp/include/qmf/posix/EventNotifier.h | 62 +++++++
+ qpid/cpp/src/CMakeLists.txt | 5 +
+ qpid/cpp/src/qmf.mk | 4 +
+ qpid/cpp/src/qmf/AgentSession.cpp | 167 +++++--------------
+ qpid/cpp/src/qmf/AgentSessionImpl.h | 175 ++++++++++++++++++++
+ qpid/cpp/src/qmf/ConsoleSession.cpp | 38 ++++-
+ qpid/cpp/src/qmf/ConsoleSessionImpl.h | 17 ++
+ qpid/cpp/src/qmf/EventNotifierImpl.cpp | 56 +++++++
+ qpid/cpp/src/qmf/EventNotifierImpl.h | 48 ++++++
+ qpid/cpp/src/qmf/PosixEventNotifier.cpp | 63 +++++++
+ qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp | 108 ++++++++++++
+ qpid/cpp/src/qmf/PosixEventNotifierImpl.h | 61 +++++++
+ qpid/cpp/src/tests/Qmf2.cpp | 104 ++++++++++++-
+ 17 files changed, 890 insertions(+), 132 deletions(-)
+ create mode 100644 qpid/cpp/bindings/qmf2/examples/cpp/event_driven_list_agents.cpp
+ create mode 100644 qpid/cpp/include/qmf/posix/EventNotifier.h
+ create mode 100644 qpid/cpp/src/qmf/AgentSessionImpl.h
+ create mode 100644 qpid/cpp/src/qmf/EventNotifierImpl.cpp
+ create mode 100644 qpid/cpp/src/qmf/EventNotifierImpl.h
+ create mode 100644 qpid/cpp/src/qmf/PosixEventNotifier.cpp
+ create mode 100644 qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp
+ create mode 100644 qpid/cpp/src/qmf/PosixEventNotifierImpl.h
+
+diff --git a/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am b/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am
+index 84207d4..062fbd0 100644
+--- a/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am
++++ b/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am
+@@ -21,7 +21,7 @@ INCLUDE = -I$(top_srcdir)/include
+
+ AM_CPPFLAGS = $(INCLUDE)
+
+-noinst_PROGRAMS=agent list_agents print_events
++noinst_PROGRAMS=agent event_driven_list_agents list_agents print_events
+
+ agent_SOURCES=agent.cpp
+ agent_LDADD=$(top_builddir)/src/libqmf2.la
+@@ -29,5 +29,8 @@ agent_LDADD=$(top_builddir)/src/libqmf2.la
+ list_agents_SOURCES=list_agents.cpp
+ list_agents_LDADD=$(top_builddir)/src/libqmf2.la
+
++event_driven_list_agents_SOURCES=event_driven_list_agents.cpp
++event_driven_list_agents_LDADD=$(top_builddir)/src/libqmf2.la
++
+ print_events_SOURCES=print_events.cpp
+ print_events_LDADD=$(top_builddir)/src/libqmf2.la
+diff --git a/qpid/cpp/bindings/qmf2/examples/cpp/event_driven_list_agents.cpp b/qpid/cpp/bindings/qmf2/examples/cpp/event_driven_list_agents.cpp
+new file mode 100644
+index 0000000..c288aa6
+--- /dev/null
++++ b/qpid/cpp/bindings/qmf2/examples/cpp/event_driven_list_agents.cpp
+@@ -0,0 +1,107 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++
++#include <sys/select.h>
++#include <time.h>
++
++#include <qpid/messaging/Connection.h>
++#include <qpid/messaging/Duration.h>
++#include <qmf/Agent.h>
++#include <qmf/ConsoleEvent.h>
++#include <qmf/ConsoleSession.h>
++#include <qpid/types/Variant.h>
++#include "qmf/posix/EventNotifier.h"
++
++#include <string>
++#include <iostream>
++
++using namespace std;
++using namespace qmf;
++using qpid::types::Variant;
++using qpid::messaging::Duration;
++
++int main(int argc, char** argv)
++{
++ string url("localhost");
++ string connectionOptions;
++ string sessionOptions;
++
++ if (argc > 1)
++ url = argv[1];
++ if (argc > 2)
++ connectionOptions = argv[2];
++ if (argc > 3)
++ sessionOptions = argv[3];
++
++ qpid::messaging::Connection connection(url, connectionOptions);
++ connection.open();
++
++ ConsoleSession session(connection, sessionOptions);
++ session.open();
++ session.setAgentFilter("");
++
++ posix::EventNotifier notifier(session);
++
++ int fd(notifier.getHandle());
++ time_t lastUpdate;
++ bool ftl = false;
++
++ time(&lastUpdate);
++
++ while (true) {
++ fd_set rfds;
++ struct timeval tv;
++ int nfds, retval;
++
++ FD_ZERO(&rfds);
++ FD_SET(fd, &rfds);
++ nfds = fd + 1;
++ tv.tv_sec = 10;
++ tv.tv_usec = 0;
++
++ retval = select(nfds, &rfds, NULL, NULL, &tv);
++
++ if (retval > 0 && FD_ISSET(fd, &rfds)) {
++ ConsoleEvent event;
++ while (session.nextEvent(event, Duration::IMMEDIATE)) {
++ string eventType = "";
++ switch(event.getType()) {
++ case CONSOLE_AGENT_ADD: eventType = "Added"; break;
++ case CONSOLE_AGENT_DEL: eventType = "Deleted"; break;
++ case CONSOLE_AGENT_RESTART: eventType = "Restarted"; break;
++ case CONSOLE_AGENT_SCHEMA_UPDATE: eventType = "Schema Updated"; break;
++ case CONSOLE_AGENT_SCHEMA_RESPONSE: eventType = "Schema Response"; break;
++ case CONSOLE_EVENT: eventType = "Event"; break;
++ case CONSOLE_QUERY_RESPONSE: eventType = "Query Response"; break;
++ case CONSOLE_METHOD_RESPONSE: eventType = "Method Response"; break;
++ case CONSOLE_EXCEPTION: eventType = "Exception"; break;
++ case CONSOLE_SUBSCRIBE_ADD: eventType = "Subscription Added"; break;
++ case CONSOLE_SUBSCRIBE_UPDATE: eventType = "Subscription Updated"; break;
++ case CONSOLE_SUBSCRIBE_DEL: eventType = "Subscription Deleted" ; break;
++ case CONSOLE_THREAD_FAILED: eventType = "Thread Failure"; break;
++ default: eventType = "[UNDEFINED]";
++ }
++ cout << "Agent " << eventType << ": " << event.getAgent().getName() << endl;
++ }
++ } else {
++ cout << "No message received within waiting period." << endl;
++ }
++ }
++}
++
+diff --git a/qpid/cpp/include/qmf/AgentSession.h b/qpid/cpp/include/qmf/AgentSession.h
+index 5ecfb04..589d364 100644
+--- a/qpid/cpp/include/qmf/AgentSession.h
++++ b/qpid/cpp/include/qmf/AgentSession.h
+@@ -188,6 +188,7 @@ namespace qmf {
+ #ifndef SWIG
+ private:
+ friend class qmf::PrivateImplRef<AgentSession>;
++ friend struct AgentSessionImplAccess;
+ #endif
+ };
+
+diff --git a/qpid/cpp/include/qmf/ConsoleSession.h b/qpid/cpp/include/qmf/ConsoleSession.h
+index 5e3a091..022485c 100644
+--- a/qpid/cpp/include/qmf/ConsoleSession.h
++++ b/qpid/cpp/include/qmf/ConsoleSession.h
+@@ -123,6 +123,7 @@ namespace qmf {
+ #ifndef SWIG
+ private:
+ friend class qmf::PrivateImplRef<ConsoleSession>;
++ friend struct ConsoleSessionImplAccess;
+ #endif
+ };
+
+diff --git a/qpid/cpp/include/qmf/posix/EventNotifier.h b/qpid/cpp/include/qmf/posix/EventNotifier.h
+new file mode 100644
+index 0000000..91817cc
+--- /dev/null
++++ b/qpid/cpp/include/qmf/posix/EventNotifier.h
+@@ -0,0 +1,62 @@
++#ifndef __QMF_POSIX_EVENT_NOTIFIER_H
++#define __QMF_POSIX_EVENT_NOTIFIER_H
++
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++
++#include <qmf/ImportExport.h>
++#include "qmf/Handle.h"
++#include "qmf/AgentSession.h"
++#include "qmf/ConsoleSession.h"
++
++namespace qmf {
++
++ class PosixEventNotifierImpl;
++ class PosixEventNotifierImplAccess;
++
++namespace posix {
++
++#ifndef SWIG
++ template <class> class PrivateImplRef;
++#endif
++
++ class QMF_CLASS_EXTERN EventNotifier : public qmf::Handle<qmf::PosixEventNotifierImpl> {
++ public:
++ QMF_EXTERN EventNotifier(::qmf::AgentSession& agentSession);
++ QMF_EXTERN EventNotifier(::qmf::ConsoleSession& consoleSession);
++ QMF_EXTERN EventNotifier(const EventNotifier& that);
++
++ QMF_EXTERN ~EventNotifier();
++
++ QMF_EXTERN EventNotifier& operator=(const EventNotifier& that);
++
++ QMF_EXTERN int getHandle() const;
++
++#ifndef SWIG
++ private:
++ friend class qmf::PrivateImplRef<EventNotifier>;
++ friend struct qmf::PosixEventNotifierImplAccess;
++#endif
++
++ };
++
++}}
++
++#endif
++
+diff --git a/qpid/cpp/src/CMakeLists.txt b/qpid/cpp/src/CMakeLists.txt
+index 978d962..2986a90 100644
+--- a/qpid/cpp/src/CMakeLists.txt
++++ b/qpid/cpp/src/CMakeLists.txt
+@@ -1093,6 +1093,7 @@ install_pdb (qmf ${QPID_COMPONENT_QMF})
+ ../include/qmf/exceptions.h
+ ../include/qmf/Handle.h
+ ../include/qmf/ImportExport.h
++ ../include/qmf/posix/EventNotifier.h
+ ../include/qmf/Query.h
+ ../include/qmf/Schema.h
+ ../include/qmf/SchemaId.h
+@@ -1122,6 +1123,10 @@ install_pdb (qmf ${QPID_COMPONENT_QMF})
+ qmf/DataAddrImpl.h
+ qmf/Data.cpp
+ qmf/DataImpl.h
++ qmf/EventNotifierImpl.h
++ qmf/EventNotifierImpl.cpp
++ qmf/PosixEventNotifier.cpp
++ qmf/PosixEventNotifierImpl.cpp
+ qmf/exceptions.cpp
+ qmf/Expression.cpp
+ qmf/Expression.h
+diff --git a/qpid/cpp/src/qmf.mk b/qpid/cpp/src/qmf.mk
+index f3462f1..4da8470 100644
+--- a/qpid/cpp/src/qmf.mk
++++ b/qpid/cpp/src/qmf.mk
+@@ -43,6 +43,7 @@ QMF2_API = \
+ ../include/qmf/ConsoleSession.h \
+ ../include/qmf/DataAddr.h \
+ ../include/qmf/Data.h \
++ ../include/qmf/posix/EventNotifier.h \
+ ../include/qmf/exceptions.h \
+ ../include/qmf/Handle.h \
+ ../include/qmf/ImportExport.h \
+@@ -104,6 +105,9 @@ libqmf2_la_SOURCES = \
+ qmf/DataAddrImpl.h \
+ qmf/Data.cpp \
+ qmf/DataImpl.h \
++ qmf/EventNotifierImpl.cpp \
++ qmf/PosixEventNotifier.cpp \
++ qmf/PosixEventNotifierImpl.cpp \
+ qmf/exceptions.cpp \
+ qmf/Expression.cpp \
+ qmf/Expression.h \
+diff --git a/qpid/cpp/src/qmf/AgentSession.cpp b/qpid/cpp/src/qmf/AgentSession.cpp
+index a88782d..d92b2a4 100644
+--- a/qpid/cpp/src/qmf/AgentSession.cpp
++++ b/qpid/cpp/src/qmf/AgentSession.cpp
+@@ -19,134 +19,7 @@
+ *
+ */
+
+-#include "qpid/RefCounted.h"
+-#include "qmf/PrivateImplRef.h"
+-#include "qmf/exceptions.h"
+-#include "qmf/AgentSession.h"
+-#include "qmf/AgentEventImpl.h"
+-#include "qmf/SchemaIdImpl.h"
+-#include "qmf/SchemaImpl.h"
+-#include "qmf/DataAddrImpl.h"
+-#include "qmf/DataImpl.h"
+-#include "qmf/QueryImpl.h"
+-#include "qmf/agentCapability.h"
+-#include "qmf/constants.h"
+-#include "qpid/sys/Mutex.h"
+-#include "qpid/sys/Condition.h"
+-#include "qpid/sys/Thread.h"
+-#include "qpid/sys/Runnable.h"
+-#include "qpid/log/Statement.h"
+-#include "qpid/messaging/Connection.h"
+-#include "qpid/messaging/Session.h"
+-#include "qpid/messaging/Receiver.h"
+-#include "qpid/messaging/Sender.h"
+-#include "qpid/messaging/Message.h"
+-#include "qpid/messaging/AddressParser.h"
+-#include "qpid/management/Buffer.h"
+-#include <queue>
+-#include <map>
+-#include <set>
+-#include <iostream>
+-#include <memory>
+-
+-using namespace std;
+-using namespace qpid::messaging;
+-using namespace qmf;
+-using qpid::types::Variant;
+-
+-namespace qmf {
+- class AgentSessionImpl : public virtual qpid::RefCounted, public qpid::sys::Runnable {
+- public:
+- ~AgentSessionImpl();
+-
+- //
+- // Methods from API handle
+- //
+- AgentSessionImpl(Connection& c, const string& o);
+- void setDomain(const string& d) { checkOpen(); domain = d; }
+- void setVendor(const string& v) { checkOpen(); attributes["_vendor"] = v; }
+- void setProduct(const string& p) { checkOpen(); attributes["_product"] = p; }
+- void setInstance(const string& i) { checkOpen(); attributes["_instance"] = i; }
+- void setAttribute(const string& k, const qpid::types::Variant& v) { checkOpen(); attributes[k] = v; }
+- const string& getName() const { return agentName; }
+- void open();
+- void close();
+- bool nextEvent(AgentEvent& e, Duration t);
+- int pendingEvents() const;
+-
+- void registerSchema(Schema& s);
+- DataAddr addData(Data& d, const string& n, bool persist);
+- void delData(const DataAddr&);
+-
+- void authAccept(AgentEvent& e);
+- void authReject(AgentEvent& e, const string& m);
+- void raiseException(AgentEvent& e, const string& s);
+- void raiseException(AgentEvent& e, const Data& d);
+- void response(AgentEvent& e, const Data& d);
+- void complete(AgentEvent& e);
+- void methodSuccess(AgentEvent& e);
+- void raiseEvent(const Data& d);
+- void raiseEvent(const Data& d, int s);
+-
+- private:
+- typedef map<DataAddr, Data, DataAddrCompare> DataIndex;
+- typedef map<SchemaId, Schema, SchemaIdCompare> SchemaMap;
+-
+- mutable qpid::sys::Mutex lock;
+- qpid::sys::Condition cond;
+- Connection connection;
+- Session session;
+- Sender directSender;
+- Sender topicSender;
+- string domain;
+- Variant::Map attributes;
+- Variant::Map options;
+- string agentName;
+- bool opened;
+- queue<AgentEvent> eventQueue;
+- qpid::sys::Thread* thread;
+- bool threadCanceled;
+- uint32_t bootSequence;
+- uint32_t interval;
+- uint64_t lastHeartbeat;
+- uint64_t lastVisit;
+- bool forceHeartbeat;
+- bool externalStorage;
+- bool autoAllowQueries;
+- bool autoAllowMethods;
+- uint32_t maxSubscriptions;
+- uint32_t minSubInterval;
+- uint32_t subLifetime;
+- bool publicEvents;
+- bool listenOnDirect;
+- bool strictSecurity;
+- uint32_t maxThreadWaitTime;
+- uint64_t schemaUpdateTime;
+- string directBase;
+- string topicBase;
+-
+- SchemaMap schemata;
+- DataIndex globalIndex;
+- map<SchemaId, DataIndex, SchemaIdCompareNoHash> schemaIndex;
+-
+- void checkOpen();
+- void setAgentName();
+- void enqueueEvent(const AgentEvent&);
+- void handleLocateRequest(const Variant::List& content, const Message& msg);
+- void handleMethodRequest(const Variant::Map& content, const Message& msg);
+- void handleQueryRequest(const Variant::Map& content, const Message& msg);
+- void handleSchemaRequest(AgentEvent&);
+- void handleV1SchemaRequest(qpid::management::Buffer&, uint32_t, const Message&);
+- void dispatch(Message);
+- void sendHeartbeat();
+- void send(Message, const Address&);
+- void flushResponses(AgentEvent&, bool);
+- void periodicProcessing(uint64_t);
+- void run();
+- };
+-}
+-
+-typedef qmf::PrivateImplRef<AgentSession> PI;
++#include "qmf/AgentSessionImpl.h"
+
+ AgentSession::AgentSession(AgentSessionImpl* impl) { PI::ctor(*this, impl); }
+ AgentSession::AgentSession(const AgentSession& s) : qmf::Handle<AgentSessionImpl>() { PI::copy(*this, s); }
+@@ -345,6 +218,8 @@ bool AgentSessionImpl::nextEvent(AgentEvent& event, Duration timeout)
+ if (!eventQueue.empty()) {
+ event = eventQueue.front();
+ eventQueue.pop();
++ if (eventQueue.empty())
++ alertEventNotifierLH(false);
+ return true;
+ }
+
+@@ -359,6 +234,19 @@ int AgentSessionImpl::pendingEvents() const
+ }
+
+
++void AgentSessionImpl::setEventNotifier(EventNotifierImpl* notifier)
++{
++ qpid::sys::Mutex::ScopedLock l(lock);
++ eventNotifier = notifier;
++}
++
++EventNotifierImpl* AgentSessionImpl::getEventNotifier() const
++{
++ qpid::sys::Mutex::ScopedLock l(lock);
++ return eventNotifier;
++}
++
++
+ void AgentSessionImpl::registerSchema(Schema& schema)
+ {
+ if (!schema.isFinalized())
+@@ -614,8 +502,10 @@ void AgentSessionImpl::enqueueEvent(const AgentEvent& event)
+ qpid::sys::Mutex::ScopedLock l(lock);
+ bool notify = eventQueue.empty();
+ eventQueue.push(event);
+- if (notify)
++ if (notify) {
+ cond.notify();
++ alertEventNotifierLH(true);
++ }
+ }
+
+
+@@ -1059,6 +949,13 @@ void AgentSessionImpl::periodicProcessing(uint64_t seconds)
+ }
+
+
++void AgentSessionImpl::alertEventNotifierLH(bool readable)
++{
++ if (eventNotifier)
++ eventNotifier->setReadable(readable);
++}
++
++
+ void AgentSessionImpl::run()
+ {
+ QPID_LOG(debug, "AgentSession thread started for agent " << agentName);
+@@ -1089,3 +986,15 @@ void AgentSessionImpl::run()
+ QPID_LOG(debug, "AgentSession thread exiting for agent " << agentName);
+ }
+
++
++AgentSessionImpl& AgentSessionImplAccess::get(AgentSession& session)
++{
++ return *session.impl;
++}
++
++
++const AgentSessionImpl& AgentSessionImplAccess::get(const AgentSession& session)
++{
++ return *session.impl;
++}
++
+diff --git a/qpid/cpp/src/qmf/AgentSessionImpl.h b/qpid/cpp/src/qmf/AgentSessionImpl.h
+new file mode 100644
+index 0000000..cf1b1d7
+--- /dev/null
++++ b/qpid/cpp/src/qmf/AgentSessionImpl.h
+@@ -0,0 +1,175 @@
++#ifndef __QMF_AGENT_SESSION_IMPL_H
++#define __QMF_AGENT_SESSION_IMPL_H
++
++/*
++ *
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ *
++ */
++
++#include "qpid/RefCounted.h"
++#include "qmf/PrivateImplRef.h"
++#include "qmf/exceptions.h"
++#include "qmf/AgentSession.h"
++#include "qmf/AgentEventImpl.h"
++#include "qmf/EventNotifierImpl.h"
++#include "qpid/messaging/Connection.h"
++#include "qpid/sys/Runnable.h"
++#include "qpid/sys/Mutex.h"
++#include "qpid/sys/Condition.h"
++#include "qpid/sys/Thread.h"
++#include "qpid/sys/Runnable.h"
++#include "qpid/log/Statement.h"
++#include "qpid/messaging/Connection.h"
++#include "qpid/messaging/Session.h"
++#include "qpid/messaging/Receiver.h"
++#include "qpid/messaging/Sender.h"
++#include "qpid/messaging/Message.h"
++#include "qpid/messaging/AddressParser.h"
++#include "qpid/management/Buffer.h"
++#include "qpid/RefCounted.h"
++#include "qmf/PrivateImplRef.h"
++#include "qmf/AgentSession.h"
++#include "qmf/exceptions.h"
++#include "qmf/AgentSession.h"
++#include "qmf/SchemaIdImpl.h"
++#include "qmf/SchemaImpl.h"
++#include "qmf/DataAddrImpl.h"
++#include "qmf/DataImpl.h"
++#include "qmf/QueryImpl.h"
++#include "qmf/agentCapability.h"
++#include "qmf/constants.h"
++
++#include <queue>
++#include <map>
++#include <iostream>
++#include <memory>
++
++using namespace std;
++using namespace qpid::messaging;
++using namespace qmf;
++using qpid::types::Variant;
++using namespace boost;
++
++typedef qmf::PrivateImplRef<AgentSession> PI;
++
++namespace qmf {
++ class AgentSessionImpl : public virtual qpid::RefCounted, public qpid::sys::Runnable {
++ public:
++ ~AgentSessionImpl();
++
++ //
++ // Methods from API handle
++ //
++ AgentSessionImpl(Connection& c, const string& o);
++ void setDomain(const string& d) { checkOpen(); domain = d; }
++ void setVendor(const string& v) { checkOpen(); attributes["_vendor"] = v; }
++ void setProduct(const string& p) { checkOpen(); attributes["_product"] = p; }
++ void setInstance(const string& i) { checkOpen(); attributes["_instance"] = i; }
++ void setAttribute(const string& k, const qpid::types::Variant& v) { checkOpen(); attributes[k] = v; }
++ const string& getName() const { return agentName; }
++ void open();
++ void close();
++ bool nextEvent(AgentEvent& e, Duration t);
++ int pendingEvents() const;
++
++ void setEventNotifier(EventNotifierImpl* eventNotifier);
++ EventNotifierImpl* getEventNotifier() const;
++
++ void registerSchema(Schema& s);
++ DataAddr addData(Data& d, const string& n, bool persist);
++ void delData(const DataAddr&);
++
++ void authAccept(AgentEvent& e);
++ void authReject(AgentEvent& e, const string& m);
++ void raiseException(AgentEvent& e, const string& s);
++ void raiseException(AgentEvent& e, const Data& d);
++ void response(AgentEvent& e, const Data& d);
++ void complete(AgentEvent& e);
++ void methodSuccess(AgentEvent& e);
++ void raiseEvent(const Data& d);
++ void raiseEvent(const Data& d, int s);
++
++ private:
++ typedef map<DataAddr, Data, DataAddrCompare> DataIndex;
++ typedef map<SchemaId, Schema, SchemaIdCompare> SchemaMap;
++
++ mutable qpid::sys::Mutex lock;
++ qpid::sys::Condition cond;
++ Connection connection;
++ Session session;
++ Sender directSender;
++ Sender topicSender;
++ string domain;
++ Variant::Map attributes;
++ Variant::Map options;
++ string agentName;
++ bool opened;
++ queue<AgentEvent> eventQueue;
++ EventNotifierImpl* eventNotifier;
++ qpid::sys::Thread* thread;
++ bool threadCanceled;
++ uint32_t bootSequence;
++ uint32_t interval;
++ uint64_t lastHeartbeat;
++ uint64_t lastVisit;
++ bool forceHeartbeat;
++ bool externalStorage;
++ bool autoAllowQueries;
++ bool autoAllowMethods;
++ uint32_t maxSubscriptions;
++ uint32_t minSubInterval;
++ uint32_t subLifetime;
++ bool publicEvents;
++ bool listenOnDirect;
++ bool strictSecurity;
++ uint32_t maxThreadWaitTime;
++ uint64_t schemaUpdateTime;
++ string directBase;
++ string topicBase;
++
++ SchemaMap schemata;
++ DataIndex globalIndex;
++ map<SchemaId, DataIndex, SchemaIdCompareNoHash> schemaIndex;
++
++ void checkOpen();
++ void setAgentName();
++ void enqueueEvent(const AgentEvent&);
++ void alertEventNotifierLH(bool readable);
++ void handleLocateRequest(const Variant::List& content, const Message& msg);
++ void handleMethodRequest(const Variant::Map& content, const Message& msg);
++ void handleQueryRequest(const Variant::Map& content, const Message& msg);
++ void handleSchemaRequest(AgentEvent&);
++ void handleV1SchemaRequest(qpid::management::Buffer&, uint32_t, const Message&);
++ void dispatch(Message);
++ void sendHeartbeat();
++ void send(Message, const Address&);
++ void flushResponses(AgentEvent&, bool);
++ void periodicProcessing(uint64_t);
++ void run();
++ };
++
++ struct AgentSessionImplAccess {
++ static AgentSessionImpl& get(AgentSession& session);
++ static const AgentSessionImpl& get(const AgentSession& session);
++ };
++}
++
++
++#endif
++
+diff --git a/qpid/cpp/src/qmf/ConsoleSession.cpp b/qpid/cpp/src/qmf/ConsoleSession.cpp
+index af83595..d084b8a 100644
+--- a/qpid/cpp/src/qmf/ConsoleSession.cpp
++++ b/qpid/cpp/src/qmf/ConsoleSession.cpp
+@@ -237,6 +237,8 @@ bool ConsoleSessionImpl::nextEvent(ConsoleEvent& event, Duration timeout)
+ if (!eventQueue.empty()) {
+ event = eventQueue.front();
+ eventQueue.pop();
++ if (eventQueue.empty())
++ alertEventNotifierLH(false);
+ return true;
+ }
+
+@@ -251,6 +253,20 @@ int ConsoleSessionImpl::pendingEvents() const
+ }
+
+
++void ConsoleSessionImpl::setEventNotifier(EventNotifierImpl* notifier)
++{
++ qpid::sys::Mutex::ScopedLock l(lock);
++ this->eventNotifier = notifier;
++}
++
++
++EventNotifierImpl* ConsoleSessionImpl::getEventNotifier() const
++{
++ qpid::sys::Mutex::ScopedLock l(lock);
++ return this->eventNotifier;
++}
++
++
+ uint32_t ConsoleSessionImpl::getAgentCount() const
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+@@ -292,8 +308,10 @@ void ConsoleSessionImpl::enqueueEventLH(const ConsoleEvent& event)
+ {
+ bool notify = eventQueue.empty();
+ eventQueue.push(event);
+- if (notify)
++ if (notify) {
+ cond.notify();
++ alertEventNotifierLH(true);
++ }
+ }
+
+
+@@ -602,6 +620,13 @@ void ConsoleSessionImpl::periodicProcessing(uint64_t seconds)
+ }
+
+
++void ConsoleSessionImpl::alertEventNotifierLH(bool readable)
++{
++ if (eventNotifier)
++ eventNotifier->setReadable(readable);
++}
++
++
+ void ConsoleSessionImpl::run()
+ {
+ QPID_LOG(debug, "ConsoleSession thread started");
+@@ -633,3 +658,14 @@ void ConsoleSessionImpl::run()
+ QPID_LOG(debug, "ConsoleSession thread exiting");
+ }
+
++
++ConsoleSessionImpl& ConsoleSessionImplAccess::get(ConsoleSession& session)
++{
++ return *session.impl;
++}
++
++
++const ConsoleSessionImpl& ConsoleSessionImplAccess::get(const ConsoleSession& session)
++{
++ return *session.impl;
++}
+diff --git a/qpid/cpp/src/qmf/ConsoleSessionImpl.h b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+index 478d24e..660fc9b 100644
+--- a/qpid/cpp/src/qmf/ConsoleSessionImpl.h
++++ b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+@@ -27,6 +27,7 @@
+ #include "qmf/SchemaId.h"
+ #include "qmf/Schema.h"
+ #include "qmf/ConsoleEventImpl.h"
++#include "qmf/EventNotifierImpl.h"
+ #include "qmf/SchemaCache.h"
+ #include "qmf/Query.h"
+ #include "qpid/sys/Mutex.h"
+@@ -41,9 +42,14 @@
+ #include "qpid/messaging/Address.h"
+ #include "qpid/management/Buffer.h"
+ #include "qpid/types/Variant.h"
++
++#include <boost/shared_ptr.hpp>
+ #include <map>
+ #include <queue>
+
++using namespace boost;
++using namespace std;
++
+ namespace qmf {
+ class ConsoleSessionImpl : public virtual qpid::RefCounted, public qpid::sys::Runnable {
+ public:
+@@ -59,6 +65,10 @@ namespace qmf {
+ void close();
+ bool nextEvent(ConsoleEvent& e, qpid::messaging::Duration t);
+ int pendingEvents() const;
++
++ void setEventNotifier(EventNotifierImpl* notifier);
++ EventNotifierImpl* getEventNotifier() const;
++
+ uint32_t getAgentCount() const;
+ Agent getAgent(uint32_t i) const;
+ Agent getConnectedBrokerAgent() const { return connectedBrokerAgent; }
+@@ -80,6 +90,7 @@ namespace qmf {
+ Query agentQuery;
+ bool opened;
+ std::queue<ConsoleEvent> eventQueue;
++ EventNotifierImpl* eventNotifier;
+ qpid::sys::Thread* thread;
+ bool threadCanceled;
+ uint64_t lastVisit;
+@@ -102,11 +113,17 @@ namespace qmf {
+ void handleAgentUpdate(const std::string&, const qpid::types::Variant::Map&, const qpid::messaging::Message&);
+ void handleV1SchemaResponse(qpid::management::Buffer&, uint32_t, const qpid::messaging::Message&);
+ void periodicProcessing(uint64_t);
++ void alertEventNotifierLH(bool readable);
+ void run();
+ uint32_t correlator() { qpid::sys::Mutex::ScopedLock l(corrlock); return nextCorrelator++; }
+
+ friend class AgentImpl;
+ };
++
++ struct ConsoleSessionImplAccess {
++ static ConsoleSessionImpl& get(ConsoleSession& session);
++ static const ConsoleSessionImpl& get(const ConsoleSession& session);
++ };
+ }
+
+ #endif
+diff --git a/qpid/cpp/src/qmf/EventNotifierImpl.cpp b/qpid/cpp/src/qmf/EventNotifierImpl.cpp
+new file mode 100644
+index 0000000..20114aa
+--- /dev/null
++++ b/qpid/cpp/src/qmf/EventNotifierImpl.cpp
+@@ -0,0 +1,56 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++
++#include "qmf/EventNotifierImpl.h"
++#include "qmf/AgentSessionImpl.h"
++#include "qmf/ConsoleSessionImpl.h"
++
++EventNotifierImpl::EventNotifierImpl(AgentSession& agentSession)
++ : readable(false), agent(agentSession)
++{
++ AgentSessionImplAccess::get(agent).setEventNotifier(this);
++}
++
++
++EventNotifierImpl::EventNotifierImpl(ConsoleSession& consoleSession)
++ : readable(false), console(consoleSession)
++{
++ ConsoleSessionImplAccess::get(console).setEventNotifier(this);
++}
++
++
++EventNotifierImpl::~EventNotifierImpl()
++{
++ if (agent.isValid())
++ AgentSessionImplAccess::get(agent).setEventNotifier(NULL);
++ if (console.isValid())
++ ConsoleSessionImplAccess::get(console).setEventNotifier(NULL);
++}
++
++void EventNotifierImpl::setReadable(bool readable)
++{
++ update(readable);
++ this->readable = readable;
++}
++
++
++bool EventNotifierImpl::isReadable() const
++{
++ return this->readable;
++}
+diff --git a/qpid/cpp/src/qmf/EventNotifierImpl.h b/qpid/cpp/src/qmf/EventNotifierImpl.h
+new file mode 100644
+index 0000000..d85f997
+--- /dev/null
++++ b/qpid/cpp/src/qmf/EventNotifierImpl.h
+@@ -0,0 +1,48 @@
++#ifndef __QMF_EVENT_NOTIFIER_IMPL_H
++#define __QMF_EVENT_NOTIFIER_IMPL_H
++
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++
++#include "qmf/AgentSession.h"
++#include "qmf/ConsoleSession.h"
++
++namespace qmf
++{
++ class EventNotifierImpl {
++ private:
++ bool readable;
++ AgentSession agent;
++ ConsoleSession console;
++
++ public:
++ EventNotifierImpl(AgentSession& agentSession);
++ EventNotifierImpl(ConsoleSession& consoleSession);
++ virtual ~EventNotifierImpl();
++
++ void setReadable(bool readable);
++ bool isReadable() const;
++
++ protected:
++ virtual void update(bool readable) = 0;
++ };
++}
++
++#endif
++
+diff --git a/qpid/cpp/src/qmf/PosixEventNotifier.cpp b/qpid/cpp/src/qmf/PosixEventNotifier.cpp
+new file mode 100644
+index 0000000..b5c7121
+--- /dev/null
++++ b/qpid/cpp/src/qmf/PosixEventNotifier.cpp
+@@ -0,0 +1,63 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++
++#include "qmf/posix/EventNotifier.h"
++#include "qmf/PosixEventNotifierImpl.h"
++#include "qmf/PrivateImplRef.h"
++
++using namespace qmf;
++using namespace std;
++
++typedef qmf::PrivateImplRef<posix::EventNotifier> PI;
++
++posix::EventNotifier::EventNotifier(AgentSession& agentSession)
++{
++ PI::ctor(*this, new PosixEventNotifierImpl(agentSession));
++}
++
++
++posix::EventNotifier::EventNotifier(ConsoleSession& consoleSession)
++{
++ PI::ctor(*this, new PosixEventNotifierImpl(consoleSession));
++}
++
++
++posix::EventNotifier::EventNotifier(const posix::EventNotifier& that)
++ : Handle<PosixEventNotifierImpl>()
++{
++ PI::copy(*this, that);
++}
++
++
++posix::EventNotifier::~EventNotifier()
++{
++ PI::dtor(*this);
++}
++
++posix::EventNotifier& posix::EventNotifier::operator=(const posix::EventNotifier& that)
++{
++ return PI::assign(*this, that);
++}
++
++
++int posix::EventNotifier::getHandle() const
++{
++ return impl->getHandle();
++}
++
+diff --git a/qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp b/qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp
+new file mode 100644
+index 0000000..abc9cad
+--- /dev/null
++++ b/qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp
+@@ -0,0 +1,108 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++
++#include "PosixEventNotifierImpl.h"
++
++#include <fcntl.h>
++#include <unistd.h>
++
++#define BUFFER_SIZE 10
++
++using namespace qmf;
++
++PosixEventNotifierImpl::PosixEventNotifierImpl(AgentSession& agentSession)
++ : EventNotifierImpl(agentSession)
++{
++ openHandle();
++}
++
++
++PosixEventNotifierImpl::PosixEventNotifierImpl(ConsoleSession& consoleSession)
++ : EventNotifierImpl(consoleSession)
++{
++ openHandle();
++}
++
++
++PosixEventNotifierImpl::~PosixEventNotifierImpl()
++{
++ closeHandle();
++}
++
++
++void PosixEventNotifierImpl::update(bool readable)
++{
++ char buffer[BUFFER_SIZE];
++
++ if(readable && !this->isReadable()) {
++ (void) ::write(myHandle, "1", 1);
++ }
++ else if(!readable && this->isReadable()) {
++ (void) ::read(yourHandle, buffer, BUFFER_SIZE);
++ }
++}
++
++
++void PosixEventNotifierImpl::openHandle()
++{
++ int pair[2];
++
++ if(::pipe(pair) == -1)
++ throw QmfException("Unable to open event notifier handle.");
++
++ yourHandle = pair[0];
++ myHandle = pair[1];
++
++ int flags;
++
++ flags = ::fcntl(yourHandle, F_GETFL);
++ if((::fcntl(yourHandle, F_SETFL, flags | O_NONBLOCK)) == -1)
++ throw QmfException("Unable to make remote handle non-blocking.");
++
++ flags = ::fcntl(myHandle, F_GETFL);
++ if((::fcntl(myHandle, F_SETFL, flags | O_NONBLOCK)) == -1)
++ throw QmfException("Unable to make local handle non-blocking.");
++}
++
++
++void PosixEventNotifierImpl::closeHandle()
++{
++ if(myHandle > 0) {
++ ::close(myHandle);
++ myHandle = -1;
++ }
++
++ if(yourHandle > 0) {
++ ::close(yourHandle);
++ yourHandle = -1;
++ }
++}
++
++
++PosixEventNotifierImpl& PosixEventNotifierImplAccess::get(posix::EventNotifier& notifier)
++{
++ return *notifier.impl;
++}
++
++
++const PosixEventNotifierImpl& PosixEventNotifierImplAccess::get(const posix::EventNotifier& notifier)
++{
++ return *notifier.impl;
++}
++
+diff --git a/qpid/cpp/src/qmf/PosixEventNotifierImpl.h b/qpid/cpp/src/qmf/PosixEventNotifierImpl.h
+new file mode 100644
+index 0000000..c8a7446
+--- /dev/null
++++ b/qpid/cpp/src/qmf/PosixEventNotifierImpl.h
+@@ -0,0 +1,61 @@
++#ifndef __QMF_POSIX_EVENT_NOTIFIER_IMPL_H
++#define __QMF_POSIX_EVENT_NOTIFIER_IMPL_H
++
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++
++#include "qmf/posix/EventNotifier.h"
++#include "qmf/EventNotifierImpl.h"
++#include "qpid/RefCounted.h"
++
++namespace qmf
++{
++ class AgentSession;
++ class ConsoleSession;
++
++ class PosixEventNotifierImpl : public EventNotifierImpl, public virtual qpid::RefCounted
++ {
++ public:
++ PosixEventNotifierImpl(AgentSession& agentSession);
++ PosixEventNotifierImpl(ConsoleSession& consoleSession);
++ virtual ~PosixEventNotifierImpl();
++
++ int getHandle() const { return yourHandle; }
++
++ private:
++ int myHandle;
++ int yourHandle;
++
++ void openHandle();
++ void closeHandle();
++
++ protected:
++ void update(bool readable);
++ };
++
++ struct PosixEventNotifierImplAccess
++ {
++ static PosixEventNotifierImpl& get(posix::EventNotifier& notifier);
++ static const PosixEventNotifierImpl& get(const posix::EventNotifier& notifier);
++ };
++
++}
++
++#endif
++
+diff --git a/qpid/cpp/src/tests/Qmf2.cpp b/qpid/cpp/src/tests/Qmf2.cpp
+index 66c774a..bc263d5 100644
+--- a/qpid/cpp/src/tests/Qmf2.cpp
++++ b/qpid/cpp/src/tests/Qmf2.cpp
+@@ -23,12 +23,36 @@
+ #include "qmf/QueryImpl.h"
+ #include "qmf/SchemaImpl.h"
+ #include "qmf/exceptions.h"
+-
++#include "qpid/messaging/Connection.h"
++#include "qmf/PosixEventNotifierImpl.h"
++#include "qmf/AgentSession.h"
++#include "qmf/AgentSessionImpl.h"
++#include "qmf/ConsoleSession.h"
++#include "qmf/ConsoleSessionImpl.h"
+ #include "unit_test.h"
+
++using namespace std;
+ using namespace qpid::types;
++using namespace qpid::messaging;
+ using namespace qmf;
+
++bool isReadable(int fd)
++{
++ fd_set rfds;
++ struct timeval tv;
++ int nfds, result;
++
++ FD_ZERO(&rfds);
++ FD_SET(fd, &rfds);
++ nfds = fd + 1;
++ tv.tv_sec = 0;
++ tv.tv_usec = 0;
++
++ result = select(nfds, &rfds, NULL, NULL, &tv);
++
++ return result > 0;
++}
++
+ namespace qpid {
+ namespace tests {
+
+@@ -315,6 +339,84 @@ QPID_AUTO_TEST_CASE(testSchema)
+ BOOST_CHECK_THROW(method.getArgument(3), QmfException);
+ }
+
++QPID_AUTO_TEST_CASE(testAgentSessionEventListener)
++{
++ Connection connection("localhost");
++ AgentSession session(connection, "");
++ posix::EventNotifier notifier(session);
++
++ AgentSessionImpl& sessionImpl = AgentSessionImplAccess::get(session);
++
++ BOOST_CHECK(sessionImpl.getEventNotifier() != 0);
++}
++
++QPID_AUTO_TEST_CASE(testConsoleSessionEventListener)
++{
++ Connection connection("localhost");
++ ConsoleSession session(connection, "");
++ posix::EventNotifier notifier(session);
++
++ ConsoleSessionImpl& sessionImpl = ConsoleSessionImplAccess::get(session);
++
++ BOOST_CHECK(sessionImpl.getEventNotifier() != 0);
++}
++
++QPID_AUTO_TEST_CASE(testGetHandle)
++{
++ Connection connection("localhost");
++ ConsoleSession session(connection, "");
++ posix::EventNotifier notifier(session);
++
++ BOOST_CHECK(notifier.getHandle() > 0);
++}
++
++QPID_AUTO_TEST_CASE(testSetReadableToFalse)
++{
++ Connection connection("localhost");
++ ConsoleSession session(connection, "");
++ posix::EventNotifier notifier(session);
++ PosixEventNotifierImplAccess::get(notifier).setReadable(false);
++
++ bool readable(isReadable(notifier.getHandle()));
++ BOOST_CHECK(!readable);
++}
++
++QPID_AUTO_TEST_CASE(testSetReadable)
++{
++ Connection connection("localhost");
++ ConsoleSession session(connection, "");
++ posix::EventNotifier notifier(session);
++ PosixEventNotifierImplAccess::get(notifier).setReadable(true);
++
++ bool readable(isReadable(notifier.getHandle()));
++ BOOST_CHECK(readable);
++}
++
++QPID_AUTO_TEST_CASE(testSetReadableMultiple)
++{
++ Connection connection("localhost");
++ ConsoleSession session(connection, "");
++ posix::EventNotifier notifier(session);
++ for (int i = 0; i < 15; i++)
++ PosixEventNotifierImplAccess::get(notifier).setReadable(true);
++ PosixEventNotifierImplAccess::get(notifier).setReadable(false);
++
++ bool readable(isReadable(notifier.getHandle()));
++ BOOST_CHECK(!readable);
++}
++
++QPID_AUTO_TEST_CASE(testDeleteNotifier)
++{
++ Connection connection("localhost");
++ ConsoleSession session(connection, "");
++ ConsoleSessionImpl& sessionImpl = ConsoleSessionImplAccess::get(session);
++ {
++ posix::EventNotifier notifier(session);
++ BOOST_CHECK(sessionImpl.getEventNotifier() != 0);
++ }
++ BOOST_CHECK(sessionImpl.getEventNotifier() == 0);
++}
++
+ QPID_AUTO_TEST_SUITE_END()
+
+ }} // namespace qpid::tests
+--
+1.7.4.4
+
+From 0918bc94f925d413d8021a855cf566f6a55c654c Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at apache.org>
+Date: Wed, 14 Sep 2011 21:41:11 +0000
+Subject: [PATCH 09/14] QPID-3484 - Fixed handling of unused return values to
+ prevent compiler warnings.
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1170860 13f79535-47bb-0310-9956-ffa450edef68
+---
+ qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp | 8 ++++++--
+ 1 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp b/qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp
+index abc9cad..011dbcc 100644
+--- a/qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp
++++ b/qpid/cpp/src/qmf/PosixEventNotifierImpl.cpp
+@@ -18,9 +18,11 @@
+ */
+
+ #include "PosixEventNotifierImpl.h"
++#include "qpid/log/Statement.h"
+
+ #include <fcntl.h>
+ #include <unistd.h>
++#include <errno.h>
+
+ #define BUFFER_SIZE 10
+
+@@ -51,10 +53,12 @@ void PosixEventNotifierImpl::update(bool readable)
+ char buffer[BUFFER_SIZE];
+
+ if(readable && !this->isReadable()) {
+- (void) ::write(myHandle, "1", 1);
++ if (::write(myHandle, "1", 1) == -1)
++ QPID_LOG(error, "PosixEventNotifierImpl::update write failed: " << errno);
+ }
+ else if(!readable && this->isReadable()) {
+- (void) ::read(yourHandle, buffer, BUFFER_SIZE);
++ if (::read(yourHandle, buffer, BUFFER_SIZE) == -1)
++ QPID_LOG(error, "PosixEventNotifierImpl::update read failed: " << errno);
+ }
+ }
+
+--
+1.7.4.4
+
+From c1fe836092355bf45c7118517e49d9307a12c7c8 Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at apache.org>
+Date: Fri, 16 Sep 2011 14:34:39 +0000
+Subject: [PATCH 10/14] QPID-3484 - Added missing constructor for
+ EventNotifier, fixed initialization bug.
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1171592 13f79535-47bb-0310-9956-ffa450edef68
+---
+ qpid/cpp/include/qmf/posix/EventNotifier.h | 1 +
+ qpid/cpp/src/qmf/AgentSession.cpp | 16 ++++++++++++++--
+ qpid/cpp/src/qmf/AgentSessionImpl.h | 1 +
+ qpid/cpp/src/qmf/ConsoleSession.cpp | 20 ++++++++++++++++----
+ qpid/cpp/src/qmf/ConsoleSessionImpl.h | 1 +
+ qpid/cpp/src/qmf/PosixEventNotifier.cpp | 2 ++
+ 6 files changed, 35 insertions(+), 6 deletions(-)
+
+diff --git a/qpid/cpp/include/qmf/posix/EventNotifier.h b/qpid/cpp/include/qmf/posix/EventNotifier.h
+index 91817cc..ebc1cb5 100644
+--- a/qpid/cpp/include/qmf/posix/EventNotifier.h
++++ b/qpid/cpp/include/qmf/posix/EventNotifier.h
+@@ -38,6 +38,7 @@ namespace posix {
+
+ class QMF_CLASS_EXTERN EventNotifier : public qmf::Handle<qmf::PosixEventNotifierImpl> {
+ public:
++ QMF_EXTERN EventNotifier(PosixEventNotifierImpl* impl = 0);
+ QMF_EXTERN EventNotifier(::qmf::AgentSession& agentSession);
+ QMF_EXTERN EventNotifier(::qmf::ConsoleSession& consoleSession);
+ QMF_EXTERN EventNotifier(const EventNotifier& that);
+diff --git a/qpid/cpp/src/qmf/AgentSession.cpp b/qpid/cpp/src/qmf/AgentSession.cpp
+index d92b2a4..251c25f 100644
+--- a/qpid/cpp/src/qmf/AgentSession.cpp
++++ b/qpid/cpp/src/qmf/AgentSession.cpp
+@@ -55,7 +55,7 @@ void AgentSession::raiseEvent(const Data& d, int s) { impl->raiseEvent(d, s); }
+ //========================================================================================
+
+ AgentSessionImpl::AgentSessionImpl(Connection& c, const string& options) :
+- connection(c), domain("default"), opened(false), thread(0), threadCanceled(false),
++ connection(c), domain("default"), opened(false), eventNotifier(0), thread(0), threadCanceled(false),
+ bootSequence(1), interval(60), lastHeartbeat(0), lastVisit(0), forceHeartbeat(false),
+ externalStorage(false), autoAllowQueries(true), autoAllowMethods(true),
+ maxSubscriptions(64), minSubInterval(3000), subLifetime(300), publicEvents(true),
+@@ -191,7 +191,7 @@ void AgentSessionImpl::open()
+ }
+
+
+-void AgentSessionImpl::close()
++void AgentSessionImpl::closeAsync()
+ {
+ if (!opened)
+ return;
+@@ -202,6 +202,18 @@ void AgentSessionImpl::close()
+ }
+
+
++void AgentSessionImpl::close()
++{
++ closeAsync();
++
++ if (thread) {
++ thread->join();
++ delete thread;
++ thread = 0;
++ }
++}
++
++
+ bool AgentSessionImpl::nextEvent(AgentEvent& event, Duration timeout)
+ {
+ uint64_t milliseconds = timeout.getMilliseconds();
+diff --git a/qpid/cpp/src/qmf/AgentSessionImpl.h b/qpid/cpp/src/qmf/AgentSessionImpl.h
+index cf1b1d7..9039a59 100644
+--- a/qpid/cpp/src/qmf/AgentSessionImpl.h
++++ b/qpid/cpp/src/qmf/AgentSessionImpl.h
+@@ -84,6 +84,7 @@ namespace qmf {
+ void setAttribute(const string& k, const qpid::types::Variant& v) { checkOpen(); attributes[k] = v; }
+ const string& getName() const { return agentName; }
+ void open();
++ void closeAsync();
+ void close();
+ bool nextEvent(AgentEvent& e, Duration t);
+ int pendingEvents() const;
+diff --git a/qpid/cpp/src/qmf/ConsoleSession.cpp b/qpid/cpp/src/qmf/ConsoleSession.cpp
+index d084b8a..2dfc894 100644
+--- a/qpid/cpp/src/qmf/ConsoleSession.cpp
++++ b/qpid/cpp/src/qmf/ConsoleSession.cpp
+@@ -67,7 +67,7 @@ Subscription ConsoleSession::subscribe(const string& q, const string& f, const s
+
+ ConsoleSessionImpl::ConsoleSessionImpl(Connection& c, const string& options) :
+ connection(c), domain("default"), maxAgentAgeMinutes(5), listenOnDirect(true), strictSecurity(false), maxThreadWaitTime(5),
+- opened(false), thread(0), threadCanceled(false), lastVisit(0), lastAgePass(0),
++ opened(false), eventNotifier(0), thread(0), threadCanceled(false), lastVisit(0), lastAgePass(0),
+ connectedBrokerInAgentList(false), schemaCache(new SchemaCache()), nextCorrelator(1)
+ {
+ if (!options.empty()) {
+@@ -210,7 +210,7 @@ void ConsoleSessionImpl::open()
+ }
+
+
+-void ConsoleSessionImpl::close()
++void ConsoleSessionImpl::closeAsync()
+ {
+ if (!opened)
+ throw QmfException("The session is already closed");
+@@ -221,6 +221,18 @@ void ConsoleSessionImpl::close()
+ }
+
+
++void ConsoleSessionImpl::close()
++{
++ closeAsync();
++
++ if (thread) {
++ thread->join();
++ delete thread;
++ thread = 0;
++ }
++}
++
++
+ bool ConsoleSessionImpl::nextEvent(ConsoleEvent& event, Duration timeout)
+ {
+ uint64_t milliseconds = timeout.getMilliseconds();
+@@ -256,14 +268,14 @@ int ConsoleSessionImpl::pendingEvents() const
+ void ConsoleSessionImpl::setEventNotifier(EventNotifierImpl* notifier)
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+- this->eventNotifier = notifier;
++ eventNotifier = notifier;
+ }
+
+
+ EventNotifierImpl* ConsoleSessionImpl::getEventNotifier() const
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+- return this->eventNotifier;
++ return eventNotifier;
+ }
+
+
+diff --git a/qpid/cpp/src/qmf/ConsoleSessionImpl.h b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+index 660fc9b..2f1f631 100644
+--- a/qpid/cpp/src/qmf/ConsoleSessionImpl.h
++++ b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+@@ -62,6 +62,7 @@ namespace qmf {
+ void setDomain(const std::string& d) { domain = d; }
+ void setAgentFilter(const std::string& f);
+ void open();
++ void closeAsync();
+ void close();
+ bool nextEvent(ConsoleEvent& e, qpid::messaging::Duration t);
+ int pendingEvents() const;
+diff --git a/qpid/cpp/src/qmf/PosixEventNotifier.cpp b/qpid/cpp/src/qmf/PosixEventNotifier.cpp
+index b5c7121..a364cc1 100644
+--- a/qpid/cpp/src/qmf/PosixEventNotifier.cpp
++++ b/qpid/cpp/src/qmf/PosixEventNotifier.cpp
+@@ -26,6 +26,8 @@ using namespace std;
+
+ typedef qmf::PrivateImplRef<posix::EventNotifier> PI;
+
++posix::EventNotifier::EventNotifier(PosixEventNotifierImpl* impl) { PI::ctor(*this, impl); }
++
+ posix::EventNotifier::EventNotifier(AgentSession& agentSession)
+ {
+ PI::ctor(*this, new PosixEventNotifierImpl(agentSession));
+--
+1.7.4.4
+
+From e5dda70d9a87b570a7386071762860d9a5eae107 Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at redhat.com>
+Date: Wed, 14 Sep 2011 14:59:18 -0400
+Subject: [PATCH 11/14] unused-result.patch
+
+---
+ qpid/cpp/src/qmf/engine/ResilientConnection.cpp | 4 ++--
+ qpid/cpp/src/qpid/broker/Daemon.cpp | 10 +++++-----
+ qpid/cpp/src/qpid/sys/posix/LockFile.cpp | 2 +-
+ qpid/cpp/src/tests/BrokerMgmtAgent.cpp | 2 +-
+ qpid/cpp/src/tests/ForkedBroker.cpp | 2 +-
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/qpid/cpp/src/qmf/engine/ResilientConnection.cpp b/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
+index 41dd9ff..851193c 100644
+--- a/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
++++ b/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
+@@ -334,7 +334,7 @@ void ResilientConnectionImpl::notify()
+ {
+ if (notifyFd != -1)
+ {
+- (void) ::write(notifyFd, ".", 1);
++ if (::write(notifyFd, ".", 1)) {}
+ }
+ }
+
+@@ -431,7 +431,7 @@ void ResilientConnectionImpl::EnqueueEvent(ResilientConnectionEvent::EventKind k
+
+ if (notifyFd != -1)
+ {
+- (void) ::write(notifyFd, ".", 1);
++ if (::write(notifyFd, ".", 1)) {}
+ }
+ }
+
+diff --git a/qpid/cpp/src/qpid/broker/Daemon.cpp b/qpid/cpp/src/qpid/broker/Daemon.cpp
+index c36538b..281345b 100644
+--- a/qpid/cpp/src/qpid/broker/Daemon.cpp
++++ b/qpid/cpp/src/qpid/broker/Daemon.cpp
+@@ -93,13 +93,13 @@ void Daemon::fork()
+ catch (const exception& e) {
+ QPID_LOG(critical, "Unexpected error: " << e.what());
+ uint16_t port = 0;
+- (void) write(pipeFds[1], &port, sizeof(uint16_t));
++ if (write(pipeFds[1], &port, sizeof(uint16_t))) {};
+
+ std::string pipeFailureMessage = e.what();
+- (void) write ( pipeFds[1],
+- pipeFailureMessage.c_str(),
+- strlen(pipeFailureMessage.c_str())
+- );
++ if (write(pipeFds[1],
++ pipeFailureMessage.c_str(),
++ strlen(pipeFailureMessage.c_str())
++ )) {};
+ }
+ }
+ else { // Parent
+diff --git a/qpid/cpp/src/qpid/sys/posix/LockFile.cpp b/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
+index f5a6c29..c1f1c37 100755
+--- a/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
++++ b/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
+@@ -58,7 +58,7 @@ LockFile::~LockFile() {
+ if (impl) {
+ int f = impl->fd;
+ if (f >= 0) {
+- (void) ::lockf(f, F_ULOCK, 0); // Suppress warnings about ignoring return value.
++ if(::lockf(f, F_ULOCK, 0)) {} // Suppress warnings about ignoring return value.
+ ::close(f);
+ impl->fd = -1;
+ }
+diff --git a/qpid/cpp/src/tests/BrokerMgmtAgent.cpp b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
+index 1d5289d..02aa87f 100644
+--- a/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
++++ b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
+@@ -604,7 +604,7 @@ namespace qpid {
+ std::stringstream key;
+ key << "testobj-" << i;
+ TestManageable *tm = new TestManageable(agent, key.str());
+- (void) tm->GetManagementObject()->writePropertiesSize();
++ if (tm->GetManagementObject()->writePropertiesSize()) {}
+ agent->addObject(tm->GetManagementObject(), key.str());
+ tmv.push_back(tm);
+ }
+diff --git a/qpid/cpp/src/tests/ForkedBroker.cpp b/qpid/cpp/src/tests/ForkedBroker.cpp
+index 10674b5..de1b42d 100644
+--- a/qpid/cpp/src/tests/ForkedBroker.cpp
++++ b/qpid/cpp/src/tests/ForkedBroker.cpp
+@@ -68,7 +68,7 @@ ForkedBroker::~ForkedBroker() {
+ }
+ if (!dataDir.empty())
+ {
+- (void) ::system(("rm -rf "+dataDir).c_str());
++ if(::system(("rm -rf "+dataDir).c_str())) {}
+ }
+ }
+
+--
+1.7.4.4
+
+From caec0216a72bf1c6bd8094b03337f0181f5ba07d Mon Sep 17 00:00:00 2001
+From: Ted Ross <tross at redhat.com>
+Date: Tue, 20 Sep 2011 11:09:10 -0400
+Subject: [PATCH 12/14] In CMake build, only build the posix event notifier
+ (qmf2) for linux, not Windows.
+
+---
+ qpid/cpp/src/CMakeLists.txt | 16 +++++++++++++---
+ 1 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/qpid/cpp/src/CMakeLists.txt b/qpid/cpp/src/CMakeLists.txt
+index 2986a90..0be42b8 100644
+--- a/qpid/cpp/src/CMakeLists.txt
++++ b/qpid/cpp/src/CMakeLists.txt
+@@ -1093,7 +1093,6 @@ install_pdb (qmf ${QPID_COMPONENT_QMF})
+ ../include/qmf/exceptions.h
+ ../include/qmf/Handle.h
+ ../include/qmf/ImportExport.h
+- ../include/qmf/posix/EventNotifier.h
+ ../include/qmf/Query.h
+ ../include/qmf/Schema.h
+ ../include/qmf/SchemaId.h
+@@ -1125,8 +1124,6 @@ install_pdb (qmf ${QPID_COMPONENT_QMF})
+ qmf/DataImpl.h
+ qmf/EventNotifierImpl.h
+ qmf/EventNotifierImpl.cpp
+- qmf/PosixEventNotifier.cpp
+- qmf/PosixEventNotifierImpl.cpp
+ qmf/exceptions.cpp
+ qmf/Expression.cpp
+ qmf/Expression.h
+@@ -1149,6 +1146,19 @@ install_pdb (qmf ${QPID_COMPONENT_QMF})
+ qmf/SubscriptionImpl.h
+ )
+
++if(NOT WIN32)
++ set (qmf2_HEADERS
++ ${qmf2_HEADERS}
++ ../include/qmf/posix/EventNotifier.h
++ )
++
++ set (qmf2_SOURCES
++ ${qmf2_SOURCES}
++ qmf/PosixEventNotifier.cpp
++ qmf/PosixEventNotifierImpl.cpp
++ )
++endif (NOT WIN32)
++
+ add_msvc_version (qmf2 library dll)
+ add_library (qmf2 SHARED ${qmf2_SOURCES})
+ target_link_libraries (qmf2 qpidmessaging qpidtypes qpidclient qpidcommon)
+--
+1.7.4.4
+
+From 258294f134d42cf131e2bcbcb5d77482664efece Mon Sep 17 00:00:00 2001
+From: Nuno Santos <nsantos at apache.org>
+Date: Thu, 8 Sep 2011 20:45:33 +0000
+Subject: [PATCH 13/14] QPID-3437: qpid-config address option confusing in
+ help
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1166897 13f79535-47bb-0310-9956-ffa450edef68
+(cherry picked from commit 3ee5b3a8b77426987bff6b65f147b27a99b027c3)
+---
+ qpid/tools/src/py/qpid-config | 7 +------
+ 1 files changed, 1 insertions(+), 6 deletions(-)
+
+diff --git a/qpid/tools/src/py/qpid-config b/qpid/tools/src/py/qpid-config
+index b6eb055..4ed1ea7 100755
+--- a/qpid/tools/src/py/qpid-config
++++ b/qpid/tools/src/py/qpid-config
+@@ -39,11 +39,6 @@ Usage: qpid-config [OPTIONS]
+ qpid-config [OPTIONS] unbind <exchange-name> <queue-name> [binding-key]"""
+
+ description = """
+-ADDRESS syntax:
+-
+- [username/password@] hostname [:<port>]
+- [username/password@] ip-address [:<port>]
+-
+ Examples:
+
+ $ qpid-config add queue q
+@@ -159,7 +154,7 @@ def OptionsAndArguments(argv):
+ group1 = OptionGroup(parser, "General Options")
+ group1.add_option("-t", "--timeout", action="store", type="int", default=10, metavar="<secs>", help="Maximum time to wait for broker connection (in seconds)")
+ group1.add_option("-b", "--bindings", action="store_true", help="Show bindings in queue or exchange list")
+- group1.add_option("-a", "--broker-addr", action="store", type="string", default="localhost:5672", metavar="<address>", help="Address of qpidd broker")
++ group1.add_option("-a", "--broker-addr", action="store", type="string", default="localhost:5672", metavar="<address>", help="Address of qpidd broker with syntax: [username/password@] hostname | ip-address [:<port>]")
+ group1.add_option("--sasl-mechanism", action="store", type="string", metavar="<mech>", help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD, DIGEST-MD5, GSSAPI). SASL automatically picks the most secure available mechanism - use this option to override.")
+ parser.add_option_group(group1)
+
+--
+1.7.4.4
+
+From 0b178e6d01d6a3c67fa55086394cf53132909cce Mon Sep 17 00:00:00 2001
+From: Nuno Santos <nsantos at apache.org>
+Date: Thu, 8 Sep 2011 20:27:49 +0000
+Subject: [PATCH 14/14] make 'qpid-config queues/exchanges
+ <queue/exchange_name>' return proper error code, for
+ scripting purposes
+
+git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1166888 13f79535-47bb-0310-9956-ffa450edef68
+(cherry picked from commit 7d5bce20c5ca6bc3869cbe2f6a73f1968c7a5abb)
+---
+ qpid/tools/src/py/qpid-config | 18 ++++++++++++++++--
+ 1 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/qpid/tools/src/py/qpid-config b/qpid/tools/src/py/qpid-config
+index 4ed1ea7..4af3c84 100755
+--- a/qpid/tools/src/py/qpid-config
++++ b/qpid/tools/src/py/qpid-config
+@@ -97,6 +97,7 @@ class Config:
+ self._flowStopSize = None
+ self._flowResumeSize = None
+ self._extra_arguments = []
++ self._returnCode = 0
+
+ config = Config()
+
+@@ -354,9 +355,16 @@ class BrokerManager:
+ caption1 = "Type "
+ caption2 = "Exchange Name"
+ maxNameLen = len(caption2)
++ found = False
+ for ex in exchanges:
+ if self.match(ex.name, filter):
+ if len(ex.name) > maxNameLen: maxNameLen = len(ex.name)
++ found = True
++ if not found:
++ global config
++ config._returnCode = 1
++ return
++
+ print "%s%-*s Attributes" % (caption1, maxNameLen, caption2)
+ line = ""
+ for i in range(((maxNameLen + len(caption1)) / 5) + 5):
+@@ -393,12 +401,18 @@ class BrokerManager:
+
+ def QueueList(self, filter):
+ queues = self.qmf.getObjects(_class="queue", _agent=self.brokerAgent)
+-
+ caption = "Queue Name"
+ maxNameLen = len(caption)
++ found = False
+ for q in queues:
+ if self.match(q.name, filter):
+ if len(q.name) > maxNameLen: maxNameLen = len(q.name)
++ found = True
++ if not found:
++ global config
++ config._returnCode = 1
++ return
++
+ print "%-*s Attributes" % (maxNameLen, caption)
+ line = ""
+ for i in range((maxNameLen / 5) + 5):
+@@ -670,7 +684,7 @@ def main(argv=None):
+ print "Failed: %s: %s" % (e.__class__.__name__, e)
+ return 1
+
+- return 0
++ return config._returnCode
+
+ if __name__ == "__main__":
+ sys.exit(main())
+--
+1.7.4.4
+
diff --git a/mingw32-qpid-cpp.spec b/mingw32-qpid-cpp.spec
index daed286..ba71015 100644
--- a/mingw32-qpid-cpp.spec
+++ b/mingw32-qpid-cpp.spec
@@ -6,20 +6,17 @@
%define __debug_install_post %{_mingw32_debug_install_post}
Name: mingw32-qpid-cpp
-Version: 0.10
-Release: 1.3%{?dist}
+Version: 0.12
+Release: 1.1%{?dist}
Summary: MinGW Windows port of AMQP C++ Daemons and Libraries
Group: Development/Libraries
License: ASL 2.0
URL: http://qpid.apache.org
-Source0: http://www.apache.org/dist/qpid/0.10/qpid-0.10.tar.gz
+Source0: http://www.apache.org/dist/qpid/0.12/qpid-0.12.tar.gz
-Patch0: QPID-3159.patch
-Patch1: qpid-mingw32.patch
-Patch2: qpid-mutable.patch
-Patch3: qpid-gcc46.patch
+Patch0: fedora.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -40,9 +37,6 @@ an AMQP message broker using the AMQP protocol.
%prep
%setup -q -n qpid-%{version}
%patch0 -p2
-%patch1 -p2
-%patch2 -p1
-%patch3 -p2
%build
%{__mkdir_p} build
@@ -51,7 +45,7 @@ pushd build
-DBUILD_MSCLFS:BOOL=OFF \
-DBUILD_MSSQL:BOOL=OFF \
-DBUILD_SSL:BOOL=OFF \
-%if "%{?dist}" == ".fc16"
+%if "%{?dist}" == ".fc17"
-DBoost_COMPILER:STRING=-gcc46 ../cpp
%else
-DBoost_COMPILER:STRING=-gcc45 ../cpp
@@ -90,6 +84,9 @@ rm -rf $RPM_BUILD_ROOT
%doc cpp/RELEASE_NOTES
%changelog
+* Thu Sep 22 2011 Ted Ross <tross at apache.org> - 0.12-1.1
+- Rebased to Qpid 0.12
+
* Wed Jul 5 2011 Ted Ross <tross at apache.org> - 0.10-1.3
- Same patch-set, rebuilt to refresh boost dependencies.
diff --git a/sources b/sources
index ae7c138..2b465fc 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-75f7e1076fddc08baaee386f9af61897 qpid-0.10.tar.gz
+19eb7a39985aef1574ec2244a22204a4 qpid-0.12.tar.gz
More information about the scm-commits
mailing list