summaryrefslogtreecommitdiff
path: root/qpid/cpp/src
diff options
context:
space:
mode:
authorStephen D. Huston <shuston@apache.org>2009-03-25 23:44:30 +0000
committerStephen D. Huston <shuston@apache.org>2009-03-25 23:44:30 +0000
commit67d330f235362bf622b95f8c4d14321272a44ba7 (patch)
tree82153e6fd6c1c77e9defc80cb2e6b34d23de25cf /qpid/cpp/src
parentb51fd45a4ed81bee144c22c2a57fc0e882d44149 (diff)
downloadqpid-python-67d330f235362bf622b95f8c4d14321272a44ba7.tar.gz
Merge from trunk tag to-cmake-25mar09 (r758432)
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/cmake@758465 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
-rw-r--r--qpid/cpp/src/Makefile.am18
-rw-r--r--qpid/cpp/src/acl.mk4
-rw-r--r--qpid/cpp/src/broker.vcproj89
-rw-r--r--qpid/cpp/src/client.vcproj104
-rw-r--r--qpid/cpp/src/cluster.mk11
-rw-r--r--qpid/cpp/src/common.vcproj107
-rw-r--r--qpid/cpp/src/qmfc.mk2
-rw-r--r--qpid/cpp/src/qmfconsole.vcproj98
-rw-r--r--qpid/cpp/src/qpid.sln16
-rwxr-xr-xqpid/cpp/src/qpid/Address.h6
-rw-r--r--qpid/cpp/src/qpid/CommonImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/DataDir.h5
-rw-r--r--qpid/cpp/src/qpid/Exception.h16
-rw-r--r--qpid/cpp/src/qpid/Modules.h7
-rw-r--r--qpid/cpp/src/qpid/Options.h26
-rw-r--r--qpid/cpp/src/qpid/Plugin.h19
-rw-r--r--qpid/cpp/src/qpid/SessionId.cpp2
-rw-r--r--qpid/cpp/src/qpid/SessionId.h11
-rw-r--r--qpid/cpp/src/qpid/SessionState.cpp14
-rw-r--r--qpid/cpp/src/qpid/SessionState.h76
-rw-r--r--qpid/cpp/src/qpid/StringUtils.h6
-rw-r--r--qpid/cpp/src/qpid/Url.h17
-rwxr-xr-xqpid/cpp/src/qpid/Version.h2
-rw-r--r--qpid/cpp/src/qpid/acl/AclPlugin.cpp13
-rw-r--r--qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp8
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/Connection.h5
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp1
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h55
-rw-r--r--qpid/cpp/src/qpid/assert.cpp2
-rw-r--r--qpid/cpp/src/qpid/broker/Bridge.cpp50
-rw-r--r--qpid/cpp/src/qpid/broker/Bridge.h5
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.cpp5
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.h18
-rw-r--r--qpid/cpp/src/qpid/broker/BrokerImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/broker/BrokerSingleton.h3
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.cpp14
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.h7
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionHandler.cpp56
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionHandler.h12
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionState.h22
-rw-r--r--qpid/cpp/src/qpid/broker/Daemon.h4
-rw-r--r--qpid/cpp/src/qpid/broker/DeliverableMessage.h9
-rw-r--r--qpid/cpp/src/qpid/broker/DeliveryRecord.h20
-rw-r--r--qpid/cpp/src/qpid/broker/DirectExchange.h24
-rw-r--r--qpid/cpp/src/qpid/broker/DtxBuffer.h7
-rw-r--r--qpid/cpp/src/qpid/broker/DtxWorkRecord.h14
-rw-r--r--qpid/cpp/src/qpid/broker/Exchange.cpp8
-rw-r--r--qpid/cpp/src/qpid/broker/Exchange.h12
-rw-r--r--qpid/cpp/src/qpid/broker/ExchangeRegistry.h17
-rw-r--r--qpid/cpp/src/qpid/broker/ExpiryPolicy.h7
-rw-r--r--qpid/cpp/src/qpid/broker/FanOutExchange.h25
-rw-r--r--qpid/cpp/src/qpid/broker/HeadersExchange.cpp45
-rw-r--r--qpid/cpp/src/qpid/broker/HeadersExchange.h27
-rw-r--r--qpid/cpp/src/qpid/broker/IncompleteMessageList.h9
-rw-r--r--qpid/cpp/src/qpid/broker/Link.cpp43
-rw-r--r--qpid/cpp/src/qpid/broker/Link.h1
-rw-r--r--qpid/cpp/src/qpid/broker/LinkRegistry.cpp63
-rw-r--r--qpid/cpp/src/qpid/broker/LinkRegistry.h2
-rw-r--r--qpid/cpp/src/qpid/broker/Message.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/Message.h24
-rw-r--r--qpid/cpp/src/qpid/broker/MessageBuilder.h8
-rw-r--r--qpid/cpp/src/qpid/broker/NullMessageStore.h79
-rw-r--r--qpid/cpp/src/qpid/broker/PersistableMessage.h19
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.cpp48
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.h58
-rw-r--r--qpid/cpp/src/qpid/broker/QueueCleaner.h5
-rw-r--r--qpid/cpp/src/qpid/broker/QueueEvents.cpp19
-rw-r--r--qpid/cpp/src/qpid/broker/QueueEvents.h21
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.cpp28
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.h26
-rw-r--r--qpid/cpp/src/qpid/broker/QueueRegistry.cpp10
-rw-r--r--qpid/cpp/src/qpid/broker/QueueRegistry.h23
-rw-r--r--qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp3
-rw-r--r--qpid/cpp/src/qpid/broker/RetryList.h7
-rw-r--r--qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp28
-rw-r--r--qpid/cpp/src/qpid/broker/SemanticState.cpp22
-rw-r--r--qpid/cpp/src/qpid/broker/SessionAdapter.cpp4
-rw-r--r--qpid/cpp/src/qpid/broker/SessionHandler.cpp25
-rw-r--r--qpid/cpp/src/qpid/broker/SessionHandler.h23
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.cpp30
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.h13
-rw-r--r--qpid/cpp/src/qpid/broker/Timer.h11
-rw-r--r--qpid/cpp/src/qpid/broker/TopicExchange.h30
-rw-r--r--qpid/cpp/src/qpid/broker/TxAccept.cpp4
-rw-r--r--qpid/cpp/src/qpid/broker/TxBuffer.h11
-rw-r--r--qpid/cpp/src/qpid/broker/TxPublish.h13
-rw-r--r--qpid/cpp/src/qpid/client/ClientImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/client/Connection.h27
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionHandler.cpp7
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionImpl.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionSettings.h7
-rw-r--r--qpid/cpp/src/qpid/client/Connector.cpp51
-rw-r--r--qpid/cpp/src/qpid/client/Dispatcher.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/FailoverManager.cpp11
-rw-r--r--qpid/cpp/src/qpid/client/FailoverManager.h11
-rw-r--r--qpid/cpp/src/qpid/client/Future.h7
-rw-r--r--qpid/cpp/src/qpid/client/FutureResult.h4
-rw-r--r--qpid/cpp/src/qpid/client/Handle.h20
-rw-r--r--qpid/cpp/src/qpid/client/LocalQueue.h15
-rw-r--r--qpid/cpp/src/qpid/client/Message.h19
-rw-r--r--qpid/cpp/src/qpid/client/MessageListener.h3
-rw-r--r--qpid/cpp/src/qpid/client/MessageReplayTracker.h16
-rw-r--r--qpid/cpp/src/qpid/client/QueueOptions.h46
-rw-r--r--qpid/cpp/src/qpid/client/SessionBase_0_10.h31
-rw-r--r--qpid/cpp/src/qpid/client/SessionImpl.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/SslConnector.cpp2
-rw-r--r--qpid/cpp/src/qpid/client/Subscription.h41
-rw-r--r--qpid/cpp/src/qpid/client/SubscriptionImpl.h37
-rw-r--r--qpid/cpp/src/qpid/client/SubscriptionManager.h49
-rw-r--r--qpid/cpp/src/qpid/client/windows/SaslFactory.cpp139
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.cpp235
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.h123
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp1
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterSettings.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.cpp67
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.h26
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp15
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionCodec.h4
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp57
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionMap.cpp96
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionMap.h88
-rw-r--r--qpid/cpp/src/qpid/cluster/Cpg.cpp39
-rw-r--r--qpid/cpp/src/qpid/cluster/Cpg.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/Decoder.cpp47
-rw-r--r--qpid/cpp/src/qpid/cluster/Decoder.h32
-rw-r--r--qpid/cpp/src/qpid/cluster/Event.cpp31
-rw-r--r--qpid/cpp/src/qpid/cluster/Event.h19
-rw-r--r--qpid/cpp/src/qpid/cluster/EventFrame.cpp10
-rw-r--r--qpid/cpp/src/qpid/cluster/EventFrame.h15
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp50
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.h24
-rw-r--r--qpid/cpp/src/qpid/cluster/LockedConnectionMap.h (renamed from qpid/cpp/src/qpid/cluster/ConnectionDecoder.h)53
-rw-r--r--qpid/cpp/src/qpid/cluster/McastFrameHandler.h (renamed from qpid/cpp/src/qpid/sys/posix/PollableCondition.h)40
-rw-r--r--qpid/cpp/src/qpid/cluster/Multicaster.cpp6
-rw-r--r--qpid/cpp/src/qpid/cluster/Multicaster.h1
-rw-r--r--qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp11
-rw-r--r--qpid/cpp/src/qpid/cluster/PollableQueue.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.cpp93
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.h11
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateExchange.h45
-rw-r--r--qpid/cpp/src/qpid/cluster/types.h11
-rw-r--r--qpid/cpp/src/qpid/console/Agent.h5
-rw-r--r--qpid/cpp/src/qpid/console/Broker.h12
-rw-r--r--qpid/cpp/src/qpid/console/ClassKey.cpp1
-rw-r--r--qpid/cpp/src/qpid/console/ClassKey.h5
-rw-r--r--qpid/cpp/src/qpid/console/ConsoleImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/console/ConsoleListener.h3
-rw-r--r--qpid/cpp/src/qpid/console/Event.h33
-rw-r--r--qpid/cpp/src/qpid/console/Object.h64
-rw-r--r--qpid/cpp/src/qpid/console/ObjectId.h5
-rw-r--r--qpid/cpp/src/qpid/console/Package.h1
-rw-r--r--qpid/cpp/src/qpid/console/SequenceManager.h5
-rw-r--r--qpid/cpp/src/qpid/console/SessionManager.h32
-rw-r--r--qpid/cpp/src/qpid/framing/AMQBody.h5
-rw-r--r--qpid/cpp/src/qpid/framing/AMQContentBody.h23
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.cpp2
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.h25
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeaderBody.h13
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h5
-rw-r--r--qpid/cpp/src/qpid/framing/AMQMethodBody.h4
-rw-r--r--qpid/cpp/src/qpid/framing/AccumulatedAck.h17
-rw-r--r--qpid/cpp/src/qpid/framing/Array.h51
-rw-r--r--qpid/cpp/src/qpid/framing/Buffer.h91
-rw-r--r--qpid/cpp/src/qpid/framing/FieldTable.h67
-rw-r--r--qpid/cpp/src/qpid/framing/FieldValue.h27
-rw-r--r--qpid/cpp/src/qpid/framing/FrameDecoder.cpp12
-rw-r--r--qpid/cpp/src/qpid/framing/FrameDecoder.h9
-rw-r--r--qpid/cpp/src/qpid/framing/FrameSet.h19
-rw-r--r--qpid/cpp/src/qpid/framing/ProtocolInitiation.h15
-rw-r--r--qpid/cpp/src/qpid/framing/ProtocolVersion.h17
-rw-r--r--qpid/cpp/src/qpid/framing/Proxy.h18
-rw-r--r--qpid/cpp/src/qpid/framing/SendContent.h5
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceNumber.h27
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceNumberSet.h7
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceSet.h17
-rw-r--r--qpid/cpp/src/qpid/framing/StructHelper.h1
-rw-r--r--qpid/cpp/src/qpid/framing/TransferContent.h27
-rw-r--r--qpid/cpp/src/qpid/framing/Uuid.h14
-rw-r--r--qpid/cpp/src/qpid/log/Logger.h31
-rw-r--r--qpid/cpp/src/qpid/log/Options.h7
-rw-r--r--qpid/cpp/src/qpid/log/OstreamOutput.h4
-rw-r--r--qpid/cpp/src/qpid/log/Selector.cpp1
-rw-r--r--qpid/cpp/src/qpid/log/Selector.h7
-rw-r--r--qpid/cpp/src/qpid/log/Statement.h6
-rw-r--r--qpid/cpp/src/qpid/log/posix/SinkOptions.cpp6
-rw-r--r--qpid/cpp/src/qpid/log/windows/SinkOptions.h8
-rw-r--r--qpid/cpp/src/qpid/management/Manageable.h3
-rw-r--r--qpid/cpp/src/qpid/management/ManagementBroker.cpp12
-rw-r--r--qpid/cpp/src/qpid/management/ManagementBroker.h1
-rw-r--r--qpid/cpp/src/qpid/management/ManagementObject.h31
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp77
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicatingEventListener.h7
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicationExchange.cpp45
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicationExchange.h2
-rw-r--r--qpid/cpp/src/qpid/sys/AggregateOutput.h15
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIO.h12
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp12
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIOHandler.h27
-rw-r--r--qpid/cpp/src/qpid/sys/Codec.h4
-rw-r--r--qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h2
-rw-r--r--qpid/cpp/src/qpid/sys/CopyOnWriteArray.h2
-rw-r--r--qpid/cpp/src/qpid/sys/DispatchHandle.cpp129
-rw-r--r--qpid/cpp/src/qpid/sys/DispatchHandle.h29
-rw-r--r--qpid/cpp/src/qpid/sys/Dispatcher.h7
-rw-r--r--qpid/cpp/src/qpid/sys/IOHandle.h6
-rw-r--r--qpid/cpp/src/qpid/sys/PollableCondition.h55
-rw-r--r--qpid/cpp/src/qpid/sys/PollableQueue.h48
-rw-r--r--qpid/cpp/src/qpid/sys/Poller.h33
-rw-r--r--qpid/cpp/src/qpid/sys/Runnable.h3
-rw-r--r--qpid/cpp/src/qpid/sys/Shlib.h11
-rw-r--r--qpid/cpp/src/qpid/sys/Socket.h26
-rw-r--r--qpid/cpp/src/qpid/sys/StrError.h3
-rw-r--r--qpid/cpp/src/qpid/sys/SystemInfo.h18
-rw-r--r--qpid/cpp/src/qpid/sys/Thread.h15
-rw-r--r--qpid/cpp/src/qpid/sys/Time.h24
-rw-r--r--qpid/cpp/src/qpid/sys/Timer.h28
-rw-r--r--qpid/cpp/src/qpid/sys/alloca.h39
-rw-r--r--qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp111
-rw-r--r--qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp4
-rw-r--r--qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp119
-rw-r--r--qpid/cpp/src/qpid/sys/posix/Socket.cpp43
-rwxr-xr-xqpid/cpp/src/qpid/sys/posix/SystemInfo.cpp24
-rw-r--r--qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp244
-rwxr-xr-xqpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp123
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslIo.cpp2
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp4
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.h2
-rw-r--r--qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp22
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/IntegerTypes.h2
-rw-r--r--qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp125
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/Socket.cpp4
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/SystemInfo.cpp38
-rw-r--r--qpid/cpp/src/qpid/sys/windows/uuid.h13
-rw-r--r--qpid/cpp/src/qpid/xml/XmlExchange.cpp128
-rw-r--r--qpid/cpp/src/qpid/xml/XmlExchange.h5
-rw-r--r--qpid/cpp/src/replication.mk6
-rw-r--r--qpid/cpp/src/tests/ClientSessionTest.cpp22
-rw-r--r--qpid/cpp/src/tests/ClusterFixture.cpp2
-rw-r--r--qpid/cpp/src/tests/DispatcherTest.cpp79
-rw-r--r--qpid/cpp/src/tests/FieldTable.cpp2
-rw-r--r--qpid/cpp/src/tests/ForkedBroker.cpp7
-rw-r--r--qpid/cpp/src/tests/FrameDecoder.cpp73
-rw-r--r--qpid/cpp/src/tests/Makefile.am16
-rw-r--r--qpid/cpp/src/tests/MessageTest.cpp5
-rw-r--r--qpid/cpp/src/tests/MessageUtils.h2
-rw-r--r--qpid/cpp/src/tests/PollerTest.cpp2
-rw-r--r--qpid/cpp/src/tests/ProxyTest.cpp1
-rw-r--r--qpid/cpp/src/tests/QueueEvents.cpp7
-rw-r--r--qpid/cpp/src/tests/QueuePolicyTest.cpp9
-rw-r--r--qpid/cpp/src/tests/ReplicationTest.cpp129
-rw-r--r--qpid/cpp/src/tests/SocketProxy.h2
-rw-r--r--qpid/cpp/src/tests/TimerTest.cpp4
-rw-r--r--qpid/cpp/src/tests/Uuid.cpp2
-rw-r--r--qpid/cpp/src/tests/client_test.vcproj34
-rw-r--r--qpid/cpp/src/tests/cluster.mk5
-rw-r--r--qpid/cpp/src/tests/cluster_test.cpp191
-rwxr-xr-xqpid/cpp/src/tests/clustered_replication_test127
-rw-r--r--qpid/cpp/src/tests/consume.vcproj34
-rw-r--r--qpid/cpp/src/tests/echotest.vcproj34
-rw-r--r--qpid/cpp/src/tests/failover_soak.cpp338
-rwxr-xr-xqpid/cpp/src/tests/federated_cluster_test47
-rwxr-xr-xqpid/cpp/src/tests/federated_cluster_test_with_node_failure23
-rw-r--r--qpid/cpp/src/tests/header_test.vcproj34
-rw-r--r--qpid/cpp/src/tests/latencytest.vcproj34
-rw-r--r--qpid/cpp/src/tests/logging.cpp16
-rw-r--r--qpid/cpp/src/tests/perftest.cpp13
-rw-r--r--qpid/cpp/src/tests/perftest.vcproj34
-rw-r--r--qpid/cpp/src/tests/publish.vcproj34
-rw-r--r--qpid/cpp/src/tests/receiver.cpp18
-rw-r--r--qpid/cpp/src/tests/receiver.vcproj34
-rw-r--r--qpid/cpp/src/tests/replaying_sender.cpp4
-rwxr-xr-xqpid/cpp/src/tests/replication_test40
-rw-r--r--qpid/cpp/src/tests/resuming_receiver.cpp19
-rwxr-xr-xqpid/cpp/src/tests/run_failover_soak12
-rwxr-xr-xqpid/cpp/src/tests/run_header_test3
-rw-r--r--qpid/cpp/src/tests/sender.cpp28
-rw-r--r--qpid/cpp/src/tests/sender.vcproj34
-rw-r--r--qpid/cpp/src/tests/shlibtest.vcproj91
-rwxr-xr-xqpid/cpp/src/tests/ssl_test3
-rwxr-xr-xqpid/cpp/src/tests/start_cluster3
-rw-r--r--qpid/cpp/src/tests/tests.sln290
-rw-r--r--qpid/cpp/src/tests/topic_listener.cpp3
-rw-r--r--qpid/cpp/src/tests/topic_listener.vcproj34
-rw-r--r--qpid/cpp/src/tests/topic_publisher.vcproj34
-rw-r--r--qpid/cpp/src/tests/txjob.vcproj34
-rw-r--r--qpid/cpp/src/tests/txshift.cpp5
-rw-r--r--qpid/cpp/src/tests/txshift.vcproj34
-rw-r--r--qpid/cpp/src/tests/txtest.vcproj34
-rw-r--r--qpid/cpp/src/tests/unit_test.h9
-rw-r--r--qpid/cpp/src/tests/unit_test.vcproj112
290 files changed, 5564 insertions, 2983 deletions
diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am
index d5b53dc502..7de05645fa 100644
--- a/qpid/cpp/src/Makefile.am
+++ b/qpid/cpp/src/Makefile.am
@@ -29,6 +29,7 @@ windows_dist = \
client.vcproj \
qmfconsole.vcproj \
protocol_gen.mak \
+ qpid/client/windows/SaslFactory.cpp \
qpid/log/windows/SinkOptions.cpp \
qpid/log/windows/SinkOptions.h \
qpid/sys/windows/check.h \
@@ -41,6 +42,7 @@ windows_dist = \
qpid/sys/windows/IOHandle.cpp \
qpid/sys/windows/IoHandlePrivate.h \
qpid/sys/windows/LockFile.cpp \
+ qpid/sys/windows/PollableCondition.cpp \
qpid/sys/windows/Mutex.h \
qpid/sys/windows/Shlib.cpp \
qpid/sys/windows/Socket.cpp \
@@ -126,7 +128,6 @@ posix_plat_src = \
qpid/sys/posix/Time.cpp \
qpid/sys/posix/Thread.cpp \
qpid/sys/posix/Shlib.cpp \
- qpid/sys/posix/SystemInfo.cpp \
qpid/sys/posix/Mutex.cpp \
qpid/sys/posix/Fork.cpp \
qpid/sys/posix/StrError.cpp \
@@ -139,7 +140,6 @@ posix_plat_hdr = \
qpid/sys/posix/PrivatePosix.h \
qpid/sys/posix/Mutex.h \
qpid/sys/posix/Fork.h \
- qpid/sys/posix/PollableCondition.h \
qpid/sys/posix/IntegerTypes.h \
qpid/sys/posix/Time.h
@@ -151,7 +151,13 @@ if HAVE_ECF
poller = qpid/sys/solaris/ECFPoller.cpp
endif
-platform_src = $(posix_plat_src) $(poller)
+if SUNOS
+ systeminfo = qpid/sys/solaris/SystemInfo.cpp
+else
+ systeminfo = qpid/sys/posix/SystemInfo.cpp
+endif
+
+platform_src = $(posix_plat_src) $(poller) $(systeminfo)
platform_hdr = $(posix_plat_hdr)
posix_broker_src = \
@@ -495,6 +501,7 @@ nobase_include_HEADERS = \
qpid/broker/Queue.h \
qpid/broker/QueueListeners.h \
qpid/broker/QueueCleaner.h \
+ qpid/broker/BrokerImportExport.h \
qpid/broker/BrokerSingleton.h \
qpid/broker/Bridge.h \
qpid/broker/Connection.h \
@@ -571,6 +578,7 @@ nobase_include_HEADERS = \
qpid/client/AckMode.h \
qpid/client/Bounds.h \
qpid/client/ChainableFrameHandler.h \
+ qpid/client/ClientImportExport.h \
qpid/client/Completion.h \
qpid/client/Connection.h \
qpid/client/ConnectionHandler.h \
@@ -666,6 +674,7 @@ nobase_include_HEADERS = \
qpid/management/ManagementEvent.h \
qpid/management/ManagementExchange.h \
qpid/management/ManagementObject.h \
+ qpid/sys/alloca.h \
qpid/sys/AggregateOutput.h \
qpid/sys/AsynchIO.h \
qpid/sys/AsynchIOHandler.h \
@@ -715,7 +724,8 @@ nobase_include_HEADERS = \
qpid/sys/Time.h \
qpid/sys/Timer.h \
qpid/sys/TimeoutHandler.h \
- qpid/sys/uuid.h
+ qpid/sys/uuid.h \
+ qpid/CommonImportExport.h
# Force build of qpidd during dist phase so help2man will work.
dist-hook: $(BUILT_SOURCES)
diff --git a/qpid/cpp/src/acl.mk b/qpid/cpp/src/acl.mk
index 2b3ab4dfd9..95b47acc1c 100644
--- a/qpid/cpp/src/acl.mk
+++ b/qpid/cpp/src/acl.mk
@@ -31,4 +31,8 @@ acl_la_SOURCES = \
qpid/acl/AclReader.h
acl_la_LIBADD = libqpidbroker.la
+if SUNOS
+ acl_la_LIBADD += libqmfagent.la libqmfconsole.la libqpidcommon.la -lboost_program_options $(SUNCC_RUNTIME_LIBS)
+endif
+
acl_la_LDFLAGS = $(PLUGINLDFLAGS)
diff --git a/qpid/cpp/src/broker.vcproj b/qpid/cpp/src/broker.vcproj
index 7a7bf337a8..e4911e0bfc 100644
--- a/qpid/cpp/src/broker.vcproj
+++ b/qpid/cpp/src/broker.vcproj
@@ -42,9 +42,9 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\broker\I386"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\broker\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="BROKER_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -97,13 +97,14 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommond.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbrokerd.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
+ ImportLibrary=".\qpidbrokerd.lib"
TargetMachine="1"
/>
<Tool
@@ -120,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbrokerd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbrokerd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\broker\I386"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Release\broker\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -155,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="BROKER_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -167,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -176,15 +178,16 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommon.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbroker.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidbroker.lib"
TargetMachine="1"
/>
<Tool
@@ -201,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbroker.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbroker.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\broker\AMD64"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\broker\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -236,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="BROKER_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -251,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -261,13 +265,14 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommond.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbrokerd.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
+ ImportLibrary=".\qpidbrokerd.lib"
TargetMachine="17"
/>
<Tool
@@ -284,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbrokerd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbrokerd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\broker\AMD64"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Release\broker\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -319,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="BROKER_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -331,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -341,15 +347,16 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommon.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbroker.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidbroker.lib"
TargetMachine="17"
/>
<Tool
@@ -366,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbroker.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbroker.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -909,12 +917,6 @@
<File
RelativePath="qpid\sys\TCPIOPlugin.cpp">
</File>
- <File
- RelativePath="qpidd.cpp">
- </File>
- <File
- RelativePath="windows\QpiddBroker.cpp">
- </File>
</Filter>
<Filter
Name="Header Files"
@@ -1306,9 +1308,6 @@
<File
RelativePath="qpid\management\ManagementObject.h">
</File>
- <File
- RelativePath="qpidd.h">
- </File>
</Filter>
</Files>
<Globals>
diff --git a/qpid/cpp/src/client.vcproj b/qpid/cpp/src/client.vcproj
index e724e04d98..28b7ec73dc 100644
--- a/qpid/cpp/src/client.vcproj
+++ b/qpid/cpp/src/client.vcproj
@@ -43,8 +43,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\client\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\client\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CLIENT_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclientsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib"
+ OutputFile="$(OutDir)\qpidclientd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidclientd.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclientd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclientd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\client\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\client\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CLIENT_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclients.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib"
+ OutputFile="$(OutDir)\qpidclient.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidclient.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclient.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclient.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\client\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\client\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CLIENT_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclientsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib"
+ OutputFile="$(OutDir)\qpidclientd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidclientd.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclientd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclientd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\client\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\client\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CLIENT_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclients.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib"
+ OutputFile="$(OutDir)\qpidclient.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidclient.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclient.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclient.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -414,9 +456,6 @@
RelativePath="qpid\client\Results.cpp">
</File>
<File
- RelativePath="qpid\client\SaslFactory.cpp">
- </File>
- <File
RelativePath="qpid\client\SessionBase_0_10.cpp">
</File>
<File
@@ -440,6 +479,9 @@
<File
RelativePath="qpid\client\SubscriptionManager.cpp">
</File>
+ <File
+ RelativePath="qpid\client\windows\SaslFactory.cpp">
+ </File>
</Filter>
<Filter
Name="Header Files"
diff --git a/qpid/cpp/src/cluster.mk b/qpid/cpp/src/cluster.mk
index 0d34788d2e..e2054d75e9 100644
--- a/qpid/cpp/src/cluster.mk
+++ b/qpid/cpp/src/cluster.mk
@@ -40,6 +40,8 @@ cluster_la_SOURCES = \
$(CMAN_SOURCES) \
qpid/cluster/Cluster.cpp \
qpid/cluster/Cluster.h \
+ qpid/cluster/Decoder.cpp \
+ qpid/cluster/Decoder.h \
qpid/cluster/PollableQueue.h \
qpid/cluster/ClusterMap.cpp \
qpid/cluster/ClusterMap.h \
@@ -49,14 +51,8 @@ cluster_la_SOURCES = \
qpid/cluster/Connection.h \
qpid/cluster/ConnectionCodec.cpp \
qpid/cluster/ConnectionCodec.h \
- qpid/cluster/ConnectionMap.h \
- qpid/cluster/ConnectionMap.cpp \
qpid/cluster/Cpg.cpp \
qpid/cluster/Cpg.h \
- qpid/cluster/Decoder.cpp \
- qpid/cluster/Decoder.h \
- qpid/cluster/ConnectionDecoder.cpp \
- qpid/cluster/ConnectionDecoder.h \
qpid/cluster/Dispatchable.h \
qpid/cluster/UpdateClient.cpp \
qpid/cluster/UpdateClient.h \
@@ -68,8 +64,11 @@ cluster_la_SOURCES = \
qpid/cluster/ExpiryPolicy.cpp \
qpid/cluster/FailoverExchange.cpp \
qpid/cluster/FailoverExchange.h \
+ qpid/cluster/UpdateExchange.h \
+ qpid/cluster/LockedConnectionMap.h \
qpid/cluster/Multicaster.cpp \
qpid/cluster/Multicaster.h \
+ qpid/cluster/McastFrameHandler.h \
qpid/cluster/NoOpConnectionOutputHandler.h \
qpid/cluster/OutputInterceptor.cpp \
qpid/cluster/OutputInterceptor.h \
diff --git a/qpid/cpp/src/common.vcproj b/qpid/cpp/src/common.vcproj
index e8c40da426..96d67b9d54 100644
--- a/qpid/cpp/src/common.vcproj
+++ b/qpid/cpp/src/common.vcproj
@@ -43,8 +43,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\common\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\common\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="COMMON_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommonsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommond.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidcommond.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommond.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommond.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\common\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\common\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="COMMON_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommons.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommon.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidcommon.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommon.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommon.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\common\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\common\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="COMMON_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommonsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommond.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidcommond.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommond.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommond.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\common\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\common\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="COMMON_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommons.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommon.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidcommon.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommon.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommon.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -378,6 +420,9 @@
RelativePath="gen\qpid\framing\ClusterConnectionExchangeBody.cpp">
</File>
<File
+ RelativePath="gen\qpid\framing\ClusterConnectionExpiryIdBody.cpp">
+ </File>
+ <File
RelativePath="gen\qpid\framing\ClusterConnectionMembershipBody.cpp">
</File>
<File
@@ -954,6 +999,9 @@
RelativePath="qpid\sys\windows\LockFile.cpp">
</File>
<File
+ RelativePath="qpid\sys\windows\PollableCondition.cpp">
+ </File>
+ <File
RelativePath="qpid\sys\windows\Shlib.cpp">
<FileConfiguration
Name="Debug|Win32">
@@ -1081,6 +1129,9 @@
RelativePath="gen\qpid\framing\ClusterConnectionExchangeBody.h">
</File>
<File
+ RelativePath="gen\qpid\framing\ClusterConnectionExpiryIdBody.h">
+ </File>
+ <File
RelativePath="gen\qpid\framing\ClusterConnectionMembershipBody.h">
</File>
<File
diff --git a/qpid/cpp/src/qmfc.mk b/qpid/cpp/src/qmfc.mk
index 46e8d82f35..a95028413d 100644
--- a/qpid/cpp/src/qmfc.mk
+++ b/qpid/cpp/src/qmfc.mk
@@ -26,6 +26,7 @@ module_hdr += \
qpid/console/Agent.h \
qpid/console/Broker.h \
qpid/console/ClassKey.h \
+ qpid/console/ConsoleImportExport.h \
qpid/console/ConsoleListener.h \
qpid/console/Event.h \
qpid/console/Object.h \
@@ -43,6 +44,7 @@ libqmfconsole_la_SOURCES = \
qpid/console/Broker.cpp \
qpid/console/ClassKey.h \
qpid/console/ClassKey.cpp \
+ qpid/console/ConsoleImportExport.h \
qpid/console/ConsoleListener.h \
qpid/console/Event.h \
qpid/console/Event.cpp \
diff --git a/qpid/cpp/src/qmfconsole.vcproj b/qpid/cpp/src/qmfconsole.vcproj
index c37055adec..d2f79af64b 100644
--- a/qpid/cpp/src/qmfconsole.vcproj
+++ b/qpid/cpp/src/qmfconsole.vcproj
@@ -43,8 +43,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\qmfconsole\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\qmfconsole\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CONSOLE_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsolesd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\qmfconsoled.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qmfconsoled.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsoled.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsoled.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\qmfconsole\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\qmfconsole\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CONSOLE_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsoles.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\qmfconsole.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qmfconsole.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsole.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsole.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\qmfconsole\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\qmfconsole\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CONSOLE_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsolesd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\qmfconsoled.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qmfconsoled.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsoled.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsoled.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\qmfconsole\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\qmfconsole\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CONSOLE_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsoles.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\qmfconsole.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qmfconsole.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsole.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsole.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
diff --git a/qpid/cpp/src/qpid.sln b/qpid/cpp/src/qpid.sln
index a296a13d25..c7004444f9 100644
--- a/qpid/cpp/src/qpid.sln
+++ b/qpid/cpp/src/qpid.sln
@@ -7,7 +7,7 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# this file will be lost the next time it is generated.
#
# MPC Command:
-# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 -static qpid.mwc
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 qpid.mwc
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "broker", "broker.vcproj", "{09613D48-FECA-1BAD-9D20-8C374564ADCF}"
ProjectSection(ProjectDependencies) = postProject
{C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF} = {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF}
@@ -25,6 +25,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmfconsole", "qmfconsole.vc
{6961DBA3-FECA-1BAD-F396-8C394564ADCF} = {6961DBA3-FECA-1BAD-F396-8C394564ADCF}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qpidbroker", "qpidbroker.vcproj", "{66213D3E-FECA-1BAD-9D20-8C374564ADCF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {09613D48-FECA-1BAD-9D20-8C374564ADCF} = {09613D48-FECA-1BAD-9D20-8C374564ADCF}
+ {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF} = {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -65,6 +71,14 @@ Global
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|Win32.Build.0 = Release|Win32
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|x64.ActiveCfg = Release|x64
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|x64.Build.0 = Release|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|Win32.Build.0 = Debug|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|x64.ActiveCfg = Debug|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|x64.Build.0 = Debug|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|Win32.ActiveCfg = Release|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|Win32.Build.0 = Release|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|x64.ActiveCfg = Release|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/qpid/cpp/src/qpid/Address.h b/qpid/cpp/src/qpid/Address.h
index 9669985165..a5a4345ba3 100755
--- a/qpid/cpp/src/qpid/Address.h
+++ b/qpid/cpp/src/qpid/Address.h
@@ -20,7 +20,7 @@
*/
#include "qpid/sys/IntegerTypes.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/variant.hpp>
#include <iosfwd>
#include <string>
@@ -31,12 +31,12 @@ namespace qpid {
/** TCP address of a broker - host:port */
struct TcpAddress {
static const uint16_t DEFAULT_PORT=5672;
- explicit TcpAddress(const std::string& host_=std::string(),uint16_t port_=DEFAULT_PORT);
+ QPID_COMMON_EXTERN explicit TcpAddress(const std::string& host_=std::string(),uint16_t port_=DEFAULT_PORT);
std::string host;
uint16_t port;
};
bool operator==(const TcpAddress& x, const TcpAddress& y);
-std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
/**@internal Not a real address type, this is a placeholder to
* demonstrate and validate multi-protocol Urls for unit tests and
diff --git a/qpid/cpp/src/qpid/CommonImportExport.h b/qpid/cpp/src/qpid/CommonImportExport.h
new file mode 100644
index 0000000000..47872646d9
--- /dev/null
+++ b/qpid/cpp/src/qpid/CommonImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_COMMON_IMPORT_EXPORT_H
+#define QPID_COMMON_IMPORT_EXPORT_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.
+ */
+
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+#if defined(COMMON_EXPORT)
+#define QPID_COMMON_EXTERN __declspec(dllexport)
+#else
+#define QPID_COMMON_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_COMMON_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/DataDir.h b/qpid/cpp/src/qpid/DataDir.h
index 6b45d8747b..dfdd498cbc 100644
--- a/qpid/cpp/src/qpid/DataDir.h
+++ b/qpid/cpp/src/qpid/DataDir.h
@@ -24,6 +24,7 @@
#include <string>
#include <memory>
#include "qpid/sys/LockFile.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -38,8 +39,8 @@ class DataDir
public:
- DataDir (std::string path);
- ~DataDir ();
+ QPID_COMMON_EXTERN DataDir (std::string path);
+ QPID_COMMON_EXTERN ~DataDir ();
bool isEnabled() { return enabled; }
const std::string& getPath() { return dirPath; }
diff --git a/qpid/cpp/src/qpid/Exception.h b/qpid/cpp/src/qpid/Exception.h
index 86bf8fbc4a..0b0bc33e93 100644
--- a/qpid/cpp/src/qpid/Exception.h
+++ b/qpid/cpp/src/qpid/Exception.h
@@ -27,7 +27,7 @@
#include "qpid/framing/enum.h"
#include "qpid/sys/StrError.h"
#include "qpid/Msg.h"
-
+#include "qpid/CommonImportExport.h"
#include <memory>
#include <string>
#include <errno.h>
@@ -41,11 +41,11 @@ namespace qpid
class Exception : public std::exception
{
public:
- explicit Exception(const std::string& message=std::string()) throw();
- virtual ~Exception() throw();
- virtual const char* what() const throw(); // prefix: message
- virtual std::string getMessage() const; // Unprefixed message
- virtual std::string getPrefix() const; // Prefix
+ QPID_COMMON_EXTERN explicit Exception(const std::string& message=std::string()) throw();
+ QPID_COMMON_EXTERN virtual ~Exception() throw();
+ QPID_COMMON_EXTERN virtual const char* what() const throw(); // prefix: message
+ QPID_COMMON_EXTERN virtual std::string getMessage() const; // Unprefixed message
+ QPID_COMMON_EXTERN virtual std::string getPrefix() const; // Prefix
private:
std::string message;
@@ -77,8 +77,8 @@ struct ConnectionException : public Exception {
};
struct ClosedException : public Exception {
- ClosedException(const std::string& msg=std::string());
- std::string getPrefix() const;
+ QPID_COMMON_EXTERN ClosedException(const std::string& msg=std::string());
+ QPID_COMMON_EXTERN std::string getPrefix() const;
};
/**
diff --git a/qpid/cpp/src/qpid/Modules.h b/qpid/cpp/src/qpid/Modules.h
index 2a3b24f359..ce06dd0ef6 100644
--- a/qpid/cpp/src/qpid/Modules.h
+++ b/qpid/cpp/src/qpid/Modules.h
@@ -25,6 +25,7 @@
#include "Options.h"
#include <string>
#include <vector>
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -32,11 +33,11 @@ struct ModuleOptions : public qpid::Options {
std::string loadDir;
std::vector<std::string> load;
bool noLoad;
- ModuleOptions(const std::string& defaultModuleDir);
+ QPID_COMMON_EXTERN ModuleOptions(const std::string& defaultModuleDir);
};
-void tryShlib(const char* libname, bool noThrow);
-void loadModuleDir (std::string dirname, bool isDefault);
+QPID_COMMON_EXTERN void tryShlib(const char* libname, bool noThrow);
+QPID_COMMON_EXTERN void loadModuleDir (std::string dirname, bool isDefault);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/Options.h b/qpid/cpp/src/qpid/Options.h
index cb86d27241..aeb7a79329 100644
--- a/qpid/cpp/src/qpid/Options.h
+++ b/qpid/cpp/src/qpid/Options.h
@@ -23,13 +23,25 @@
*/
#include "qpid/Exception.h"
+
+// Disable warnings triggered by boost.
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable : 4251 4275)
+#endif
+
#include <boost/program_options.hpp>
#include <boost/format.hpp>
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
#include <sstream>
#include <iterator>
#include <algorithm>
#include <string>
-
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace po=boost::program_options;
@@ -37,7 +49,7 @@ namespace po=boost::program_options;
///@internal
-std::string prettyArg(const std::string&, const std::string&);
+QPID_COMMON_EXTERN std::string prettyArg(const std::string&, const std::string&);
/** @internal Normally only constructed by optValue() */
template <class T>
@@ -192,24 +204,20 @@ options_description_less_easy_init
#endif
-
-
-
-
struct Options : public po::options_description {
struct Exception : public qpid::Exception {
Exception(const std::string& msg) : qpid::Exception(msg) {}
};
- Options(const std::string& name=std::string());
+ QPID_COMMON_EXTERN Options(const std::string& name=std::string());
/**
* Parses options from argc/argv, environment variables and config file.
* Note the filename argument can reference an options variable that
* is updated by argc/argv or environment variable parsing.
*/
- void parse(int argc, char const* const* argv,
+ QPID_COMMON_EXTERN void parse(int argc, char const* const* argv,
const std::string& configfile=std::string(),
bool allowUnknown = false);
@@ -242,7 +250,7 @@ struct Options : public po::options_description {
* Standard options for configuration
*/
struct CommonOptions : public Options {
- CommonOptions(const std::string& name=std::string(),
+ QPID_COMMON_EXTERN CommonOptions(const std::string& name=std::string(),
const std::string& configfile=std::string());
bool help;
bool version;
diff --git a/qpid/cpp/src/qpid/Plugin.h b/qpid/cpp/src/qpid/Plugin.h
index 50d8e01227..913152f9e1 100644
--- a/qpid/cpp/src/qpid/Plugin.h
+++ b/qpid/cpp/src/qpid/Plugin.h
@@ -24,6 +24,7 @@
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
#include <vector>
+#include "qpid/CommonImportExport.h"
/**@file Generic plug-in framework. */
@@ -46,10 +47,10 @@ class Plugin : private boost::noncopyable {
{
public:
/** Calls finalize() if not already called. */
- virtual ~Target();
+ QPID_COMMON_EXTERN virtual ~Target();
/** Run all the finalizers */
- void finalize();
+ QPID_COMMON_EXTERN void finalize();
/** Add a function to run when finalize() is called */
void addFinalizer(const boost::function<void()>&);
@@ -65,9 +66,9 @@ class Plugin : private boost::noncopyable {
* member variable in a library so it is registered during
* initialization when the library is loaded.
*/
- Plugin();
+ QPID_COMMON_EXTERN Plugin();
- virtual ~Plugin();
+ QPID_COMMON_EXTERN virtual ~Plugin();
/**
* Configuration options for the plugin.
@@ -76,7 +77,7 @@ class Plugin : private boost::noncopyable {
* @return An options group or 0 for no options. Default returns 0.
* Plugin retains ownership of return value.
*/
- virtual Options* getOptions();
+ QPID_COMMON_EXTERN virtual Options* getOptions();
/**
* Initialize Plugin functionality on a Target, called before
@@ -101,16 +102,16 @@ class Plugin : private boost::noncopyable {
/** List of registered Plugin objects.
* Caller must not delete plugin pointers.
*/
- static const Plugins& getPlugins();
+ QPID_COMMON_EXTERN static const Plugins& getPlugins();
/** Call earlyInitialize() on all registered plugins */
- static void earlyInitAll(Target&);
+ QPID_COMMON_EXTERN static void earlyInitAll(Target&);
/** Call initialize() on all registered plugins */
- static void initializeAll(Target&);
+ QPID_COMMON_EXTERN static void initializeAll(Target&);
/** For each registered plugin, add plugin.getOptions() to opts. */
- static void addOptions(Options& opts);
+ QPID_COMMON_EXTERN static void addOptions(Options& opts);
};
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/SessionId.cpp b/qpid/cpp/src/qpid/SessionId.cpp
index fce6619f5d..098998015f 100644
--- a/qpid/cpp/src/qpid/SessionId.cpp
+++ b/qpid/cpp/src/qpid/SessionId.cpp
@@ -35,7 +35,7 @@ bool SessionId::operator==(const SessionId& id) const {
}
std::ostream& operator<<(std::ostream& o, const SessionId& id) {
- return o << id.getName() << "@" << id.getUserId();
+ return o << id.getUserId() << "." << id.getName();
}
std::string SessionId::str() const {
diff --git a/qpid/cpp/src/qpid/SessionId.h b/qpid/cpp/src/qpid/SessionId.h
index 291c42a2bb..bf52f9856b 100644
--- a/qpid/cpp/src/qpid/SessionId.h
+++ b/qpid/cpp/src/qpid/SessionId.h
@@ -24,6 +24,7 @@
#include <boost/operators.hpp>
#include <string>
+#include <qpid/CommonImportExport.h>
namespace qpid {
@@ -42,16 +43,16 @@ class SessionId : boost::totally_ordered1<SessionId> {
std::string userId;
std::string name;
public:
- SessionId(const std::string& userId=std::string(), const std::string& name=std::string());
+ QPID_COMMON_EXTERN SessionId(const std::string& userId=std::string(), const std::string& name=std::string());
std::string getUserId() const { return userId; }
std::string getName() const { return name; }
- bool operator<(const SessionId&) const ;
- bool operator==(const SessionId& id) const;
+ QPID_COMMON_EXTERN bool operator<(const SessionId&) const ;
+ QPID_COMMON_EXTERN bool operator==(const SessionId& id) const;
// Convert to a string
- std::string str() const;
+ QPID_COMMON_EXTERN std::string str() const;
};
-std::ostream& operator<<(std::ostream&, const SessionId&);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SessionId&);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/SessionState.cpp b/qpid/cpp/src/qpid/SessionState.cpp
index ac75b5c5ff..3e844fb24b 100644
--- a/qpid/cpp/src/qpid/SessionState.cpp
+++ b/qpid/cpp/src/qpid/SessionState.cpp
@@ -113,7 +113,8 @@ SessionState::ReplayRange SessionState::senderExpected(const SessionPoint& expec
void SessionState::senderRecord(const AMQFrame& f) {
if (isControl(f)) return; // Ignore control frames.
- QPID_LOG_IF(debug, f.getMethod(), getId() << ": sent cmd " << sender.sendPoint.command << ": " << *f.getMethod());
+ QPID_LOG(trace, getId() << ": sent cmd " << sender.sendPoint.command << ": " << *f.getBody());
+
stateful = true;
if (timeout) sender.replayList.push_back(f);
sender.unflushedSize += f.encodedSize();
@@ -183,6 +184,7 @@ void SessionState::receiverSetCommandPoint(const SessionPoint& point) {
}
bool SessionState::receiverRecord(const AMQFrame& f) {
+ if (receiverTrackingDisabled) return true; //Very nasty hack for push bridges
if (isControl(f)) return true; // Ignore control frames.
stateful = true;
receiver.expected.advance(f);
@@ -192,12 +194,13 @@ bool SessionState::receiverRecord(const AMQFrame& f) {
receiver.received = receiver.expected;
receiver.incomplete += receiverGetCurrent();
}
- QPID_LOG_IF(debug, f.getMethod(), getId() << ": recv cmd " << receiverGetCurrent() << ": " << *f.getMethod());
- QPID_LOG_IF(debug, !firstTime, "Ignoring duplicate frame: " << receiverGetCurrent() << ": " << f);
+ QPID_LOG(trace, getId() << ": recv cmd " << receiverGetCurrent() << ": " << *f.getBody());
+ if (!firstTime) QPID_LOG(trace, "Ignoring duplicate frame.");
return firstTime;
}
void SessionState::receiverCompleted(SequenceNumber command, bool cumulative) {
+ if (receiverTrackingDisabled) return; //Very nasty hack for push bridges
assert(receiver.incomplete.contains(command)); // Internal error to complete command twice.
SequenceNumber first =cumulative ? receiver.incomplete.front() : command;
SequenceNumber last = command;
@@ -237,7 +240,7 @@ SessionState::Configuration::Configuration(size_t flush, size_t hard) :
replayFlushLimit(flush), replayHardLimit(hard) {}
SessionState::SessionState(const SessionId& i, const Configuration& c)
- : id(i), timeout(), config(c), stateful()
+ : id(i), timeout(), config(c), stateful(), receiverTrackingDisabled(false)
{
QPID_LOG(debug, "SessionState::SessionState " << id << ": " << this);
}
@@ -275,4 +278,7 @@ void SessionState::setState(
receiver.bytesSinceKnownCompleted = 0;
}
+void SessionState::disableReceiverTracking() { receiverTrackingDisabled = true; }
+void SessionState::enableReceiverTracking() { receiverTrackingDisabled = false; }
+
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/SessionState.h b/qpid/cpp/src/qpid/SessionState.h
index bf4ff6d326..da28738546 100644
--- a/qpid/cpp/src/qpid/SessionState.h
+++ b/qpid/cpp/src/qpid/SessionState.h
@@ -31,6 +31,7 @@
#include <boost/range/iterator_range.hpp>
#include <vector>
#include <iosfwd>
+#include <qpid/CommonImportExport.h>
namespace qpid {
using framing::SequenceNumber;
@@ -38,19 +39,19 @@ using framing::SequenceSet;
/** A point in the session. Points to command id + offset */
struct SessionPoint : boost::totally_ordered1<SessionPoint> {
- SessionPoint(SequenceNumber command = 0, uint64_t offset = 0);
+ QPID_COMMON_EXTERN SessionPoint(SequenceNumber command = 0, uint64_t offset = 0);
SequenceNumber command;
uint64_t offset;
/** Advance past frame f */
- void advance(const framing::AMQFrame& f);
+ QPID_COMMON_EXTERN void advance(const framing::AMQFrame& f);
- bool operator<(const SessionPoint&) const;
- bool operator==(const SessionPoint&) const;
+ QPID_COMMON_EXTERN bool operator<(const SessionPoint&) const;
+ QPID_COMMON_EXTERN bool operator==(const SessionPoint&) const;
};
-std::ostream& operator<<(std::ostream&, const SessionPoint&);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SessionPoint&);
/**
* Support for session idempotence barrier and resume as defined in
@@ -78,14 +79,14 @@ class SessionState {
typedef boost::iterator_range<ReplayList::iterator> ReplayRange;
struct Configuration {
- Configuration(size_t flush=1024*1024, size_t hard=0);
+ QPID_COMMON_EXTERN Configuration(size_t flush=1024*1024, size_t hard=0);
size_t replayFlushLimit; // Flush when the replay list >= N bytes. 0 disables.
size_t replayHardLimit; // Kill session if replay list > N bytes. 0 disables.
};
- SessionState(const SessionId& =SessionId(), const Configuration& =Configuration());
+ QPID_COMMON_EXTERN SessionState(const SessionId& =SessionId(), const Configuration& =Configuration());
- virtual ~SessionState();
+ QPID_COMMON_EXTERN virtual ~SessionState();
bool hasState() const;
@@ -100,78 +101,78 @@ class SessionState {
// ==== Functions for sender state.
/** Record frame f for replay. Should not be called during replay. */
- virtual void senderRecord(const framing::AMQFrame& f);
+ QPID_COMMON_EXTERN virtual void senderRecord(const framing::AMQFrame& f);
/** @return true if we should send flush for confirmed and completed commands. */
- virtual bool senderNeedFlush() const;
+ QPID_COMMON_EXTERN virtual bool senderNeedFlush() const;
/** Called when flush for confirmed and completed commands is sent to peer. */
- virtual void senderRecordFlush();
+ QPID_COMMON_EXTERN virtual void senderRecordFlush();
/** True if we should reply to the next incoming completed command */
- virtual bool senderNeedKnownCompleted() const;
+ QPID_COMMON_EXTERN virtual bool senderNeedKnownCompleted() const;
/** Called when knownCompleted is sent to peer. */
- virtual void senderRecordKnownCompleted();
+ QPID_COMMON_EXTERN virtual void senderRecordKnownCompleted();
/** Called when the peer confirms up to comfirmed. */
- virtual void senderConfirmed(const SessionPoint& confirmed);
+ QPID_COMMON_EXTERN virtual void senderConfirmed(const SessionPoint& confirmed);
/** Called when the peer indicates commands completed */
- virtual void senderCompleted(const SequenceSet& commands);
+ QPID_COMMON_EXTERN virtual void senderCompleted(const SequenceSet& commands);
/** Point from which the next new (not replayed) data will be sent. */
- virtual SessionPoint senderGetCommandPoint();
+ QPID_COMMON_EXTERN virtual SessionPoint senderGetCommandPoint();
/** Set of outstanding incomplete commands */
- virtual SequenceSet senderGetIncomplete() const;
+ QPID_COMMON_EXTERN virtual SequenceSet senderGetIncomplete() const;
/** Point from which we can replay. */
- virtual SessionPoint senderGetReplayPoint() const;
+ QPID_COMMON_EXTERN virtual SessionPoint senderGetReplayPoint() const;
/** Peer expecting commands from this point.
*@return Range of frames to be replayed.
*/
- virtual ReplayRange senderExpected(const SessionPoint& expected);
+ QPID_COMMON_EXTERN virtual ReplayRange senderExpected(const SessionPoint& expected);
// ==== Functions for receiver state
/** Set the command point. */
- virtual void receiverSetCommandPoint(const SessionPoint& point);
+ QPID_COMMON_EXTERN virtual void receiverSetCommandPoint(const SessionPoint& point);
/** Returns true if frame should be be processed, false if it is a duplicate. */
- virtual bool receiverRecord(const framing::AMQFrame& f);
+ QPID_COMMON_EXTERN virtual bool receiverRecord(const framing::AMQFrame& f);
/** Command completed locally */
- virtual void receiverCompleted(SequenceNumber command, bool cumulative=false);
+ QPID_COMMON_EXTERN virtual void receiverCompleted(SequenceNumber command, bool cumulative=false);
/** Peer has indicated commands are known completed */
- virtual void receiverKnownCompleted(const SequenceSet& commands);
+ QPID_COMMON_EXTERN virtual void receiverKnownCompleted(const SequenceSet& commands);
/** True if the next completed control should set the timely-reply argument
* to request a knonw-completed response.
*/
- virtual bool receiverNeedKnownCompleted() const;
+ QPID_COMMON_EXTERN virtual bool receiverNeedKnownCompleted() const;
/** Get the incoming command point */
- virtual const SessionPoint& receiverGetExpected() const;
+ QPID_COMMON_EXTERN virtual const SessionPoint& receiverGetExpected() const;
/** Get the received high-water-mark, may be > getExpected() during replay */
- virtual const SessionPoint& receiverGetReceived() const;
+ QPID_COMMON_EXTERN virtual const SessionPoint& receiverGetReceived() const;
/** Completed received commands that the peer may not know about. */
- virtual const SequenceSet& receiverGetUnknownComplete() const;
+ QPID_COMMON_EXTERN virtual const SequenceSet& receiverGetUnknownComplete() const;
/** Incomplete received commands. */
- virtual const SequenceSet& receiverGetIncomplete() const;
+ QPID_COMMON_EXTERN virtual const SequenceSet& receiverGetIncomplete() const;
/** ID of the command currently being handled. */
- virtual SequenceNumber receiverGetCurrent() const;
+ QPID_COMMON_EXTERN virtual SequenceNumber receiverGetCurrent() const;
/** Set the state variables, used to create a session that will resume
* from some previously established point.
*/
- virtual void setState(
+ QPID_COMMON_EXTERN virtual void setState(
const SequenceNumber& replayStart,
const SequenceNumber& sendCommandPoint,
const SequenceSet& sentIncomplete,
@@ -181,6 +182,20 @@ class SessionState {
const SequenceSet& receivedIncomplete
);
+ /**
+ * So called 'push' bridges work by faking a subscribe request
+ * (and the accompanying flows etc) to the local broker to initiate
+ * the outflow of messages for the bridge.
+ *
+ * As the peer doesn't send these it cannot include them in its
+ * session state. To keep the session state on either side of the
+ * bridge in sync, this hack allows the tracking of state for
+ * received messages to be disabled for the faked commands and
+ * subsequently re-enabled.
+ */
+ QPID_COMMON_EXTERN void disableReceiverTracking();
+ QPID_COMMON_EXTERN void enableReceiverTracking();
+
private:
struct SendState {
@@ -209,6 +224,7 @@ class SessionState {
uint32_t timeout;
Configuration config;
bool stateful;
+ bool receiverTrackingDisabled;//very nasty hack for 'push' bridges
};
inline bool operator==(const SessionId& id, const SessionState& s) { return s == id; }
diff --git a/qpid/cpp/src/qpid/StringUtils.h b/qpid/cpp/src/qpid/StringUtils.h
index 3120e43334..4130fae017 100644
--- a/qpid/cpp/src/qpid/StringUtils.h
+++ b/qpid/cpp/src/qpid/StringUtils.h
@@ -22,6 +22,8 @@
*
*/
+#include "qpid/CommonImportExport.h"
+
#include <string>
#include <vector>
@@ -31,12 +33,12 @@ namespace qpid {
* Split 'in' into words using delimiters in 'delims' and put
* resulting strings into 'out' vector.
*/
-void split(std::vector<std::string>& out, const std::string& in, const std::string& delims);
+QPID_COMMON_EXTERN void split(std::vector<std::string>& out, const std::string& in, const std::string& delims);
/**
* Split 'in' into words using delimiters in 'delims' and return the
* resulting strings in a vector.
*/
-std::vector<std::string> split(const std::string& in, const std::string& delims);
+QPID_COMMON_EXTERN std::vector<std::string> split(const std::string& in, const std::string& delims);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/Url.h b/qpid/cpp/src/qpid/Url.h
index 07ca46e70c..353eac28f3 100644
--- a/qpid/cpp/src/qpid/Url.h
+++ b/qpid/cpp/src/qpid/Url.h
@@ -25,10 +25,11 @@
#include <vector>
#include <new>
#include <ostream>
+#include "qpid/CommonImportExport.h"
namespace qpid {
-std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
/** An AMQP URL contains a list of addresses */
struct Url : public std::vector<Address> {
@@ -38,12 +39,12 @@ struct Url : public std::vector<Address> {
/** Url with local IP address(es), may be more than one address
* on a multi-homed host. */
- static Url getIpAddressesUrl(uint16_t port);
+ QPID_COMMON_EXTERN static Url getIpAddressesUrl(uint16_t port);
struct Invalid : public Exception { Invalid(const std::string& s); };
/** Convert to string form. */
- std::string str() const;
+ QPID_COMMON_EXTERN std::string str() const;
/** Empty URL. */
Url() {}
@@ -62,14 +63,14 @@ struct Url : public std::vector<Address> {
Url& operator=(const std::string& s) { parse(s); return *this; }
/** Throw Invalid if the URL does not contain any addresses. */
- void throwIfEmpty() const;
+ QPID_COMMON_EXTERN void throwIfEmpty() const;
/** Replace contents with parsed URL as defined in
* https://wiki.108.redhat.com/jira/browse/AMQP-95
*@exception Invalid if the url is invalid.
*/
- void parse(const char* url);
- void parse(const std::string& url) { parse(url.c_str()); }
+ QPID_COMMON_EXTERN void parse(const char* url);
+ QPID_COMMON_EXTERN void parse(const std::string& url) { parse(url.c_str()); }
/** Replace contesnts with parsed URL as defined in
* https://wiki.108.redhat.com/jira/browse/AMQP-95
@@ -84,8 +85,8 @@ struct Url : public std::vector<Address> {
inline bool operator==(const Url& a, const Url& b) { return a.str()==b.str(); }
inline bool operator!=(const Url& a, const Url& b) { return a.str()!=b.str(); }
-std::ostream& operator<<(std::ostream& os, const Url& url);
-std::istream& operator>>(std::istream& is, Url& url);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const Url& url);
+QPID_COMMON_EXTERN std::istream& operator>>(std::istream& is, Url& url);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/Version.h b/qpid/cpp/src/qpid/Version.h
index 9bd561b7a9..ab7957e000 100755
--- a/qpid/cpp/src/qpid/Version.h
+++ b/qpid/cpp/src/qpid/Version.h
@@ -36,7 +36,7 @@ namespace qpid {
# endif
#else
const std::string product = "qpidc";
- const std::string version = "0.3";
+ const std::string version = "0.5";
const std::string saslName = "qpid-broker";
#endif
}
diff --git a/qpid/cpp/src/qpid/acl/AclPlugin.cpp b/qpid/cpp/src/qpid/acl/AclPlugin.cpp
index 7310139041..4c6efa19dd 100644
--- a/qpid/cpp/src/qpid/acl/AclPlugin.cpp
+++ b/qpid/cpp/src/qpid/acl/AclPlugin.cpp
@@ -62,15 +62,10 @@ struct AclPlugin : public Plugin {
if (acl) throw Exception("ACL plugin cannot be initialized twice in one process.");
- if (values.aclFile.at(0) == '/')
- {
- values.aclFile = values.aclFile;
- }
- else
- {
- std::ostringstream oss;
- oss << b.getDataDir().getPath() << "/" << values.aclFile;
- values.aclFile = oss.str();
+ if (values.aclFile.at(0) != '/' && !b.getDataDir().getPath().empty()) {
+ std::ostringstream oss;
+ oss << b.getDataDir().getPath() << "/" << values.aclFile;
+ values.aclFile = oss.str();
}
acl = new Acl(values, b);
diff --git a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
index 1e2f4cdd78..7c70c12213 100644
--- a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
+++ b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
@@ -151,7 +151,7 @@ void ManagementAgentImpl::init(const client::ConnectionSettings& settings,
// TODO: Abstract the socket calls for portability
if (extThread) {
int pair[2];
- int result = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
+ int result = socketpair(PF_UNIX, SOCK_STREAM, 0, pair);
if (result == -1) {
return;
}
@@ -485,6 +485,9 @@ void ManagementAgentImpl::handleGetQuery(Buffer& inBuffer, uint32_t sequence, st
Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
@@ -508,6 +511,9 @@ void ManagementAgentImpl::handleGetQuery(Buffer& inBuffer, uint32_t sequence, st
Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
diff --git a/qpid/cpp/src/qpid/amqp_0_10/Connection.h b/qpid/cpp/src/qpid/amqp_0_10/Connection.h
index 743a7de3aa..3e0a5d1ee8 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/Connection.h
+++ b/qpid/cpp/src/qpid/amqp_0_10/Connection.h
@@ -27,6 +27,7 @@
#include "qpid/sys/ConnectionInputHandler.h"
#include "qpid/sys/ConnectionOutputHandler.h"
#include "qpid/sys/Mutex.h"
+#include "qpid/broker/BrokerImportExport.h"
#include <boost/intrusive_ptr.hpp>
#include <memory>
#include <deque>
@@ -56,8 +57,8 @@ class Connection : public sys::ConnectionCodec,
size_t buffered;
public:
- Connection(sys::OutputControl&, const std::string& id, bool isClient);
- void setInputHandler(std::auto_ptr<sys::ConnectionInputHandler> c);
+ QPID_BROKER_EXTERN Connection(sys::OutputControl&, const std::string& id, bool isClient);
+ QPID_BROKER_EXTERN void setInputHandler(std::auto_ptr<sys::ConnectionInputHandler> c);
size_t decode(const char* buffer, size_t size);
size_t encode(const char* buffer, size_t size);
bool isClosed() const;
diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
index f58d59cbd7..db957051d8 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
+++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
@@ -277,7 +277,6 @@ void SessionHandler::sendCompletion() {
}
void SessionHandler::sendAttach(bool force) {
- CHECK_ATTACHED("session.send-attach");
QPID_LOG(debug, "SessionHandler::sendAttach attach id=" << getState()->getId());
peer.attach(getState()->getId().getName(), force);
if (getState()->hasState())
diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
index d7af7dd6c7..0b158ec2b4 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
+++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
@@ -26,6 +26,7 @@
#include "qpid/framing/AMQP_AllProxy.h"
#include "qpid/framing/AMQP_AllOperations.h"
#include "qpid/SessionState.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -43,8 +44,8 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
public framing::FrameHandler::InOutHandler
{
public:
- SessionHandler(framing::FrameHandler* out=0, uint16_t channel=0);
- ~SessionHandler();
+ QPID_COMMON_EXTERN SessionHandler(framing::FrameHandler* out=0, uint16_t channel=0);
+ QPID_COMMON_EXTERN ~SessionHandler();
void setChannel(uint16_t ch) { channel = ch; }
uint16_t getChannel() const { return channel.get(); }
@@ -55,35 +56,35 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
virtual framing::FrameHandler* getInHandler() = 0;
// Non-protocol methods, called locally to initiate some action.
- void sendDetach();
- void sendCompletion();
- void sendAttach(bool force);
- void sendTimeout(uint32_t t);
- void sendFlush();
- void markReadyToSend();//TODO: only needed for inter-broker bridge; cleanup
+ QPID_COMMON_EXTERN void sendDetach();
+ QPID_COMMON_EXTERN void sendCompletion();
+ QPID_COMMON_EXTERN void sendAttach(bool force);
+ QPID_COMMON_EXTERN void sendTimeout(uint32_t t);
+ QPID_COMMON_EXTERN void sendFlush();
+ QPID_COMMON_EXTERN void markReadyToSend();//TODO: only needed for inter-broker bridge; cleanup
/** True if the handler is ready to send and receive */
bool ready() const;
// Protocol methods
- void attach(const std::string& name, bool force);
- void attached(const std::string& name);
- void detach(const std::string& name);
- void detached(const std::string& name, uint8_t code);
-
- void requestTimeout(uint32_t t);
- void timeout(uint32_t t);
-
- void commandPoint(const framing::SequenceNumber& id, uint64_t offset);
- void expected(const framing::SequenceSet& commands, const framing::Array& fragments);
- void confirmed(const framing::SequenceSet& commands,const framing::Array& fragments);
- void completed(const framing::SequenceSet& commands, bool timelyReply);
- void knownCompleted(const framing::SequenceSet& commands);
- void flush(bool expected, bool confirmed, bool completed);
- void gap(const framing::SequenceSet& commands);
+ QPID_COMMON_EXTERN void attach(const std::string& name, bool force);
+ QPID_COMMON_EXTERN void attached(const std::string& name);
+ QPID_COMMON_EXTERN void detach(const std::string& name);
+ QPID_COMMON_EXTERN void detached(const std::string& name, uint8_t code);
+
+ QPID_COMMON_EXTERN void requestTimeout(uint32_t t);
+ QPID_COMMON_EXTERN void timeout(uint32_t t);
+
+ QPID_COMMON_EXTERN void commandPoint(const framing::SequenceNumber& id, uint64_t offset);
+ QPID_COMMON_EXTERN void expected(const framing::SequenceSet& commands, const framing::Array& fragments);
+ QPID_COMMON_EXTERN void confirmed(const framing::SequenceSet& commands,const framing::Array& fragments);
+ QPID_COMMON_EXTERN void completed(const framing::SequenceSet& commands, bool timelyReply);
+ QPID_COMMON_EXTERN void knownCompleted(const framing::SequenceSet& commands);
+ QPID_COMMON_EXTERN void flush(bool expected, bool confirmed, bool completed);
+ QPID_COMMON_EXTERN void gap(const framing::SequenceSet& commands);
protected:
- virtual void invoke(const framing::AMQMethodBody& m);
+ QPID_COMMON_EXTERN virtual void invoke(const framing::AMQMethodBody& m);
virtual void setState(const std::string& sessionName, bool force) = 0;
virtual void channelException(framing::session::DetachCode code, const std::string& msg) = 0;
@@ -94,9 +95,9 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
virtual void readyToSend() {}
virtual void readyToReceive() {}
- virtual void handleDetach();
- virtual void handleIn(framing::AMQFrame&);
- virtual void handleOut(framing::AMQFrame&);
+ QPID_COMMON_EXTERN virtual void handleDetach();
+ QPID_COMMON_EXTERN virtual void handleIn(framing::AMQFrame&);
+ QPID_COMMON_EXTERN virtual void handleOut(framing::AMQFrame&);
framing::ChannelHandler channel;
framing::AMQP_AllProxy::Session peer;
diff --git a/qpid/cpp/src/qpid/assert.cpp b/qpid/cpp/src/qpid/assert.cpp
index 5d039da528..bf36d3be86 100644
--- a/qpid/cpp/src/qpid/assert.cpp
+++ b/qpid/cpp/src/qpid/assert.cpp
@@ -35,7 +35,7 @@ void assert_fail(char const * expr, char const * function, char const * file, lo
#ifdef NDEBUG
throw framing::InternalErrorException(msg.str());
#else
- std::cerr << msg << std::endl;
+ std::cerr << msg.str() << std::endl;
abort();
#endif
}
diff --git a/qpid/cpp/src/qpid/broker/Bridge.cpp b/qpid/cpp/src/qpid/broker/Bridge.cpp
index 38a9b5d64c..4d275b958f 100644
--- a/qpid/cpp/src/qpid/broker/Bridge.cpp
+++ b/qpid/cpp/src/qpid/broker/Bridge.cpp
@@ -22,6 +22,7 @@
#include "ConnectionState.h"
#include "Connection.h"
#include "LinkRegistry.h"
+#include "SessionState.h"
#include "qpid/agent/ManagementAgent.h"
#include "qpid/framing/FieldTable.h"
@@ -80,31 +81,31 @@ Bridge::~Bridge()
mgmtObject->resourceDestroy();
}
-void Bridge::create(ConnectionState& c)
+void Bridge::create(Connection& c)
{
+ connState = &c;
FieldTable options;
if (args.i_sync) options.setInt("qpid.sync_frequency", args.i_sync);
- connState = &c;
+ SessionHandler& sessionHandler = c.getChannel(id);
if (args.i_srcIsLocal) {
if (args.i_dynamic)
throw Exception("Dynamic routing not supported for push routes");
// Point the bridging commands at the local connection handler
- Connection* conn = dynamic_cast<Connection*>(&c);
- if (conn == 0)
- return;
- pushHandler.reset(new PushHandler(conn));
+ pushHandler.reset(new PushHandler(&c));
channelHandler.reset(new framing::ChannelHandler(id, pushHandler.get()));
+
+ session.reset(new framing::AMQP_ServerProxy::Session(*channelHandler));
+ peer.reset(new framing::AMQP_ServerProxy(*channelHandler));
+
+ session->attach(name, false);
+ session->commandPoint(0,0);
} else {
+ sessionHandler.attachAs(name);
// Point the bridging commands at the remote peer broker
- channelHandler.reset(new framing::ChannelHandler(id, &(connState->getOutput())));
+ peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out));
}
- session.reset(new framing::AMQP_ServerProxy::Session(*channelHandler));
- peer.reset(new framing::AMQP_ServerProxy(*channelHandler));
-
- session->attach(name, false);
- session->commandPoint(0,0);
-
+ if (args.i_srcIsLocal) sessionHandler.getSession()->disableReceiverTracking();
if (args.i_srcIsQueue) {
peer->getMessage().subscribe(args.i_src, args.i_dest, args.i_sync ? 0 : 1, 0, false, "", 0, options);
peer->getMessage().flow(args.i_dest, 0, 0xFFFFFFFF);
@@ -116,7 +117,7 @@ void Bridge::create(ConnectionState& c)
if (args.i_tag.size()) {
queueSettings.setString("qpid.trace.id", args.i_tag);
} else {
- const string& peerTag = connState->getFederationPeerTag();
+ const string& peerTag = c.getFederationPeerTag();
if (peerTag.size())
queueSettings.setString("qpid.trace.id", peerTag);
}
@@ -129,7 +130,7 @@ void Bridge::create(ConnectionState& c)
queueSettings.setString("qpid.trace.exclude", localTag);
}
- bool durable = false;//should this be an arg, or would be use srcIsQueue for durable queues?
+ bool durable = false;//should this be an arg, or would we use srcIsQueue for durable queues?
bool autoDelete = !durable;//auto delete transient queues?
peer->getQueue().declare(queueName, "", false, durable, true, autoDelete, queueSettings);
if (!args.i_dynamic)
@@ -148,12 +149,23 @@ void Bridge::create(ConnectionState& c)
QPID_LOG(debug, "Activated static route from exchange " << args.i_src << " to " << args.i_dest);
}
}
+ if (args.i_srcIsLocal) sessionHandler.getSession()->enableReceiverTracking();
}
-void Bridge::cancel()
+void Bridge::cancel(Connection& c)
{
+ if (args.i_srcIsLocal) {
+ //recreate peer to be sure that the session handler reference
+ //is valid (it could have been deleted due to a detach)
+ SessionHandler& sessionHandler = c.getChannel(id);
+ peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out));
+ }
peer->getMessage().cancel(args.i_dest);
peer->getSession().detach(name);
+}
+
+void Bridge::closed()
+{
if (args.i_dynamic) {
Exchange::shared_ptr exchange = link->getBroker()->getExchanges().get(args.i_src);
if (exchange.get() != 0)
@@ -166,13 +178,13 @@ void Bridge::destroy()
listener(this);
}
-void Bridge::setPersistenceId(uint64_t id) const
+void Bridge::setPersistenceId(uint64_t pId) const
{
if (mgmtObject != 0 && persistenceId == 0) {
ManagementAgent* agent = ManagementAgent::Singleton::getInstance();
- agent->addObject (mgmtObject, id);
+ agent->addObject (mgmtObject, pId);
}
- persistenceId = id;
+ persistenceId = pId;
}
const string& Bridge::getName() const
diff --git a/qpid/cpp/src/qpid/broker/Bridge.h b/qpid/cpp/src/qpid/broker/Bridge.h
index c530a5d696..dae28ddeaa 100644
--- a/qpid/cpp/src/qpid/broker/Bridge.h
+++ b/qpid/cpp/src/qpid/broker/Bridge.h
@@ -52,8 +52,9 @@ public:
const qmf::org::apache::qpid::broker::ArgsLinkBridge& args);
~Bridge();
- void create(ConnectionState& c);
- void cancel();
+ void create(Connection& c);
+ void cancel(Connection& c);
+ void closed();
void destroy();
bool isDurable() { return args.i_durable; }
diff --git a/qpid/cpp/src/qpid/broker/Broker.cpp b/qpid/cpp/src/qpid/broker/Broker.cpp
index 95f55bb596..3f9effc08f 100644
--- a/qpid/cpp/src/qpid/broker/Broker.cpp
+++ b/qpid/cpp/src/qpid/broker/Broker.cpp
@@ -199,6 +199,7 @@ Broker::Broker(const Broker::Options& conf) :
}
QueuePolicy::setDefaultMaxSize(conf.queueLimit);
+ queues.setQueueEvents(&queueEvents);
// Early-Initialize plugins
const Plugin::Plugins& plugins=Plugin::getPlugins();
@@ -383,9 +384,9 @@ Manageable::status_t Broker::ManagementMethod (uint32_t methodId,
_qmf::ArgsBrokerQueueMoveMessages& moveArgs=
dynamic_cast<_qmf::ArgsBrokerQueueMoveMessages&>(args);
if (queueMoveMessages(moveArgs.i_srcQueue, moveArgs.i_destQueue, moveArgs.i_qty))
- status = Manageable::STATUS_OK;
+ status = Manageable::STATUS_OK;
else
- return Manageable::STATUS_INVALID_PARAMETER;
+ return Manageable::STATUS_INVALID_PARAMETER;
break;
}
default:
diff --git a/qpid/cpp/src/qpid/broker/Broker.h b/qpid/cpp/src/qpid/broker/Broker.h
index a52a0f67e0..5a1529a3ba 100644
--- a/qpid/cpp/src/qpid/broker/Broker.h
+++ b/qpid/cpp/src/qpid/broker/Broker.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "ConnectionFactory.h"
#include "ConnectionToken.h"
#include "DirectExchange.h"
@@ -80,15 +81,16 @@ struct NoSuchTransportException : qpid::Exception
* A broker instance.
*/
class Broker : public sys::Runnable, public Plugin::Target,
- public management::Manageable, public RefCounted
+ public management::Manageable,
+ public RefCounted
{
- public:
+public:
struct Options : public qpid::Options {
static const std::string DEFAULT_DATA_DIR_LOCATION;
static const std::string DEFAULT_DATA_DIR_NAME;
- Options(const std::string& name="Broker Options");
+ QPID_BROKER_EXTERN Options(const std::string& name="Broker Options");
bool noDataDir;
std::string dataDir;
@@ -148,9 +150,9 @@ class Broker : public sys::Runnable, public Plugin::Target,
virtual ~Broker();
- Broker(const Options& configuration);
- static boost::intrusive_ptr<Broker> create(const Options& configuration);
- static boost::intrusive_ptr<Broker> create(int16_t port = DEFAULT_PORT);
+ QPID_BROKER_EXTERN Broker(const Options& configuration);
+ static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(const Options& configuration);
+ static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(int16_t port = DEFAULT_PORT);
/**
* Return listening port. If called before bind this is
@@ -169,7 +171,7 @@ class Broker : public sys::Runnable, public Plugin::Target,
/** Shut down the broker */
virtual void shutdown();
- void setStore (MessageStore*);
+ QPID_BROKER_EXTERN void setStore (MessageStore*);
MessageStore& getStore() { return *store; }
void setAcl (AclModule* _acl) {acl = _acl;}
AclModule* getAcl() { return acl; }
@@ -229,7 +231,7 @@ class Broker : public sys::Runnable, public Plugin::Target,
boost::function<std::vector<Url> ()> getKnownBrokers;
- static const std::string TCP_TRANSPORT;
+ static QPID_BROKER_EXTERN const std::string TCP_TRANSPORT;
void setRecovery(bool set) { recovery = set; }
bool getRecovery() const { return recovery; }
diff --git a/qpid/cpp/src/qpid/broker/BrokerImportExport.h b/qpid/cpp/src/qpid/broker/BrokerImportExport.h
new file mode 100644
index 0000000000..2edc90993e
--- /dev/null
+++ b/qpid/cpp/src/qpid/broker/BrokerImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_BROKER_IMPORT_EXPORT_H
+#define QPID_BROKER_IMPORT_EXPORT_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.
+ */
+
+#if defined(WIN32) && !defined(QPID_BROKER_STATIC)
+#if defined(BROKER_EXPORT)
+#define QPID_BROKER_EXTERN __declspec(dllexport)
+#else
+#define QPID_BROKER_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_BROKER_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/broker/BrokerSingleton.h b/qpid/cpp/src/qpid/broker/BrokerSingleton.h
index 22b707506b..3a842ee05a 100644
--- a/qpid/cpp/src/qpid/broker/BrokerSingleton.h
+++ b/qpid/cpp/src/qpid/broker/BrokerSingleton.h
@@ -20,6 +20,7 @@
*/
#include "Broker.h"
+#include "BrokerImportExport.h"
namespace qpid {
namespace broker {
@@ -36,7 +37,7 @@ namespace broker {
*
* THREAD UNSAFE.
*/
-class BrokerSingleton : public boost::intrusive_ptr<Broker>
+class QPID_BROKER_EXTERN BrokerSingleton : public boost::intrusive_ptr<Broker>
{
public:
BrokerSingleton();
diff --git a/qpid/cpp/src/qpid/broker/Connection.cpp b/qpid/cpp/src/qpid/broker/Connection.cpp
index b7446a2220..b06e06d353 100644
--- a/qpid/cpp/src/qpid/broker/Connection.cpp
+++ b/qpid/cpp/src/qpid/broker/Connection.cpp
@@ -80,7 +80,8 @@ Connection::Connection(ConnectionOutputHandler* out_, Broker& broker_, const std
void Connection::requestIOProcessing(boost::function0<void> callback)
{
- ioCallback = callback;
+ ScopedLock<Mutex> l(ioCallbackLock);
+ ioCallbacks.push(callback);
out.activateOutput();
}
@@ -221,10 +222,13 @@ bool Connection::hasOutput() { return outputTasks.hasOutput(); }
bool Connection::doOutput() {
try{
- if (ioCallback)
- ioCallback(); // Lend the IO thread for management processing
- ioCallback = 0;
-
+ {
+ ScopedLock<Mutex> l(ioCallbackLock);
+ while (!ioCallbacks.empty()) {
+ ioCallbacks.front()(); // Lend the IO thread for management processing
+ ioCallbacks.pop();
+ }
+ }
if (mgmtClosing)
close(connection::CLOSE_CODE_CONNECTION_FORCED, "Closed by Management Request");
else
diff --git a/qpid/cpp/src/qpid/broker/Connection.h b/qpid/cpp/src/qpid/broker/Connection.h
index 71e03d76d4..b659fe6468 100644
--- a/qpid/cpp/src/qpid/broker/Connection.h
+++ b/qpid/cpp/src/qpid/broker/Connection.h
@@ -25,6 +25,7 @@
#include <memory>
#include <sstream>
#include <vector>
+#include <queue>
#include <boost/ptr_container/ptr_map.hpp>
@@ -47,6 +48,7 @@
#include "qpid/sys/ConnectionOutputHandler.h"
#include "qpid/sys/Socket.h"
#include "qpid/sys/TimeoutHandler.h"
+#include "qpid/sys/Mutex.h"
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/bind.hpp>
@@ -119,12 +121,15 @@ class Connection : public sys::ConnectionInputHandler,
const bool isLink;
bool mgmtClosing;
const std::string mgmtId;
- boost::function0<void> ioCallback;
+ sys::Mutex ioCallbackLock;
+ std::queue<boost::function0<void> > ioCallbacks;
qmf::org::apache::qpid::broker::Connection* mgmtObject;
LinkRegistry& links;
management::ManagementAgent* agent;
Timer& timer;
boost::intrusive_ptr<TimerTask> heartbeatTimer;
+ public:
+ qmf::org::apache::qpid::broker::Connection* getMgmtObject() { return mgmtObject; }
};
}}
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
index f136d61462..63212c7794 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
+++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
@@ -24,8 +24,7 @@
#include "Connection.h"
#include "SecureConnection.h"
#include "qpid/Url.h"
-#include "qpid/framing/ClientInvoker.h"
-#include "qpid/framing/ServerInvoker.h"
+#include "qpid/framing/AllInvoker.h"
#include "qpid/framing/enum.h"
#include "qpid/log/Statement.h"
#include "qpid/sys/SecurityLayer.h"
@@ -46,37 +45,33 @@ const std::string en_US = "en_US";
const std::string QPID_FED_LINK = "qpid.fed_link";
const std::string QPID_FED_TAG = "qpid.federation_tag";
const std::string SESSION_FLOW_CONTROL("qpid.session_flow");
+const std::string CLIENT_PROCESS_NAME("qpid.client_process");
+const std::string CLIENT_PID("qpid.client_pid");
+const std::string CLIENT_PPID("qpid.client_ppid");
const int SESSION_FLOW_CONTROL_VER = 1;
}
void ConnectionHandler::close(connection::CloseCode code, const string& text)
{
- handler->client.close(code, text);
+ handler->proxy.close(code, text);
}
void ConnectionHandler::heartbeat()
{
- handler->client.heartbeat();
+ handler->proxy.heartbeat();
}
void ConnectionHandler::handle(framing::AMQFrame& frame)
{
AMQMethodBody* method=frame.getBody()->getMethod();
try{
- bool handled = false;
- if (handler->serverMode) {
- handled = invoke(static_cast<AMQP_ServerOperations::ConnectionHandler&>(*handler.get()), *method);
- } else {
- handled = invoke(static_cast<AMQP_ClientOperations::ConnectionHandler&>(*handler.get()), *method);
- }
- if (!handled) {
+ if (!invoke(static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler.get()), *method)) {
handler->connection.getChannel(frame.getChannel()).in(frame);
}
-
}catch(ConnectionException& e){
- handler->client.close(e.code, e.what());
+ handler->proxy.close(e.code, e.what());
}catch(std::exception& e){
- handler->client.close(541/*internal error*/, e.what());
+ handler->proxy.close(541/*internal error*/, e.what());
}
}
@@ -88,7 +83,7 @@ void ConnectionHandler::setSecureConnection(SecureConnection* secured)
ConnectionHandler::ConnectionHandler(Connection& connection, bool isClient) : handler(new Handler(connection, isClient)) {}
ConnectionHandler::Handler::Handler(Connection& c, bool isClient) :
- client(c.getOutput()), server(c.getOutput()),
+ proxy(c.getOutput()),
connection(c), serverMode(!isClient), acl(0), secured(0)
{
if (serverMode) {
@@ -106,7 +101,7 @@ ConnectionHandler::Handler::Handler(Connection& c, bool isClient) :
Array locales(0x95);
boost::shared_ptr<FieldValue> l(new Str16Value(en_US));
locales.add(l);
- client.start(properties, mechanisms, locales);
+ proxy.start(properties, mechanisms, locales);
}
}
@@ -136,14 +131,27 @@ void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProper
connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));
if (connection.isFederationLink()) {
if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){
- client.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link");
+ proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link");
return;
}
QPID_LOG(info, "Connection is a federation link");
}
- if ( clientProperties.getAsInt(SESSION_FLOW_CONTROL) == SESSION_FLOW_CONTROL_VER ) {
+ if (clientProperties.getAsInt(SESSION_FLOW_CONTROL) == SESSION_FLOW_CONTROL_VER) {
connection.setClientThrottling();
}
+
+ if (connection.getMgmtObject() != 0) {
+ string procName = clientProperties.getAsString(CLIENT_PROCESS_NAME);
+ uint32_t pid = clientProperties.getAsInt(CLIENT_PID);
+ uint32_t ppid = clientProperties.getAsInt(CLIENT_PPID);
+
+ if (!procName.empty())
+ connection.getMgmtObject()->set_remoteProcessName(procName);
+ if (pid != 0)
+ connection.getMgmtObject()->set_remotePid(pid);
+ if (ppid != 0)
+ connection.getMgmtObject()->set_remoteParentPid(ppid);
+ }
}
void ConnectionHandler::Handler::secureOk(const string& response)
@@ -177,7 +185,7 @@ void ConnectionHandler::Handler::open(const string& /*virtualHost*/,
framing::Array array(0x95); // str16 array
for (std::vector<Url>::iterator i = urls.begin(); i < urls.end(); ++i)
array.add(boost::shared_ptr<Str16Value>(new Str16Value(i->str())));
- client.openOk(array);
+ proxy.openOk(array);
//install security layer if one has been negotiated:
if (secured) {
@@ -196,7 +204,7 @@ void ConnectionHandler::Handler::close(uint16_t replyCode, const string& replyTe
if (replyCode == framing::connection::CLOSE_CODE_CONNECTION_FORCED)
connection.notifyConnectionForced(replyText);
- client.closeOk();
+ proxy.closeOk();
connection.getOutput().close();
}
@@ -222,12 +230,12 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
FieldTable ft;
ft.setInt(QPID_FED_LINK,1);
ft.setString(QPID_FED_TAG, connection.getBroker().getFederationTag());
- server.startOk(ft, mechanism, response, en_US);
+ proxy.startOk(ft, mechanism, response, en_US);
}
void ConnectionHandler::Handler::secure(const string& /*challenge*/)
{
- server.secureOk("");
+ proxy.secureOk("");
}
void ConnectionHandler::Handler::tune(uint16_t channelMax,
@@ -237,8 +245,8 @@ void ConnectionHandler::Handler::tune(uint16_t channelMax,
{
connection.setFrameMax(frameMax);
connection.setHeartbeat(heartbeatMax);
- server.tuneOk(channelMax, frameMax, heartbeatMax);
- server.open("/", Array(), true);
+ proxy.tuneOk(channelMax, frameMax, heartbeatMax);
+ proxy.open("/", Array(), true);
}
void ConnectionHandler::Handler::openOk(const framing::Array& knownHosts)
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.h b/qpid/cpp/src/qpid/broker/ConnectionHandler.h
index b24c10e9e8..ac4816dafa 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionHandler.h
+++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.h
@@ -25,10 +25,8 @@
#include "SaslAuthenticator.h"
#include "qpid/framing/amqp_types.h"
#include "qpid/framing/AMQFrame.h"
-#include "qpid/framing/AMQP_ClientOperations.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-#include "qpid/framing/AMQP_ServerOperations.h"
-#include "qpid/framing/AMQP_ServerProxy.h"
+#include "qpid/framing/AMQP_AllOperations.h"
+#include "qpid/framing/AMQP_AllProxy.h"
#include "qpid/framing/enum.h"
#include "qpid/framing/FrameHandler.h"
#include "qpid/framing/ProtocolInitiation.h"
@@ -44,11 +42,9 @@ class SecureConnection;
class ConnectionHandler : public framing::FrameHandler
{
- struct Handler : public framing::AMQP_ServerOperations::ConnectionHandler,
- public framing::AMQP_ClientOperations::ConnectionHandler
+ struct Handler : public framing::AMQP_AllOperations::ConnectionHandler
{
- framing::AMQP_ClientProxy::Connection client;
- framing::AMQP_ServerProxy::Connection server;
+ framing::AMQP_AllProxy::Connection proxy;
Connection& connection;
bool serverMode;
std::auto_ptr<SaslAuthenticator> authenticator;
diff --git a/qpid/cpp/src/qpid/broker/ConnectionState.h b/qpid/cpp/src/qpid/broker/ConnectionState.h
index 0e9d211b56..b712af11f5 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionState.h
+++ b/qpid/cpp/src/qpid/broker/ConnectionState.h
@@ -48,8 +48,9 @@ class ConnectionState : public ConnectionToken, public management::Manageable
heartbeatmax(120),
stagingThreshold(broker.getStagingThreshold()),
federationLink(true),
- clientSupportsThrottling(false)
- {}
+ clientSupportsThrottling(false),
+ clusterOrderOut(0)
+ {}
virtual ~ConnectionState () {}
@@ -75,7 +76,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable
const string& getFederationPeerTag() const { return federationPeerTag; }
std::vector<Url>& getKnownHosts() { return knownHosts; }
- void setClientThrottling() { clientSupportsThrottling = true; }
+ void setClientThrottling(bool set=true) { clientSupportsThrottling = set; }
bool getClientThrottling() const { return clientSupportsThrottling; }
Broker& getBroker() { return broker; }
@@ -86,11 +87,21 @@ class ConnectionState : public ConnectionToken, public management::Manageable
//contained output tasks
sys::AggregateOutput outputTasks;
- sys::ConnectionOutputHandlerPtr& getOutput() { return out; }
+ sys::ConnectionOutputHandler& getOutput() { return out; }
framing::ProtocolVersion getVersion() const { return version; }
-
void setOutputHandler(qpid::sys::ConnectionOutputHandler* o) { out.set(o); }
+ /**
+ * If the broker is part of a cluster, this is a handler provided
+ * by cluster code. It ensures consistent ordering of commands
+ * that are sent based on criteria that are not predictably
+ * ordered cluster-wide, e.g. a timer firing.
+ */
+ framing::FrameHandler* getClusterOrderOutput() { return clusterOrderOut; }
+ void setClusterOrderOutput(framing::FrameHandler& fh) { clusterOrderOut = &fh; }
+
+ virtual void requestIOProcessing (boost::function0<void>) = 0;
+
protected:
framing::ProtocolVersion version;
uint32_t framemax;
@@ -103,6 +114,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable
string federationPeerTag;
std::vector<Url> knownHosts;
bool clientSupportsThrottling;
+ framing::FrameHandler* clusterOrderOut;
};
}}
diff --git a/qpid/cpp/src/qpid/broker/Daemon.h b/qpid/cpp/src/qpid/broker/Daemon.h
index 98468debb7..a9cd98bce2 100644
--- a/qpid/cpp/src/qpid/broker/Daemon.h
+++ b/qpid/cpp/src/qpid/broker/Daemon.h
@@ -19,10 +19,12 @@
*
*/
-#include <string>
+#include "qpid/sys/IntegerTypes.h"
#include <boost/scoped_ptr.hpp>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
+#include <string>
+
namespace qpid {
namespace broker {
diff --git a/qpid/cpp/src/qpid/broker/DeliverableMessage.h b/qpid/cpp/src/qpid/broker/DeliverableMessage.h
index f5db473c22..ad944c746b 100644
--- a/qpid/cpp/src/qpid/broker/DeliverableMessage.h
+++ b/qpid/cpp/src/qpid/broker/DeliverableMessage.h
@@ -21,6 +21,7 @@
#ifndef _DeliverableMessage_
#define _DeliverableMessage_
+#include "BrokerImportExport.h"
#include "Deliverable.h"
#include "Queue.h"
#include "Message.h"
@@ -32,10 +33,10 @@ namespace qpid {
class DeliverableMessage : public Deliverable{
boost::intrusive_ptr<Message> msg;
public:
- DeliverableMessage(const boost::intrusive_ptr<Message>& msg);
- virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
- Message& getMessage();
- uint64_t contentSize();
+ QPID_BROKER_EXTERN DeliverableMessage(const boost::intrusive_ptr<Message>& msg);
+ QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
+ QPID_BROKER_EXTERN Message& getMessage();
+ QPID_BROKER_EXTERN uint64_t contentSize();
virtual ~DeliverableMessage(){}
};
}
diff --git a/qpid/cpp/src/qpid/broker/DeliveryRecord.h b/qpid/cpp/src/qpid/broker/DeliveryRecord.h
index d7ccab0726..2b2d4d0515 100644
--- a/qpid/cpp/src/qpid/broker/DeliveryRecord.h
+++ b/qpid/cpp/src/qpid/broker/DeliveryRecord.h
@@ -26,6 +26,7 @@
#include <vector>
#include <ostream>
#include "qpid/framing/SequenceSet.h"
+#include "BrokerImportExport.h"
#include "Queue.h"
#include "QueuedMessage.h"
#include "DeliveryId.h"
@@ -74,17 +75,16 @@ class DeliveryRecord
const uint32_t credit;
public:
- DeliveryRecord(
- const QueuedMessage& msg,
- const Queue::shared_ptr& queue,
- const std::string& tag,
- bool acquired,
- bool accepted,
- bool windowing,
- uint32_t credit=0 // Only used if msg is empty.
+ QPID_BROKER_EXTERN DeliveryRecord(const QueuedMessage& msg,
+ const Queue::shared_ptr& queue,
+ const std::string& tag,
+ bool acquired,
+ bool accepted,
+ bool windowing,
+ uint32_t credit=0 // Only used if msg is empty.
);
- bool matches(DeliveryId tag) const;
+ QPID_BROKER_EXTERN bool matches(DeliveryId tag) const;
bool matchOrAfter(DeliveryId tag) const;
bool after(DeliveryId tag) const;
bool coveredBy(const framing::SequenceSet* const range) const;
@@ -119,7 +119,7 @@ class DeliveryRecord
const QueuedMessage& getMessage() const { return msg; }
framing::SequenceNumber getId() const { return id; }
Queue::shared_ptr getQueue() const { return queue; }
- friend bool operator<(const DeliveryRecord&, const DeliveryRecord&);
+ friend QPID_BROKER_EXTERN bool operator<(const DeliveryRecord&, const DeliveryRecord&);
friend std::ostream& operator<<(std::ostream&, const DeliveryRecord&);
};
diff --git a/qpid/cpp/src/qpid/broker/DirectExchange.h b/qpid/cpp/src/qpid/broker/DirectExchange.h
index ba60469df8..27d101c4fe 100644
--- a/qpid/cpp/src/qpid/broker/DirectExchange.h
+++ b/qpid/cpp/src/qpid/broker/DirectExchange.h
@@ -23,6 +23,7 @@
#include <map>
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/CopyOnWriteArray.h"
@@ -44,18 +45,27 @@ class DirectExchange : public virtual Exchange {
public:
static const std::string typeName;
- DirectExchange(const std::string& name, management::Manageable* parent = 0);
- DirectExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args, management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN DirectExchange(const std::string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN DirectExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~DirectExchange();
+ QPID_BROKER_EXTERN virtual ~DirectExchange();
virtual bool supportsDynamicBinding() { return true; }
};
diff --git a/qpid/cpp/src/qpid/broker/DtxBuffer.h b/qpid/cpp/src/qpid/broker/DtxBuffer.h
index b302632037..ce37d09b7a 100644
--- a/qpid/cpp/src/qpid/broker/DtxBuffer.h
+++ b/qpid/cpp/src/qpid/broker/DtxBuffer.h
@@ -21,6 +21,7 @@
#ifndef _DtxBuffer_
#define _DtxBuffer_
+#include "BrokerImportExport.h"
#include "TxBuffer.h"
#include "qpid/sys/Mutex.h"
@@ -37,9 +38,9 @@ namespace qpid {
public:
typedef boost::shared_ptr<DtxBuffer> shared_ptr;
- DtxBuffer(const std::string& xid = "");
- ~DtxBuffer();
- void markEnded();
+ QPID_BROKER_EXTERN DtxBuffer(const std::string& xid = "");
+ QPID_BROKER_EXTERN ~DtxBuffer();
+ QPID_BROKER_EXTERN void markEnded();
bool isEnded();
void setSuspended(bool suspended);
bool isSuspended();
diff --git a/qpid/cpp/src/qpid/broker/DtxWorkRecord.h b/qpid/cpp/src/qpid/broker/DtxWorkRecord.h
index 6677784c32..21fc759d66 100644
--- a/qpid/cpp/src/qpid/broker/DtxWorkRecord.h
+++ b/qpid/cpp/src/qpid/broker/DtxWorkRecord.h
@@ -21,6 +21,7 @@
#ifndef _DtxWorkRecord_
#define _DtxWorkRecord_
+#include "BrokerImportExport.h"
#include "DtxBuffer.h"
#include "DtxTimeout.h"
#include "TransactionalStore.h"
@@ -61,12 +62,13 @@ class DtxWorkRecord
void abort();
bool prepare(TransactionContext* txn);
public:
- DtxWorkRecord(const std::string& xid, TransactionalStore* const store);
- ~DtxWorkRecord();
- bool prepare();
- bool commit(bool onePhase);
- void rollback();
- void add(DtxBuffer::shared_ptr ops);
+ QPID_BROKER_EXTERN DtxWorkRecord(const std::string& xid,
+ TransactionalStore* const store);
+ QPID_BROKER_EXTERN ~DtxWorkRecord();
+ QPID_BROKER_EXTERN bool prepare();
+ QPID_BROKER_EXTERN bool commit(bool onePhase);
+ QPID_BROKER_EXTERN void rollback();
+ QPID_BROKER_EXTERN void add(DtxBuffer::shared_ptr ops);
void recover(std::auto_ptr<TPCTransactionContext> txn, DtxBuffer::shared_ptr ops);
void timedout();
void setTimeout(boost::intrusive_ptr<DtxTimeout> t) { timeout = t; }
diff --git a/qpid/cpp/src/qpid/broker/Exchange.cpp b/qpid/cpp/src/qpid/broker/Exchange.cpp
index f8b9e4b183..dd1fe98b2c 100644
--- a/qpid/cpp/src/qpid/broker/Exchange.cpp
+++ b/qpid/cpp/src/qpid/broker/Exchange.cpp
@@ -102,8 +102,8 @@ static const std::string QPID_MANAGEMENT("qpid.management");
Exchange::Exchange(const string& _name, bool _durable, const qpid::framing::FieldTable& _args,
Manageable* parent)
- : name(_name), durable(_durable), args(_args), alternateUsers(0), persistenceId(0),
- sequence(false), sequenceNo(0), ive(false), mgmtExchange(0)
+ : name(_name), durable(_durable), alternateUsers(0), persistenceId(0),
+ args(_args), sequence(false), sequenceNo(0), ive(false), mgmtExchange(0)
{
if (parent != 0)
{
@@ -275,3 +275,7 @@ bool Exchange::MatchQueue::operator()(Exchange::Binding::shared_ptr b)
{
return b->queue == queue;
}
+
+void Exchange::setProperties(const boost::intrusive_ptr<Message>& msg) {
+ msg->getProperties<DeliveryProperties>()->setExchange(getName());
+}
diff --git a/qpid/cpp/src/qpid/broker/Exchange.h b/qpid/cpp/src/qpid/broker/Exchange.h
index 488549bbf6..9260222342 100644
--- a/qpid/cpp/src/qpid/broker/Exchange.h
+++ b/qpid/cpp/src/qpid/broker/Exchange.h
@@ -23,6 +23,7 @@
*/
#include <boost/shared_ptr.hpp>
+#include "BrokerImportExport.h"
#include "Deliverable.h"
#include "Queue.h"
#include "MessageStore.h"
@@ -58,12 +59,12 @@ public:
private:
const std::string name;
const bool durable;
- mutable qpid::framing::FieldTable args;
boost::shared_ptr<Exchange> alternate;
uint32_t alternateUsers;
mutable uint64_t persistenceId;
protected:
+ mutable qpid::framing::FieldTable args;
bool sequence;
mutable qpid::sys::Mutex sequenceLock;
int64_t sequenceNo;
@@ -123,7 +124,7 @@ public:
explicit Exchange(const std::string& name, management::Manageable* parent = 0);
Exchange(const std::string& _name, bool _durable, const qpid::framing::FieldTable& _args,
management::Manageable* parent = 0);
- virtual ~Exchange();
+ QPID_BROKER_EXTERN virtual ~Exchange();
const std::string& getName() const { return name; }
bool isDurable() { return durable; }
@@ -139,15 +140,16 @@ public:
virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
virtual bool isBound(Queue::shared_ptr queue, const std::string* const routingKey, const qpid::framing::FieldTable* const args) = 0;
+ virtual void setProperties(const boost::intrusive_ptr<Message>&);
virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
-
+
//PersistableExchange:
void setPersistenceId(uint64_t id) const;
uint64_t getPersistenceId() const { return persistenceId; }
uint32_t encodedSize() const;
- void encode(framing::Buffer& buffer) const;
+ QPID_BROKER_EXTERN virtual void encode(framing::Buffer& buffer) const;
- static Exchange::shared_ptr decode(ExchangeRegistry& exchanges, framing::Buffer& buffer);
+ static QPID_BROKER_EXTERN Exchange::shared_ptr decode(ExchangeRegistry& exchanges, framing::Buffer& buffer);
// Manageable entry points
management::ManagementObject* GetManagementObject(void) const;
diff --git a/qpid/cpp/src/qpid/broker/ExchangeRegistry.h b/qpid/cpp/src/qpid/broker/ExchangeRegistry.h
index 787b7896f0..9ca432e41c 100644
--- a/qpid/cpp/src/qpid/broker/ExchangeRegistry.h
+++ b/qpid/cpp/src/qpid/broker/ExchangeRegistry.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "MessageStore.h"
#include "qpid/framing/FieldTable.h"
@@ -45,13 +46,17 @@ class ExchangeRegistry{
bool, const qpid::framing::FieldTable&, qpid::management::Manageable*> FactoryFunction;
ExchangeRegistry () : parent(0) {}
- std::pair<Exchange::shared_ptr, bool> declare(const std::string& name, const std::string& type)
+ QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare
+ (const std::string& name, const std::string& type)
throw(UnknownExchangeTypeException);
- std::pair<Exchange::shared_ptr, bool> declare(const std::string& name, const std::string& type,
- bool durable, const qpid::framing::FieldTable& args = framing::FieldTable())
- throw(UnknownExchangeTypeException);
- void destroy(const std::string& name);
- Exchange::shared_ptr get(const std::string& name);
+ QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare
+ (const std::string& name,
+ const std::string& type,
+ bool durable,
+ const qpid::framing::FieldTable& args = framing::FieldTable())
+ throw(UnknownExchangeTypeException);
+ QPID_BROKER_EXTERN void destroy(const std::string& name);
+ QPID_BROKER_EXTERN Exchange::shared_ptr get(const std::string& name);
Exchange::shared_ptr getDefault();
/**
diff --git a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
index 1b7316f6f9..cefe9b7552 100644
--- a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
@@ -23,6 +23,7 @@
*/
#include "qpid/RefCounted.h"
+#include "BrokerImportExport.h"
namespace qpid {
namespace broker {
@@ -35,9 +36,9 @@ class Message;
class ExpiryPolicy : public RefCounted
{
public:
- virtual ~ExpiryPolicy();
- virtual void willExpire(Message&);
- virtual bool hasExpired(Message&);
+ QPID_BROKER_EXTERN virtual ~ExpiryPolicy();
+ QPID_BROKER_EXTERN virtual void willExpire(Message&);
+ QPID_BROKER_EXTERN virtual bool hasExpired(Message&);
};
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/FanOutExchange.h b/qpid/cpp/src/qpid/broker/FanOutExchange.h
index 5884a19732..edfc4395f4 100644
--- a/qpid/cpp/src/qpid/broker/FanOutExchange.h
+++ b/qpid/cpp/src/qpid/broker/FanOutExchange.h
@@ -23,6 +23,7 @@
#include <map>
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/CopyOnWriteArray.h"
@@ -38,22 +39,30 @@ class FanOutExchange : public virtual Exchange {
public:
static const std::string typeName;
- FanOutExchange(const std::string& name, management::Manageable* parent = 0);
- FanOutExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN FanOutExchange(const std::string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN FanOutExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~FanOutExchange();
+ QPID_BROKER_EXTERN virtual ~FanOutExchange();
virtual bool supportsDynamicBinding() { return true; }
};
diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
index 104b34da8b..09fb2d9bef 100644
--- a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
+++ b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
@@ -105,33 +105,42 @@ bool HeadersExchange::unbind(Queue::shared_ptr queue, const string& bindingKey,
void HeadersExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* args){
- if (!args) return;//can't match if there were no headers passed in
+ if (!args) {
+ //can't match if there were no headers passed in
+ if (mgmtExchange != 0) {
+ mgmtExchange->inc_msgReceives();
+ mgmtExchange->inc_byteReceives(msg.contentSize());
+ mgmtExchange->inc_msgDrops();
+ mgmtExchange->inc_byteDrops(msg.contentSize());
+ }
+ return;
+ }
+
PreRoute pr(msg, this);
uint32_t count(0);
Bindings::ConstPtr p = bindings.snapshot();
if (p.get()){
- for (std::vector<Binding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); ++i, count++) {
- if (match((*i)->args, *args)) msg.deliverTo((*i)->queue);
- if ((*i)->mgmtBinding != 0)
- (*i)->mgmtBinding->inc_msgMatched ();
+ for (std::vector<Binding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); ++i) {
+ if (match((*i)->args, *args)) {
+ msg.deliverTo((*i)->queue);
+ count++;
+ if ((*i)->mgmtBinding != 0)
+ (*i)->mgmtBinding->inc_msgMatched();
+ }
}
}
- if (mgmtExchange != 0)
- {
- mgmtExchange->inc_msgReceives ();
- mgmtExchange->inc_byteReceives (msg.contentSize ());
- if (count == 0)
- {
- mgmtExchange->inc_msgDrops ();
- mgmtExchange->inc_byteDrops (msg.contentSize ());
- }
- else
- {
- mgmtExchange->inc_msgRoutes (count);
- mgmtExchange->inc_byteRoutes (count * msg.contentSize ());
+ if (mgmtExchange != 0) {
+ mgmtExchange->inc_msgReceives();
+ mgmtExchange->inc_byteReceives(msg.contentSize());
+ if (count == 0) {
+ mgmtExchange->inc_msgDrops();
+ mgmtExchange->inc_byteDrops(msg.contentSize());
+ } else {
+ mgmtExchange->inc_msgRoutes(count);
+ mgmtExchange->inc_byteRoutes(count * msg.contentSize());
}
}
}
diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.h b/qpid/cpp/src/qpid/broker/HeadersExchange.h
index e10fab2250..2b01f9ecae 100644
--- a/qpid/cpp/src/qpid/broker/HeadersExchange.h
+++ b/qpid/cpp/src/qpid/broker/HeadersExchange.h
@@ -22,6 +22,7 @@
#define _HeadersExchange_
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/CopyOnWriteArray.h"
@@ -59,24 +60,32 @@ class HeadersExchange : public virtual Exchange {
public:
static const std::string typeName;
- HeadersExchange(const string& name, management::Manageable* parent = 0);
- HeadersExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN HeadersExchange(const string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN HeadersExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~HeadersExchange();
+ QPID_BROKER_EXTERN virtual ~HeadersExchange();
- static bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
+ static QPID_BROKER_EXTERN bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
static bool equal(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
};
diff --git a/qpid/cpp/src/qpid/broker/IncompleteMessageList.h b/qpid/cpp/src/qpid/broker/IncompleteMessageList.h
index f89c0023b0..449194d571 100644
--- a/qpid/cpp/src/qpid/broker/IncompleteMessageList.h
+++ b/qpid/cpp/src/qpid/broker/IncompleteMessageList.h
@@ -21,6 +21,7 @@
#ifndef _IncompleteMessageList_
#define _IncompleteMessageList_
+#include "BrokerImportExport.h"
#include "qpid/sys/Monitor.h"
#include "qpid/broker/Message.h"
#include <boost/intrusive_ptr.hpp>
@@ -43,11 +44,11 @@ class IncompleteMessageList
public:
typedef Message::MessageCallback CompletionListener;
- IncompleteMessageList();
- ~IncompleteMessageList();
+ QPID_BROKER_EXTERN IncompleteMessageList();
+ QPID_BROKER_EXTERN ~IncompleteMessageList();
- void add(boost::intrusive_ptr<Message> msg);
- void process(const CompletionListener& l, bool sync);
+ QPID_BROKER_EXTERN void add(boost::intrusive_ptr<Message> msg);
+ QPID_BROKER_EXTERN void process(const CompletionListener& l, bool sync);
void each(const CompletionListener& l);
};
diff --git a/qpid/cpp/src/qpid/broker/Link.cpp b/qpid/cpp/src/qpid/broker/Link.cpp
index e36635831b..dd1a1fa0b4 100644
--- a/qpid/cpp/src/qpid/broker/Link.cpp
+++ b/qpid/cpp/src/qpid/broker/Link.cpp
@@ -158,7 +158,7 @@ void Link::closed (int, std::string text)
}
for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
- (*i)->cancel();
+ (*i)->closed();
created.push_back(*i);
}
active.clear();
@@ -217,21 +217,27 @@ void Link::add(Bridge::shared_ptr bridge)
void Link::cancel(Bridge::shared_ptr bridge)
{
- Mutex::ScopedLock mutex(lock);
-
- for (Bridges::iterator i = created.begin(); i != created.end(); i++) {
- if ((*i).get() == bridge.get()) {
- created.erase(i);
- break;
+ {
+ Mutex::ScopedLock mutex(lock);
+
+ for (Bridges::iterator i = created.begin(); i != created.end(); i++) {
+ if ((*i).get() == bridge.get()) {
+ created.erase(i);
+ break;
+ }
}
- }
- for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
- if ((*i).get() == bridge.get()) {
- bridge->cancel();
- active.erase(i);
- break;
+ for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
+ if ((*i).get() == bridge.get()) {
+ cancellations.push_back(bridge);
+ bridge->closed();
+ active.erase(i);
+ break;
+ }
}
}
+ if (!cancellations.empty()) {
+ connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
+ }
}
void Link::ioThreadProcessing()
@@ -242,7 +248,7 @@ void Link::ioThreadProcessing()
return;
QPID_LOG(debug, "Link::ioThreadProcessing()");
- //process any pending creates
+ //process any pending creates and/or cancellations
if (!created.empty()) {
for (Bridges::iterator i = created.begin(); i != created.end(); ++i) {
active.push_back(*i);
@@ -250,6 +256,13 @@ void Link::ioThreadProcessing()
}
created.clear();
}
+ if (!cancellations.empty()) {
+ for (Bridges::iterator i = cancellations.begin(); i != cancellations.end(); ++i) {
+ active.push_back(*i);
+ (*i)->cancel(*connection);
+ }
+ cancellations.clear();
+ }
}
void Link::setConnection(Connection* c)
@@ -284,7 +297,7 @@ void Link::maintenanceVisit ()
}
}
}
- else if (state == STATE_OPERATIONAL && !created.empty() && connection != 0)
+ else if (state == STATE_OPERATIONAL && (!created.empty() || !cancellations.empty()) && connection != 0)
connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
}
diff --git a/qpid/cpp/src/qpid/broker/Link.h b/qpid/cpp/src/qpid/broker/Link.h
index 8e741c6eb7..39014b0ec0 100644
--- a/qpid/cpp/src/qpid/broker/Link.h
+++ b/qpid/cpp/src/qpid/broker/Link.h
@@ -67,6 +67,7 @@ namespace qpid {
typedef std::vector<Bridge::shared_ptr> Bridges;
Bridges created; // Bridges pending creation
Bridges active; // Bridges active
+ Bridges cancellations; // Bridges pending cancellation
uint channelCounter;
Connection* connection;
management::ManagementAgent* agent;
diff --git a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
index 97b1c32d64..7d4ab7548e 100644
--- a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
+++ b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
@@ -19,19 +19,24 @@
*
*/
#include "LinkRegistry.h"
+#include "Connection.h"
#include "qpid/log/Statement.h"
#include <iostream>
+#include <boost/format.hpp>
using namespace qpid::broker;
using namespace qpid::sys;
using std::pair;
using std::stringstream;
using boost::intrusive_ptr;
+using boost::format;
+using boost::str;
namespace _qmf = qmf::org::apache::qpid::broker;
#define LINK_MAINT_INTERVAL 2
-LinkRegistry::LinkRegistry (Broker* _broker) : broker(_broker), parent(0), store(0), passive(false), passiveChanged(false)
+LinkRegistry::LinkRegistry (Broker* _broker) : broker(_broker), parent(0), store(0), passive(false), passiveChanged(false),
+ realm(broker ? broker->getOptions().realm : "")
{
timer.add (intrusive_ptr<TimerTask> (new Periodic(*this)));
}
@@ -233,66 +238,70 @@ MessageStore* LinkRegistry::getStore() const {
return store;
}
-void LinkRegistry::notifyConnection(const std::string& key, Connection* c)
+Link::shared_ptr LinkRegistry::findLink(const std::string& key)
{
Mutex::ScopedLock locker(lock);
LinkMap::iterator l = links.find(key);
- if (l != links.end())
- {
- l->second->established();
- l->second->setConnection(c);
+ if (l != links.end()) return l->second;
+ else return Link::shared_ptr();
+}
+
+void LinkRegistry::notifyConnection(const std::string& key, Connection* c)
+{
+ Link::shared_ptr link = findLink(key);
+ if (link) {
+ link->established();
+ link->setConnection(c);
+ c->setUserId(str(format("%1%@%2%") % link->getUsername() % realm));
}
}
void LinkRegistry::notifyClosed(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l != links.end())
- l->second->closed(0, "Closed by peer");
+ Link::shared_ptr link = findLink(key);
+ if (link) {
+ link->closed(0, "Closed by peer");
+ }
}
void LinkRegistry::notifyConnectionForced(const std::string& key, const std::string& text)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l != links.end())
- l->second->notifyConnectionForced(text);
+ Link::shared_ptr link = findLink(key);
+ if (link) {
+ link->notifyConnectionForced(text);
+ }
}
std::string LinkRegistry::getAuthMechanism(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l != links.end())
- return l->second->getAuthMechanism();
+ Link::shared_ptr link = findLink(key);
+ if (link)
+ return link->getAuthMechanism();
return string("ANONYMOUS");
}
std::string LinkRegistry::getAuthCredentials(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l == links.end())
+ Link::shared_ptr link = findLink(key);
+ if (!link)
return string();
string result;
result += '\0';
- result += l->second->getUsername();
+ result += link->getUsername();
result += '\0';
- result += l->second->getPassword();
+ result += link->getPassword();
return result;
}
std::string LinkRegistry::getAuthIdentity(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l == links.end())
+ Link::shared_ptr link = findLink(key);
+ if (!link)
return string();
- return l->second->getUsername();
+ return link->getUsername();
}
diff --git a/qpid/cpp/src/qpid/broker/LinkRegistry.h b/qpid/cpp/src/qpid/broker/LinkRegistry.h
index 884228bd63..2397dbc6f3 100644
--- a/qpid/cpp/src/qpid/broker/LinkRegistry.h
+++ b/qpid/cpp/src/qpid/broker/LinkRegistry.h
@@ -66,9 +66,11 @@ namespace broker {
MessageStore* store;
bool passive;
bool passiveChanged;
+ std::string realm;
void periodicMaintenance ();
bool updateAddress(const std::string& oldKey, const TcpAddress& newAddress);
+ Link::shared_ptr findLink(const std::string& key);
static std::string createKey(const TcpAddress& address);
public:
diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp
index 133e2b5ad1..40b5515829 100644
--- a/qpid/cpp/src/qpid/broker/Message.cpp
+++ b/qpid/cpp/src/qpid/broker/Message.cpp
@@ -160,6 +160,7 @@ void Message::decodeContent(framing::Buffer& buffer)
//body on a frame then add that frame to the frameset
AMQFrame frame((AMQContentBody()));
frame.castBody<AMQContentBody>()->decode(buffer, buffer.available());
+ frame.setFirstSegment(false);
frames.append(frame);
} else {
//adjust header flags
@@ -382,4 +383,9 @@ void Message::resetEnqueueCompleteCallback() { enqueueCallback = 0; }
void Message::setDequeueCompleteCallback(MessageCallback& cb) { dequeueCallback = &cb; }
void Message::resetDequeueCompleteCallback() { dequeueCallback = 0; }
+framing::FieldTable& Message::getOrInsertHeaders()
+{
+ return getProperties<MessageProperties>()->getApplicationHeaders();
+}
+
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/Message.h b/qpid/cpp/src/qpid/broker/Message.h
index 96fcf61dfc..458c6c7d1a 100644
--- a/qpid/cpp/src/qpid/broker/Message.h
+++ b/qpid/cpp/src/qpid/broker/Message.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "PersistableMessage.h"
#include "MessageAdapter.h"
#include "qpid/framing/amqp_types.h"
@@ -51,8 +52,8 @@ class Message : public PersistableMessage {
public:
typedef boost::function<void (const boost::intrusive_ptr<Message>&)> MessageCallback;
- Message(const framing::SequenceNumber& id = framing::SequenceNumber());
- ~Message();
+ QPID_BROKER_EXTERN Message(const framing::SequenceNumber& id = framing::SequenceNumber());
+ QPID_BROKER_EXTERN ~Message();
uint64_t getPersistenceId() const { return persistenceId; }
void setPersistenceId(uint64_t _persistenceId) const { persistenceId = _persistenceId; }
@@ -65,17 +66,18 @@ public:
const framing::SequenceNumber& getCommandId() { return frames.getId(); }
- uint64_t contentSize() const;
+ QPID_BROKER_EXTERN uint64_t contentSize() const;
- std::string getRoutingKey() const;
+ QPID_BROKER_EXTERN std::string getRoutingKey() const;
const boost::shared_ptr<Exchange> getExchange(ExchangeRegistry&) const;
- std::string getExchangeName() const;
+ QPID_BROKER_EXTERN std::string getExchangeName() const;
bool isImmediate() const;
- const framing::FieldTable* getApplicationHeaders() const;
- bool isPersistent();
+ QPID_BROKER_EXTERN const framing::FieldTable* getApplicationHeaders() const;
+ framing::FieldTable& getOrInsertHeaders();
+ QPID_BROKER_EXTERN bool isPersistent();
bool requiresAccept();
- void setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e);
+ QPID_BROKER_EXTERN void setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e);
void setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e);
bool hasExpired();
sys::AbsTime getExpiration() const { return expiration; }
@@ -124,8 +126,8 @@ public:
uint32_t encodedHeaderSize() const;
uint32_t encodedContentSize() const;
- void decodeHeader(framing::Buffer& buffer);
- void decodeContent(framing::Buffer& buffer);
+ QPID_BROKER_EXTERN void decodeHeader(framing::Buffer& buffer);
+ QPID_BROKER_EXTERN void decodeContent(framing::Buffer& buffer);
/**
* Releases the in-memory content data held by this
@@ -139,7 +141,7 @@ public:
void sendContent(const Queue& queue, framing::FrameHandler& out, uint16_t maxFrameSize) const;
void sendHeader(framing::FrameHandler& out, uint16_t maxFrameSize) const;
- bool isContentLoaded() const;
+ QPID_BROKER_EXTERN bool isContentLoaded() const;
bool isExcluded(const std::vector<std::string>& excludes) const;
void addTraceId(const std::string& id);
diff --git a/qpid/cpp/src/qpid/broker/MessageBuilder.h b/qpid/cpp/src/qpid/broker/MessageBuilder.h
index 395de024ab..1f5a2a8b84 100644
--- a/qpid/cpp/src/qpid/broker/MessageBuilder.h
+++ b/qpid/cpp/src/qpid/broker/MessageBuilder.h
@@ -21,6 +21,7 @@
#ifndef _MessageBuilder_
#define _MessageBuilder_
+#include "BrokerImportExport.h"
#include "qpid/framing/FrameHandler.h"
#include "qpid/framing/SequenceNumber.h"
#include "qpid/RefCounted.h"
@@ -34,10 +35,11 @@ namespace qpid {
class MessageBuilder : public framing::FrameHandler{
public:
- MessageBuilder(MessageStore* const store, uint64_t stagingThreshold);
- void handle(framing::AMQFrame& frame);
+ QPID_BROKER_EXTERN MessageBuilder(MessageStore* const store,
+ uint64_t stagingThreshold);
+ QPID_BROKER_EXTERN void handle(framing::AMQFrame& frame);
boost::intrusive_ptr<Message> getMessage() { return message; }
- void start(const framing::SequenceNumber& id);
+ QPID_BROKER_EXTERN void start(const framing::SequenceNumber& id);
void end();
private:
enum State {DORMANT, METHOD, HEADER, CONTENT};
diff --git a/qpid/cpp/src/qpid/broker/NullMessageStore.h b/qpid/cpp/src/qpid/broker/NullMessageStore.h
index d99c751d26..a44f8d2804 100644
--- a/qpid/cpp/src/qpid/broker/NullMessageStore.h
+++ b/qpid/cpp/src/qpid/broker/NullMessageStore.h
@@ -22,6 +22,7 @@
#define _NullMessageStore_
#include <set>
+#include "BrokerImportExport.h"
#include "MessageStore.h"
#include "Queue.h"
@@ -38,46 +39,54 @@ class NullMessageStore : public MessageStore
std::set<std::string> prepared;
uint64_t nextPersistenceId;
public:
- NullMessageStore();
+ QPID_BROKER_EXTERN NullMessageStore();
- virtual bool init(const Options* options);
- virtual std::auto_ptr<TransactionContext> begin();
- virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid);
- virtual void prepare(TPCTransactionContext& txn);
- virtual void commit(TransactionContext& txn);
- virtual void abort(TransactionContext& txn);
- virtual void collectPreparedXids(std::set<std::string>& xids);
+ QPID_BROKER_EXTERN virtual bool init(const Options* options);
+ QPID_BROKER_EXTERN virtual std::auto_ptr<TransactionContext> begin();
+ QPID_BROKER_EXTERN virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid);
+ QPID_BROKER_EXTERN virtual void prepare(TPCTransactionContext& txn);
+ QPID_BROKER_EXTERN virtual void commit(TransactionContext& txn);
+ QPID_BROKER_EXTERN virtual void abort(TransactionContext& txn);
+ QPID_BROKER_EXTERN virtual void collectPreparedXids(std::set<std::string>& xids);
- virtual void create(PersistableQueue& queue, const framing::FieldTable& args);
- virtual void destroy(PersistableQueue& queue);
- virtual void create(const PersistableExchange& exchange, const framing::FieldTable& args);
- virtual void destroy(const PersistableExchange& exchange);
+ QPID_BROKER_EXTERN virtual void create(PersistableQueue& queue,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void destroy(PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void create(const PersistableExchange& exchange,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void destroy(const PersistableExchange& exchange);
- virtual void bind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args);
- virtual void unbind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args);
- virtual void create(const PersistableConfig& config);
- virtual void destroy(const PersistableConfig& config);
- virtual void recover(RecoveryManager& queues);
- virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg);
- virtual void destroy(PersistableMessage& msg);
- virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg,
- const std::string& data);
- virtual void loadContent(const qpid::broker::PersistableQueue& queue,
- const boost::intrusive_ptr<const PersistableMessage>& msg, std::string& data,
- uint64_t offset, uint32_t length);
- virtual void enqueue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- virtual void dequeue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue);
- virtual void flush(const qpid::broker::PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void bind(const PersistableExchange& exchange,
+ const PersistableQueue& queue,
+ const std::string& key,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void unbind(const PersistableExchange& exchange,
+ const PersistableQueue& queue,
+ const std::string& key,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void create(const PersistableConfig& config);
+ QPID_BROKER_EXTERN virtual void destroy(const PersistableConfig& config);
+ QPID_BROKER_EXTERN virtual void recover(RecoveryManager& queues);
+ QPID_BROKER_EXTERN virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg);
+ QPID_BROKER_EXTERN virtual void destroy(PersistableMessage& msg);
+ QPID_BROKER_EXTERN virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg,
+ const std::string& data);
+ QPID_BROKER_EXTERN virtual void loadContent(const qpid::broker::PersistableQueue& queue,
+ const boost::intrusive_ptr<const PersistableMessage>& msg,
+ std::string& data,
+ uint64_t offset,
+ uint32_t length);
+ QPID_BROKER_EXTERN virtual void enqueue(TransactionContext* ctxt,
+ const boost::intrusive_ptr<PersistableMessage>& msg,
+ const PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void dequeue(TransactionContext* ctxt,
+ const boost::intrusive_ptr<PersistableMessage>& msg,
+ const PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void flush(const qpid::broker::PersistableQueue& queue);
~NullMessageStore(){}
- virtual bool isNull() const;
+ QPID_BROKER_EXTERN virtual bool isNull() const;
static bool isNullStore(const MessageStore*);
};
diff --git a/qpid/cpp/src/qpid/broker/PersistableMessage.h b/qpid/cpp/src/qpid/broker/PersistableMessage.h
index 4f2e3abafa..92f89ba578 100644
--- a/qpid/cpp/src/qpid/broker/PersistableMessage.h
+++ b/qpid/cpp/src/qpid/broker/PersistableMessage.h
@@ -26,6 +26,7 @@
#include <list>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
+#include "BrokerImportExport.h"
#include "Persistable.h"
#include "qpid/framing/amqp_types.h"
#include "qpid/sys/Mutex.h"
@@ -93,21 +94,23 @@ class PersistableMessage : public Persistable
bool isContentReleased() const;
- bool isEnqueueComplete();
+ QPID_BROKER_EXTERN bool isEnqueueComplete();
- void enqueueComplete();
+ QPID_BROKER_EXTERN void enqueueComplete();
- void enqueueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store);
+ QPID_BROKER_EXTERN void enqueueAsync(PersistableQueue::shared_ptr queue,
+ MessageStore* _store);
- void enqueueAsync();
+ QPID_BROKER_EXTERN void enqueueAsync();
- bool isDequeueComplete();
+ QPID_BROKER_EXTERN bool isDequeueComplete();
- void dequeueComplete();
+ QPID_BROKER_EXTERN void dequeueComplete();
- void dequeueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store);
+ QPID_BROKER_EXTERN void dequeueAsync(PersistableQueue::shared_ptr queue,
+ MessageStore* _store);
- void dequeueAsync();
+ QPID_BROKER_EXTERN void dequeueAsync();
};
}}
diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp
index 3ae53c8ea9..aa0cd8ca31 100644
--- a/qpid/cpp/src/qpid/broker/Queue.cpp
+++ b/qpid/cpp/src/qpid/broker/Queue.cpp
@@ -32,6 +32,7 @@
#include "qpid/log/Statement.h"
#include "qpid/management/ManagementBroker.h"
#include "qpid/framing/reply_exceptions.h"
+#include "qpid/framing/FieldTable.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Time.h"
#include "qmf/org/apache/qpid/broker/ArgsQueuePurge.h"
@@ -68,6 +69,9 @@ const std::string qpidLastValueQueueNoBrowse("qpid.last_value_queue_no_browse");
const std::string qpidPersistLastNode("qpid.persist_last_node");
const std::string qpidVQMatchProperty("qpid.LVQ_key");
const std::string qpidQueueEventGeneration("qpid.queue_event_generation");
+//following feature is not ready for general use as it doesn't handle
+//the case where a message is enqueued on more than one queue well enough:
+const std::string qpidInsertSequenceNumbers("qpid.insert_sequence_numbers");
const int ENQUEUE_ONLY=1;
const int ENQUEUE_AND_DEQUEUE=2;
@@ -93,7 +97,8 @@ Queue::Queue(const string& _name, bool _autodelete,
policyExceeded(false),
mgmtObject(0),
eventMode(0),
- eventMgr(0)
+ eventMgr(0),
+ insertSeqNo(0)
{
if (parent != 0)
{
@@ -176,7 +181,7 @@ void Queue::deliver(boost::intrusive_ptr<Message>& msg){
void Queue::recover(boost::intrusive_ptr<Message>& msg){
- push(msg);
+ push(msg, true);
msg->enqueueComplete(); // mark the message as enqueued
mgntEnqStats(msg);
@@ -545,12 +550,13 @@ void Queue::popMsg(QueuedMessage& qmsg)
++dequeueTracker;
}
-void Queue::push(boost::intrusive_ptr<Message>& msg){
+void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){
QueueListeners::NotificationSet copy;
{
Mutex::ScopedLock locker(messageLock);
QueuedMessage qm(this, msg, ++sequence);
if (policy.get()) policy->tryEnqueue(qm);
+ if (insertSeqNo) msg->getOrInsertHeaders().setInt64(seqNoKey, sequence);
LVQ::iterator i;
const framing::FieldTable* ft = msg->getApplicationHeaders();
@@ -566,14 +572,21 @@ void Queue::push(boost::intrusive_ptr<Message>& msg){
boost::intrusive_ptr<Message> old = i->second->getReplacementMessage(this);
if (!old) old = i->second;
i->second->setReplacementMessage(msg,this);
- dequeued(QueuedMessage(qm.queue, old, qm.position));
+ if (isRecovery) {
+ //can't issue new requests for the store until
+ //recovery is complete
+ pendingDequeues.push_back(QueuedMessage(qm.queue, old, qm.position));
+ } else {
+ dequeue(0, QueuedMessage(qm.queue, old, qm.position));
+ }
}
}else {
messages.push_back(qm);
listeners.populate(copy);
}
- if (eventMode && eventMgr) {
- eventMgr->enqueued(qm);
+ if (eventMode) {
+ if (eventMgr) eventMgr->enqueued(qm);
+ else QPID_LOG(warning, "Enqueue manager not set, events not generated for " << getName());
}
}
copy.notify();
@@ -664,7 +677,7 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg)
msg->addTraceId(traceId);
}
- if (msg->isPersistent() && store && !lastValueQueue) {
+ if (msg->isPersistent() && store) {
msg->enqueueAsync(shared_from_this(), store); //increment to async counter -- for message sent to more than one queue
boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg);
store->enqueue(ctxt, pmsg, *this);
@@ -676,14 +689,14 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg)
// return true if store exists,
bool Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
{
- if (policy.get() && !policy->isEnqueued(msg)) return false;
{
Mutex::ScopedLock locker(messageLock);
+ if (policy.get() && !policy->isEnqueued(msg)) return false;
if (!ctxt) {
dequeued(msg);
}
}
- if (msg.payload->isPersistent() && store && !lastValueQueue) {
+ if (msg.payload->isPersistent() && store) {
msg.payload->dequeueAsync(shared_from_this(), store); //increment to async counter -- for message sent to more than one queue
boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg.payload);
store->dequeue(ctxt, pmsg, *this);
@@ -765,6 +778,9 @@ void Queue::configure(const FieldTable& _settings, bool recovering)
eventMode = _settings.getAsInt(qpidQueueEventGeneration);
+ FieldTable::ValuePtr p =_settings.get(qpidInsertSequenceNumbers);
+ if (p && p->convertsTo<std::string>()) insertSequenceNumbers(p->get<std::string>());
+
if (mgmtObject != 0)
mgmtObject->set_arguments (_settings);
@@ -976,3 +992,17 @@ void Queue::setQueueEventManager(QueueEvents& mgr)
{
eventMgr = &mgr;
}
+
+void Queue::recoveryComplete()
+{
+ //process any pending dequeues
+ for_each(pendingDequeues.begin(), pendingDequeues.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
+ pendingDequeues.clear();
+}
+
+void Queue::insertSequenceNumbers(const std::string& key)
+{
+ seqNoKey = key;
+ insertSeqNo = !seqNoKey.empty();
+ QPID_LOG(debug, "Inserting sequence numbers as " << key);
+}
diff --git a/qpid/cpp/src/qpid/broker/Queue.h b/qpid/cpp/src/qpid/broker/Queue.h
index 14849b3c8e..d1f71581d6 100644
--- a/qpid/cpp/src/qpid/broker/Queue.h
+++ b/qpid/cpp/src/qpid/broker/Queue.h
@@ -21,6 +21,8 @@
* under the License.
*
*/
+
+#include "BrokerImportExport.h"
#include "OwnershipToken.h"
#include "Consumer.h"
#include "Message.h"
@@ -85,6 +87,7 @@ namespace qpid {
std::vector<std::string> traceExclude;
QueueListeners listeners;
Messages messages;
+ Messages pendingDequeues;//used to avoid dequeuing during recovery
LVQ lvq;
mutable qpid::sys::Mutex consumerLock;
mutable qpid::sys::Mutex messageLock;
@@ -100,8 +103,10 @@ namespace qpid {
RateTracker dequeueTracker;
int eventMode;
QueueEvents* eventMgr;
+ bool insertSeqNo;
+ std::string seqNoKey;
- void push(boost::intrusive_ptr<Message>& msg);
+ void push(boost::intrusive_ptr<Message>& msg, bool isRecovery=false);
void setPolicy(std::auto_ptr<QueuePolicy> policy);
bool seek(QueuedMessage& msg, Consumer::shared_ptr position);
bool getNextMessage(QueuedMessage& msg, Consumer::shared_ptr c);
@@ -149,13 +154,14 @@ namespace qpid {
typedef std::vector<shared_ptr> vector;
- Queue(const string& name, bool autodelete = false,
- MessageStore* const store = 0,
- const OwnershipToken* const owner = 0,
- management::Manageable* parent = 0);
- ~Queue();
+ QPID_BROKER_EXTERN Queue(const string& name,
+ bool autodelete = false,
+ MessageStore* const store = 0,
+ const OwnershipToken* const owner = 0,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN ~Queue();
- bool dispatch(Consumer::shared_ptr);
+ QPID_BROKER_EXTERN bool dispatch(Consumer::shared_ptr);
/**
* Check whether there would be a message available for
* dispatch to this consumer. If not, the consumer will be
@@ -167,24 +173,28 @@ namespace qpid {
void create(const qpid::framing::FieldTable& settings);
// "recovering" means we are doing a MessageStore recovery.
- void configure(const qpid::framing::FieldTable& settings, bool recovering = false);
+ QPID_BROKER_EXTERN void configure(const qpid::framing::FieldTable& settings,
+ bool recovering = false);
void destroy();
- void bound(const string& exchange, const string& key, const qpid::framing::FieldTable& args);
- void unbind(ExchangeRegistry& exchanges, Queue::shared_ptr shared_ref);
+ QPID_BROKER_EXTERN void bound(const string& exchange,
+ const string& key,
+ const qpid::framing::FieldTable& args);
+ QPID_BROKER_EXTERN void unbind(ExchangeRegistry& exchanges,
+ Queue::shared_ptr shared_ref);
- bool acquire(const QueuedMessage& msg);
+ QPID_BROKER_EXTERN bool acquire(const QueuedMessage& msg);
bool acquireMessageAt(const qpid::framing::SequenceNumber& position, QueuedMessage& message);
/**
* Delivers a message to the queue. Will record it as
* enqueued if persistent then process it.
*/
- void deliver(boost::intrusive_ptr<Message>& msg);
+ QPID_BROKER_EXTERN void deliver(boost::intrusive_ptr<Message>& msg);
/**
* Dispatches the messages immediately to a consumer if
* one is available or stores it for later if not.
*/
- void process(boost::intrusive_ptr<Message>& msg);
+ QPID_BROKER_EXTERN void process(boost::intrusive_ptr<Message>& msg);
/**
* Returns a message to the in-memory queue (due to lack
* of acknowledegement from a receiver). If a consumer is
@@ -197,17 +207,18 @@ namespace qpid {
*/
void recover(boost::intrusive_ptr<Message>& msg);
- void consume(Consumer::shared_ptr c, bool exclusive = false);
- void cancel(Consumer::shared_ptr c);
+ QPID_BROKER_EXTERN void consume(Consumer::shared_ptr c,
+ bool exclusive = false);
+ QPID_BROKER_EXTERN void cancel(Consumer::shared_ptr c);
uint32_t purge(const uint32_t purge_request = 0); //defaults to all messages
- void purgeExpired();
+ QPID_BROKER_EXTERN void purgeExpired();
//move qty # of messages to destination Queue destq
uint32_t move(const Queue::shared_ptr destq, uint32_t qty);
- uint32_t getMessageCount() const;
- uint32_t getConsumerCount() const;
+ QPID_BROKER_EXTERN uint32_t getMessageCount() const;
+ QPID_BROKER_EXTERN uint32_t getConsumerCount() const;
inline const string& getName() const { return name; }
bool isExclusiveOwner(const OwnershipToken* const o) const;
void releaseExclusiveOwnership();
@@ -223,8 +234,8 @@ namespace qpid {
/**
* used to take messages from in memory and flush down to disk.
*/
- void setLastNodeFailure();
- void clearLastNodeFailure();
+ QPID_BROKER_EXTERN void setLastNodeFailure();
+ QPID_BROKER_EXTERN void clearLastNodeFailure();
bool enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg);
/**
@@ -240,7 +251,7 @@ namespace qpid {
/**
* Gets the next available message
*/
- QueuedMessage get();
+ QPID_BROKER_EXTERN QueuedMessage get();
/** Get the message at position pos */
QueuedMessage find(framing::SequenceNumber pos) const;
@@ -290,6 +301,11 @@ namespace qpid {
void setPosition(framing::SequenceNumber pos);
int getEventMode();
void setQueueEventManager(QueueEvents&);
+ void insertSequenceNumbers(const std::string& key);
+ /**
+ * Notify queue that recovery has completed.
+ */
+ void recoveryComplete();
};
}
}
diff --git a/qpid/cpp/src/qpid/broker/QueueCleaner.h b/qpid/cpp/src/qpid/broker/QueueCleaner.h
index 7903266f5f..007826f33e 100644
--- a/qpid/cpp/src/qpid/broker/QueueCleaner.h
+++ b/qpid/cpp/src/qpid/broker/QueueCleaner.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "Timer.h"
namespace qpid {
@@ -34,8 +35,8 @@ class QueueRegistry;
class QueueCleaner
{
public:
- QueueCleaner(QueueRegistry& queues, Timer& timer);
- void start(qpid::sys::Duration period);
+ QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, Timer& timer);
+ QPID_BROKER_EXTERN void start(qpid::sys::Duration period);
private:
class Task : public TimerTask
{
diff --git a/qpid/cpp/src/qpid/broker/QueueEvents.cpp b/qpid/cpp/src/qpid/broker/QueueEvents.cpp
index a6517e1bfe..7525e4cb76 100644
--- a/qpid/cpp/src/qpid/broker/QueueEvents.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueEvents.cpp
@@ -20,12 +20,13 @@
*/
#include "QueueEvents.h"
#include "qpid/Exception.h"
+#include "qpid/log/Statement.h"
namespace qpid {
namespace broker {
QueueEvents::QueueEvents(const boost::shared_ptr<sys::Poller>& poller) :
- eventQueue(boost::bind(&QueueEvents::handle, this, _1), poller)
+ eventQueue(boost::bind(&QueueEvents::handle, this, _1), poller), enabled(true)
{
eventQueue.start();
}
@@ -37,12 +38,12 @@ QueueEvents::~QueueEvents()
void QueueEvents::enqueued(const QueuedMessage& m)
{
- eventQueue.push(Event(ENQUEUE, m));
+ if (enabled) eventQueue.push(Event(ENQUEUE, m));
}
void QueueEvents::dequeued(const QueuedMessage& m)
{
- eventQueue.push(Event(DEQUEUE, m));
+ if (enabled) eventQueue.push(Event(DEQUEUE, m));
}
void QueueEvents::registerListener(const std::string& id, const EventListener& listener)
@@ -81,6 +82,18 @@ void QueueEvents::shutdown()
if (!eventQueue.empty() && !listeners.empty()) eventQueue.shutdown();
}
+void QueueEvents::enable()
+{
+ enabled = true;
+ QPID_LOG(debug, "Queue events enabled");
+}
+
+void QueueEvents::disable()
+{
+ enabled = false;
+ QPID_LOG(debug, "Queue events disabled");
+}
+
QueueEvents::Event::Event(EventType t, const QueuedMessage& m) : type(t), msg(m) {}
diff --git a/qpid/cpp/src/qpid/broker/QueueEvents.h b/qpid/cpp/src/qpid/broker/QueueEvents.h
index 2ba69e33e6..82abd3d20a 100644
--- a/qpid/cpp/src/qpid/broker/QueueEvents.h
+++ b/qpid/cpp/src/qpid/broker/QueueEvents.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "QueuedMessage.h"
#include "qpid/sys/Mutex.h"
#include "qpid/sys/PollableQueue.h"
@@ -48,25 +49,29 @@ class QueueEvents
EventType type;
QueuedMessage msg;
- Event(EventType, const QueuedMessage&);
+ QPID_BROKER_EXTERN Event(EventType, const QueuedMessage&);
};
typedef boost::function<void (Event)> EventListener;
- QueueEvents(const boost::shared_ptr<sys::Poller>& poller);
- ~QueueEvents();
- void enqueued(const QueuedMessage&);
- void dequeued(const QueuedMessage&);
- void registerListener(const std::string& id, const EventListener&);
- void unregisterListener(const std::string& id);
+ QPID_BROKER_EXTERN QueueEvents(const boost::shared_ptr<sys::Poller>& poller);
+ QPID_BROKER_EXTERN ~QueueEvents();
+ QPID_BROKER_EXTERN void enqueued(const QueuedMessage&);
+ QPID_BROKER_EXTERN void dequeued(const QueuedMessage&);
+ QPID_BROKER_EXTERN void registerListener(const std::string& id,
+ const EventListener&);
+ QPID_BROKER_EXTERN void unregisterListener(const std::string& id);
+ void enable();
+ void disable();
//process all outstanding events
- void shutdown();
+ QPID_BROKER_EXTERN void shutdown();
private:
typedef qpid::sys::PollableQueue<Event> EventQueue;
typedef std::map<std::string, EventListener> Listeners;
EventQueue eventQueue;
Listeners listeners;
+ volatile bool enabled;
qpid::sys::Mutex lock;//protect listeners from concurrent access
void handle(EventQueue::Queue& e);
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
index 41a6709d27..c59736969f 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
@@ -126,7 +126,7 @@ std::string QueuePolicy::getType(const FieldTable& settings)
FieldTable::ValuePtr v = settings.get(typeKey);
if (v && v->convertsTo<std::string>()) {
std::string t = v->get<std::string>();
- transform(t.begin(), t.end(), t.begin(), tolower);
+ std::transform(t.begin(), t.end(), t.begin(), tolower);
if (t == REJECT || t == FLOW_TO_DISK || t == RING || t == RING_STRICT) return t;
}
return FLOW_TO_DISK;
@@ -197,11 +197,12 @@ void RingQueuePolicy::enqueued(const QueuedMessage& m)
void RingQueuePolicy::dequeued(const QueuedMessage& m)
{
qpid::sys::Mutex::ScopedLock l(lock);
- QueuePolicy::dequeued(m);
//find and remove m from queue
- for (Messages::iterator i = queue.begin(); i != queue.end() && m.position <= i->position; i++) {
- if (i->position == m.position) {
+ for (Messages::iterator i = queue.begin(); i != queue.end(); i++) {
+ if (i->payload == m.payload) {
queue.erase(i);
+ //now update count and size
+ QueuePolicy::dequeued(m);
break;
}
}
@@ -210,9 +211,11 @@ void RingQueuePolicy::dequeued(const QueuedMessage& m)
bool RingQueuePolicy::isEnqueued(const QueuedMessage& m)
{
qpid::sys::Mutex::ScopedLock l(lock);
- //for non-strict ring policy, a message can be dequeued before acked; need to detect this
- for (Messages::iterator i = queue.begin(); i != queue.end() && m.position <= i->position; i++) {
- if (i->position == m.position) {
+ //for non-strict ring policy, a message can be replaced (and
+ //therefore dequeued) before it is accepted or released by
+ //subscriber; need to detect this
+ for (Messages::const_iterator i = queue.begin(); i != queue.end(); i++) {
+ if (i->payload == m.payload) {
return true;
}
}
@@ -236,13 +239,10 @@ bool RingQueuePolicy::checkLimit(const QueuedMessage& m)
oldest = queue.front();
}
if (oldest.queue->acquire(oldest) || !strict) {
- qpid::sys::Mutex::ScopedLock l(lock);
- if (oldest.position == queue.front().position) {
- queue.pop_front();
- QPID_LOG(debug, "Ring policy triggered in queue "
- << (m.queue ? m.queue->getName() : std::string("unknown queue"))
- << ": removed message " << oldest.position << " to make way for " << m.position);
- }
+ oldest.queue->dequeue(0, oldest);
+ QPID_LOG(debug, "Ring policy triggered in queue "
+ << (m.queue ? m.queue->getName() : std::string("unknown queue"))
+ << ": removed message " << oldest.position << " to make way for " << m.position);
return true;
} else {
QPID_LOG(debug, "Ring policy could not be triggered in queue "
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.h b/qpid/cpp/src/qpid/broker/QueuePolicy.h
index 0e8c15aa0e..45992f87ac 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.h
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.h
@@ -24,6 +24,7 @@
#include <deque>
#include <iostream>
#include <memory>
+#include "BrokerImportExport.h"
#include "QueuedMessage.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/AtomicValue.h"
@@ -47,20 +48,20 @@ class QueuePolicy
static std::string getType(const qpid::framing::FieldTable& settings);
public:
- static const std::string maxCountKey;
- static const std::string maxSizeKey;
- static const std::string typeKey;
- static const std::string REJECT;
- static const std::string FLOW_TO_DISK;
- static const std::string RING;
- static const std::string RING_STRICT;
+ static QPID_BROKER_EXTERN const std::string maxCountKey;
+ static QPID_BROKER_EXTERN const std::string maxSizeKey;
+ static QPID_BROKER_EXTERN const std::string typeKey;
+ static QPID_BROKER_EXTERN const std::string REJECT;
+ static QPID_BROKER_EXTERN const std::string FLOW_TO_DISK;
+ static QPID_BROKER_EXTERN const std::string RING;
+ static QPID_BROKER_EXTERN const std::string RING_STRICT;
virtual ~QueuePolicy() {}
- void tryEnqueue(const QueuedMessage&);
+ QPID_BROKER_EXTERN void tryEnqueue(const QueuedMessage&);
virtual void dequeued(const QueuedMessage&);
virtual bool isEnqueued(const QueuedMessage&);
virtual bool checkLimit(const QueuedMessage&);
- void update(qpid::framing::FieldTable& settings);
+ QPID_BROKER_EXTERN void update(qpid::framing::FieldTable& settings);
uint32_t getMaxCount() const { return maxCount; }
uint64_t getMaxSize() const { return maxSize; }
void encode(framing::Buffer& buffer) const;
@@ -68,10 +69,11 @@ class QueuePolicy
uint32_t encodedSize() const;
- static std::auto_ptr<QueuePolicy> createQueuePolicy(const qpid::framing::FieldTable& settings);
- static std::auto_ptr<QueuePolicy> createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
+ static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(const qpid::framing::FieldTable& settings);
+ static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
static void setDefaultMaxSize(uint64_t);
- friend std::ostream& operator<<(std::ostream&, const QueuePolicy&);
+ friend QPID_BROKER_EXTERN std::ostream& operator<<(std::ostream&,
+ const QueuePolicy&);
protected:
QueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
index 2cb801bf83..d079e543c4 100644
--- a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
@@ -19,6 +19,7 @@
*
*/
#include "QueueRegistry.h"
+#include "QueueEvents.h"
#include "qpid/log/Statement.h"
#include <sstream>
#include <assert.h>
@@ -27,7 +28,7 @@ using namespace qpid::broker;
using namespace qpid::sys;
QueueRegistry::QueueRegistry() :
- counter(1), store(0), parent(0), lastNode(false) {}
+ counter(1), store(0), events(0), parent(0), lastNode(false) {}
QueueRegistry::~QueueRegistry(){}
@@ -43,7 +44,8 @@ QueueRegistry::declare(const string& declareName, bool durable,
if (i == queues.end()) {
Queue::shared_ptr queue(new Queue(name, autoDelete, durable ? store : 0, owner, parent));
queues[name] = queue;
- if (lastNode) queue->setLastNodeFailure();
+ if (lastNode) queue->setLastNodeFailure();
+ if (events) queue->setQueueEventManager(*events);
return std::pair<Queue::shared_ptr, bool>(queue, true);
} else {
@@ -105,3 +107,7 @@ void QueueRegistry::updateQueueClusterState(bool _lastNode)
lastNode = _lastNode;
}
+void QueueRegistry::setQueueEvents(QueueEvents* e)
+{
+ events = e;
+}
diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.h b/qpid/cpp/src/qpid/broker/QueueRegistry.h
index c53ba668cc..3c02afedc4 100644
--- a/qpid/cpp/src/qpid/broker/QueueRegistry.h
+++ b/qpid/cpp/src/qpid/broker/QueueRegistry.h
@@ -21,6 +21,7 @@
#ifndef _QueueRegistry_
#define _QueueRegistry_
+#include "BrokerImportExport.h"
#include "Queue.h"
#include "qpid/sys/Mutex.h"
#include "qpid/management/Manageable.h"
@@ -31,6 +32,8 @@
namespace qpid {
namespace broker {
+class QueueEvents;
+
/**
* A registry of queues indexed by queue name.
*
@@ -38,10 +41,10 @@ namespace broker {
* are deleted when and only when they are no longer in use.
*
*/
-class QueueRegistry{
+class QueueRegistry {
public:
- QueueRegistry();
- ~QueueRegistry();
+ QPID_BROKER_EXTERN QueueRegistry();
+ QPID_BROKER_EXTERN ~QueueRegistry();
/**
* Declare a queue.
@@ -49,8 +52,11 @@ class QueueRegistry{
* @return The queue and a boolean flag which is true if the queue
* was created by this declare call false if it already existed.
*/
- std::pair<Queue::shared_ptr, bool> declare(const string& name, bool durable = false, bool autodelete = false,
- const OwnershipToken* owner = 0);
+ QPID_BROKER_EXTERN std::pair<Queue::shared_ptr, bool> declare
+ (const string& name,
+ bool durable = false,
+ bool autodelete = false,
+ const OwnershipToken* owner = 0);
/**
* Destroy the named queue.
@@ -64,7 +70,7 @@ class QueueRegistry{
* subsequent calls to find or declare with the same name.
*
*/
- void destroy (const string& name);
+ QPID_BROKER_EXTERN void destroy(const string& name);
template <class Test> bool destroyIf(const string& name, Test test)
{
qpid::sys::RWlock::ScopedWlock locker(lock);
@@ -79,13 +85,15 @@ class QueueRegistry{
/**
* Find the named queue. Return 0 if not found.
*/
- Queue::shared_ptr find(const string& name);
+ QPID_BROKER_EXTERN Queue::shared_ptr find(const string& name);
/**
* Generate unique queue name.
*/
string generateName();
+ void setQueueEvents(QueueEvents*);
+
/**
* Set the store to use. May only be called once.
*/
@@ -120,6 +128,7 @@ private:
mutable qpid::sys::RWlock lock;
int counter;
MessageStore* store;
+ QueueEvents* events;
management::Manageable* parent;
bool lastNode; //used to set mode on queue declare
diff --git a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
index 8030cf7d0e..5f8b57fa0b 100644
--- a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
+++ b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
@@ -149,7 +149,8 @@ RecoverableConfig::shared_ptr RecoveryManagerImpl::recoverConfig(framing::Buffer
void RecoveryManagerImpl::recoveryComplete()
{
- //TODO (finalise binding setup etc)
+ //notify all queues
+ queues.eachQueue(boost::bind(&Queue::recoveryComplete, _1));
}
bool RecoverableMessageImpl::loadContent(uint64_t available)
diff --git a/qpid/cpp/src/qpid/broker/RetryList.h b/qpid/cpp/src/qpid/broker/RetryList.h
index 013233ef00..3cdba72ecf 100644
--- a/qpid/cpp/src/qpid/broker/RetryList.h
+++ b/qpid/cpp/src/qpid/broker/RetryList.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "qpid/Address.h"
#include "qpid/Url.h"
@@ -35,9 +36,9 @@ namespace broker {
class RetryList
{
public:
- RetryList();
- void reset(const std::vector<Url>& urls);
- bool next(TcpAddress& address);
+ QPID_BROKER_EXTERN RetryList();
+ QPID_BROKER_EXTERN void reset(const std::vector<Url>& urls);
+ QPID_BROKER_EXTERN bool next(TcpAddress& address);
private:
std::vector<Url> urls;
size_t urlIndex;
diff --git a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
index 736b051945..edc66444ec 100644
--- a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
+++ b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
@@ -141,21 +141,31 @@ NullAuthenticator::~NullAuthenticator() {}
void NullAuthenticator::getMechanisms(Array& mechanisms)
{
mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("ANONYMOUS")));
+ mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("PLAIN")));//useful for testing
}
void NullAuthenticator::start(const string& mechanism, const string& response)
{
if (mechanism == "PLAIN") { // Old behavior
- if (response.size() > 0 && response[0] == (char) 0) {
- string temp = response.substr(1);
- string::size_type i = temp.find((char)0);
- string uid = temp.substr(0, i);
- string pwd = temp.substr(i + 1);
- i = uid.find_last_of(realm);
- if (i == string::npos || i != (uid.size() - 1)) {
- uid = str(format("%1%@%2%") % uid % realm);
+ if (response.size() > 0) {
+ string uid;
+ string::size_type i = response.find((char)0);
+ if (i == 0 && response.size() > 1) {
+ //no authorization id; use authentication id
+ i = response.find((char)0, 1);
+ if (i != string::npos) uid = response.substr(1, i-1);
+ } else if (i != string::npos) {
+ //authorization id is first null delimited field
+ uid = response.substr(0, i);
+ }//else not a valid SASL PLAIN response, throw error?
+ if (!uid.empty()) {
+ //append realm if it has not already been added
+ i = uid.find(realm);
+ if (i == string::npos || realm.size() + i < uid.size()) {
+ uid = str(format("%1%@%2%") % uid % realm);
+ }
+ connection.setUserId(uid);
}
- connection.setUserId(uid);
}
} else {
connection.setUserId("anonymous");
diff --git a/qpid/cpp/src/qpid/broker/SemanticState.cpp b/qpid/cpp/src/qpid/broker/SemanticState.cpp
index 4f751e43b7..3c7c6d9afa 100644
--- a/qpid/cpp/src/qpid/broker/SemanticState.cpp
+++ b/qpid/cpp/src/qpid/broker/SemanticState.cpp
@@ -355,20 +355,12 @@ const std::string nullstring;
}
void SemanticState::route(intrusive_ptr<Message> msg, Deliverable& strategy) {
+ msg->setTimestamp(getSession().getBroker().getExpiryPolicy());
+
std::string exchangeName = msg->getExchangeName();
- //TODO: the following should be hidden behind message (using MessageAdapter or similar)
-
- if (msg->isA<MessageTransferBody>()) {
- // Do not replace the delivery-properties.exchange if it is is already set.
- // This is used internally (by the cluster) to force the exchange name on a message.
- // The client library ensures this is always empty for messages from normal clients.
- if (!msg->hasProperties<DeliveryProperties>() || msg->getProperties<DeliveryProperties>()->getExchange().empty())
- msg->getProperties<DeliveryProperties>()->setExchange(exchangeName);
- msg->setTimestamp(getSession().getBroker().getExpiryPolicy());
- }
- if (!cacheExchange || cacheExchange->getName() != exchangeName){
+ if (!cacheExchange || cacheExchange->getName() != exchangeName)
cacheExchange = session.getBroker().getExchanges().get(exchangeName);
- }
+ cacheExchange->setProperties(msg);
/* verify the userid if specified: */
std::string id =
@@ -516,14 +508,16 @@ void SemanticState::ConsumerImpl::setCreditMode()
void SemanticState::ConsumerImpl::addByteCredit(uint32_t value)
{
if (byteCredit != 0xFFFFFFFF) {
- byteCredit += value;
+ if (value == 0xFFFFFFFF) byteCredit = value;
+ else byteCredit += value;
}
}
void SemanticState::ConsumerImpl::addMessageCredit(uint32_t value)
{
if (msgCredit != 0xFFFFFFFF) {
- msgCredit += value;
+ if (value == 0xFFFFFFFF) msgCredit = value;
+ else msgCredit += value;
}
}
diff --git a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
index ae160fabc7..96c47085f0 100644
--- a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
@@ -362,10 +362,6 @@ void SessionAdapter::QueueHandlerImpl::declare(const string& name, const string&
getBroker().getExchanges().getDefault()->bind(queue, name, 0);
queue->bound(getBroker().getExchanges().getDefault()->getName(), name, arguments);
- //if event generation is turned on, pass in a pointer to
- //the QueueEvents instance to use
- if (queue->getEventMode()) queue->setQueueEventManager(getBroker().getQueueEvents());
-
//handle automatic cleanup:
if (exclusive) {
exclusiveQueues.push_back(queue);
diff --git a/qpid/cpp/src/qpid/broker/SessionHandler.cpp b/qpid/cpp/src/qpid/broker/SessionHandler.cpp
index 2c4de478f6..442c3eb34b 100644
--- a/qpid/cpp/src/qpid/broker/SessionHandler.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionHandler.cpp
@@ -34,7 +34,8 @@ using namespace qpid::sys;
SessionHandler::SessionHandler(Connection& c, ChannelId ch)
: amqp_0_10::SessionHandler(&c.getOutput(), ch),
connection(c),
- proxy(out)
+ proxy(out),
+ clusterOrderProxy(c.getClusterOrderOutput() ? new SetChannelProxy(ch, c.getClusterOrderOutput()) : 0)
{}
SessionHandler::~SessionHandler() {}
@@ -84,11 +85,23 @@ void SessionHandler::readyToSend() {
if (session.get()) session->readyToSend();
}
-// TODO aconway 2008-05-12: hacky - handle attached for bridge clients.
-// We need to integrate the client code so we can run a real client
-// in the bridge.
-//
-void SessionHandler::attached(const std::string& name) {
+/**
+ * Used by inter-broker bridges to set up session id and attach
+ */
+void SessionHandler::attachAs(const std::string& name)
+{
+ SessionId id(connection.getUserId(), name);
+ SessionState::Configuration config = connection.broker.getSessionManager().getSessionConfig();
+ session.reset(new SessionState(connection.getBroker(), *this, id, config));
+ sendAttach(false);
+}
+
+/**
+ * TODO: this is a little ugly, fix it; its currently still relied on
+ * for 'push' bridges
+ */
+void SessionHandler::attached(const std::string& name)
+{
if (session.get()) {
amqp_0_10::SessionHandler::attached(name);
} else {
diff --git a/qpid/cpp/src/qpid/broker/SessionHandler.h b/qpid/cpp/src/qpid/broker/SessionHandler.h
index 7449db1560..ffc032f64c 100644
--- a/qpid/cpp/src/qpid/broker/SessionHandler.h
+++ b/qpid/cpp/src/qpid/broker/SessionHandler.h
@@ -54,10 +54,20 @@ class SessionHandler : public amqp_0_10::SessionHandler {
framing::AMQP_ClientProxy& getProxy() { return proxy; }
const framing::AMQP_ClientProxy& getProxy() const { return proxy; }
+ /**
+ * If commands are sent based on the local time (e.g. in timers), they don't have
+ * a well-defined ordering across cluster nodes.
+ * This proxy is for sending such commands. In a clustered broker it will take steps
+ * to synchronize command order across the cluster. In a stand-alone broker
+ * it is just a synonym for getProxy()
+ */
+ framing::AMQP_ClientProxy& getClusterOrderProxy() {
+ return clusterOrderProxy.get() ? *clusterOrderProxy : proxy;
+ }
+
virtual void handleDetach();
-
- // Overrides
- void attached(const std::string& name);
+ void attached(const std::string& name);//used by 'pushing' inter-broker bridges
+ void attachAs(const std::string& name);//used by 'pulling' inter-broker bridges
protected:
virtual void setState(const std::string& sessionName, bool force);
@@ -69,9 +79,16 @@ class SessionHandler : public amqp_0_10::SessionHandler {
virtual void readyToSend();
private:
+ struct SetChannelProxy : public framing::AMQP_ClientProxy { // Proxy that sets the channel.
+ framing::ChannelHandler setChannel;
+ SetChannelProxy(uint16_t ch, framing::FrameHandler* out)
+ : framing::AMQP_ClientProxy(setChannel), setChannel(ch, out) {}
+ };
+
Connection& connection;
framing::AMQP_ClientProxy proxy;
std::auto_ptr<SessionState> session;
+ std::auto_ptr<SetChannelProxy> clusterOrderProxy;
};
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/SessionState.cpp b/qpid/cpp/src/qpid/broker/SessionState.cpp
index 82ffede3f9..7e5f605753 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionState.cpp
@@ -66,7 +66,7 @@ SessionState::SessionState(
uint32_t maxRate = broker.getOptions().maxSessionRate;
if (maxRate) {
if (handler->getConnection().getClientThrottling()) {
- rateFlowcontrol = new RateFlowcontrol(maxRate);
+ rateFlowcontrol.reset(new RateFlowcontrol(maxRate));
} else {
QPID_LOG(warning, getId() << ": Unable to flow control client - client doesn't support");
}
@@ -212,11 +212,15 @@ struct ScheduledCreditTask : public TimerTask {
void fire() {
// This is the best we can currently do to avoid a destruction/fire race
if (!isCancelled()) {
- if ( !sessionState.processSendCredit(0) ) {
- QPID_LOG(warning, sessionState.getId() << ": Reschedule sending credit");
- reset();
- timer.add(this);
- }
+ sessionState.getConnection().requestIOProcessing(boost::bind(&ScheduledCreditTask::sendCredit, this));
+ }
+ }
+
+ void sendCredit() {
+ if ( !sessionState.processSendCredit(0) ) {
+ QPID_LOG(warning, sessionState.getId() << ": Reschedule sending credit");
+ reset();
+ timer.add(this);
}
}
};
@@ -274,7 +278,8 @@ bool SessionState::processSendCredit(uint32_t msgs)
if ( msgs > 0 && rateFlowcontrol->flowStopped() ) {
QPID_LOG(warning, getId() << ": producer throttling violation");
// TODO: Probably do message.stop("") first time then disconnect
- getProxy().getMessage().stop("");
+ // See comment on getClusterOrderProxy() in .h file
+ getClusterOrderProxy().getMessage().stop("");
return true;
}
AbsTime now = AbsTime::now();
@@ -282,7 +287,7 @@ bool SessionState::processSendCredit(uint32_t msgs)
if (mgmtObject) mgmtObject->dec_clientCredit(msgs);
if ( sendCredit>0 ) {
QPID_LOG(debug, getId() << ": send producer credit " << sendCredit);
- getProxy().getMessage().flow("", 0, sendCredit);
+ getClusterOrderProxy().getMessage().flow("", 0, sendCredit);
rateFlowcontrol->sentCredit(now, sendCredit);
if (mgmtObject) mgmtObject->inc_clientCredit(sendCredit);
return true;
@@ -363,8 +368,9 @@ void SessionState::readyToSend() {
// Issue initial credit - use a heuristic here issue min of 300 messages or 1 secs worth
uint32_t credit = std::min(rateFlowcontrol->getRate(), 300U);
QPID_LOG(debug, getId() << ": Issuing producer message credit " << credit);
- getProxy().getMessage().setFlowMode("", 0);
- getProxy().getMessage().flow("", 0, credit);
+ // See comment on getClusterOrderProxy() in .h file
+ getClusterOrderProxy().getMessage().setFlowMode("", 0);
+ getClusterOrderProxy().getMessage().flow("", 0, credit);
rateFlowcontrol->sentCredit(AbsTime::now(), credit);
if (mgmtObject) mgmtObject->inc_clientCredit(credit);
}
@@ -372,4 +378,8 @@ void SessionState::readyToSend() {
Broker& SessionState::getBroker() { return broker; }
+framing::AMQP_ClientProxy& SessionState::getClusterOrderProxy() {
+ return handler->getClusterOrderProxy();
+}
+
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/SessionState.h b/qpid/cpp/src/qpid/broker/SessionState.h
index c435a741f8..bdfed87905 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.h
+++ b/qpid/cpp/src/qpid/broker/SessionState.h
@@ -56,7 +56,7 @@ class Message;
class SessionHandler;
class SessionManager;
class RateFlowcontrol;
-class TimerTask;
+struct TimerTask;
/**
* Broker-side session state includes session's handler chains, which
@@ -125,6 +125,15 @@ class SessionState : public qpid::SessionState,
void sendAcceptAndCompletion();
+ /**
+ * If commands are sent based on the local time (e.g. in timers), they don't have
+ * a well-defined ordering across cluster nodes.
+ * This proxy is for sending such commands. In a clustered broker it will take steps
+ * to synchronize command order across the cluster. In a stand-alone broker
+ * it is just a synonym for getProxy()
+ */
+ framing::AMQP_ClientProxy& getClusterOrderProxy();
+
Broker& broker;
SessionHandler* handler;
sys::AbsTime expiry; // Used by SessionManager.
@@ -138,7 +147,7 @@ class SessionState : public qpid::SessionState,
// State used for producer flow control (rate limited)
qpid::sys::Mutex rateLock;
- RateFlowcontrol* rateFlowcontrol;
+ boost::scoped_ptr<RateFlowcontrol> rateFlowcontrol;
boost::intrusive_ptr<TimerTask> flowControlTimer;
friend class SessionManager;
diff --git a/qpid/cpp/src/qpid/broker/Timer.h b/qpid/cpp/src/qpid/broker/Timer.h
index be4ac9d056..564fec5804 100644
--- a/qpid/cpp/src/qpid/broker/Timer.h
+++ b/qpid/cpp/src/qpid/broker/Timer.h
@@ -21,6 +21,7 @@
#ifndef _Timer_
#define _Timer_
+#include "BrokerImportExport.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Thread.h"
#include "qpid/sys/Runnable.h"
@@ -43,9 +44,9 @@ struct TimerTask : public RefCounted {
qpid::sys::AbsTime time;
volatile bool cancelled;
- TimerTask(qpid::sys::Duration timeout);
+ QPID_BROKER_EXTERN TimerTask(qpid::sys::Duration timeout);
TimerTask(qpid::sys::AbsTime time);
- virtual ~TimerTask();
+ QPID_BROKER_EXTERN virtual ~TimerTask();
void reset();
void cancel();
bool isCancelled() const;
@@ -69,10 +70,10 @@ class Timer : private qpid::sys::Runnable {
virtual void run();
public:
- Timer();
- virtual ~Timer();
+ QPID_BROKER_EXTERN Timer();
+ QPID_BROKER_EXTERN virtual ~Timer();
- void add(boost::intrusive_ptr<TimerTask> task);
+ QPID_BROKER_EXTERN void add(boost::intrusive_ptr<TimerTask> task);
void start();
void stop();
diff --git a/qpid/cpp/src/qpid/broker/TopicExchange.h b/qpid/cpp/src/qpid/broker/TopicExchange.h
index f3a2e221f7..24bf5f7bca 100644
--- a/qpid/cpp/src/qpid/broker/TopicExchange.h
+++ b/qpid/cpp/src/qpid/broker/TopicExchange.h
@@ -23,6 +23,7 @@
#include <map>
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/Monitor.h"
@@ -40,7 +41,7 @@ class Tokens : public std::vector<std::string> {
/** Tokenize s, provides automatic conversion of string to Tokens */
Tokens(const std::string& s) { operator=(s); }
/** Tokenizing assignment operator s */
- Tokens & operator=(const std::string& s);
+ QPID_BROKER_EXTERN Tokens & operator=(const std::string& s);
void key(std::string& key) const;
private:
@@ -60,12 +61,12 @@ class TopicPattern : public Tokens
// Default copy, assign, dtor are sufficient.
TopicPattern(const Tokens& tokens) { operator=(tokens); }
TopicPattern(const std::string& str) { operator=(str); }
- TopicPattern& operator=(const Tokens&);
+ QPID_BROKER_EXTERN TopicPattern& operator=(const Tokens&);
TopicPattern& operator=(const std::string& str) { return operator=(Tokens(str)); }
/** Match a topic */
bool match(const std::string& topic) { return match(Tokens(topic)); }
- bool match(const Tokens& topic) const;
+ QPID_BROKER_EXTERN bool match(const Tokens& topic) const;
private:
void normalize();
@@ -84,21 +85,30 @@ class TopicExchange : public virtual Exchange {
public:
static const std::string typeName;
- TopicExchange(const string& name, management::Manageable* parent = 0);
- TopicExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args, management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN TopicExchange(const string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN TopicExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~TopicExchange();
+ QPID_BROKER_EXTERN virtual ~TopicExchange();
virtual bool supportsDynamicBinding() { return true; }
};
diff --git a/qpid/cpp/src/qpid/broker/TxAccept.cpp b/qpid/cpp/src/qpid/broker/TxAccept.cpp
index c7001e5526..73f365d509 100644
--- a/qpid/cpp/src/qpid/broker/TxAccept.cpp
+++ b/qpid/cpp/src/qpid/broker/TxAccept.cpp
@@ -50,12 +50,12 @@ void TxAccept::RangeOps::operator()(SequenceNumber start, SequenceNumber end)
void TxAccept::RangeOps::prepare(TransactionContext* ctxt)
{
- for_each(ranges.begin(), ranges.end(), bind(&RangeOp::prepare, _1, ctxt));
+ std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::prepare, _1, ctxt));
}
void TxAccept::RangeOps::commit()
{
- for_each(ranges.begin(), ranges.end(), bind(&RangeOp::commit, _1));
+ std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::commit, _1));
//now remove if isRedundant():
if (!ranges.empty()) {
ack_iterator i = ranges.front().range.start;
diff --git a/qpid/cpp/src/qpid/broker/TxBuffer.h b/qpid/cpp/src/qpid/broker/TxBuffer.h
index aabb5ea0b1..f63a65f115 100644
--- a/qpid/cpp/src/qpid/broker/TxBuffer.h
+++ b/qpid/cpp/src/qpid/broker/TxBuffer.h
@@ -24,6 +24,7 @@
#include <algorithm>
#include <functional>
#include <vector>
+#include "BrokerImportExport.h"
#include "TransactionalStore.h"
#include "TxOp.h"
@@ -68,7 +69,7 @@ namespace qpid {
/**
* Adds an operation to the transaction.
*/
- void enlist(TxOp::shared_ptr op);
+ QPID_BROKER_EXTERN void enlist(TxOp::shared_ptr op);
/**
* Requests that all ops are prepared. This should
@@ -81,7 +82,7 @@ namespace qpid {
* @returns true if all the operations prepared
* successfully, false if not.
*/
- bool prepare(TransactionContext* const ctxt);
+ QPID_BROKER_EXTERN bool prepare(TransactionContext* const ctxt);
/**
* Signals that the ops all prepared successfully and can
@@ -91,7 +92,7 @@ namespace qpid {
* Should only be called after a call to prepare() returns
* true.
*/
- void commit();
+ QPID_BROKER_EXTERN void commit();
/**
* Signals that all ops can be rolled back.
@@ -100,13 +101,13 @@ namespace qpid {
* returns true (2pc) or instead of a prepare call
* ('server-local')
*/
- void rollback();
+ QPID_BROKER_EXTERN void rollback();
/**
* Helper method for managing the process of server local
* commit
*/
- bool commitLocal(TransactionalStore* const store);
+ QPID_BROKER_EXTERN bool commitLocal(TransactionalStore* const store);
// Used by cluster to replicate transaction status.
void accept(TxOpConstVisitor& v) const;
diff --git a/qpid/cpp/src/qpid/broker/TxPublish.h b/qpid/cpp/src/qpid/broker/TxPublish.h
index 1f73cb8767..ebe3b51f3d 100644
--- a/qpid/cpp/src/qpid/broker/TxPublish.h
+++ b/qpid/cpp/src/qpid/broker/TxPublish.h
@@ -21,6 +21,7 @@
#ifndef _TxPublish_
#define _TxPublish_
+#include "BrokerImportExport.h"
#include "Queue.h"
#include "Deliverable.h"
#include "Message.h"
@@ -65,19 +66,19 @@ namespace qpid {
std::list<Queue::shared_ptr> queues;
public:
- TxPublish(boost::intrusive_ptr<Message> msg);
- virtual bool prepare(TransactionContext* ctxt) throw();
- virtual void commit() throw();
- virtual void rollback() throw();
+ QPID_BROKER_EXTERN TxPublish(boost::intrusive_ptr<Message> msg);
+ QPID_BROKER_EXTERN virtual bool prepare(TransactionContext* ctxt) throw();
+ QPID_BROKER_EXTERN virtual void commit() throw();
+ QPID_BROKER_EXTERN virtual void rollback() throw();
virtual Message& getMessage() { return *msg; };
- virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
+ QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
virtual ~TxPublish(){}
virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); }
- uint64_t contentSize();
+ QPID_BROKER_EXTERN uint64_t contentSize();
boost::intrusive_ptr<Message> getMessage() const { return msg; }
const std::list<Queue::shared_ptr> getQueues() const { return queues; }
diff --git a/qpid/cpp/src/qpid/client/ClientImportExport.h b/qpid/cpp/src/qpid/client/ClientImportExport.h
new file mode 100644
index 0000000000..0e6e5660d6
--- /dev/null
+++ b/qpid/cpp/src/qpid/client/ClientImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_CLIENT_IMPORT_EXPORT_H
+#define QPID_CLIENT_IMPORT_EXPORT_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.
+ */
+
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+#if defined(CLIENT_EXPORT)
+#define QPID_CLIENT_EXTERN __declspec(dllexport)
+#else
+#define QPID_CLIENT_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_CLIENT_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/client/Connection.h b/qpid/cpp/src/qpid/client/Connection.h
index 03631ef56f..846ac33790 100644
--- a/qpid/cpp/src/qpid/client/Connection.h
+++ b/qpid/cpp/src/qpid/client/Connection.h
@@ -24,6 +24,7 @@
#include <map>
#include <string>
#include "qpid/client/Session.h"
+#include "qpid/client/ClientImportExport.h"
namespace qpid {
@@ -58,9 +59,9 @@ class Connection
* Creates a connection object, but does not open the connection.
* @see open()
*/
- Connection();
+ QPID_CLIENT_EXTERN Connection();
- ~Connection();
+ QPID_CLIENT_EXTERN ~Connection();
/**
* Opens a connection to a broker.
@@ -79,7 +80,7 @@ class Connection
* hosts, where implemented(!), provide namespace partitioning
* within a single broker).
*/
- void open(const std::string& host, int port = 5672,
+ QPID_CLIENT_EXTERN void open(const std::string& host, int port = 5672,
const std::string& uid = "guest",
const std::string& pwd = "guest",
const std::string& virtualhost = "/", uint16_t maxFrameSize=65535);
@@ -101,7 +102,7 @@ class Connection
* hosts, where implemented(!), provide namespace partitioning
* within a single broker).
*/
- void open(const Url& url,
+ QPID_CLIENT_EXTERN void open(const Url& url,
const std::string& uid = "guest",
const std::string& pwd = "guest",
const std::string& virtualhost = "/", uint16_t maxFrameSize=65535);
@@ -116,14 +117,14 @@ class Connection
* @param settings used for any settings not provided by the URL.
* Settings provided by the url (e.g. host, port) are ignored.
*/
- void open(const Url& url, const ConnectionSettings& settings);
+ QPID_CLIENT_EXTERN void open(const Url& url, const ConnectionSettings& settings);
/**
* Opens a connection to a broker.
*
* @param the settings to use (host, port etc). @see ConnectionSettings.
*/
- void open(const ConnectionSettings& settings);
+ QPID_CLIENT_EXTERN void open(const ConnectionSettings& settings);
/**
* Close the connection.
@@ -131,7 +132,7 @@ class Connection
* Any further use of this connection (without reopening it) will
* not succeed.
*/
- void close();
+ QPID_CLIENT_EXTERN void close();
/**
* Create a new session on this connection. Sessions allow
@@ -174,23 +175,23 @@ class Connection
* If the name is empty (the default) then a unique name will be
* chosen using a Universally-unique identifier (UUID) algorithm.
*/
- Session newSession(const std::string& name=std::string(), uint32_t timeoutSeconds = 0);
+ QPID_CLIENT_EXTERN Session newSession(const std::string& name=std::string(), uint32_t timeoutSeconds = 0);
/**
* Resume a suspended session. A session may be resumed
* on a different connection to the one that created it.
*/
- void resume(Session& session);
+ QPID_CLIENT_EXTERN void resume(Session& session);
- bool isOpen() const;
+ QPID_CLIENT_EXTERN bool isOpen() const;
- std::vector<Url> getKnownBrokers();
- void registerFailureCallback ( boost::function<void ()> fn );
+ QPID_CLIENT_EXTERN std::vector<Url> getKnownBrokers();
+ QPID_CLIENT_EXTERN void registerFailureCallback ( boost::function<void ()> fn );
/**
* Return the set of client negotiated settings
*/
- const ConnectionSettings& getNegotiatedSettings();
+ QPID_CLIENT_EXTERN const ConnectionSettings& getNegotiatedSettings();
friend class ConnectionAccess; ///<@internal
friend class SessionBase_0_10; ///<@internal
diff --git a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
index 377b84c019..6efdb91e96 100644
--- a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
@@ -28,6 +28,7 @@
#include "qpid/framing/reply_exceptions.h"
#include "qpid/log/Helpers.h"
#include "qpid/log/Statement.h"
+#include "qpid/sys/SystemInfo.h"
using namespace qpid::client;
using namespace qpid::framing;
@@ -52,6 +53,9 @@ const std::string INVALID_STATE_OPEN_OK("open-ok received in invalid state");
const std::string INVALID_STATE_CLOSE_OK("close-ok received in invalid state");
const std::string SESSION_FLOW_CONTROL("qpid.session_flow");
+const std::string CLIENT_PROCESS_NAME("qpid.client_process");
+const std::string CLIENT_PID("qpid.client_pid");
+const std::string CLIENT_PPID("qpid.client_ppid");
const int SESSION_FLOW_CONTROL_VER = 1;
}
@@ -80,6 +84,9 @@ ConnectionHandler::ConnectionHandler(const ConnectionSettings& s, ProtocolVersio
FINISHED.insert(CLOSED);
properties.setInt(SESSION_FLOW_CONTROL, SESSION_FLOW_CONTROL_VER);
+ properties.setString(CLIENT_PROCESS_NAME, sys::SystemInfo::getProcessName());
+ properties.setInt(CLIENT_PID, sys::SystemInfo::getProcessId());
+ properties.setInt(CLIENT_PPID, sys::SystemInfo::getParentProcessId());
}
void ConnectionHandler::incoming(AMQFrame& frame)
diff --git a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
index 8e27d78479..745bdb63b5 100644
--- a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
@@ -180,6 +180,9 @@ void ConnectionImpl::close()
template <class F> void ConnectionImpl::closeInternal(const F& f) {
+ if (heartbeatTask) {
+ heartbeatTask->cancel();
+ }
{
Mutex::ScopedUnlock u(lock);
connector->close();
diff --git a/qpid/cpp/src/qpid/client/ConnectionSettings.h b/qpid/cpp/src/qpid/client/ConnectionSettings.h
index f60b11a4ab..71fef219b4 100644
--- a/qpid/cpp/src/qpid/client/ConnectionSettings.h
+++ b/qpid/cpp/src/qpid/client/ConnectionSettings.h
@@ -25,6 +25,7 @@
#include "qpid/Options.h"
#include "qpid/log/Options.h"
#include "qpid/Url.h"
+#include "qpid/client/ClientImportExport.h"
#include <iostream>
#include <exception>
@@ -42,14 +43,14 @@ namespace client {
*/
struct ConnectionSettings {
- ConnectionSettings();
- virtual ~ConnectionSettings();
+ QPID_CLIENT_EXTERN ConnectionSettings();
+ QPID_CLIENT_EXTERN virtual ~ConnectionSettings();
/**
* Allows socket to be configured; default only sets tcp-nodelay
* based on the flag set. Can be overridden.
*/
- virtual void configureSocket(qpid::sys::Socket&) const;
+ QPID_CLIENT_EXTERN virtual void configureSocket(qpid::sys::Socket&) const;
/**
* The protocol used for the connection (defaults to 'tcp')
diff --git a/qpid/cpp/src/qpid/client/Connector.cpp b/qpid/cpp/src/qpid/client/Connector.cpp
index e6355601df..c251233082 100644
--- a/qpid/cpp/src/qpid/client/Connector.cpp
+++ b/qpid/cpp/src/qpid/client/Connector.cpp
@@ -92,8 +92,6 @@ class TCPConnector : public Connector, public sys::Codec, private sys::Runnable
framing::ProtocolVersion version;
bool initiated;
-
- sys::Mutex closedLock;
bool closed;
bool joined;
@@ -185,7 +183,7 @@ TCPConnector::~TCPConnector() {
}
void TCPConnector::connect(const std::string& host, int port){
- Mutex::ScopedLock l(closedLock);
+ Mutex::ScopedLock l(lock);
assert(closed);
try {
socket.connect(host, port);
@@ -207,7 +205,7 @@ void TCPConnector::connect(const std::string& host, int port){
}
void TCPConnector::init(){
- Mutex::ScopedLock l(closedLock);
+ Mutex::ScopedLock l(lock);
assert(joined);
ProtocolInitiation init(version);
writeDataBlock(init);
@@ -216,17 +214,21 @@ void TCPConnector::init(){
}
bool TCPConnector::closeInternal() {
- Mutex::ScopedLock l(closedLock);
- bool ret = !closed;
+ bool ret;
+ {
+ Mutex::ScopedLock l(lock);
+ ret = !closed;
if (!closed) {
closed = true;
+ aio->queueForDeletion();
poller->shutdown();
}
- if (!joined && receiver.id() != Thread::current().id()) {
- joined = true;
- Mutex::ScopedUnlock u(closedLock);
- receiver.join();
+ if (joined || receiver.id() == Thread::current().id()) {
+ return ret;
}
+ joined = true;
+ }
+ receiver.join();
return ret;
}
@@ -259,21 +261,19 @@ const std::string& TCPConnector::getIdentifier() const {
}
void TCPConnector::send(AMQFrame& frame) {
+ Mutex::ScopedLock l(lock);
+ frames.push_back(frame);
+ //only ask to write if this is the end of a frameset or if we
+ //already have a buffers worth of data
+ currentSize += frame.encodedSize();
bool notifyWrite = false;
- {
- Mutex::ScopedLock l(lock);
- frames.push_back(frame);
- //only ask to write if this is the end of a frameset or if we
- //already have a buffers worth of data
- currentSize += frame.encodedSize();
- if (frame.getEof()) {
- lastEof = frames.size();
- notifyWrite = true;
- } else {
- notifyWrite = (currentSize >= maxFrameSize);
- }
+ if (frame.getEof()) {
+ lastEof = frames.size();
+ notifyWrite = true;
+ } else {
+ notifyWrite = (currentSize >= maxFrameSize);
}
- if (notifyWrite) aio->notifyPendingWrite();
+ if (notifyWrite && !closed) aio->notifyPendingWrite();
}
void TCPConnector::handleClosed() {
@@ -384,14 +384,13 @@ void TCPConnector::run() {
assert(protect);
try {
Dispatcher d(poller);
-
+
for (int i = 0; i < 32; i++) {
aio->queueReadBuffer(new Buff(maxFrameSize));
}
-
+
aio->start(poller);
d.run();
- aio->queueForDeletion();
socket.close();
} catch (const std::exception& e) {
QPID_LOG(error, QPID_MSG("FAIL " << identifier << ": " << e.what()));
diff --git a/qpid/cpp/src/qpid/client/Dispatcher.cpp b/qpid/cpp/src/qpid/client/Dispatcher.cpp
index 27cc4184f9..8d8574520a 100644
--- a/qpid/cpp/src/qpid/client/Dispatcher.cpp
+++ b/qpid/cpp/src/qpid/client/Dispatcher.cpp
@@ -136,8 +136,7 @@ void Dispatcher::listen(const boost::intrusive_ptr<SubscriptionImpl>& subscripti
void Dispatcher::cancel(const std::string& destination) {
ScopedLock<Mutex> l(lock);
- listeners.erase(destination);
- if (autoStop && listeners.empty())
+ if (listeners.erase(destination) && running && autoStop && listeners.empty())
queue->close();
}
diff --git a/qpid/cpp/src/qpid/client/FailoverManager.cpp b/qpid/cpp/src/qpid/client/FailoverManager.cpp
index ab9dbca70f..86b50a0a61 100644
--- a/qpid/cpp/src/qpid/client/FailoverManager.cpp
+++ b/qpid/cpp/src/qpid/client/FailoverManager.cpp
@@ -21,12 +21,15 @@
#include "FailoverManager.h"
#include "qpid/Exception.h"
#include "qpid/log/Statement.h"
+#include "qpid/sys/Time.h"
namespace qpid {
namespace client {
using qpid::sys::Monitor;
+using qpid::sys::AbsTime;
+using qpid::sys::Duration;
FailoverManager::FailoverManager(const ConnectionSettings& s,
ReconnectionStrategy* rs) : settings(s), strategy(rs), state(IDLE) {}
@@ -35,15 +38,21 @@ void FailoverManager::execute(Command& c)
{
bool retry = false;
bool completed = false;
+ AbsTime failed;
while (!completed) {
try {
AsyncSession session = connect().newSession();
+ if (retry) {
+ Duration failoverTime(failed, AbsTime::now());
+ QPID_LOG(info, "Failed over for " << &c << " in " << (failoverTime/qpid::sys::TIME_MSEC) << " milliseconds");
+ }
c.execute(session, retry);
session.sync();//TODO: shouldn't be required
session.close();
completed = true;
} catch(const TransportFailure&) {
- retry = true;
+ retry = true;
+ failed = AbsTime::now();
}
}
}
diff --git a/qpid/cpp/src/qpid/client/FailoverManager.h b/qpid/cpp/src/qpid/client/FailoverManager.h
index 8b6eeda8a1..bef5e18840 100644
--- a/qpid/cpp/src/qpid/client/FailoverManager.h
+++ b/qpid/cpp/src/qpid/client/FailoverManager.h
@@ -27,6 +27,7 @@
#include "qpid/Exception.h"
#include "qpid/client/AsyncSession.h"
#include "qpid/sys/Monitor.h"
+#include "qpid/client/ClientImportExport.h"
#include <vector>
namespace qpid {
@@ -84,7 +85,7 @@ class FailoverManager
* to edit or reorder the list of urls to which reconnection is
* attempted
*/
- FailoverManager(const ConnectionSettings& settings, ReconnectionStrategy* strategy = 0);
+ QPID_CLIENT_EXTERN FailoverManager(const ConnectionSettings& settings, ReconnectionStrategy* strategy = 0);
/**
* Return the current connection if open or attept to reconnect to
* the specified list of urls. If no list is specified the list of
@@ -95,15 +96,15 @@ class FailoverManager
* If the full list is tried and all attempts fail,
* CannotConnectException is thrown.
*/
- Connection& connect(std::vector<Url> brokers = std::vector<Url>());
+ QPID_CLIENT_EXTERN Connection& connect(std::vector<Url> brokers = std::vector<Url>());
/**
* Return the current connection whether open or not
*/
- Connection& getConnection();
+ QPID_CLIENT_EXTERN Connection& getConnection();
/**
* Close the current connection
*/
- void close();
+ QPID_CLIENT_EXTERN void close();
/**
* Reliably execute the specified command. This involves creating
* a session on which to carry out the work of the command,
@@ -116,7 +117,7 @@ class FailoverManager
* on failover to ensure they continue to use the same logical
* connection.
*/
- void execute(Command&);
+ QPID_CLIENT_EXTERN void execute(Command&);
private:
enum State {IDLE, CONNECTING, CANT_CONNECT};
diff --git a/qpid/cpp/src/qpid/client/Future.h b/qpid/cpp/src/qpid/client/Future.h
index 67f39cdf3f..ea01522fe8 100644
--- a/qpid/cpp/src/qpid/client/Future.h
+++ b/qpid/cpp/src/qpid/client/Future.h
@@ -30,6 +30,7 @@
#include "FutureCompletion.h"
#include "FutureResult.h"
#include "SessionImpl.h"
+#include "ClientImportExport.h"
namespace qpid {
namespace client {
@@ -54,9 +55,9 @@ public:
}
}
- void wait(SessionImpl& session);
- bool isComplete(SessionImpl& session);
- void setFutureResult(boost::shared_ptr<FutureResult> r);
+ QPID_CLIENT_EXTERN void wait(SessionImpl& session);
+ QPID_CLIENT_EXTERN bool isComplete(SessionImpl& session);
+ QPID_CLIENT_EXTERN void setFutureResult(boost::shared_ptr<FutureResult> r);
};
}}
diff --git a/qpid/cpp/src/qpid/client/FutureResult.h b/qpid/cpp/src/qpid/client/FutureResult.h
index e97d80476d..64428c0341 100644
--- a/qpid/cpp/src/qpid/client/FutureResult.h
+++ b/qpid/cpp/src/qpid/client/FutureResult.h
@@ -23,6 +23,8 @@
#define _FutureResult_
#include <string>
+
+#include "ClientImportExport.h"
#include "qpid/framing/amqp_framing.h"
#include "FutureCompletion.h"
@@ -36,7 +38,7 @@ class FutureResult : public FutureCompletion
{
std::string result;
public:
- const std::string& getResult(SessionImpl& session) const;
+ QPID_CLIENT_EXTERN const std::string& getResult(SessionImpl& session) const;
void received(const std::string& result);
};
diff --git a/qpid/cpp/src/qpid/client/Handle.h b/qpid/cpp/src/qpid/client/Handle.h
index 4fd82b7646..d8b822d0f9 100644
--- a/qpid/cpp/src/qpid/client/Handle.h
+++ b/qpid/cpp/src/qpid/client/Handle.h
@@ -22,6 +22,8 @@
*
*/
+#include "qpid/client/ClientImportExport.h"
+
namespace qpid {
namespace client {
@@ -34,23 +36,23 @@ template <class T> class HandlePrivate;
*/
template <class T> class Handle {
public:
- ~Handle();
- Handle(const Handle&);
- Handle& operator=(const Handle&);
+ QPID_CLIENT_EXTERN ~Handle();
+ QPID_CLIENT_EXTERN Handle(const Handle&);
+ QPID_CLIENT_EXTERN Handle& operator=(const Handle&);
/**@return true if handle is valid, i.e. not null. */
- bool isValid() const { return impl; }
+ QPID_CLIENT_EXTERN bool isValid() const { return impl; }
/**@return true if handle is null. It is an error to call any function on a null handle. */
- bool isNull() const { return !impl; }
+ QPID_CLIENT_EXTERN bool isNull() const { return !impl; }
- operator bool() const { return impl; }
- bool operator !() const { return impl; }
+ QPID_CLIENT_EXTERN operator bool() const { return impl; }
+ QPID_CLIENT_EXTERN bool operator !() const { return impl; }
- void swap(Handle<T>&);
+ QPID_CLIENT_EXTERN void swap(Handle<T>&);
protected:
- Handle(T* =0);
+ QPID_CLIENT_EXTERN Handle(T* =0);
T* impl;
friend class HandlePrivate<T>;
diff --git a/qpid/cpp/src/qpid/client/LocalQueue.h b/qpid/cpp/src/qpid/client/LocalQueue.h
index 30ea00612d..5b739d4303 100644
--- a/qpid/cpp/src/qpid/client/LocalQueue.h
+++ b/qpid/cpp/src/qpid/client/LocalQueue.h
@@ -22,6 +22,7 @@
*
*/
+#include "ClientImportExport.h"
#include "qpid/client/Message.h"
#include "qpid/client/Subscription.h"
#include "qpid/client/Demux.h"
@@ -75,16 +76,16 @@ class LocalQueue {
*
* LocalQueue is an alternative to implementing a MessageListener.
*/
- LocalQueue();
+ QPID_CLIENT_EXTERN LocalQueue();
- ~LocalQueue();
+ QPID_CLIENT_EXTERN ~LocalQueue();
/** Wait up to timeout for the next message from the local queue.
*@param result Set to the message from the queue.
*@param timeout wait up this timeout for a message to appear.
*@return true if result was set, false if queue was empty after timeout.
*/
- bool get(Message& result, sys::Duration timeout=0);
+ QPID_CLIENT_EXTERN bool get(Message& result, sys::Duration timeout=0);
/** Get the next message off the local queue, or wait up to the timeout
* for message from the broker queue.
@@ -92,16 +93,16 @@ class LocalQueue {
*@return message from the queue.
*@throw ClosedException if subscription is closed or timeout exceeded.
*/
- Message get(sys::Duration timeout=sys::TIME_INFINITE);
+ QPID_CLIENT_EXTERN Message get(sys::Duration timeout=sys::TIME_INFINITE);
/** Synonym for get() */
- Message pop(sys::Duration timeout=sys::TIME_INFINITE);
+ QPID_CLIENT_EXTERN Message pop(sys::Duration timeout=sys::TIME_INFINITE);
/** Return true if local queue is empty. */
- bool empty() const;
+ QPID_CLIENT_EXTERN bool empty() const;
/** Number of messages on the local queue */
- size_t size() const;
+ QPID_CLIENT_EXTERN size_t size() const;
private:
Demux::QueuePtr queue;
diff --git a/qpid/cpp/src/qpid/client/Message.h b/qpid/cpp/src/qpid/client/Message.h
index 3f932efd8b..235e20f97d 100644
--- a/qpid/cpp/src/qpid/client/Message.h
+++ b/qpid/cpp/src/qpid/client/Message.h
@@ -25,6 +25,7 @@
#include "qpid/client/Session.h"
#include "qpid/framing/MessageTransferBody.h"
#include "qpid/framing/TransferContent.h"
+#include "qpid/client/ClientImportExport.h"
namespace qpid {
namespace client {
@@ -111,7 +112,7 @@ public:
*@param data Data for the message body.
*@param routingKey Passed to the exchange that routes the message.
*/
- Message(const std::string& data=std::string(),
+ QPID_CLIENT_EXTERN Message(const std::string& data=std::string(),
const std::string& routingKey=std::string());
/** The destination of messages sent to the broker is the exchange
@@ -119,26 +120,26 @@ public:
* the delivery tag identifyig the local subscription (often this
* is the name of the subscribed queue.)
*/
- std::string getDestination() const;
+ QPID_CLIENT_EXTERN std::string getDestination() const;
/** Check the redelivered flag. */
- bool isRedelivered() const;
+ QPID_CLIENT_EXTERN bool isRedelivered() const;
/** Set the redelivered flag. */
- void setRedelivered(bool redelivered);
+ QPID_CLIENT_EXTERN void setRedelivered(bool redelivered);
/** Get a modifyable reference to the message headers. */
- framing::FieldTable& getHeaders();
+ QPID_CLIENT_EXTERN framing::FieldTable& getHeaders();
/** Get a non-modifyable reference to the message headers. */
- const framing::FieldTable& getHeaders() const;
+ QPID_CLIENT_EXTERN const framing::FieldTable& getHeaders() const;
///@internal
- const framing::MessageTransferBody& getMethod() const;
+ QPID_CLIENT_EXTERN const framing::MessageTransferBody& getMethod() const;
///@internal
- const framing::SequenceNumber& getId() const;
+ QPID_CLIENT_EXTERN const framing::SequenceNumber& getId() const;
/**@internal for incoming messages */
- Message(const framing::FrameSet& frameset);
+ QPID_CLIENT_EXTERN Message(const framing::FrameSet& frameset);
private:
//method and id are only set for received messages:
diff --git a/qpid/cpp/src/qpid/client/MessageListener.h b/qpid/cpp/src/qpid/client/MessageListener.h
index 75aad6521b..b86aa10c54 100644
--- a/qpid/cpp/src/qpid/client/MessageListener.h
+++ b/qpid/cpp/src/qpid/client/MessageListener.h
@@ -19,6 +19,7 @@
*
*/
#include <string>
+#include "qpid/client/ClientImportExport.h"
#ifndef _MessageListener_
#define _MessageListener_
@@ -85,7 +86,7 @@ namespace client {
class MessageListener{
public:
- virtual ~MessageListener();
+ QPID_CLIENT_EXTERN virtual ~MessageListener();
/** Called for each message arriving from the broker. Override
* in your own subclass to process messages.
diff --git a/qpid/cpp/src/qpid/client/MessageReplayTracker.h b/qpid/cpp/src/qpid/client/MessageReplayTracker.h
index 45b16fb704..280cbae4a5 100644
--- a/qpid/cpp/src/qpid/client/MessageReplayTracker.h
+++ b/qpid/cpp/src/qpid/client/MessageReplayTracker.h
@@ -23,7 +23,7 @@
*/
#include "AsyncSession.h"
#include "Message.h"
-
+#include "qpid/client/ClientImportExport.h"
#include <list>
#include <string>
@@ -37,13 +37,13 @@ namespace client {
class MessageReplayTracker
{
public:
- MessageReplayTracker(uint flushInterval);
- void send(const Message& message, const std::string& destination = "");
- void init(AsyncSession session);
- void replay(AsyncSession session);
- void setFlushInterval(uint interval);
- uint getFlushInterval();
- void checkCompletion();
+ QPID_CLIENT_EXTERN MessageReplayTracker(uint flushInterval);
+ QPID_CLIENT_EXTERN void send(const Message& message, const std::string& destination = "");
+ QPID_CLIENT_EXTERN void init(AsyncSession session);
+ QPID_CLIENT_EXTERN void replay(AsyncSession session);
+ QPID_CLIENT_EXTERN void setFlushInterval(uint interval);
+ QPID_CLIENT_EXTERN uint getFlushInterval();
+ QPID_CLIENT_EXTERN void checkCompletion();
template <class F> void foreach(F& f) {
for (std::list<ReplayRecord>::const_iterator i = buffer.begin(); i != buffer.end(); i++) {
diff --git a/qpid/cpp/src/qpid/client/QueueOptions.h b/qpid/cpp/src/qpid/client/QueueOptions.h
index d159378198..57d9487217 100644
--- a/qpid/cpp/src/qpid/client/QueueOptions.h
+++ b/qpid/cpp/src/qpid/client/QueueOptions.h
@@ -18,6 +18,8 @@
* under the License.
*
*/
+
+#include "ClientImportExport.h"
#include "qpid/framing/FieldTable.h"
#ifndef _QueueOptions_
@@ -36,8 +38,8 @@ enum QueueOrderingPolicy {FIFO, LVQ, LVQ_NO_BROWSE};
class QueueOptions: public framing::FieldTable
{
public:
- QueueOptions();
- virtual ~QueueOptions();
+ QPID_CLIENT_EXTERN QueueOptions();
+ QPID_CLIENT_EXTERN virtual ~QueueOptions();
/**
* Sets the queue sizing policy
@@ -51,58 +53,58 @@ class QueueOptions: public framing::FieldTable
* @param maxSize Set the max number of bytes for the sizing policies
* @param setMaxCount Set the max number of messages for the sizing policies
*/
- void setSizePolicy(QueueSizePolicy sp, uint64_t maxSize, uint32_t maxCount );
+ QPID_CLIENT_EXTERN void setSizePolicy(QueueSizePolicy sp, uint64_t maxSize, uint32_t maxCount );
/**
* Enables the persisting of a queue to the store module when a cluster fails down to it's last
* node. Does so optimistically. Will start persisting when cluster count >1 again.
*/
- void setPersistLastNode();
+ QPID_CLIENT_EXTERN void setPersistLastNode();
/**
* Sets the odering policy on the Queue, default ordering is FIFO.
*/
- void setOrdering(QueueOrderingPolicy op);
+ QPID_CLIENT_EXTERN void setOrdering(QueueOrderingPolicy op);
/**
* Use broker defualt sizing ploicy
*/
- void clearSizePolicy();
+ QPID_CLIENT_EXTERN void clearSizePolicy();
/**
* Clear Persist Last Node Policy
*/
- void clearPersistLastNode();
+ QPID_CLIENT_EXTERN void clearPersistLastNode();
/**
* get the key used match LVQ in args for message transfer
*/
- void getLVQKey(std::string& key);
+ QPID_CLIENT_EXTERN void getLVQKey(std::string& key);
/**
* Use default odering policy
*/
- void clearOrdering();
+ QPID_CLIENT_EXTERN void clearOrdering();
/**
* Turns on event generation for this queue (either enqueue only
* or for enqueue and dequeue events); the events can then be
* processed by a regsitered broker plugin.
*/
- void enableQueueEvents(bool enqueueOnly);
+ QPID_CLIENT_EXTERN void enableQueueEvents(bool enqueueOnly);
- static const std::string strMaxCountKey;
- static const std::string strMaxSizeKey;
- static const std::string strTypeKey;
- static const std::string strREJECT;
- static const std::string strFLOW_TO_DISK;
- static const std::string strRING;
- static const std::string strRING_STRICT;
- static const std::string strLastValueQueue;
- static const std::string strPersistLastNode;
- static const std::string strLVQMatchProperty;
- static const std::string strLastValueQueueNoBrowse;
- static const std::string strQueueEventMode;
+ static QPID_CLIENT_EXTERN const std::string strMaxCountKey;
+ static QPID_CLIENT_EXTERN const std::string strMaxSizeKey;
+ static QPID_CLIENT_EXTERN const std::string strTypeKey;
+ static QPID_CLIENT_EXTERN const std::string strREJECT;
+ static QPID_CLIENT_EXTERN const std::string strFLOW_TO_DISK;
+ static QPID_CLIENT_EXTERN const std::string strRING;
+ static QPID_CLIENT_EXTERN const std::string strRING_STRICT;
+ static QPID_CLIENT_EXTERN const std::string strLastValueQueue;
+ static QPID_CLIENT_EXTERN const std::string strPersistLastNode;
+ static QPID_CLIENT_EXTERN const std::string strLVQMatchProperty;
+ static QPID_CLIENT_EXTERN const std::string strLastValueQueueNoBrowse;
+ static QPID_CLIENT_EXTERN const std::string strQueueEventMode;
};
}
diff --git a/qpid/cpp/src/qpid/client/SessionBase_0_10.h b/qpid/cpp/src/qpid/client/SessionBase_0_10.h
index 091c977053..3ae21936f6 100644
--- a/qpid/cpp/src/qpid/client/SessionBase_0_10.h
+++ b/qpid/cpp/src/qpid/client/SessionBase_0_10.h
@@ -33,6 +33,7 @@
#include "qpid/client/SessionImpl.h"
#include "qpid/client/TypedResult.h"
#include "qpid/shared_ptr.h"
+#include "qpid/client/ClientImportExport.h"
#include <string>
namespace qpid {
@@ -65,19 +66,19 @@ class SessionBase_0_10 {
typedef framing::TransferContent DefaultContent;
///@internal
- SessionBase_0_10();
- ~SessionBase_0_10();
+ QPID_CLIENT_EXTERN SessionBase_0_10();
+ QPID_CLIENT_EXTERN ~SessionBase_0_10();
/** Get the next message frame-set from the session. */
- framing::FrameSet::shared_ptr get();
+ QPID_CLIENT_EXTERN framing::FrameSet::shared_ptr get();
/** Get the session ID */
- SessionId getId() const;
+ QPID_CLIENT_EXTERN SessionId getId() const;
/** Close the session.
* A session is automatically closed when all handles to it are destroyed.
*/
- void close();
+ QPID_CLIENT_EXTERN void close();
/**
* Synchronize the session: sync() waits until all commands issued
@@ -88,25 +89,25 @@ class SessionBase_0_10 {
* AsyncSession::executionSync() directly in the unusual event
* that you want to do an asynchronous sync.
*/
- void sync();
+ QPID_CLIENT_EXTERN void sync();
/** Set the timeout for this session. */
- uint32_t timeout(uint32_t seconds);
+ QPID_CLIENT_EXTERN uint32_t timeout(uint32_t seconds);
/** Suspend the session - detach it from its connection */
- void suspend();
+ QPID_CLIENT_EXTERN void suspend();
/** Resume a suspended session with a new connection */
- void resume(Connection);
+ QPID_CLIENT_EXTERN void resume(Connection);
/** Get the channel associated with this session */
- uint16_t getChannel() const;
+ QPID_CLIENT_EXTERN uint16_t getChannel() const;
- Execution& getExecution();
- void flush();
- void markCompleted(const framing::SequenceSet& ids, bool notifyPeer);
- void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer);
- void sendCompletion();
+ QPID_CLIENT_EXTERN Execution& getExecution();
+ QPID_CLIENT_EXTERN void flush();
+ QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceSet& ids, bool notifyPeer);
+ QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer);
+ QPID_CLIENT_EXTERN void sendCompletion();
protected:
boost::shared_ptr<SessionImpl> impl;
diff --git a/qpid/cpp/src/qpid/client/SessionImpl.cpp b/qpid/cpp/src/qpid/client/SessionImpl.cpp
index ee542a9cf8..5df376efa0 100644
--- a/qpid/cpp/src/qpid/client/SessionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/SessionImpl.cpp
@@ -512,6 +512,7 @@ void SessionImpl::detach(const std::string& _name)
if (id.getName() != _name) throw InternalErrorException("Incorrect session name");
setState(DETACHED);
QPID_LOG(info, "Session detached by peer: " << id);
+ proxy.detached(_name, DETACH_CODE_NORMAL);
}
void SessionImpl::detached(const std::string& _name, uint8_t _code) {
@@ -744,7 +745,8 @@ void SessionImpl::assertOpen() const
void SessionImpl::handleClosed()
{
- demux.close(exceptionHolder.empty() ? new ClosedException() : exceptionHolder);
+ demux.close(exceptionHolder.empty() ?
+ sys::ExceptionHolder(new ClosedException()) : exceptionHolder);
results.close();
}
diff --git a/qpid/cpp/src/qpid/client/SslConnector.cpp b/qpid/cpp/src/qpid/client/SslConnector.cpp
index 75c3f5677e..a4298dd4ca 100644
--- a/qpid/cpp/src/qpid/client/SslConnector.cpp
+++ b/qpid/cpp/src/qpid/client/SslConnector.cpp
@@ -221,6 +221,7 @@ bool SslConnector::closeInternal() {
bool ret = !closed;
if (!closed) {
closed = true;
+ aio->queueForDeletion();
poller->shutdown();
}
if (!joined && receiver.id() != Thread::current().id()) {
@@ -386,7 +387,6 @@ void SslConnector::run(){
aio->start(poller);
d.run();
- aio->queueForDeletion();
socket.close();
} catch (const std::exception& e) {
QPID_LOG(error, e.what());
diff --git a/qpid/cpp/src/qpid/client/Subscription.h b/qpid/cpp/src/qpid/client/Subscription.h
index 47bb5d42a5..43c6100254 100644
--- a/qpid/cpp/src/qpid/client/Subscription.h
+++ b/qpid/cpp/src/qpid/client/Subscription.h
@@ -26,6 +26,7 @@
#include "qpid/client/SubscriptionSettings.h"
#include "qpid/client/Handle.h"
#include "qpid/client/Message.h"
+#include "qpid/client/ClientImportExport.h"
namespace qpid {
namespace client {
@@ -39,74 +40,74 @@ class SubscriptionManager;
*/
class Subscription : public Handle<SubscriptionImpl> {
public:
- Subscription(SubscriptionImpl* si=0) : Handle<SubscriptionImpl>(si) {}
+ QPID_CLIENT_EXTERN Subscription(SubscriptionImpl* si=0) : Handle<SubscriptionImpl>(si) {}
- /** The name of the subsctription, used as the "destination" for messages from the broker.
+ /** The name of the subscription, used as the "destination" for messages from the broker.
* Usually the same as the queue name but can be set differently.
*/
- std::string getName() const;
+ QPID_CLIENT_EXTERN std::string getName() const;
/** Name of the queue this subscription subscribes to */
- std::string getQueue() const;
+ QPID_CLIENT_EXTERN std::string getQueue() const;
/** Get the flow control and acknowledgement settings for this subscription */
- const SubscriptionSettings& getSettings() const;
+ QPID_CLIENT_EXTERN const SubscriptionSettings& getSettings() const;
/** Set the flow control parameters */
- void setFlowControl(const FlowControl&);
+ QPID_CLIENT_EXTERN void setFlowControl(const FlowControl&);
/** Automatically acknowledge (acquire and accept) batches of n messages.
* You can disable auto-acknowledgement by setting n=0, and use acquire() and accept()
* to manually acquire and accept messages.
*/
- void setAutoAck(unsigned int n);
+ QPID_CLIENT_EXTERN void setAutoAck(unsigned int n);
/** Get the set of ID's for messages received by this subscription but not yet acquired.
* This will always be empty if getSettings().acquireMode=ACQUIRE_MODE_PRE_ACQUIRED
*/
- SequenceSet getUnacquired() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnacquired() const;
/** Get the set of ID's for messages received by this subscription but not yet accepted. */
- SequenceSet getUnaccepted() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnaccepted() const;
/** Acquire messageIds and remove them from the unacquired set.
* oAdd them to the unaccepted set if getSettings().acceptMode == ACCEPT_MODE_EXPLICIT.
*/
- void acquire(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void acquire(const SequenceSet& messageIds);
/** Accept messageIds and remove them from the unaccepted set.
*@pre messageIds is a subset of getUnaccepted()
*/
- void accept(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void accept(const SequenceSet& messageIds);
/** Release messageIds and remove them from the unaccepted set.
*@pre messageIds is a subset of getUnaccepted()
*/
- void release(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds);
/* Acquire a single message */
- void acquire(const Message& m) { acquire(SequenceSet(m.getId())); }
+ QPID_CLIENT_EXTERN void acquire(const Message& m) { acquire(SequenceSet(m.getId())); }
/* Accept a single message */
- void accept(const Message& m) { accept(SequenceSet(m.getId())); }
+ QPID_CLIENT_EXTERN void accept(const Message& m) { accept(SequenceSet(m.getId())); }
/* Release a single message */
- void release(const Message& m) { release(SequenceSet(m.getId())); }
+ QPID_CLIENT_EXTERN void release(const Message& m) { release(SequenceSet(m.getId())); }
/** Get the session associated with this subscription */
- Session getSession() const;
+ QPID_CLIENT_EXTERN Session getSession() const;
/** Get the subscription manager associated with this subscription */
- SubscriptionManager& getSubscriptionManager() const;
+ QPID_CLIENT_EXTERN SubscriptionManager& getSubscriptionManager() const;
/** Cancel the subscription. */
- void cancel();
+ QPID_CLIENT_EXTERN void cancel();
/** Grant the specified amount of message credit */
- void grantMessageCredit(uint32_t);
+ QPID_CLIENT_EXTERN void grantMessageCredit(uint32_t);
/** Grant the specified amount of byte credit */
- void grantByteCredit(uint32_t);
+ QPID_CLIENT_EXTERN void grantByteCredit(uint32_t);
friend class SubscriptionManager;
};
diff --git a/qpid/cpp/src/qpid/client/SubscriptionImpl.h b/qpid/cpp/src/qpid/client/SubscriptionImpl.h
index 74fbacb951..e2b970ce05 100644
--- a/qpid/cpp/src/qpid/client/SubscriptionImpl.h
+++ b/qpid/cpp/src/qpid/client/SubscriptionImpl.h
@@ -30,6 +30,7 @@
#include "qpid/framing/SequenceSet.h"
#include "qpid/sys/Mutex.h"
#include "qpid/RefCounted.h"
+#include "qpid/client/ClientImportExport.h"
#include <memory>
namespace qpid {
@@ -39,62 +40,62 @@ class SubscriptionManager;
class SubscriptionImpl : public RefCounted, public MessageListener {
public:
- SubscriptionImpl(SubscriptionManager&, const std::string& queue,
+ QPID_CLIENT_EXTERN SubscriptionImpl(SubscriptionManager&, const std::string& queue,
const SubscriptionSettings&, const std::string& name, MessageListener* =0);
/** The name of the subsctription, used as the "destination" for messages from the broker.
* Usually the same as the queue name but can be set differently.
*/
- std::string getName() const;
+ QPID_CLIENT_EXTERN std::string getName() const;
/** Name of the queue this subscription subscribes to */
- std::string getQueue() const;
+ QPID_CLIENT_EXTERN std::string getQueue() const;
/** Get the flow control and acknowledgement settings for this subscription */
- const SubscriptionSettings& getSettings() const;
+ QPID_CLIENT_EXTERN const SubscriptionSettings& getSettings() const;
/** Set the flow control parameters */
- void setFlowControl(const FlowControl&);
+ QPID_CLIENT_EXTERN void setFlowControl(const FlowControl&);
/** Automatically acknowledge (acquire and accept) batches of n messages.
* You can disable auto-acknowledgement by setting n=0, and use acquire() and accept()
* to manually acquire and accept messages.
*/
- void setAutoAck(size_t n);
+ QPID_CLIENT_EXTERN void setAutoAck(size_t n);
/** Get the set of ID's for messages received by this subscription but not yet acquired.
* This will always be empty if acquireMode=ACQUIRE_MODE_PRE_ACQUIRED
*/
- SequenceSet getUnacquired() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnacquired() const;
/** Get the set of ID's for messages acquired by this subscription but not yet accepted. */
- SequenceSet getUnaccepted() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnaccepted() const;
/** Acquire messageIds and remove them from the un-acquired set for the session. */
- void acquire(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void acquire(const SequenceSet& messageIds);
/** Accept messageIds and remove them from the un-accepted set for the session. */
- void accept(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void accept(const SequenceSet& messageIds);
/** Release messageIds and remove them from the un-accepted set for the session. */
- void release(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds);
/** Get the session associated with this subscription */
- Session getSession() const;
+ QPID_CLIENT_EXTERN Session getSession() const;
/** Get the subscription manager associated with this subscription */
- SubscriptionManager& getSubscriptionManager() const;
+ QPID_CLIENT_EXTERN SubscriptionManager& getSubscriptionManager() const;
/** Send subscription request and issue appropriate flow control commands. */
- void subscribe();
+ QPID_CLIENT_EXTERN void subscribe();
/** Cancel the subscription. */
- void cancel();
+ QPID_CLIENT_EXTERN void cancel();
/** Grant specified credit for this subscription **/
- void grantCredit(framing::message::CreditUnit unit, uint32_t value);
+ QPID_CLIENT_EXTERN void grantCredit(framing::message::CreditUnit unit, uint32_t value);
- void received(Message&);
+ QPID_CLIENT_EXTERN void received(Message&);
/**
* Set up demux diversion for messages sent to this subscription
@@ -104,7 +105,7 @@ class SubscriptionImpl : public RefCounted, public MessageListener {
* Cancel any demux diversion that may have been setup for this
* subscription
*/
- void cancelDiversion();
+ QPID_CLIENT_EXTERN void cancelDiversion();
private:
diff --git a/qpid/cpp/src/qpid/client/SubscriptionManager.h b/qpid/cpp/src/qpid/client/SubscriptionManager.h
index 6b45092931..91ad2b6d56 100644
--- a/qpid/cpp/src/qpid/client/SubscriptionManager.h
+++ b/qpid/cpp/src/qpid/client/SubscriptionManager.h
@@ -30,6 +30,7 @@
#include <qpid/client/LocalQueue.h>
#include <qpid/client/Subscription.h>
#include <qpid/sys/Runnable.h>
+#include <qpid/client/ClientImportExport.h>
#include <set>
#include <sstream>
@@ -97,7 +98,7 @@ class SubscriptionManager : public sys::Runnable
{
public:
/** Create a new SubscriptionManager associated with a session */
- SubscriptionManager(const Session& session);
+ QPID_CLIENT_EXTERN SubscriptionManager(const Session& session);
/**
* Subscribe a MessagesListener to receive messages from queue.
@@ -110,7 +111,7 @@ class SubscriptionManager : public sys::Runnable
*@param settings settings for the subscription.
*@param name unique destination name for the subscription, defaults to queue name.
*/
- Subscription subscribe(MessageListener& listener,
+ QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener,
const std::string& queue,
const SubscriptionSettings& settings,
const std::string& name=std::string());
@@ -125,7 +126,7 @@ class SubscriptionManager : public sys::Runnable
*@param name unique destination name for the subscription, defaults to queue name.
* If not specified, the queue name is used.
*/
- Subscription subscribe(LocalQueue& localQueue,
+ QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue,
const std::string& queue,
const SubscriptionSettings& settings,
const std::string& name=std::string());
@@ -141,7 +142,7 @@ class SubscriptionManager : public sys::Runnable
*@param name unique destination name for the subscription, defaults to queue name.
* If not specified, the queue name is used.
*/
- Subscription subscribe(MessageListener& listener,
+ QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener,
const std::string& queue,
const std::string& name=std::string());
@@ -154,7 +155,7 @@ class SubscriptionManager : public sys::Runnable
*@param name unique destination name for the subscription, defaults to queue name.
* If not specified, the queue name is used.
*/
- Subscription subscribe(LocalQueue& localQueue,
+ QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue,
const std::string& queue,
const std::string& name=std::string());
@@ -164,53 +165,53 @@ class SubscriptionManager : public sys::Runnable
*@param timeout wait up this timeout for a message to appear.
*@return true if result was set, false if no message available after timeout.
*/
- bool get(Message& result, const std::string& queue, sys::Duration timeout=0);
+ QPID_CLIENT_EXTERN bool get(Message& result, const std::string& queue, sys::Duration timeout=0);
/** Get a single message from a queue.
*@param timeout wait up this timeout for a message to appear.
*@return message from the queue.
*@throw Exception if the timeout is exceeded.
*/
- Message get(const std::string& queue, sys::Duration timeout=sys::TIME_INFINITE);
+ QPID_CLIENT_EXTERN Message get(const std::string& queue, sys::Duration timeout=sys::TIME_INFINITE);
/** Get a subscription by name.
*@throw Exception if not found.
*/
- Subscription getSubscription(const std::string& name) const;
+ QPID_CLIENT_EXTERN Subscription getSubscription(const std::string& name) const;
/** Cancel a subscription. See also: Subscription.cancel() */
- void cancel(const std::string& name);
+ QPID_CLIENT_EXTERN void cancel(const std::string& name);
/** Deliver messages in the current thread until stop() is called.
* Only one thread may be running in a SubscriptionManager at a time.
* @see run
*/
- void run();
+ QPID_CLIENT_EXTERN void run();
/** Start a new thread to deliver messages.
* Only one thread may be running in a SubscriptionManager at a time.
* @see start
*/
- void start();
+ QPID_CLIENT_EXTERN void start();
/**
* Wait for the thread started by a call to start() to complete.
*/
- void wait();
+ QPID_CLIENT_EXTERN void wait();
/** If set true, run() will stop when all subscriptions
* are cancelled. If false, run will only stop when stop()
* is called. True by default.
*/
- void setAutoStop(bool set=true);
+ QPID_CLIENT_EXTERN void setAutoStop(bool set=true);
/** Stop delivery. Causes run() to return, or the thread started with start() to exit. */
- void stop();
+ QPID_CLIENT_EXTERN void stop();
static const uint32_t UNLIMITED=0xFFFFFFFF;
/** Set the flow control for a subscription. */
- void setFlowControl(const std::string& name, const FlowControl& flow);
+ QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, const FlowControl& flow);
/** Set the flow control for a subscription.
*@param name: name of the subscription.
@@ -218,22 +219,22 @@ class SubscriptionManager : public sys::Runnable
*@param bytes: byte credit.
*@param window: if true use window-based flow control.
*/
- void setFlowControl(const std::string& name, uint32_t messages, uint32_t bytes, bool window=true);
+ QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, uint32_t messages, uint32_t bytes, bool window=true);
/** Set the default settings for subscribe() calls that don't
* include a SubscriptionSettings parameter.
*/
- void setDefaultSettings(const SubscriptionSettings& s) { defaultSettings = s; }
+ QPID_CLIENT_EXTERN void setDefaultSettings(const SubscriptionSettings& s) { defaultSettings = s; }
/** Get the default settings for subscribe() calls that don't
* include a SubscriptionSettings parameter.
*/
- const SubscriptionSettings& getDefaultSettings() const { return defaultSettings; }
+ QPID_CLIENT_EXTERN const SubscriptionSettings& getDefaultSettings() const { return defaultSettings; }
/** Get the default settings for subscribe() calls that don't
* include a SubscriptionSettings parameter.
*/
- SubscriptionSettings& getDefaultSettings() { return defaultSettings; }
+ QPID_CLIENT_EXTERN SubscriptionSettings& getDefaultSettings() { return defaultSettings; }
/**
* Set the default flow control settings for subscribe() calls
@@ -243,7 +244,7 @@ class SubscriptionManager : public sys::Runnable
*@param bytes: byte credit.
*@param window: if true use window-based flow control.
*/
- void setFlowControl(uint32_t messages, uint32_t bytes, bool window=true) {
+ QPID_CLIENT_EXTERN void setFlowControl(uint32_t messages, uint32_t bytes, bool window=true) {
defaultSettings.flowControl = FlowControl(messages, bytes, window);
}
@@ -251,16 +252,16 @@ class SubscriptionManager : public sys::Runnable
*Set the default accept-mode for subscribe() calls that don't
*include a SubscriptionSettings parameter.
*/
- void setAcceptMode(AcceptMode mode) { defaultSettings.acceptMode = mode; }
+ QPID_CLIENT_EXTERN void setAcceptMode(AcceptMode mode) { defaultSettings.acceptMode = mode; }
/**
* Set the default acquire-mode subscribe()s that don't specify SubscriptionSettings.
*/
- void setAcquireMode(AcquireMode mode) { defaultSettings.acquireMode = mode; }
+ QPID_CLIENT_EXTERN void setAcquireMode(AcquireMode mode) { defaultSettings.acquireMode = mode; }
- void registerFailoverHandler ( boost::function<void ()> fh );
+ QPID_CLIENT_EXTERN void registerFailoverHandler ( boost::function<void ()> fh );
- Session getSession() const;
+ QPID_CLIENT_EXTERN Session getSession() const;
private:
mutable sys::Mutex lock;
diff --git a/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp
new file mode 100644
index 0000000000..58956609a4
--- /dev/null
+++ b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp
@@ -0,0 +1,139 @@
+/*
+ *
+ * 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/client/SaslFactory.h"
+#include "qpid/client/ConnectionSettings.h"
+
+#include "qpid/Exception.h"
+#include "qpid/framing/reply_exceptions.h"
+#include "qpid/sys/SecurityLayer.h"
+#include "qpid/log/Statement.h"
+
+#include "boost/tokenizer.hpp"
+
+namespace qpid {
+namespace client {
+
+using qpid::sys::SecurityLayer;
+using qpid::framing::InternalErrorException;
+
+class WindowsSasl : public Sasl
+{
+ public:
+ WindowsSasl(const ConnectionSettings&);
+ ~WindowsSasl();
+ std::string start(const std::string& mechanisms);
+ std::string step(const std::string& challenge);
+ std::string getMechanism();
+ std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize);
+ private:
+ ConnectionSettings settings;
+ std::string mechanism;
+};
+
+qpid::sys::Mutex SaslFactory::lock;
+std::auto_ptr<SaslFactory> SaslFactory::instance;
+
+SaslFactory::SaslFactory()
+{
+}
+
+SaslFactory::~SaslFactory()
+{
+}
+
+SaslFactory& SaslFactory::getInstance()
+{
+ qpid::sys::Mutex::ScopedLock l(lock);
+ if (!instance.get()) {
+ instance = std::auto_ptr<SaslFactory>(new SaslFactory());
+ }
+ return *instance;
+}
+
+std::auto_ptr<Sasl> SaslFactory::create(const ConnectionSettings& settings)
+{
+ std::auto_ptr<Sasl> sasl(new WindowsSasl(settings));
+ return sasl;
+}
+
+namespace {
+ const std::string ANONYMOUS = "ANONYMOUS";
+ const std::string PLAIN = "PLAIN";
+}
+
+WindowsSasl::WindowsSasl(const ConnectionSettings& s)
+ : settings(s)
+{
+}
+
+WindowsSasl::~WindowsSasl()
+{
+}
+
+std::string WindowsSasl::start(const std::string& mechanisms)
+{
+ QPID_LOG(debug, "WindowsSasl::start(" << mechanisms << ")");
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" ");
+ bool havePlain = false;
+ bool haveAnon = false;
+ tokenizer mechs(mechanisms, sep);
+ for (tokenizer::iterator mech = mechs.begin();
+ mech != mechs.end();
+ ++mech) {
+ if (*mech == ANONYMOUS)
+ haveAnon = true;
+ else if (*mech == PLAIN)
+ havePlain = true;
+ }
+ if (!haveAnon && !havePlain)
+ throw InternalErrorException(QPID_MSG("Sasl error: no common mechanism"));
+
+ std::string resp = "";
+ if (havePlain) {
+ mechanism = PLAIN;
+ resp = ((char)0) + settings.username + ((char)0) + settings.password;
+ }
+ else {
+ mechanism = ANONYMOUS;
+ }
+ return resp;
+}
+
+std::string WindowsSasl::step(const std::string& challenge)
+{
+ // Shouldn't get this for PLAIN...
+ throw InternalErrorException(QPID_MSG("Sasl step error"));
+}
+
+std::string WindowsSasl::getMechanism()
+{
+ return mechanism;
+}
+
+std::auto_ptr<SecurityLayer> WindowsSasl::getSecurityLayer(uint16_t maxFrameSize)
+{
+ return std::auto_ptr<SecurityLayer>(0);
+}
+
+}} // namespace qpid::client
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.cpp b/qpid/cpp/src/qpid/cluster/Cluster.cpp
index 6221b0054c..f8e412f1e6 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.cpp
+++ b/qpid/cpp/src/qpid/cluster/Cluster.cpp
@@ -21,7 +21,9 @@
#include "Connection.h"
#include "UpdateClient.h"
#include "FailoverExchange.h"
+#include "UpdateExchange.h"
+#include "qpid/assert.h"
#include "qmf/org/apache/qpid/cluster/ArgsClusterStopClusterNode.h"
#include "qmf/org/apache/qpid/cluster/Package.h"
#include "qpid/broker/Broker.h"
@@ -91,9 +93,10 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
cpg(*this),
name(settings.name),
myUrl(settings.url.empty() ? Url() : Url(settings.url)),
- myId(cpg.self()),
+ self(cpg.self()),
readMax(settings.readMax),
writeEstimate(settings.writeEstimate),
+ expiryPolicy(new ExpiryPolicy(mcast, self, broker.getTimer())),
mcast(cpg, poller, boost::bind(&Cluster::leave, this)),
dispatcher(cpg, poller, boost::bind(&Cluster::leave, this)),
deliverEventQueue(boost::bind(&Cluster::deliveredEvent, this, _1),
@@ -104,15 +107,12 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
boost::bind(&Cluster::leave, this),
"Error delivering frames",
poller),
- connections(*this),
- decoder(boost::bind(&PollableFrameQueue::push, &deliverFrameQueue, _1), connections),
- expiryPolicy(new ExpiryPolicy(boost::bind(&Cluster::isLeader, this), mcast, myId, broker.getTimer())),
- frameId(0),
initialized(false),
+ decoder(boost::bind(&Cluster::deliverFrame, this, _1)),
+ discarding(true),
state(INIT),
lastSize(0),
- lastBroker(false),
- sequence(0)
+ lastBroker(false)
{
mAgent = ManagementAgent::Singleton::getInstance();
if (mAgent != 0){
@@ -122,7 +122,13 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
mgmtObject->set_status("JOINING");
}
+ // Failover exchange provides membership updates to clients.
failoverExchange.reset(new FailoverExchange(this));
+ broker.getExchanges().registerExchange(failoverExchange);
+
+ // Update exchange is used during updates to replicate messages without modifying delivery-properties.exchange.
+ broker.getExchanges().registerExchange(boost::shared_ptr<broker::Exchange>(new UpdateExchange(this)));
+
if (settings.quorum) quorum.init();
cpg.join(name);
// pump the CPG dispatch manually till we get initialized.
@@ -149,21 +155,21 @@ void Cluster::initialize() {
// Called in connection thread to insert a client connection.
void Cluster::addLocalConnection(const boost::intrusive_ptr<Connection>& c) {
- Lock l(lock);
- connections.insert(c);
+ localConnections.insert(c);
}
// Called in connection thread to insert an updated shadow connection.
void Cluster::addShadowConnection(const boost::intrusive_ptr<Connection>& c) {
- Lock l(lock);
- assert(state <= UPDATEE); // Only during update.
- connections.insert(c);
+ // Safe to use connections here because we're pre-catchup, either
+ // discarding or stalled, so deliveredFrame is not processing any
+ // connection events.
+ assert(discarding);
+ connections.insert(ConnectionMap::value_type(c->getId(), c));
}
+// Called by Connection::deliverClose() in deliverFrameQueue thread.
void Cluster::erase(const ConnectionId& id) {
- // Called only by Connection::deliverClose in deliver thread, no need to lock.
connections.erase(id);
- decoder.erase(id);
}
std::vector<string> Cluster::getIds() const {
@@ -193,7 +199,6 @@ void Cluster::leave(Lock&) {
if (state != LEFT) {
state = LEFT;
QPID_LOG(notice, *this << " leaving cluster " << name);
- connections.clear();
try { broker.shutdown(); }
catch (const std::exception& e) {
QPID_LOG(critical, *this << " error during broker shutdown: " << e.what());
@@ -213,52 +218,88 @@ void Cluster::deliver(
MemberId from(nodeid, pid);
framing::Buffer buf(static_cast<char*>(msg), msg_len);
Event e(Event::decodeCopy(from, buf));
- e.setSequence(sequence++);
- if (from == myId) // Record self-deliveries for flow control.
+ if (from == self) // Record self-deliveries for flow control.
mcast.selfDeliver(e);
- deliver(e);
+ deliverEvent(e);
}
-void Cluster::deliver(const Event& e) {
- if (state == LEFT) return;
- QPID_LATENCY_INIT(e);
+void Cluster::deliverEvent(const Event& e) {
deliverEventQueue.push(e);
}
-// Handler for deliverEventQueue
+void Cluster::deliverFrame(const EventFrame& e) {
+ deliverFrameQueue.push(e);
+}
+
+// Handler for deliverEventQueue.
+// This thread decodes frames from events.
void Cluster::deliveredEvent(const Event& e) {
- QPID_LATENCY_RECORD("delivered event queue", e);
- Buffer buf(const_cast<char*>(e.getData()), e.getSize());
- if (e.getType() == CONTROL) {
- AMQFrame frame;
- while (frame.decode(buf))
- deliverFrameQueue.push(EventFrame(e, frame));
+ QPID_LOG(trace, *this << " DLVR: " << e);
+ if (e.isCluster()) {
+ EventFrame ef(e, e.getFrame());
+ // Stop the deliverEventQueue on update offers.
+ // This preserves the connection decoder fragments for an update.
+ ClusterUpdateOfferBody* offer = dynamic_cast<ClusterUpdateOfferBody*>(ef.frame.getBody());
+ if (offer)
+ deliverEventQueue.stop();
+ deliverFrame(ef);
}
- else if (e.getType() == DATA)
- decoder.decode(e, e.getData());
+ else if(!discarding) {
+ if (e.isControl())
+ deliverFrame(EventFrame(e, e.getFrame()));
+ else
+ decoder.decode(e, e.getData());
+}
+ else // Discard connection events if discarding is set.
+ QPID_LOG(trace, *this << " DROP: " << e);
}
-// Handler for deliverFrameQueue
+// Handler for deliverFrameQueue.
+// This thread executes the main logic.
void Cluster::deliveredFrame(const EventFrame& e) {
Mutex::ScopedLock l(lock);
- const_cast<AMQFrame&>(e.frame).setClusterId(frameId++);
- QPID_LOG(trace, *this << " DLVR: " << e);
- QPID_LATENCY_RECORD("delivered frame queue", e.frame);
- if (e.isCluster()) { // Cluster control frame
+ if (e.isCluster()) {
+ QPID_LOG(trace, *this << " DLVR: " << e);
ClusterDispatcher dispatch(*this, e.connectionId.getMember(), l);
if (!framing::invoke(dispatch, *e.frame.getBody()).wasHandled())
throw Exception(QPID_MSG("Invalid cluster control"));
}
- else { // Connection frame.
- if (state <= UPDATEE) {
- QPID_LOG(trace, *this << " DROP: " << e);
- return;
- }
- boost::intrusive_ptr<Connection> connection = connections.get(e.connectionId);
- if (connection) // Ignore frames to closed local connections.
+ else if (state >= CATCHUP) {
+ QPID_LOG(trace, *this << " DLVR: " << e);
+ ConnectionPtr connection = getConnection(e.connectionId, l);
+ if (connection)
connection->deliveredFrame(e);
}
- QPID_LATENCY_RECORD("processed", e.frame);
+ else // Drop connection frames while state < CATCHUP
+ QPID_LOG(trace, *this << " DROP: " << e);
+}
+
+// Called in deliverFrameQueue thread
+ConnectionPtr Cluster::getConnection(const ConnectionId& id, Lock&) {
+ ConnectionPtr cp;
+ ConnectionMap::iterator i = connections.find(id);
+ if (i != connections.end())
+ cp = i->second;
+ else {
+ if(id.getMember() == self)
+ cp = localConnections.getErase(id);
+ else {
+ // New remote connection, create a shadow.
+ std::ostringstream mgmtId;
+ mgmtId << id;
+ cp = new Connection(*this, shadowOut, mgmtId.str(), id);
+ }
+ if (cp)
+ connections.insert(ConnectionMap::value_type(id, cp));
+ }
+ return cp;
+}
+
+Cluster::ConnectionVector Cluster::getConnections(Lock&) {
+ ConnectionVector result(connections.size());
+ std::transform(connections.begin(), connections.end(), result.begin(),
+ boost::bind(&ConnectionMap::value_type::second, _1));
+ return result;
}
struct AddrList {
@@ -306,42 +347,45 @@ void Cluster::configChange (
std::string addresses;
for (cpg_address* p = current; p < current+nCurrent; ++p)
addresses.append(MemberId(*p).str());
- deliver(Event::control(ClusterConfigChangeBody(ProtocolVersion(), addresses), myId));
+ deliverEvent(Event::control(ClusterConfigChangeBody(ProtocolVersion(), addresses), self));
}
void Cluster::setReady(Lock&) {
state = READY;
if (mgmtObject!=0) mgmtObject->set_status("ACTIVE");
mcast.release();
+ broker.getQueueEvents().enable();
}
void Cluster::configChange(const MemberId&, const std::string& addresses, Lock& l) {
bool memberChange = map.configChange(addresses);
if (state == LEFT) return;
- if (!map.isAlive(myId)) { // Final config change.
+ if (!map.isAlive(self)) { // Final config change.
leave(l);
return;
}
if (state == INIT) { // First configChange
if (map.aliveCount() == 1) {
- setClusterId(true);
+ setClusterId(true, l);
+ discarding = false;
setReady(l);
- map = ClusterMap(myId, myUrl, true);
+ map = ClusterMap(self, myUrl, true);
memberUpdate(l);
QPID_LOG(notice, *this << " first in cluster");
}
else { // Joining established group.
state = JOINER;
QPID_LOG(info, *this << " joining cluster: " << map);
- mcast.mcastControl(ClusterUpdateRequestBody(ProtocolVersion(), myUrl.str()), myId);
+ mcast.mcastControl(ClusterUpdateRequestBody(ProtocolVersion(), myUrl.str()), self);
elders = map.getAlive();
- elders.erase(myId);
+ elders.erase(self);
broker.getLinks().setPassive(true);
+ broker.getQueueEvents().disable();
}
- }
- else if (state >= READY && memberChange) {
+ }
+ else if (state >= CATCHUP && memberChange) {
memberUpdate(l);
elders = ClusterMap::intersection(elders, map.getAlive());
if (elders.empty()) {
@@ -351,13 +395,11 @@ void Cluster::configChange(const MemberId&, const std::string& addresses, Lock&
}
}
-bool Cluster::isLeader() const { return elders.empty(); }
-
-void Cluster::tryMakeOffer(const MemberId& id, Lock& ) {
+void Cluster::makeOffer(const MemberId& id, Lock& ) {
if (state == READY && map.isJoiner(id)) {
state = OFFER;
QPID_LOG(info, *this << " send update-offer to " << id);
- mcast.mcastControl(ClusterUpdateOfferBody(ProtocolVersion(), id, clusterId), myId);
+ mcast.mcastControl(ClusterUpdateOfferBody(ProtocolVersion(), id, clusterId), self);
}
}
@@ -367,88 +409,89 @@ void Cluster::tryMakeOffer(const MemberId& id, Lock& ) {
// callbacks will be invoked.
//
void Cluster::brokerShutdown() {
- if (state != LEFT) {
- try { cpg.shutdown(); }
- catch (const std::exception& e) {
- QPID_LOG(error, *this << " shutting down CPG: " << e.what());
- }
+ try { cpg.shutdown(); }
+ catch (const std::exception& e) {
+ QPID_LOG(error, *this << " shutting down CPG: " << e.what());
}
delete this;
}
void Cluster::updateRequest(const MemberId& id, const std::string& url, Lock& l) {
map.updateRequest(id, url);
- tryMakeOffer(id, l);
+ makeOffer(id, l);
}
void Cluster::ready(const MemberId& id, const std::string& url, Lock& l) {
if (map.ready(id, Url(url)))
memberUpdate(l);
- if (state == CATCHUP && id == myId) {
+ if (state == CATCHUP && id == self) {
setReady(l);
QPID_LOG(notice, *this << " caught up, active cluster member");
}
}
void Cluster::updateOffer(const MemberId& updater, uint64_t updateeInt, const Uuid& uuid, Lock& l) {
+ // NOTE: deliverEventQueue has been stopped at the update offer by
+ // deliveredEvent in case an update is required.
if (state == LEFT) return;
MemberId updatee(updateeInt);
boost::optional<Url> url = map.updateOffer(updater, updatee);
- if (updater == myId) {
+ if (updater == self) {
assert(state == OFFER);
- if (url) { // My offer was first.
+ if (url) // My offer was first.
updateStart(updatee, *url, l);
- }
else { // Another offer was first.
+ deliverEventQueue.start(); // Don't need to update
setReady(l);
QPID_LOG(info, *this << " cancelled update offer to " << updatee);
- tryMakeOffer(map.firstJoiner(), l); // Maybe make another offer.
+ makeOffer(map.firstJoiner(), l); // Maybe make another offer.
}
}
- else if (updatee == myId && url) {
+ else if (updatee == self && url) {
assert(state == JOINER);
- setClusterId(uuid);
+ setClusterId(uuid, l);
state = UPDATEE;
QPID_LOG(info, *this << " receiving update from " << updater);
- deliverFrameQueue.stop();
checkUpdateIn(l);
}
+ else
+ deliverEventQueue.start(); // Don't need to update
}
-void Cluster::updateStart(const MemberId& updatee, const Url& url, Lock&) {
+void Cluster::updateStart(const MemberId& updatee, const Url& url, Lock& l) {
+ // NOTE: deliverEventQueue is already stopped at the stall point by deliveredEvent.
if (state == LEFT) return;
assert(state == OFFER);
state = UPDATER;
- QPID_LOG(info, *this << " stall for update to " << updatee << " at " << url);
- deliverFrameQueue.stop();
- if (updateThread.id()) updateThread.join(); // Join the previous updatethread.
+ QPID_LOG(info, *this << " sending update to " << updatee << " at " << url);
+ if (updateThread.id())
+ updateThread.join(); // Join the previous updateThread to avoid leaks.
client::ConnectionSettings cs;
cs.username = settings.username;
cs.password = settings.password;
cs.mechanism = settings.mechanism;
updateThread = Thread(
- new UpdateClient(myId, updatee, url, broker, map, frameId, connections.values(),
+ new UpdateClient(self, updatee, url, broker, map, *expiryPolicy, getConnections(l), decoder,
boost::bind(&Cluster::updateOutDone, this),
boost::bind(&Cluster::updateOutError, this, _1),
cs));
}
// Called in update thread.
-void Cluster::updateInDone(const ClusterMap& m, uint64_t fid) {
+void Cluster::updateInDone(const ClusterMap& m) {
Lock l(lock);
updatedMap = m;
- frameId = fid;
checkUpdateIn(l);
}
-void Cluster::checkUpdateIn(Lock& ) {
- if (state == LEFT) return;
+void Cluster::checkUpdateIn(Lock&) {
if (state == UPDATEE && updatedMap) {
map = *updatedMap;
- mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), myId);
+ mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self);
state = CATCHUP;
+ discarding = false; // ok to set, we're stalled for update.
QPID_LOG(info, *this << " received update, starting catch-up");
- deliverFrameQueue.start();
+ deliverEventQueue.start();
}
}
@@ -462,8 +505,8 @@ void Cluster::updateOutDone(Lock& l) {
assert(state == UPDATER);
state = READY;
mcast.release();
- deliverFrameQueue.start();
- tryMakeOffer(map.firstJoiner(), l); // Try another offer
+ deliverEventQueue.start(); // Start processing events again.
+ makeOffer(map.firstJoiner(), l); // Try another offer
}
void Cluster::updateOutError(const std::exception& e) {
@@ -487,7 +530,7 @@ Manageable::status_t Cluster::ManagementMethod (uint32_t methodId, Args& args, s
{
_qmf::ArgsClusterStopClusterNode& iargs = (_qmf::ArgsClusterStopClusterNode&) args;
stringstream stream;
- stream << myId;
+ stream << self;
if (iargs.i_brokerId == stream.str())
stopClusterNode(l);
}
@@ -508,7 +551,7 @@ void Cluster::stopClusterNode(Lock& l) {
void Cluster::stopFullCluster(Lock& ) {
QPID_LOG(notice, *this << " shutting down cluster " << name);
- mcast.mcastControl(ClusterShutdownBody(), myId);
+ mcast.mcastControl(ClusterShutdownBody(), self);
}
void Cluster::memberUpdate(Lock& l) {
@@ -518,13 +561,13 @@ void Cluster::memberUpdate(Lock& l) {
size_t size = urls.size();
failoverExchange->setUrls(urls);
- if (size == 1 && lastSize > 1 && state >= READY) {
- QPID_LOG(info, *this << " last broker standing, update queue policies");
+ if (size == 1 && lastSize > 1 && state >= CATCHUP) {
+ QPID_LOG(notice, *this << " last broker standing, update queue policies");
lastBroker = true;
broker.getQueues().updateQueueClusterState(true);
}
else if (size > 1 && lastBroker) {
- QPID_LOG(info, *this << " last broker standing joined by " << size-1 << " replicas, updating queue policies" << size);
+ QPID_LOG(notice, *this << " last broker standing joined by " << size-1 << " replicas, updating queue policies" << size);
lastBroker = false;
broker.getQueues().updateQueueClusterState(false);
}
@@ -546,17 +589,23 @@ void Cluster::memberUpdate(Lock& l) {
mgmtObject->set_memberIDs(idstr);
}
- // Close connections belonging to members that have now been excluded
- connections.update(myId, map);
+ // Erase connections belonging to members that have left the cluster.
+ ConnectionMap::iterator i = connections.begin();
+ while (i != connections.end()) {
+ ConnectionMap::iterator j = i++;
+ MemberId m = j->second->getId().getMember();
+ if (m != self && !map.isMember(m))
+ connections.erase(j);
+ }
}
std::ostream& operator<<(std::ostream& o, const Cluster& cluster) {
static const char* STATE[] = { "INIT", "JOINER", "UPDATEE", "CATCHUP", "READY", "OFFER", "UPDATER", "LEFT" };
- return o << cluster.myId << "(" << STATE[cluster.state] << ")";
+ return o << cluster.self << "(" << STATE[cluster.state] << ")";
}
MemberId Cluster::getId() const {
- return myId; // Immutable, no need to lock.
+ return self; // Immutable, no need to lock.
}
broker::Broker& Cluster::getBroker() const {
@@ -571,11 +620,11 @@ void Cluster::checkQuorum() {
}
}
-void Cluster::setClusterId(const Uuid& uuid) {
+void Cluster::setClusterId(const Uuid& uuid, Lock&) {
clusterId = uuid;
if (mgmtObject) {
stringstream stream;
- stream << myId;
+ stream << self;
mgmtObject->set_clusterID(clusterId.str());
mgmtObject->set_memberID(stream.str());
}
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.h b/qpid/cpp/src/qpid/cluster/Cluster.h
index 8c5eb06ff7..b716e2d781 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.h
+++ b/qpid/cpp/src/qpid/cluster/Cluster.h
@@ -19,34 +19,34 @@
*
*/
-#include "ClusterSettings.h"
#include "ClusterMap.h"
-#include "ConnectionMap.h"
+#include "ClusterSettings.h"
#include "Cpg.h"
+#include "Decoder.h"
#include "Event.h"
+#include "EventFrame.h"
+#include "ExpiryPolicy.h"
#include "FailoverExchange.h"
+#include "LockedConnectionMap.h"
#include "Multicaster.h"
-#include "EventFrame.h"
#include "NoOpConnectionOutputHandler.h"
+#include "PollableQueue.h"
#include "PollerDispatch.h"
#include "Quorum.h"
-#include "Decoder.h"
-#include "PollableQueue.h"
-#include "ExpiryPolicy.h"
+#include "qmf/org/apache/qpid/cluster/Cluster.h"
+#include "qpid/Url.h"
#include "qpid/broker/Broker.h"
-#include "qpid/sys/Monitor.h"
#include "qpid/management/Manageable.h"
-#include "qpid/Url.h"
-#include "qmf/org/apache/qpid/cluster/Cluster.h"
+#include "qpid/sys/Monitor.h"
-#include <boost/intrusive_ptr.hpp>
#include <boost/bind.hpp>
+#include <boost/intrusive_ptr.hpp>
#include <boost/optional.hpp>
#include <algorithm>
-#include <vector>
#include <map>
+#include <vector>
namespace qpid {
@@ -58,6 +58,7 @@ class Uuid;
namespace cluster {
class Connection;
+class EventFrame;
/**
* Connection to the cluster
@@ -65,82 +66,91 @@ class Connection;
class Cluster : private Cpg::Handler, public management::Manageable {
public:
typedef boost::intrusive_ptr<Connection> ConnectionPtr;
- typedef std::vector<ConnectionPtr> Connections;
+ typedef std::vector<ConnectionPtr> ConnectionVector;
- /** Construct the cluster in plugin earlyInitialize */
+ // Public functions are thread safe unless otherwise mentioned in a comment.
+
+ // Construct the cluster in plugin earlyInitialize.
Cluster(const ClusterSettings&, broker::Broker&);
virtual ~Cluster();
- /** Join the cluster in plugin initialize. Requires transport
- * plugins to be available.. */
+ // Called by plugin initialize: cluster start-up requires transport plugins .
+ // Thread safety: only called by plugin initialize.
void initialize();
- // Connection map - called in connection threads.
+ // Connection map.
void addLocalConnection(const ConnectionPtr&);
void addShadowConnection(const ConnectionPtr&);
void erase(const ConnectionId&);
- // URLs of current cluster members - called in connection threads.
+ // URLs of current cluster members.
std::vector<std::string> getIds() const;
std::vector<Url> getUrls() const;
boost::shared_ptr<FailoverExchange> getFailoverExchange() const { return failoverExchange; }
- // Leave the cluster - called in any thread.
+ // Leave the cluster - called when fatal errors occur.
void leave();
// Update completed - called in update thread
- void updateInDone(const ClusterMap&, uint64_t frameId);
+ void updateInDone(const ClusterMap&);
MemberId getId() const;
broker::Broker& getBroker() const;
Multicaster& getMulticast() { return mcast; }
- boost::function<bool ()> isQuorate;
- void checkQuorum(); // called in connection threads.
+ void checkQuorum();
size_t getReadMax() { return readMax; }
size_t getWriteEstimate() { return writeEstimate; }
- bool isLeader() const; // Called in deliver thread.
+ void deliverFrame(const EventFrame&);
+
+ // Called only during update by Connection::shadowReady
+ Decoder& getDecoder() { return decoder; }
+
+ ExpiryPolicy& getExpiryPolicy() { return *expiryPolicy; }
private:
typedef sys::Monitor::ScopedLock Lock;
typedef PollableQueue<Event> PollableEventQueue;
typedef PollableQueue<EventFrame> PollableFrameQueue;
+ typedef std::map<ConnectionId, ConnectionPtr> ConnectionMap;
- // NB: The final Lock& parameter on functions below is used to mark functions
- // that should only be called by a function that already holds the lock.
- // The parameter makes it hard to forget since you have to have an instance of
- // a Lock to call the unlocked functions.
-
+ // NB: A dummy Lock& parameter marks functions that must only be
+ // called with Cluster::lock locked.
+
void leave(Lock&);
std::vector<std::string> getIds(Lock&) const;
std::vector<Url> getUrls(Lock&) const;
- // Make an offer if we can - called in deliver thread.
- void tryMakeOffer(const MemberId&, Lock&);
-
- // Called in main thread in ~Broker.
+ // == Called in main thread from Broker destructor.
void brokerShutdown();
+ // == Called in deliverEventQueue thread
+ void deliveredEvent(const Event&);
+
+ // == Called in deliverFrameQueue thread
+ void deliveredFrame(const EventFrame&);
+
// Cluster controls implement XML methods from cluster.xml.
- // Called in deliver thread.
- //
void updateRequest(const MemberId&, const std::string&, Lock&);
void updateOffer(const MemberId& updater, uint64_t updatee, const framing::Uuid&, Lock&);
void ready(const MemberId&, const std::string&, Lock&);
void configChange(const MemberId&, const std::string& addresses, Lock& l);
void messageExpired(const MemberId&, uint64_t, Lock& l);
void shutdown(const MemberId&, Lock&);
- void deliveredEvent(const Event&);
- void deliveredFrame(const EventFrame&);
- // Helper, called in deliver thread.
+ // Helper functions
+ ConnectionPtr getConnection(const ConnectionId&, Lock&);
+ ConnectionVector getConnections(Lock&);
void updateStart(const MemberId& updatee, const Url& url, Lock&);
-
+ void makeOffer(const MemberId&, Lock&);
void setReady(Lock&);
+ void memberUpdate(Lock&);
+ void setClusterId(const framing::Uuid&, Lock&);
+ // == Called in CPG dispatch thread
void deliver( // CPG deliver callback.
cpg_handle_t /*handle*/,
struct cpg_name *group,
@@ -149,7 +159,7 @@ class Cluster : private Cpg::Handler, public management::Manageable {
void* /*msg*/,
int /*msg_len*/);
- void deliver(const Event&);
+ void deliverEvent(const Event&);
void configChange( // CPG config change callback.
cpg_handle_t /*handle*/,
@@ -159,23 +169,21 @@ class Cluster : private Cpg::Handler, public management::Manageable {
struct cpg_address */*joined*/, int /*nJoined*/
);
+ // == Called in management threads.
virtual qpid::management::ManagementObject* GetManagementObject() const;
virtual management::Manageable::status_t ManagementMethod (uint32_t methodId, management::Args& args, std::string& text);
void stopClusterNode(Lock&);
void stopFullCluster(Lock&);
- void memberUpdate(Lock&);
- // Called in connection IO threads .
+ // == Called in connection IO threads .
void checkUpdateIn(Lock&);
- // Called in UpdateClient thread.
+ // == Called in UpdateClient thread.
void updateOutDone();
void updateOutError(const std::exception&);
void updateOutDone(Lock&);
- void setClusterId(const framing::Uuid&);
-
// Immutable members set on construction, never changed.
ClusterSettings settings;
broker::Broker& broker;
@@ -184,34 +192,38 @@ class Cluster : private Cpg::Handler, public management::Manageable {
Cpg cpg;
const std::string name;
Url myUrl;
- const MemberId myId;
+ const MemberId self;
const size_t readMax;
const size_t writeEstimate;
framing::Uuid clusterId;
NoOpConnectionOutputHandler shadowOut;
qpid::management::ManagementAgent* mAgent;
+ boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
// Thread safe members
Multicaster mcast;
PollerDispatch dispatcher;
PollableEventQueue deliverEventQueue;
PollableFrameQueue deliverFrameQueue;
- ConnectionMap connections;
boost::shared_ptr<FailoverExchange> failoverExchange;
Quorum quorum;
-
- // Used only in delivery thread
- Decoder decoder;
- ClusterMap::Set elders;
- boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
- uint64_t frameId;
+ LockedConnectionMap localConnections;
// Used only during initialization
bool initialized;
- // Remaining members are protected by lock
+ // Used only in deliverEventQueue thread or when stalled for update.
+ Decoder decoder;
+ bool discarding;
+
+ // Remaining members are protected by lock.
+ // FIXME aconway 2009-03-06: Most of these members are also only used in
+ // deliverFrameQueue thread or during stall. Review and separate members
+ // that require a lock, drop lock when not needed.
+ //
mutable sys::Monitor lock;
+
// Local cluster state, cluster map
enum {
INIT, ///< Initial state, no CPG messages received.
@@ -223,15 +235,16 @@ class Cluster : private Cpg::Handler, public management::Manageable {
UPDATER, ///< Offer accepted, sending a state update.
LEFT ///< Final state, left the cluster.
} state;
+
+ ConnectionMap connections;
ClusterMap map;
+ ClusterMap::Set elders;
size_t lastSize;
bool lastBroker;
- uint64_t sequence;
-
- // Update related
sys::Thread updateThread;
boost::optional<ClusterMap> updatedMap;
+
friend std::ostream& operator<<(std::ostream&, const Cluster&);
friend class ClusterDispatcher;
};
diff --git a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
index 132043f91a..adb6621caf 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
+++ b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
@@ -138,7 +138,6 @@ struct ClusterPlugin : public Plugin {
broker->setConnectionFactory(
boost::shared_ptr<sys::ConnectionCodec::Factory>(
new ConnectionCodec::Factory(broker->getConnectionFactory(), *cluster)));
- broker->getExchanges().registerExchange(cluster->getFailoverExchange());
ManagementBroker* mgmt = dynamic_cast<ManagementBroker*>(ManagementAgent::Singleton::getInstance());
if (mgmt) {
std::auto_ptr<IdAllocator> allocator(new UpdateClientIdAllocator());
diff --git a/qpid/cpp/src/qpid/cluster/ClusterSettings.h b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
index a8f33be75e..88e8829dfe 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterSettings.h
+++ b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
@@ -35,7 +35,7 @@ struct ClusterSettings {
size_t readMax, writeEstimate;
std::string username, password, mechanism;
- ClusterSettings() : quorum(false), readMax(10), writeEstimate(64), username("guest"), password("guest") {}
+ ClusterSettings() : quorum(false), readMax(10), writeEstimate(64) {}
Url getUrl(uint16_t port) const {
if (url.empty()) return Url::getIpAddressesUrl(port);
diff --git a/qpid/cpp/src/qpid/cluster/Connection.cpp b/qpid/cpp/src/qpid/cluster/Connection.cpp
index 1a3f7c4ef7..aa7d082720 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.cpp
+++ b/qpid/cpp/src/qpid/cluster/Connection.cpp
@@ -40,6 +40,7 @@
#include "qpid/framing/ConnectionCloseOkBody.h"
#include "qpid/log/Statement.h"
#include "qpid/sys/LatencyMetric.h"
+#include "qpid/sys/AtomicValue.h"
#include <boost/current_function.hpp>
@@ -58,27 +59,36 @@ using namespace framing;
NoOpConnectionOutputHandler Connection::discardHandler;
-// Shadow connections
-Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
- const std::string& wrappedId, ConnectionId myId)
- : cluster(c), self(myId), catchUp(false), output(*this, out),
- connection(&output, cluster.getBroker(), wrappedId), expectProtocolHeader(false)
+namespace {
+sys::AtomicValue<uint64_t> idCounter;
+}
+
+// Shadow connection
+Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out, const std::string& logId, const ConnectionId& id)
+ : cluster(c), self(id), catchUp(false), output(*this, out),
+ connection(&output, cluster.getBroker(), logId), expectProtocolHeader(false),
+ mcastFrameHandler(cluster.getMulticast(), self)
{ init(); }
-// Local connections
+// Local connection
Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
- const std::string& wrappedId, MemberId myId, bool isCatchUp, bool isLink)
- : cluster(c), self(myId, this), catchUp(isCatchUp), output(*this, out),
- connection(&output, cluster.getBroker(), wrappedId, isLink, catchUp ? ++catchUpId : 0),
- expectProtocolHeader(isLink)
+ const std::string& logId, MemberId member, bool isCatchUp, bool isLink)
+ : cluster(c), self(member, ++idCounter), catchUp(isCatchUp), output(*this, out),
+ connection(&output, cluster.getBroker(), logId, isLink, catchUp ? ++catchUpId : 0),
+ expectProtocolHeader(isLink), mcastFrameHandler(cluster.getMulticast(), self)
{ init(); }
void Connection::init() {
QPID_LOG(debug, cluster << " new connection: " << *this);
- if (isLocalClient()) {
+ if (isLocalClient()) {
+ connection.setClusterOrderOutput(mcastFrameHandler); // Actively send cluster-order frames from local node
cluster.addLocalConnection(this);
giveReadCredit(cluster.getReadMax());
}
+ else { // Shadow or catch-up connection
+ connection.setClusterOrderOutput(nullFrameHandler); // Passive, discard cluster-order frames
+ connection.setClientThrottling(false); // Disable client throttling, done by active node.
+ }
}
void Connection::giveReadCredit(int credit) {
@@ -140,10 +150,16 @@ bool Connection::checkUnsupported(const AMQBody& body) {
void Connection::deliveredFrame(const EventFrame& f) {
assert(!catchUp);
currentChannel = f.frame.getChannel();
- if (!framing::invoke(*this, *f.frame.getBody()).wasHandled() // Connection contol.
+ if (f.frame.getBody() // frame can be emtpy with just readCredit
+ && !framing::invoke(*this, *f.frame.getBody()).wasHandled() // Connection contol.
&& !checkUnsupported(*f.frame.getBody())) // Unsupported operation.
{
- connection.received(const_cast<AMQFrame&>(f.frame)); // Pass to broker connection.
+ if (f.type == DATA) // incoming data frames to broker::Connection
+ connection.received(const_cast<AMQFrame&>(f.frame));
+ else { // frame control, send frame via SessionState
+ broker::SessionState* ss = connection.getChannel(f.frame.getChannel()).getSession();
+ if (ss) ss->out(const_cast<AMQFrame&>(f.frame));
+ }
}
giveReadCredit(f.readCredit);
}
@@ -186,12 +202,12 @@ void Connection::left() {
connection.closed();
}
-// Decode data from local clients.
+// ConnectoinCodec::decode receives read buffers from directly-connected clients.
size_t Connection::decode(const char* buffer, size_t size) {
if (catchUp) { // Handle catch-up locally.
Buffer buf(const_cast<char*>(buffer), size);
while (localDecoder.decode(buf))
- received(localDecoder.frame);
+ received(localDecoder.getFrame());
}
else { // Multicast local connections.
assert(isLocal());
@@ -242,6 +258,7 @@ void Connection::sessionState(
const SequenceSet& unknownCompleted,
const SequenceSet& receivedIncomplete)
{
+
sessionState().setState(
replayStart,
sendCommandPoint,
@@ -253,21 +270,23 @@ void Connection::sessionState(
QPID_LOG(debug, cluster << " received session state update for " << sessionState().getId());
}
-void Connection::shadowReady(uint64_t memberId, uint64_t connectionId, const string& username) {
- ConnectionId shadow = ConnectionId(memberId, connectionId);
- QPID_LOG(debug, cluster << " catch-up connection " << *this << " becomes shadow " << shadow);
- self = shadow;
+void Connection::shadowReady(uint64_t memberId, uint64_t connectionId, const string& username, const string& fragment) {
+ ConnectionId shadowId = ConnectionId(memberId, connectionId);
+ QPID_LOG(debug, cluster << " catch-up connection " << *this << " becomes shadow " << shadowId);
+ self = shadowId;
connection.setUserId(username);
+ // OK to use decoder here because we are stalled for update.
+ cluster.getDecoder().get(self).setFragment(fragment.data(), fragment.size());
}
-void Connection::membership(const FieldTable& joiners, const FieldTable& members, uint64_t frameId) {
+void Connection::membership(const FieldTable& joiners, const FieldTable& members) {
QPID_LOG(debug, cluster << " incoming update complete on connection " << *this);
- cluster.updateInDone(ClusterMap(joiners, members), frameId);
+ cluster.updateInDone(ClusterMap(joiners, members));
self.second = 0; // Mark this as completed update connection.
}
bool Connection::isLocal() const {
- return self.first == cluster.getId() && self.second == this;
+ return self.first == cluster.getId() && self.second;
}
bool Connection::isShadow() const {
@@ -333,6 +352,10 @@ void Connection::queuePosition(const string& qname, const SequenceNumber& positi
q->setPosition(position);
}
+void Connection::expiryId(uint64_t id) {
+ cluster.getExpiryPolicy().setId(id);
+}
+
std::ostream& operator<<(std::ostream& o, const Connection& c) {
const char* type="unknown";
if (c.isLocal()) type = "local";
diff --git a/qpid/cpp/src/qpid/cluster/Connection.h b/qpid/cpp/src/qpid/cluster/Connection.h
index 98b47e1bc0..6434f763a8 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.h
+++ b/qpid/cpp/src/qpid/cluster/Connection.h
@@ -27,14 +27,15 @@
#include "OutputInterceptor.h"
#include "NoOpConnectionOutputHandler.h"
#include "EventFrame.h"
+#include "McastFrameHandler.h"
#include "qpid/broker/Connection.h"
#include "qpid/amqp_0_10/Connection.h"
#include "qpid/sys/AtomicValue.h"
#include "qpid/sys/ConnectionInputHandler.h"
#include "qpid/sys/ConnectionOutputHandler.h"
-#include "qpid/framing/FrameDecoder.h"
#include "qpid/framing/SequenceNumber.h"
+#include "qpid/framing/FrameDecoder.h"
#include <iosfwd>
@@ -63,10 +64,10 @@ class Connection :
public:
typedef sys::PollableQueue<EventFrame> PollableFrameQueue;
- /** Local connection, use this in ConnectionId */
- Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& id, MemberId, bool catchUp, bool isLink);
- /** Shadow connection */
- Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& id, ConnectionId);
+ /** Local connection. */
+ Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& logId, MemberId, bool catchUp, bool isLink);
+ /** Shadow connection. */
+ Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& logId, const ConnectionId& id);
~Connection();
ConnectionId getId() const { return self; }
@@ -99,7 +100,7 @@ class Connection :
/** Called if the connectors member has left the cluster */
void left();
- // ConnectionCodec methods
+ // ConnectionCodec methods - called by IO layer with a read buffer.
size_t decode(const char* buffer, size_t size);
// Called for data delivered from the cluster.
@@ -117,9 +118,9 @@ class Connection :
const framing::SequenceNumber& received,
const framing::SequenceSet& unknownCompleted, const SequenceSet& receivedIncomplete);
- void shadowReady(uint64_t memberId, uint64_t connectionId, const std::string& username);
+ void shadowReady(uint64_t memberId, uint64_t connectionId, const std::string& username, const std::string& fragment);
- void membership(const framing::FieldTable&, const framing::FieldTable&, uint64_t frameId);
+ void membership(const framing::FieldTable&, const framing::FieldTable&);
void deliveryRecord(const std::string& queue,
const framing::SequenceNumber& position,
@@ -134,6 +135,7 @@ class Connection :
uint32_t credit);
void queuePosition(const std::string&, const framing::SequenceNumber&);
+ void expiryId(uint64_t);
void txStart();
void txAccept(const framing::SequenceSet&);
@@ -148,8 +150,12 @@ class Connection :
void exchange(const std::string& encoded);
void giveReadCredit(int credit);
-
+
private:
+ struct NullFrameHandler : public framing::FrameHandler {
+ void handle(framing::AMQFrame&) {}
+ };
+
void init();
bool checkUnsupported(const framing::AMQBody& body);
void deliverClose();
@@ -174,6 +180,8 @@ class Connection :
framing::ChannelId currentChannel;
boost::shared_ptr<broker::TxBuffer> txBuffer;
bool expectProtocolHeader;
+ McastFrameHandler mcastFrameHandler;
+ NullFrameHandler nullFrameHandler;
static qpid::sys::AtomicValue<uint64_t> catchUpId;
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp b/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp
index 442ac1438f..007337792b 100644
--- a/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp
+++ b/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp
@@ -44,18 +44,15 @@ ConnectionCodec::Factory::create(ProtocolVersion v, sys::OutputControl& out, con
return 0;
}
-// Used for outgoing Link connections, we don't care.
+// Used for outgoing Link connections
sys::ConnectionCodec*
-ConnectionCodec::Factory::create(sys::OutputControl& out, const std::string& id) {
- return new ConnectionCodec(out, id, cluster, false, true);
- //return next->create(out, id);
+ConnectionCodec::Factory::create(sys::OutputControl& out, const std::string& logId) {
+ return new ConnectionCodec(out, logId, cluster, false, true);
}
-ConnectionCodec::ConnectionCodec(sys::OutputControl& out, const std::string& id, Cluster& cluster, bool catchUp, bool isLink)
- : codec(out, id, isLink),
- interceptor(new Connection(cluster, codec, id, cluster.getId(), catchUp, isLink)),
- id(interceptor->getId()),
- localId(id)
+ConnectionCodec::ConnectionCodec(sys::OutputControl& out, const std::string& logId, Cluster& cluster, bool catchUp, bool isLink)
+ : codec(out, logId, isLink),
+ interceptor(new Connection(cluster, codec, logId, cluster.getId(), catchUp, isLink))
{
std::auto_ptr<sys::ConnectionInputHandler> ih(new ProxyInputHandler(interceptor));
codec.setInputHandler(ih);
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionCodec.h b/qpid/cpp/src/qpid/cluster/ConnectionCodec.h
index 69c2b0c3c8..ea01b7abb9 100644
--- a/qpid/cpp/src/qpid/cluster/ConnectionCodec.h
+++ b/qpid/cpp/src/qpid/cluster/ConnectionCodec.h
@@ -56,7 +56,7 @@ class ConnectionCodec : public sys::ConnectionCodec {
sys::ConnectionCodec* create(sys::OutputControl&, const std::string& id);
};
- ConnectionCodec(sys::OutputControl& out, const std::string& id, Cluster& c, bool catchUp, bool isLink);
+ ConnectionCodec(sys::OutputControl& out, const std::string& logId, Cluster& c, bool catchUp, bool isLink);
~ConnectionCodec();
// ConnectionCodec functions.
@@ -71,8 +71,6 @@ class ConnectionCodec : public sys::ConnectionCodec {
private:
amqp_0_10::Connection codec;
boost::intrusive_ptr<cluster::Connection> interceptor;
- cluster::ConnectionId id;
- std::string localId;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp b/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp
deleted file mode 100644
index 3c18cf751e..0000000000
--- a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "ConnectionDecoder.h"
-#include "EventFrame.h"
-#include "ConnectionMap.h"
-
-namespace qpid {
-namespace cluster {
-
-using namespace framing;
-
-ConnectionDecoder::ConnectionDecoder(const Handler& h) : handler(h) {}
-
-void ConnectionDecoder::decode(const EventHeader& eh, const void* data, ConnectionMap& map) {
- assert(eh.getType() == DATA); // Only handle connection data events.
- const char* cp = static_cast<const char*>(data);
- Buffer buf(const_cast<char*>(cp), eh.getSize());
- if (decoder.decode(buf)) { // Decoded a frame
- AMQFrame frame(decoder.frame);
- while (decoder.decode(buf)) {
- handler(EventFrame(eh, frame));
- frame = decoder.frame;
- }
- // Set read-credit on the last frame ending in this event.
- // Credit will be given when this frame is processed.
- handler(EventFrame(eh, frame, 1));
- }
- else {
- // We must give 1 unit read credit per event.
- // This event does not complete any frames so
- // we give read credit directly.
- ConnectionPtr connection = map.getLocal(eh.getConnectionId());
- if (connection)
- connection->giveReadCredit(1);
- }
-}
-
-}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp b/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp
deleted file mode 100644
index b412bb13cc..0000000000
--- a/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "ConnectionMap.h"
-#include "Cluster.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-
-namespace qpid {
-namespace cluster {
-
-using framing::InternalErrorException;
-
-void ConnectionMap::insert(ConnectionPtr p) {
- std::pair<Map::iterator, bool> ib = map.insert(Map::value_type(p->getId(), p));
- if (!ib.second) {
- assert(0);
- throw InternalErrorException(QPID_MSG("Duplicate connection replica: " << p->getId()));
- }
-}
-
-void ConnectionMap::erase(const ConnectionId& id) {
- Map::iterator i = map.find(id);
- if (i == map.end()) {
- assert(0);
- QPID_LOG(warning, "Erase non-existent connection replica: " << id);
- }
- map.erase(i);
-}
-
-ConnectionMap::ConnectionPtr ConnectionMap::get(const ConnectionId& id) {
- Map::const_iterator i = map.find(id);
- if (i == map.end()) {
- // Deleted local connection.
- if(id.getMember() == cluster.getId())
- return 0;
- // New remote connection, create a shadow.
- std::ostringstream mgmtId;
- mgmtId << id;
- ConnectionPtr cp = new Connection(cluster, shadowOut, mgmtId.str(), id);
- std::pair<Map::iterator, bool> ib = map.insert(Map::value_type(id, cp));
- if (!ib.second)
- throw InternalErrorException(QPID_MSG("Duplicate entry in cluster connection map: " << id));
- i = ib.first;
- }
- return i->second;
-}
-
-ConnectionMap::ConnectionPtr ConnectionMap::getLocal(const ConnectionId& id) {
- if (id.getMember() != cluster.getId()) return 0;
- Map::const_iterator i = map.find(id);
- assert(i != map.end()); // FIXME aconway 2009-02-11: remove or exception.
- return i == map.end() ? 0 : i->second;
-}
-
-ConnectionMap::Vector ConnectionMap::values() const {
- Vector result(map.size());
- std::transform(map.begin(), map.end(), result.begin(),
- boost::bind(&Map::value_type::second, _1));
- return result;
-}
-
-void ConnectionMap::update(MemberId myId, const ClusterMap& cluster) {
- for (Map::iterator i = map.begin(); i != map.end(); ) {
- MemberId member = i->first.getMember();
- if (member != myId && !cluster.isMember(member)) {
- i->second->left();
- map.erase(i++);
- } else {
- i++;
- }
- }
-}
-
-void ConnectionMap::clear() {
- map.clear();
-}
-
-}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionMap.h b/qpid/cpp/src/qpid/cluster/ConnectionMap.h
deleted file mode 100644
index f8aa663339..0000000000
--- a/qpid/cpp/src/qpid/cluster/ConnectionMap.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef QPID_CLUSTER_CONNECTIONMAP_H
-#define QPID_CLUSTER_CONNECTIONMAP_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 "types.h"
-#include "Connection.h"
-#include "ClusterMap.h"
-#include "NoOpConnectionOutputHandler.h"
-#include "qpid/sys/Mutex.h"
-#include <boost/intrusive_ptr.hpp>
-#include <map>
-
-namespace qpid {
-namespace cluster {
-
-class Cluster;
-
-/**
- * Thread safe map of connections. The map is used in:
- * - deliver thread to look connections and create new shadow connections.
- * - local catch-up connection threads to add a caught-up shadow connections.
- * - local client connection threads when local connections are created.
- */
-class ConnectionMap {
- public:
- typedef boost::intrusive_ptr<cluster::Connection> ConnectionPtr;
- typedef std::vector<ConnectionPtr> Vector;
-
- ConnectionMap(Cluster& c) : cluster(c) {}
-
- /** Insert a local connection or a caught up shadow connection.
- * Called in local connection thread.
- */
- void insert(ConnectionPtr p);
-
- /** Erase a closed connection. Called in deliver thread. */
- void erase(const ConnectionId& id);
-
- /** Get an existing connection. Returns 0 if id is a closed local
- * connections, frames for closed connections should be ignored.
- */
- ConnectionPtr get(const ConnectionId& id);
-
- /** If ID is a local connection and in the map return it, else return 0 */
- ConnectionPtr getLocal(const ConnectionId& id);
-
- /** Get connections for sending an update. */
- Vector values() const;
-
- /** Remove connections who's members are no longer in the cluster. Deliver thread. */
- void update(MemberId myId, const ClusterMap& cluster);
-
-
- void clear();
-
- size_t size() const;
-
- private:
- typedef std::map<ConnectionId, ConnectionPtr> Map;
-
- Cluster& cluster;
- NoOpConnectionOutputHandler shadowOut;
- Map map;
-};
-
-
-}} // namespace qpid::cluster
-
-#endif /*!QPID_CLUSTER_CONNECTIONMAP_H*/
diff --git a/qpid/cpp/src/qpid/cluster/Cpg.cpp b/qpid/cpp/src/qpid/cluster/Cpg.cpp
index c5a1b72003..915a578989 100644
--- a/qpid/cpp/src/qpid/cluster/Cpg.cpp
+++ b/qpid/cpp/src/qpid/cluster/Cpg.cpp
@@ -107,17 +107,16 @@ void Cpg::leave() {
check(cpg_leave(handle, &group), cantLeaveMsg(group));
}
-bool Cpg::isFlowControlEnabled() {
- cpg_flow_control_state_t flowState;
- check(cpg_flow_control_state_get(handle, &flowState), "Cannot get CPG flow control status.");
- return flowState == CPG_FLOW_CONTROL_ENABLED;
-}
+
+
bool Cpg::mcast(const iovec* iov, int iovLen) {
- if (isFlowControlEnabled()) {
- QPID_LOG(debug, "CPG flow control enabled")
+ // Check for flow control
+ cpg_flow_control_state_t flowState;
+ check(cpg_flow_control_state_get(handle, &flowState), "Cannot get CPG flow control status.");
+ if (flowState == CPG_FLOW_CONTROL_ENABLED)
return false;
- }
+
cpg_error_t result;
do {
result = cpg_mcast_joined(handle, CPG_TYPE_AGREED, const_cast<iovec*>(iov), iovLen);
@@ -149,9 +148,13 @@ void Cpg::dispatchBlocking() {
string Cpg::errorStr(cpg_error_t err, const std::string& msg) {
std::ostringstream os;
os << msg << ": ";
+ // FIXME aconway 2009-03-11: The commented out cases below are
+ // because of mistakes in the latest corosync header files.
+ // The code should be re-instated when that is sorted out.
+ //
switch (err) {
case CPG_OK: os << "ok"; break;
- case CPG_ERR_LIBRARY: os << "library"; break;
+ // case CPG_ERR_LIBRARY: os << "library"; break;
case CPG_ERR_TIMEOUT: os << "timeout"; break;
case CPG_ERR_TRY_AGAIN: os << "try again"; break;
case CPG_ERR_INVALID_PARAM: os << "invalid param"; break;
@@ -161,8 +164,8 @@ string Cpg::errorStr(cpg_error_t err, const std::string& msg) {
case CPG_ERR_NOT_EXIST: os << "not exist"; break;
case CPG_ERR_EXIST: os << "exist"; break;
case CPG_ERR_NOT_SUPPORTED: os << "not supported"; break;
- case CPG_ERR_SECURITY: os << "security"; break;
- case CPG_ERR_TOO_MANY_GROUPS: os << "too many groups"; break;
+ // case CPG_ERR_SECURITY: os << "security"; break;
+ // case CPG_ERR_TOO_MANY_GROUPS: os << "too many groups"; break;
default: os << ": unknown cpg error " << err;
};
os << " (" << err << ")";
@@ -203,13 +206,19 @@ ostream& operator<<(ostream& o, const ConnectionId& c) {
std::string MemberId::str() const {
char s[8];
- reinterpret_cast<uint32_t&>(s[0]) = htonl(first);
- reinterpret_cast<uint32_t&>(s[4]) = htonl(second);
+ uint32_t x;
+ x = htonl(first);
+ ::memcpy(s, &x, 4);
+ x = htonl(second);
+ ::memcpy(s+4, &x, 4);
return std::string(s,8);
}
MemberId::MemberId(const std::string& s) {
- first = ntohl(reinterpret_cast<const uint32_t&>(s[0]));
- second = ntohl(reinterpret_cast<const uint32_t&>(s[4]));
+ uint32_t x;
+ memcpy(&x, &s[0], 4);
+ first = ntohl(x);
+ memcpy(&x, &s[4], 4);
+ second = ntohl(x);
}
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/Cpg.h b/qpid/cpp/src/qpid/cluster/Cpg.h
index 5ac5a5bdbc..ac27a09ae6 100644
--- a/qpid/cpp/src/qpid/cluster/Cpg.h
+++ b/qpid/cpp/src/qpid/cluster/Cpg.h
@@ -114,8 +114,6 @@ class Cpg : public sys::IOHandle {
int getFd();
- bool isFlowControlEnabled();
-
private:
static std::string errorStr(cpg_error_t err, const std::string& msg);
static std::string cantJoinMsg(const Name&);
diff --git a/qpid/cpp/src/qpid/cluster/Decoder.cpp b/qpid/cpp/src/qpid/cluster/Decoder.cpp
index 1ba36bb521..b337ef43f4 100644
--- a/qpid/cpp/src/qpid/cluster/Decoder.cpp
+++ b/qpid/cpp/src/qpid/cluster/Decoder.cpp
@@ -18,33 +18,44 @@
* under the License.
*
*/
-
#include "Decoder.h"
-#include "Event.h"
+#include "EventFrame.h"
+#include "qpid/framing/ClusterConnectionDeliverCloseBody.h"
#include "qpid/framing/Buffer.h"
-#include "qpid/ptr_map.h"
+#include "qpid/framing/AMQFrame.h"
+
namespace qpid {
namespace cluster {
-using namespace framing;
-
-Decoder::Decoder(const Handler& h, ConnectionMap& cm) : handler(h), connections(cm) {}
-
-void Decoder::decode(const EventHeader& eh, const void* data) {
- ConnectionId id = eh.getConnectionId();
- Map::iterator i = map.find(id);
- if (i == map.end()) {
- std::pair<Map::iterator, bool> ib = map.insert(id, new ConnectionDecoder(handler));
- i = ib.first;
+void Decoder::decode(const EventHeader& eh, const char* data) {
+ assert(eh.getType() == DATA); // Only handle connection data events.
+ const char* cp = static_cast<const char*>(data);
+ framing::Buffer buf(const_cast<char*>(cp), eh.getSize());
+ framing::FrameDecoder& decoder = map[eh.getConnectionId()];
+ if (decoder.decode(buf)) { // Decoded a frame
+ framing::AMQFrame frame(decoder.getFrame());
+ while (decoder.decode(buf)) {
+ process(EventFrame(eh, frame));
+ frame = decoder.getFrame();
+ }
+ // Set read-credit on the last frame ending in this event.
+ // Credit will be given when this frame is processed.
+ process(EventFrame(eh, frame, 1));
}
- ptr_map_ptr(i)->decode(eh, data, connections);
+ else {
+ // We must give 1 unit read credit per event.
+ // This event does not complete any frames so
+ // send an empty frame with the read credit.
+ process(EventFrame(eh, framing::AMQFrame(), 1));
+ }
}
-void Decoder::erase(const ConnectionId& c) {
- Map::iterator i = map.find(c);
- if (i != map.end())
- map.erase(i);
+void Decoder::process(const EventFrame& ef) {
+ //need to check that this is not the empty frame mentioned above
+ if (ef.frame.getBody() && ef.frame.getMethod() && ef.frame.getMethod()->isA<framing::ClusterConnectionDeliverCloseBody>())
+ map.erase(ef.connectionId);
+ callback(ef);
}
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/Decoder.h b/qpid/cpp/src/qpid/cluster/Decoder.h
index 50f6afa491..acde4258a2 100644
--- a/qpid/cpp/src/qpid/cluster/Decoder.h
+++ b/qpid/cpp/src/qpid/cluster/Decoder.h
@@ -22,44 +22,36 @@
*
*/
-#include "ConnectionDecoder.h"
#include "types.h"
-#include <boost/ptr_container/ptr_map.hpp>
+#include "qpid/framing/FrameDecoder.h"
+#include <boost/function.hpp>
+#include <map>
namespace qpid {
namespace cluster {
+class EventFrame;
class EventHeader;
-class ConnectionMap;
/**
- * Holds a map of ConnectionDecoders. Decodes Events into EventFrames
- * and forwards EventFrames to a handler.
- *
- * THREAD UNSAFE: Called sequentially with un-decoded cluster events from CPG.
+ * A map of decoders for connections.
*/
class Decoder
{
public:
- typedef boost::function<void(const EventFrame&)> Handler;
-
- Decoder(const Handler& h, ConnectionMap&);
+ typedef boost::function<void(const EventFrame&)> FrameHandler;
- /** Takes EventHeader + data rather than Event so that the caller can
- * pass a pointer to connection data or a CPG buffer directly without copy.
- */
- void decode(const EventHeader& eh, const void* data);
-
- /** Erase the decoder for a connection. */
+ Decoder(FrameHandler fh) : callback(fh) {}
+ void decode(const EventHeader& eh, const char* data);
void erase(const ConnectionId&);
+ framing::FrameDecoder& get(const ConnectionId& c) { return map[c]; }
private:
- typedef boost::ptr_map<ConnectionId, ConnectionDecoder> Map;
- Handler handler;
+ typedef std::map<ConnectionId, framing::FrameDecoder> Map;
Map map;
- ConnectionMap& connections;
+ void process(const EventFrame&);
+ FrameHandler callback;
};
-
}} // namespace qpid::cluster
#endif /*!QPID_CLUSTER_DECODER_H*/
diff --git a/qpid/cpp/src/qpid/cluster/Event.cpp b/qpid/cpp/src/qpid/cluster/Event.cpp
index e30b961b3e..1cb010c266 100644
--- a/qpid/cpp/src/qpid/cluster/Event.cpp
+++ b/qpid/cpp/src/qpid/cluster/Event.cpp
@@ -23,6 +23,7 @@
#include "Cpg.h"
#include "qpid/framing/Buffer.h"
#include "qpid/framing/AMQFrame.h"
+#include "qpid/assert.h"
#include <ostream>
#include <iterator>
#include <algorithm>
@@ -31,6 +32,7 @@ namespace qpid {
namespace cluster {
using framing::Buffer;
+using framing::AMQFrame;
const size_t EventHeader::HEADER_SIZE =
sizeof(uint8_t) + // type
@@ -42,7 +44,7 @@ const size_t EventHeader::HEADER_SIZE =
;
EventHeader::EventHeader(EventType t, const ConnectionId& c, size_t s)
- : type(t), connectionId(c), size(s), sequence(0) {}
+ : type(t), connectionId(c), size(s) {}
Event::Event() {}
@@ -57,7 +59,7 @@ void EventHeader::decode(const MemberId& m, framing::Buffer& buf) {
type = (EventType)buf.getOctet();
if(type != DATA && type != CONTROL)
throw Exception("Invalid multicast event type");
- connectionId = ConnectionId(m, reinterpret_cast<Connection*>(buf.getLongLong()));
+ connectionId = ConnectionId(m, buf.getLongLong());
size = buf.getLong();
#ifdef QPID_LATENCY_METRIC
latency_metric_timestamp = buf.getLongLong();
@@ -74,14 +76,17 @@ Event Event::decodeCopy(const MemberId& m, framing::Buffer& buf) {
return e;
}
-Event Event::control(const framing::AMQBody& body, const ConnectionId& cid) {
- framing::AMQFrame f(body);
+Event Event::control(const framing::AMQFrame& f, const ConnectionId& cid) {
Event e(CONTROL, cid, f.encodedSize());
Buffer buf(e);
f.encode(buf);
return e;
}
+Event Event::control(const framing::AMQBody& body, const ConnectionId& cid) {
+ return control(framing::AMQFrame(body), cid);
+}
+
iovec Event::toIovec() {
encodeHeader();
iovec iov = { const_cast<char*>(getStore()), getStoreSize() };
@@ -90,7 +95,7 @@ iovec Event::toIovec() {
void EventHeader::encode(Buffer& b) const {
b.putOctet(type);
- b.putLongLong(reinterpret_cast<uint64_t>(connectionId.getPointer()));
+ b.putLongLong(connectionId.getNumber());
b.putLong(size);
#ifdef QPID_LATENCY_METRIC
b.putLongLong(latency_metric_timestamp);
@@ -108,12 +113,22 @@ Event::operator Buffer() const {
return Buffer(const_cast<char*>(getData()), getSize());
}
+AMQFrame Event::getFrame() const {
+ assert(type == CONTROL);
+ Buffer buf(*this);
+ AMQFrame frame;
+ QPID_ASSERT(frame.decode(buf));
+ return frame;
+}
+
static const char* EVENT_TYPE_NAMES[] = { "data", "control" };
+std::ostream& operator << (std::ostream& o, EventType t) {
+ return o << EVENT_TYPE_NAMES[t];
+}
+
std::ostream& operator << (std::ostream& o, const EventHeader& e) {
- o << "[event " << e.getConnectionId() << "/" << e.getSequence()
- << " " << EVENT_TYPE_NAMES[e.getType()]
- << " " << e.getSize() << " bytes]";
+ o << "Event[" << e.getConnectionId() << " " << e.getType() << " " << e.getSize() << " bytes]";
return o;
}
diff --git a/qpid/cpp/src/qpid/cluster/Event.h b/qpid/cpp/src/qpid/cluster/Event.h
index f1de248f89..e05ad60bcf 100644
--- a/qpid/cpp/src/qpid/cluster/Event.h
+++ b/qpid/cpp/src/qpid/cluster/Event.h
@@ -24,6 +24,7 @@
#include "types.h"
#include "qpid/RefCountedBuffer.h"
+#include "qpid/framing/AMQFrame.h"
#include "qpid/sys/LatencyMetric.h"
#include <sys/uio.h> // For iovec
#include <iosfwd>
@@ -34,6 +35,7 @@ namespace qpid {
namespace framing {
class AMQBody;
+class AMQFrame;
class Buffer;
}
@@ -55,11 +57,9 @@ class EventHeader : public ::qpid::sys::LatencyMetricTimestamp {
/** Size of header + payload. */
size_t getStoreSize() { return size + HEADER_SIZE; }
- uint64_t getSequence() const { return sequence; }
- void setSequence(uint64_t n) { sequence = n; }
-
- bool isCluster() const { return connectionId.getPointer() == 0; }
- bool isConnection() const { return connectionId.getPointer() != 0; }
+ bool isCluster() const { return connectionId.getNumber() == 0; }
+ bool isConnection() const { return connectionId.getNumber() != 0; }
+ bool isControl() const { return type == CONTROL; }
protected:
static const size_t HEADER_SIZE;
@@ -67,7 +67,6 @@ class EventHeader : public ::qpid::sys::LatencyMetricTimestamp {
EventType type;
ConnectionId connectionId;
size_t size;
- uint64_t sequence;
};
/**
@@ -83,8 +82,11 @@ class Event : public EventHeader {
/** Create an event copied from delivered data. */
static Event decodeCopy(const MemberId& m, framing::Buffer&);
- /** Create an event containing a control */
+ /** Create a control event. */
static Event control(const framing::AMQBody&, const ConnectionId&);
+
+ /** Create a control event. */
+ static Event control(const framing::AMQFrame&, const ConnectionId&);
// Data excluding header.
char* getData() { return store + HEADER_SIZE; }
@@ -93,6 +95,8 @@ class Event : public EventHeader {
// Store including header
char* getStore() { return store; }
const char* getStore() const { return store; }
+
+ framing::AMQFrame getFrame() const;
operator framing::Buffer() const;
@@ -105,6 +109,7 @@ class Event : public EventHeader {
};
std::ostream& operator << (std::ostream&, const EventHeader&);
+
}} // namespace qpid::cluster
#endif /*!QPID_CLUSTER_EVENT_H*/
diff --git a/qpid/cpp/src/qpid/cluster/EventFrame.cpp b/qpid/cpp/src/qpid/cluster/EventFrame.cpp
index ba01c170dd..9350c801f5 100644
--- a/qpid/cpp/src/qpid/cluster/EventFrame.cpp
+++ b/qpid/cpp/src/qpid/cluster/EventFrame.cpp
@@ -24,16 +24,20 @@
namespace qpid {
namespace cluster {
-EventFrame::EventFrame() : sequence(0) {}
+EventFrame::EventFrame() {}
EventFrame::EventFrame(const EventHeader& e, const framing::AMQFrame& f, int rc)
- : connectionId(e.getConnectionId()), frame(f), sequence(e.getSequence()), readCredit(rc)
+ : connectionId(e.getConnectionId()), frame(f), readCredit(rc), type(e.getType())
{
QPID_LATENCY_INIT(frame);
}
std::ostream& operator<<(std::ostream& o, const EventFrame& e) {
- return o << e.connectionId << "/" << e.sequence << " " << e.frame << " rc=" << e.readCredit;
+ if (e.frame.getBody()) o << e.frame;
+ else o << "null-frame";
+ o << " " << e.type << " " << e.connectionId;
+ if (e.readCredit) o << " read-credit=" << e.readCredit;
+ return o;
}
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/EventFrame.h b/qpid/cpp/src/qpid/cluster/EventFrame.h
index 7f33cedb5b..d6ff58dd38 100644
--- a/qpid/cpp/src/qpid/cluster/EventFrame.h
+++ b/qpid/cpp/src/qpid/cluster/EventFrame.h
@@ -42,22 +42,15 @@ struct EventFrame
EventFrame(const EventHeader& e, const framing::AMQFrame& f, int rc=0);
- bool isCluster() const { return !connectionId.getPointer(); }
- bool isConnection() const { return connectionId.getPointer(); }
+ bool isCluster() const { return connectionId.getNumber() == 0; }
+ bool isConnection() const { return connectionId.getNumber() != 0; }
bool isLastInEvent() const { return readCredit; }
- // True if this frame follows immediately after frame e.
- bool follows(const EventFrame& e) const {
- return sequence == e.sequence || (sequence == e.sequence+1 && e.readCredit);
- }
-
- bool operator<(const EventFrame& e) const { return sequence < e.sequence; }
-
ConnectionId connectionId;
framing::AMQFrame frame;
- uint64_t sequence;
- int readCredit; // last frame in an event, give credit when processed.
+ int readCredit; ///< last frame in an event, give credit when processed.
+ EventType type;
};
std::ostream& operator<<(std::ostream& o, const EventFrame& e);
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
index 690acfc3ad..409180c499 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
@@ -30,48 +30,46 @@
namespace qpid {
namespace cluster {
-ExpiryPolicy::ExpiryPolicy(const boost::function<bool()> & f, Multicaster& m, const MemberId& id, broker::Timer& t)
- : expiredPolicy(new Expired), isLeader(f), mcast(m), memberId(id), timer(t) {}
-
-namespace {
-uint64_t clusterId(const broker::Message& m) {
- assert(m.getFrames().begin() != m.getFrames().end());
- return m.getFrames().begin()->getClusterId();
-}
+ExpiryPolicy::ExpiryPolicy(Multicaster& m, const MemberId& id, broker::Timer& t)
+ : expiryId(0), expiredPolicy(new Expired), mcast(m), memberId(id), timer(t) {}
struct ExpiryTask : public broker::TimerTask {
ExpiryTask(const boost::intrusive_ptr<ExpiryPolicy>& policy, uint64_t id, sys::AbsTime when)
- : TimerTask(when), expiryPolicy(policy), messageId(id) {}
- void fire() { expiryPolicy->sendExpire(messageId); }
+ : TimerTask(when), expiryPolicy(policy), expiryId(id) {}
+ void fire() { expiryPolicy->sendExpire(expiryId); }
boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
- const uint64_t messageId;
+ const uint64_t expiryId;
};
-}
void ExpiryPolicy::willExpire(broker::Message& m) {
- timer.add(new ExpiryTask(this, clusterId(m), m.getExpiration()));
+ uint64_t id = expiryId++;
+ assert(unexpiredById.find(id) == unexpiredById.end());
+ assert(unexpiredByMessage.find(&m) == unexpiredByMessage.end());
+ unexpiredById[id] = &m;
+ unexpiredByMessage[&m] = id;
+ timer.add(new ExpiryTask(this, id, m.getExpiration()));
}
bool ExpiryPolicy::hasExpired(broker::Message& m) {
- sys::Mutex::ScopedLock l(lock);
- IdSet::iterator i = expired.find(clusterId(m));
- if (i != expired.end()) {
- expired.erase(i);
- const_cast<broker::Message&>(m).setExpiryPolicy(expiredPolicy); // hasExpired() == true;
- return true;
- }
- return false;
+ return unexpiredByMessage.find(&m) == unexpiredByMessage.end();
}
void ExpiryPolicy::sendExpire(uint64_t id) {
- sys::Mutex::ScopedLock l(lock);
- if (isLeader())
- mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId);
+ mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId);
}
void ExpiryPolicy::deliverExpire(uint64_t id) {
- sys::Mutex::ScopedLock l(lock);
- expired.insert(id);
+ IdMessageMap::iterator i = unexpiredById.find(id);
+ if (i != unexpiredById.end()) {
+ i->second->setExpiryPolicy(expiredPolicy); // hasExpired() == true;
+ unexpiredByMessage.erase(i->second);
+ unexpiredById.erase(i);
+ }
+}
+
+boost::optional<uint64_t> ExpiryPolicy::getId(broker::Message& m) {
+ MessageIdMap::iterator i = unexpiredByMessage.find(&m);
+ return i == unexpiredByMessage.end() ? boost::optional<uint64_t>() : i->second;
}
bool ExpiryPolicy::Expired::hasExpired(broker::Message&) { return true; }
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
index 7fb63c731e..9f8b1a9236 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
@@ -27,11 +27,15 @@
#include "qpid/sys/Mutex.h"
#include <boost/function.hpp>
#include <boost/intrusive_ptr.hpp>
-#include <set>
+#include <boost/optional.hpp>
+#include <map>
namespace qpid {
-namespace broker { class Timer; }
+namespace broker {
+class Timer;
+class Message;
+}
namespace cluster {
class Multicaster;
@@ -42,7 +46,7 @@ class Multicaster;
class ExpiryPolicy : public broker::ExpiryPolicy
{
public:
- ExpiryPolicy(const boost::function<bool()> & isLeader, Multicaster&, const MemberId&, broker::Timer&);
+ ExpiryPolicy(Multicaster&, const MemberId&, broker::Timer&);
void willExpire(broker::Message&);
@@ -54,18 +58,24 @@ class ExpiryPolicy : public broker::ExpiryPolicy
// Cluster delivers expiry notice.
void deliverExpire(uint64_t);
+ void setId(uint64_t id) { expiryId = id; }
+ uint64_t getId() const { return expiryId; }
+
+ boost::optional<uint64_t> getId(broker::Message&);
+
private:
- sys::Mutex lock;
- typedef std::set<uint64_t> IdSet;
+ typedef std::map<broker::Message*, uint64_t> MessageIdMap;
+ typedef std::map<uint64_t, broker::Message*> IdMessageMap;
struct Expired : public broker::ExpiryPolicy {
bool hasExpired(broker::Message&);
void willExpire(broker::Message&);
};
- IdSet expired;
+ MessageIdMap unexpiredByMessage;
+ IdMessageMap unexpiredById;
+ uint64_t expiryId;
boost::intrusive_ptr<Expired> expiredPolicy;
- boost::function<bool()> isLeader;
Multicaster& mcast;
MemberId memberId;
broker::Timer& timer;
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.h b/qpid/cpp/src/qpid/cluster/LockedConnectionMap.h
index 449387c1cc..8b2f6dae8e 100644
--- a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.h
+++ b/qpid/cpp/src/qpid/cluster/LockedConnectionMap.h
@@ -1,5 +1,5 @@
-#ifndef QPID_CLUSTER_CONNECTIONDECODER_H
-#define QPID_CLUSTER_CONNECTIONDECODER_H
+#ifndef QPID_CLUSTER_LOCKEDCONNECTIONMAP_H
+#define QPID_CLUSTER_LOCKEDCONNECTIONMAP_H
/*
*
@@ -22,40 +22,41 @@
*
*/
-#include "qpid/framing/FrameDecoder.h"
-#include <boost/function.hpp>
+#include "types.h"
+#include "qpid/sys/Mutex.h"
+#include "Connection.h"
namespace qpid {
namespace cluster {
-class EventHeader;
-class EventFrame;
-class ConnectionMap;
-
/**
- * Decodes delivered connection data Event's as EventFrame's for a
- * connection replica, local or shadow. Manages state for frame
- * fragments and flow control.
- *
- * THREAD UNSAFE: connection events are decoded in sequence.
+ * Thread safe map of connections.
*/
-class ConnectionDecoder
+class LockedConnectionMap
{
public:
- typedef boost::function<void(const EventFrame&)> Handler;
-
- ConnectionDecoder(const Handler& h);
-
- /** Takes EventHeader + data rather than Event so that the caller can
- * pass a pointer to connection data or a CPG buffer directly without copy.
- */
- void decode(const EventHeader& eh, const void* data, ConnectionMap& connections);
+ void insert(const ConnectionPtr& c) {
+ sys::Mutex::ScopedLock l(lock);
+ map[c->getId()] = c;
+ }
+
+ ConnectionPtr getErase(const ConnectionId& c) {
+ sys::Mutex::ScopedLock l(lock);
+ Map::iterator i = map.find(c);
+ if (i != map.end()) {
+ ConnectionPtr cp = i->second;
+ map.erase(i);
+ return cp;
+ }
+ else
+ return 0;
+ }
private:
- Handler handler;
- framing::FrameDecoder decoder;
+ typedef std::map<ConnectionId, ConnectionPtr> Map;
+ mutable sys::Mutex lock;
+ Map map;
};
-
}} // namespace qpid::cluster
-#endif /*!QPID_CLUSTER_CONNECTIONDECODER_H*/
+#endif /*!QPID_CLUSTER_LOCKEDCONNECTIONMAP_H*/
diff --git a/qpid/cpp/src/qpid/sys/posix/PollableCondition.h b/qpid/cpp/src/qpid/cluster/McastFrameHandler.h
index 4ec277b0ec..5127c31c84 100644
--- a/qpid/cpp/src/qpid/sys/posix/PollableCondition.h
+++ b/qpid/cpp/src/qpid/cluster/McastFrameHandler.h
@@ -1,5 +1,5 @@
-#ifndef QPID_SYS_POSIX_POLLABLECONDITION_H
-#define QPID_SYS_POSIX_POLLABLECONDITION_H
+#ifndef QPID_CLUSTER_MCASTFRAMEHANDLER_H
+#define QPID_CLUSTER_MCASTFRAMEHANDLER_H
/*
*
@@ -22,35 +22,25 @@
*
*/
-#include "qpid/sys/IOHandle.h"
+#include "types.h"
+#include "Multicaster.h"
+#include "qpid/framing/FrameHandler.h"
namespace qpid {
-namespace sys {
+namespace cluster {
/**
- * A pollable condition to integrate in-process conditions with IO
- * conditions in a polling loop.
- *
- * Setting the condition makes it readable for a poller.
- *
- * Writable/disconnected conditions are undefined and should not be
- * polled for.
+ * A frame handler that multicasts frames as CONTROL events.
*/
-class PollableCondition : public sys::IOHandle {
+class McastFrameHandler : public framing::FrameHandler
+{
public:
- PollableCondition();
-
- /** Set the condition, triggers readable in a poller. */
- void set();
-
- /** Get the current state of the condition, then clear it.
- *@return The state of the condition before it was cleared.
- */
- bool clear();
-
+ McastFrameHandler(Multicaster& m, const ConnectionId& cid) : mcast(m), connection(cid) {}
+ void handle(framing::AMQFrame& frame) { mcast.mcastControl(frame, connection); }
private:
- int writeFd;
+ Multicaster& mcast;
+ ConnectionId connection;
};
-}} // namespace qpid::sys
+}} // namespace qpid::cluster
-#endif /*!QPID_SYS_POSIX_POLLABLECONDITION_H*/
+#endif /*!QPID_CLUSTER_MCASTFRAMEHANDLER_H*/
diff --git a/qpid/cpp/src/qpid/cluster/Multicaster.cpp b/qpid/cpp/src/qpid/cluster/Multicaster.cpp
index 239b3f5f35..f0738ab08f 100644
--- a/qpid/cpp/src/qpid/cluster/Multicaster.cpp
+++ b/qpid/cpp/src/qpid/cluster/Multicaster.cpp
@@ -24,6 +24,7 @@
#include "qpid/log/Statement.h"
#include "qpid/sys/LatencyMetric.h"
#include "qpid/framing/AMQBody.h"
+#include "qpid/framing/AMQFrame.h"
namespace qpid {
namespace cluster {
@@ -43,6 +44,11 @@ void Multicaster::mcastControl(const framing::AMQBody& body, const ConnectionId&
mcast(Event::control(body, id));
}
+void Multicaster::mcastControl(const framing::AMQFrame& frame, const ConnectionId& id) {
+ QPID_LOG(trace, "MCAST " << id << ": " << frame);
+ mcast(Event::control(frame, id));
+}
+
void Multicaster::mcastBuffer(const char* data, size_t size, const ConnectionId& id) {
Event e(DATA, id, size);
memcpy(e.getData(), data, size);
diff --git a/qpid/cpp/src/qpid/cluster/Multicaster.h b/qpid/cpp/src/qpid/cluster/Multicaster.h
index 1dfee47bd5..d1c3115977 100644
--- a/qpid/cpp/src/qpid/cluster/Multicaster.h
+++ b/qpid/cpp/src/qpid/cluster/Multicaster.h
@@ -50,6 +50,7 @@ class Multicaster
boost::function<void()> onError
);
void mcastControl(const framing::AMQBody& controlBody, const ConnectionId&);
+ void mcastControl(const framing::AMQFrame& controlFrame, const ConnectionId&);
void mcastBuffer(const char*, size_t, const ConnectionId&);
void mcast(const Event& e);
/** End holding mode, held events are mcast */
diff --git a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
index 45a369eea9..cd42446016 100644
--- a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
+++ b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
@@ -70,17 +70,12 @@ void OutputInterceptor::giveReadCredit(int32_t credit) {
// Called in write thread when the IO layer has no more data to write.
// We do nothing in the write thread, we run doOutput only on delivery
// of doOutput requests.
-bool OutputInterceptor::doOutput() {
- QPID_LOG(trace, parent << " write idle.");
- return false;
-}
+bool OutputInterceptor::doOutput() { return false; }
// Delivery of doOutput allows us to run the real connection doOutput()
// which tranfers frames to the codec for writing.
//
void OutputInterceptor::deliverDoOutput(size_t requested) {
- QPID_LATENCY_RECORD("deliver do-output", *this);
- QPID_LATENCY_CLEAR(*this);
size_t buf = getBuffered();
if (parent.isLocal())
writeEstimate.delivered(requested, sent, buf); // Update the estimate.
@@ -91,9 +86,7 @@ void OutputInterceptor::deliverDoOutput(size_t requested) {
moreOutput = parent.getBrokerConnection().doOutput();
} while (sent < requested && moreOutput);
sent += buf; // Include buffered data in the sent total.
-
- QPID_LOG(trace, "Delivered doOutput: requested=" << requested << " output=" << sent << " more=" << moreOutput);
-
+ QPID_LOG(trace, parent << " delivereDoOutput: requested=" << requested << " sent=" << sent << " more=" << moreOutput);
if (parent.isLocal() && moreOutput) {
QPID_LOG(trace, parent << " deliverDoOutput - sending doOutput, more output available.");
sendDoOutput();
diff --git a/qpid/cpp/src/qpid/cluster/PollableQueue.h b/qpid/cpp/src/qpid/cluster/PollableQueue.h
index e0422e2449..a44c39ad85 100644
--- a/qpid/cpp/src/qpid/cluster/PollableQueue.h
+++ b/qpid/cpp/src/qpid/cluster/PollableQueue.h
@@ -52,6 +52,8 @@ template <class T> class PollableQueue : public sys::PollableQueue<T> {
}
catch (const std::exception& e) {
QPID_LOG(error, message << ": " << e.what());
+ values.clear();
+ this->stop();
error();
}
}
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
index 18746ccb7e..97eae7efa3 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
@@ -22,6 +22,8 @@
#include "Cluster.h"
#include "ClusterMap.h"
#include "Connection.h"
+#include "Decoder.h"
+#include "ExpiryPolicy.h"
#include "qpid/client/SessionBase_0_10Access.h"
#include "qpid/client/ConnectionAccess.h"
#include "qpid/broker/Broker.h"
@@ -86,33 +88,40 @@ void send(client::AsyncSession& s, const AMQBody& body) {
// TODO aconway 2008-09-24: optimization: update connections/sessions in parallel.
UpdateClient::UpdateClient(const MemberId& updater, const MemberId& updatee, const Url& url,
- broker::Broker& broker, const ClusterMap& m, uint64_t frameId_,
- const Cluster::Connections& cons,
+ broker::Broker& broker, const ClusterMap& m, ExpiryPolicy& expiry_,
+ const Cluster::ConnectionVector& cons, Decoder& decoder_,
const boost::function<void()>& ok,
const boost::function<void(const std::exception&)>& fail,
const client::ConnectionSettings& cs
)
: updaterId(updater), updateeId(updatee), updateeUrl(url), updaterBroker(broker), map(m),
- frameId(frameId_), connections(cons),
+ expiry(expiry_), connections(cons), decoder(decoder_),
connection(catchUpConnection()), shadowConnection(catchUpConnection()),
- done(ok), failed(fail)
+ done(ok), failed(fail), connectionSettings(cs)
{
connection.open(url, cs);
- session = connection.newSession("update_shared");
+ session = connection.newSession(UPDATE);
}
UpdateClient::~UpdateClient() {}
// Reserved exchange/queue name for catch-up, avoid clashes with user queues/exchanges.
-const std::string UpdateClient::UPDATE("qpid.qpid-update");
+const std::string UpdateClient::UPDATE("qpid.cluster-update");
+
+void UpdateClient::run() {
+ try {
+ update();
+ done();
+ } catch (const std::exception& e) {
+ failed(e);
+ }
+ delete this;
+}
void UpdateClient::update() {
QPID_LOG(debug, updaterId << " updating state to " << updateeId << " at " << updateeUrl);
Broker& b = updaterBroker;
b.getExchanges().eachExchange(boost::bind(&UpdateClient::updateExchange, this, _1));
-
- // Update exchange is used to route messages to the proper queue without modifying routing key.
- session.exchangeDeclare(arg::exchange=UPDATE, arg::type="fanout", arg::autoDelete=true);
b.getQueues().eachQueue(boost::bind(&UpdateClient::updateQueue, this, _1));
// Update queue is used to transfer acquired messages that are no longer on their original queue.
session.queueDeclare(arg::queue=UPDATE, arg::autoDelete=true);
@@ -121,25 +130,15 @@ void UpdateClient::update() {
std::for_each(connections.begin(), connections.end(), boost::bind(&UpdateClient::updateConnection, this, _1));
+ ClusterConnectionProxy(session).expiryId(expiry.getId());
ClusterConnectionMembershipBody membership;
map.toMethodBody(membership);
- membership.setFrameId(frameId);
AMQFrame frame(membership);
client::ConnectionAccess::getImpl(connection)->handle(frame);
connection.close();
QPID_LOG(debug, updaterId << " updated state to " << updateeId << " at " << updateeUrl);
}
-void UpdateClient::run() {
- try {
- update();
- done();
- } catch (const std::exception& e) {
- failed(e);
- }
- delete this;
-}
-
namespace {
template <class T> std::string encode(const T& t) {
std::string encoded;
@@ -152,8 +151,7 @@ template <class T> std::string encode(const T& t) {
void UpdateClient::updateExchange(const boost::shared_ptr<Exchange>& ex) {
QPID_LOG(debug, updaterId << " updating exchange " << ex->getName());
- ClusterConnectionProxy proxy(session);
- proxy.exchange(encode(*ex));
+ ClusterConnectionProxy(session).exchange(encode(*ex));
}
/** Bind a queue to the update exchange and update messges to it
@@ -164,24 +162,40 @@ class MessageUpdater {
bool haveLastPos;
framing::SequenceNumber lastPos;
client::AsyncSession session;
-
+ ExpiryPolicy& expiry;
+
public:
- MessageUpdater(const string& q, const client::AsyncSession s) : queue(q), haveLastPos(false), session(s) {
+ MessageUpdater(const string& q, const client::AsyncSession s, ExpiryPolicy& expiry_) : queue(q), haveLastPos(false), session(s), expiry(expiry_) {
session.exchangeBind(queue, UpdateClient::UPDATE);
}
~MessageUpdater() {
- session.exchangeUnbind(queue, UpdateClient::UPDATE);
+ try {
+ session.exchangeUnbind(queue, UpdateClient::UPDATE);
+ }
+ catch (const std::exception& e) {
+ // Don't throw in a destructor.
+ QPID_LOG(error, "Unbinding update queue " << queue << ": " << e.what());
+ }
}
void updateQueuedMessage(const broker::QueuedMessage& message) {
+ // Send the queue position if necessary.
if (!haveLastPos || message.position - lastPos != 1) {
ClusterConnectionProxy(session).queuePosition(queue, message.position.getValue()-1);
haveLastPos = true;
}
lastPos = message.position;
+
+ // Send the expiry ID if necessary.
+ if (message.payload->getProperties<DeliveryProperties>()->getTtl()) {
+ boost::optional<uint64_t> expiryId = expiry.getId(*message.payload);
+ if (!expiryId) return; // Message already expired, don't replicate.
+ ClusterConnectionProxy(session).expiryId(*expiryId);
+ }
+
SessionBase_0_10Access sb(session);
framing::MessageTransferBody transfer(
framing::ProtocolVersion(), UpdateClient::UPDATE, message::ACCEPT_MODE_NONE, message::ACQUIRE_MODE_PRE_ACQUIRED);
@@ -204,16 +218,13 @@ class MessageUpdater {
void updateMessage(const boost::intrusive_ptr<broker::Message>& message) {
updateQueuedMessage(broker::QueuedMessage(0, message, haveLastPos? lastPos.getValue()+1 : 1));
}
-
-
};
-
void UpdateClient::updateQueue(const boost::shared_ptr<Queue>& q) {
QPID_LOG(debug, updaterId << " updating queue " << q->getName());
ClusterConnectionProxy proxy(session);
proxy.queue(encode(*q));
- MessageUpdater updater(q->getName(), session);
+ MessageUpdater updater(q->getName(), session, expiry);
q->eachMessage(boost::bind(&MessageUpdater::updateQueuedMessage, &updater, _1));
q->eachBinding(boost::bind(&UpdateClient::updateBinding, this, q->getName(), _1));
}
@@ -228,13 +239,16 @@ void UpdateClient::updateConnection(const boost::intrusive_ptr<Connection>& upda
shadowConnection = catchUpConnection();
broker::Connection& bc = updateConnection->getBrokerConnection();
- // FIXME aconway 2008-10-20: What authentication info to use on reconnect?
- shadowConnection.open(updateeUrl, bc.getUserId(), ""/*password*/, "/"/*vhost*/, bc.getFrameMax());
+ connectionSettings.maxFrameSize = bc.getFrameMax();
+ shadowConnection.open(updateeUrl, connectionSettings);
bc.eachSessionHandler(boost::bind(&UpdateClient::updateSession, this, _1));
+ // Safe to use decoder here because we are stalled for update.
+ std::pair<const char*, size_t> fragment = decoder.get(updateConnection->getId()).getFragment();
ClusterConnectionProxy(shadowConnection).shadowReady(
updateConnection->getId().getMember(),
- reinterpret_cast<uint64_t>(updateConnection->getId().getPointer()),
- updateConnection->getBrokerConnection().getUserId()
+ updateConnection->getId().getNumber(),
+ bc.getUserId(),
+ string(fragment.first, fragment.second)
);
shadowConnection.close();
QPID_LOG(debug, updaterId << " updated connection " << *updateConnection);
@@ -269,7 +283,7 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
SequenceNumber received = ss->receiverGetReceived().command;
if (inProgress)
--received;
-
+
// Reset command-sequence state.
proxy.sessionState(
ss->senderGetReplayPoint().command,
@@ -285,9 +299,6 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
if (inProgress) {
inProgress->getFrames().map(simpl->out);
}
-
- // FIXME aconway 2008-09-23: update session replay list.
-
QPID_LOG(debug, updaterId << " updated session " << sh.getSession()->getId());
}
@@ -322,7 +333,7 @@ void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) {
// If the message is acquired then it is no longer on the
// updatees queue, put it on the update queue for updatee to pick up.
//
- MessageUpdater(UPDATE, shadowSession).updateQueuedMessage(dr.getMessage());
+ MessageUpdater(UPDATE, shadowSession, expiry).updateQueuedMessage(dr.getMessage());
}
ClusterConnectionProxy(shadowSession).deliveryRecord(
dr.getQueue()->getName(),
@@ -341,8 +352,8 @@ void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) {
class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
public:
- TxOpUpdater(UpdateClient& dc, client::AsyncSession s)
- : MessageUpdater(UpdateClient::UPDATE, s), parent(dc), session(s), proxy(s) {}
+ TxOpUpdater(UpdateClient& dc, client::AsyncSession s, ExpiryPolicy& expiry)
+ : MessageUpdater(UpdateClient::UPDATE, s, expiry), parent(dc), session(s), proxy(s) {}
void operator()(const broker::DtxAck& ) {
throw InternalErrorException("DTX transactions not currently supported by cluster.");
@@ -385,7 +396,7 @@ void UpdateClient::updateTxState(broker::SemanticState& s) {
broker::TxBuffer::shared_ptr txBuffer = s.getTxBuffer();
if (txBuffer) {
proxy.txStart();
- TxOpUpdater updater(*this, shadowSession);
+ TxOpUpdater updater(*this, shadowSession, expiry);
txBuffer->accept(updater);
proxy.txEnd();
}
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.h b/qpid/cpp/src/qpid/cluster/UpdateClient.h
index 23f647c820..23d061b7e4 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.h
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.h
@@ -46,6 +46,7 @@ class SessionHandler;
class DeliveryRecord;
class SessionState;
class SemanticState;
+class Decoder;
} // namespace broker
@@ -54,6 +55,8 @@ namespace cluster {
class Cluster;
class Connection;
class ClusterMap;
+class Decoder;
+class ExpiryPolicy;
/**
* A client that updates the contents of a local broker to a remote one using AMQP.
@@ -63,8 +66,8 @@ class UpdateClient : public sys::Runnable {
static const std::string UPDATE; // Name for special update queue and exchange.
UpdateClient(const MemberId& updater, const MemberId& updatee, const Url&,
- broker::Broker& donor, const ClusterMap& map, uint64_t sequence,
- const std::vector<boost::intrusive_ptr<Connection> >& ,
+ broker::Broker& donor, const ClusterMap& map, ExpiryPolicy& expiry,
+ const std::vector<boost::intrusive_ptr<Connection> >&, Decoder&,
const boost::function<void()>& done,
const boost::function<void(const std::exception&)>& fail,
const client::ConnectionSettings&
@@ -92,12 +95,14 @@ class UpdateClient : public sys::Runnable {
Url updateeUrl;
broker::Broker& updaterBroker;
ClusterMap map;
- uint64_t frameId;
+ ExpiryPolicy& expiry;
std::vector<boost::intrusive_ptr<Connection> > connections;
+ Decoder& decoder;
client::Connection connection, shadowConnection;
client::AsyncSession session, shadowSession;
boost::function<void()> done;
boost::function<void(const std::exception& e)> failed;
+ client::ConnectionSettings connectionSettings;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/UpdateExchange.h b/qpid/cpp/src/qpid/cluster/UpdateExchange.h
new file mode 100644
index 0000000000..7a4a484c8a
--- /dev/null
+++ b/qpid/cpp/src/qpid/cluster/UpdateExchange.h
@@ -0,0 +1,45 @@
+#ifndef QPID_CLUSTER_UPDATEEXCHANGE_H
+#define QPID_CLUSTER_UPDATEEXCHANGE_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 "UpdateClient.h"
+#include "qpid/broker/FanOutExchange.h"
+
+
+namespace qpid {
+namespace cluster {
+
+/**
+ * A keyless exchange (like fanout exchange) that does not modify deliver-properties.exchange
+ * on messages.
+ */
+class UpdateExchange : public broker::FanOutExchange
+{
+ public:
+ UpdateExchange(management::Manageable* parent) : broker::Exchange(UpdateClient::UPDATE, parent), broker::FanOutExchange(UpdateClient::UPDATE, parent) {}
+ void setProperties(const boost::intrusive_ptr<broker::Message>&) {}
+};
+
+}} // namespace qpid::cluster
+
+#endif /*!QPID_CLUSTER_UPDATEEXCHANGE_H*/
diff --git a/qpid/cpp/src/qpid/cluster/types.h b/qpid/cpp/src/qpid/cluster/types.h
index d1d6fdc427..c19152e4d8 100644
--- a/qpid/cpp/src/qpid/cluster/types.h
+++ b/qpid/cpp/src/qpid/cluster/types.h
@@ -68,16 +68,17 @@ inline bool operator==(const cpg_address& caddr, const MemberId& id) { return id
std::ostream& operator<<(std::ostream&, const MemberId&);
-struct ConnectionId : public std::pair<MemberId, Connection*> {
- ConnectionId(const MemberId& m=MemberId(), Connection* c=0) : std::pair<MemberId, Connection*> (m,c) {}
- ConnectionId(uint64_t m, uint64_t c)
- : std::pair<MemberId, Connection*>(MemberId(m), reinterpret_cast<Connection*>(c)) {}
+struct ConnectionId : public std::pair<MemberId, uint64_t> {
+ ConnectionId(const MemberId& m=MemberId(), uint64_t c=0) : std::pair<MemberId, uint64_t> (m,c) {}
+ ConnectionId(uint64_t m, uint64_t c) : std::pair<MemberId, uint64_t>(MemberId(m), c) {}
MemberId getMember() const { return first; }
- Connection* getPointer() const { return second; }
+ uint64_t getNumber() const { return second; }
};
std::ostream& operator<<(std::ostream&, const ConnectionId&);
+std::ostream& operator<<(std::ostream&, EventType);
+
}} // namespace qpid::cluster
#endif /*!QPID_CLUSTER_TYPES_H*/
diff --git a/qpid/cpp/src/qpid/console/Agent.h b/qpid/cpp/src/qpid/console/Agent.h
index 3307a1b44b..884d4c92bd 100644
--- a/qpid/cpp/src/qpid/console/Agent.h
+++ b/qpid/cpp/src/qpid/console/Agent.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_AGENT_H_
#include "Broker.h"
+#include "ConsoleImportExport.h"
namespace qpid {
namespace console {
@@ -30,7 +31,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class Agent {
+ class QPID_CONSOLE_EXTERN Agent {
public:
typedef std::vector<Agent*> Vector;
@@ -49,7 +50,7 @@ namespace console {
const std::string label;
};
- std::ostream& operator<<(std::ostream& o, const Agent& agent);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Agent& agent);
}
}
diff --git a/qpid/cpp/src/qpid/console/Broker.h b/qpid/cpp/src/qpid/console/Broker.h
index 9df2380dff..ddbd973dfe 100644
--- a/qpid/cpp/src/qpid/console/Broker.h
+++ b/qpid/cpp/src/qpid/console/Broker.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_BROKER_H_
#define _QPID_CONSOLE_BROKER_H_
+#include "ConsoleImportExport.h"
#include "qpid/client/Connection.h"
#include "qpid/client/ConnectionSettings.h"
#include "qpid/client/SubscriptionManager.h"
@@ -50,8 +51,9 @@ namespace console {
*/
class Broker : public client::MessageListener {
public:
- Broker(SessionManager& sm, client::ConnectionSettings& settings);
- ~Broker();
+ QPID_CONSOLE_EXTERN Broker(SessionManager& sm,
+ client::ConnectionSettings& settings);
+ QPID_CONSOLE_EXTERN ~Broker();
bool isConnected() const { return connected; }
const std::string& getError() const { return error; }
@@ -61,7 +63,7 @@ namespace console {
void addBinding(const std::string& key) {
connThreadBody.bindExchange("qpid.management", key);
}
- std::string getUrl() const;
+ QPID_CONSOLE_EXTERN std::string getUrl() const;
private:
friend class SessionManager;
@@ -120,10 +122,10 @@ namespace console {
void setBrokerId(const framing::Uuid& id) { brokerId = id; }
void appendAgents(std::vector<Agent*>& agents) const;
- friend std::ostream& operator<<(std::ostream& o, const Broker& k);
+ friend QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Broker& k);
};
- std::ostream& operator<<(std::ostream& o, const Broker& k);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Broker& k);
}
}
diff --git a/qpid/cpp/src/qpid/console/ClassKey.cpp b/qpid/cpp/src/qpid/console/ClassKey.cpp
index 1780b03f94..b97eb3ca44 100644
--- a/qpid/cpp/src/qpid/console/ClassKey.cpp
+++ b/qpid/cpp/src/qpid/console/ClassKey.cpp
@@ -21,6 +21,7 @@
#include "ClassKey.h"
#include <string.h>
+#include <cstdio>
using namespace std;
using namespace qpid::console;
diff --git a/qpid/cpp/src/qpid/console/ClassKey.h b/qpid/cpp/src/qpid/console/ClassKey.h
index f6617e22d5..821b01c4ef 100644
--- a/qpid/cpp/src/qpid/console/ClassKey.h
+++ b/qpid/cpp/src/qpid/console/ClassKey.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_CLASSKEY_H_
#include <string>
+#include "ConsoleImportExport.h"
#include "Package.h"
#include "qpid/framing/Buffer.h"
@@ -32,7 +33,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class ClassKey {
+ class QPID_CONSOLE_EXTERN ClassKey {
public:
static const int HASH_SIZE = 16;
@@ -57,7 +58,7 @@ namespace console {
uint8_t hash[HASH_SIZE];
};
- std::ostream& operator<<(std::ostream& o, const ClassKey& k);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ClassKey& k);
}
}
diff --git a/qpid/cpp/src/qpid/console/ConsoleImportExport.h b/qpid/cpp/src/qpid/console/ConsoleImportExport.h
new file mode 100644
index 0000000000..e2d0af9db3
--- /dev/null
+++ b/qpid/cpp/src/qpid/console/ConsoleImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_CONSOLE_IMPORT_EXPORT_H
+#define QPID_CONSOLE_IMPORT_EXPORT_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.
+ */
+
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+#if defined(CONSOLE_EXPORT)
+#define QPID_CONSOLE_EXTERN __declspec(dllexport)
+#else
+#define QPID_CONSOLE_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_CONSOLE_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/console/ConsoleListener.h b/qpid/cpp/src/qpid/console/ConsoleListener.h
index d0db6034f6..d661c63120 100644
--- a/qpid/cpp/src/qpid/console/ConsoleListener.h
+++ b/qpid/cpp/src/qpid/console/ConsoleListener.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_CONSOLE_LISTENER_H_
#include <string>
+#include "ConsoleImportExport.h"
#include "Broker.h"
#include "ClassKey.h"
#include "Object.h"
@@ -36,7 +37,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class ConsoleListener{
+ class QPID_CONSOLE_EXTERN ConsoleListener{
public:
virtual ~ConsoleListener() {};
diff --git a/qpid/cpp/src/qpid/console/Event.h b/qpid/cpp/src/qpid/console/Event.h
index 14f5a64716..4d51708965 100644
--- a/qpid/cpp/src/qpid/console/Event.h
+++ b/qpid/cpp/src/qpid/console/Event.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_EVENT_H_
#define _QPID_CONSOLE_EVENT_H_
+#include "ConsoleImportExport.h"
#include "Object.h"
#include "qpid/framing/Uuid.h"
#include "qpid/framing/FieldTable.h"
@@ -46,26 +47,28 @@ namespace console {
SEV_WARNING = 4, SEV_NOTICE = 5, SEV_INFO = 6, SEV_DEBUG = 7
} Severity;
- Event(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer);
+ QPID_CONSOLE_EXTERN Event(Broker* broker,
+ SchemaClass* schemaClass,
+ framing::Buffer& buffer);
Broker* getBroker() const { return broker; }
- const ClassKey& getClassKey() const;
+ QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const;
SchemaClass* getSchema() const { return schema; }
const Object::AttributeMap& getAttributes() const { return attributes; }
uint64_t getTimestamp() const { return timestamp; }
uint8_t getSeverity() const { return severity; }
- std::string getSeverityString() const;
+ QPID_CONSOLE_EXTERN std::string getSeverityString() const;
- ObjectId attrRef(const std::string& key) const;
- uint32_t attrUint(const std::string& key) const;
- int32_t attrInt(const std::string& key) const;
- uint64_t attrUint64(const std::string& key) const;
- int64_t attrInt64(const std::string& key) const;
- std::string attrString(const std::string& key) const;
- bool attrBool(const std::string& key) const;
- float attrFloat(const std::string& key) const;
- double attrDouble(const std::string& key) const;
- framing::Uuid attrUuid(const std::string& key) const;
- framing::FieldTable attrMap(const std::string& key) const;
+ QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const;
+ QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const;
+ QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const;
+ QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const;
private:
Broker* broker;
@@ -75,7 +78,7 @@ namespace console {
Object::AttributeMap attributes;
};
- std::ostream& operator<<(std::ostream& o, const Event& event);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Event& event);
}
}
diff --git a/qpid/cpp/src/qpid/console/Object.h b/qpid/cpp/src/qpid/console/Object.h
index 2c6993fc8a..d2fb09ecca 100644
--- a/qpid/cpp/src/qpid/console/Object.h
+++ b/qpid/cpp/src/qpid/console/Object.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_OBJECT_H_
#define _QPID_CONSOLE_OBJECT_H_
+#include "ConsoleImportExport.h"
#include "ObjectId.h"
#include "qpid/framing/Uuid.h"
#include "qpid/framing/FieldTable.h"
@@ -55,47 +56,50 @@ namespace console {
public:
typedef std::vector<Object> Vector;
struct AttributeMap : public std::map<std::string, boost::shared_ptr<Value> > {
- void addRef(const std::string& key, const ObjectId& val);
- void addUint(const std::string& key, uint32_t val);
- void addInt(const std::string& key, int32_t val);
- void addUint64(const std::string& key, uint64_t val);
- void addInt64(const std::string& key, int64_t val);
- void addString(const std::string& key, const std::string& val);
- void addBool(const std::string& key, bool val);
- void addFloat(const std::string& key, float val);
- void addDouble(const std::string& key, double val);
- void addUuid(const std::string& key, const framing::Uuid& val);
- void addMap(const std::string& key, const framing::FieldTable& val);
+ QPID_CONSOLE_EXTERN void addRef(const std::string& key, const ObjectId& val);
+ QPID_CONSOLE_EXTERN void addUint(const std::string& key, uint32_t val);
+ QPID_CONSOLE_EXTERN void addInt(const std::string& key, int32_t val);
+ QPID_CONSOLE_EXTERN void addUint64(const std::string& key, uint64_t val);
+ QPID_CONSOLE_EXTERN void addInt64(const std::string& key, int64_t val);
+ QPID_CONSOLE_EXTERN void addString(const std::string& key, const std::string& val);
+ QPID_CONSOLE_EXTERN void addBool(const std::string& key, bool val);
+ QPID_CONSOLE_EXTERN void addFloat(const std::string& key, float val);
+ QPID_CONSOLE_EXTERN void addDouble(const std::string& key, double val);
+ QPID_CONSOLE_EXTERN void addUuid(const std::string& key, const framing::Uuid& val);
+ QPID_CONSOLE_EXTERN void addMap(const std::string& key, const framing::FieldTable& val);
};
- Object(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer, bool prop, bool stat);
- ~Object();
+ QPID_CONSOLE_EXTERN Object(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer, bool prop, bool stat);
+ QPID_CONSOLE_EXTERN ~Object();
Broker* getBroker() const { return broker; }
const ObjectId& getObjectId() const { return objectId; }
- const ClassKey& getClassKey() const;
+ QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const;
SchemaClass* getSchema() const { return schema; }
uint64_t getCurrentTime() const { return currentTime; }
uint64_t getCreateTime() const { return createTime; }
uint64_t getDeleteTime() const { return deleteTime; }
bool isDeleted() const { return deleteTime != 0; }
- std::string getIndex() const;
- void mergeUpdate(const Object& updated);
+ QPID_CONSOLE_EXTERN std::string getIndex() const;
+ QPID_CONSOLE_EXTERN void mergeUpdate(const Object& updated);
const AttributeMap& getAttributes() const { return attributes; }
- void invokeMethod(const std::string name, const AttributeMap& args, MethodResponse& result);
- void handleMethodResp(framing::Buffer& buffer, uint32_t sequence);
+ QPID_CONSOLE_EXTERN void invokeMethod(const std::string name,
+ const AttributeMap& args,
+ MethodResponse& result);
+ QPID_CONSOLE_EXTERN void handleMethodResp(framing::Buffer& buffer,
+ uint32_t sequence);
- ObjectId attrRef(const std::string& key) const;
- uint32_t attrUint(const std::string& key) const;
- int32_t attrInt(const std::string& key) const;
- uint64_t attrUint64(const std::string& key) const;
- int64_t attrInt64(const std::string& key) const;
- std::string attrString(const std::string& key) const;
- bool attrBool(const std::string& key) const;
- float attrFloat(const std::string& key) const;
- double attrDouble(const std::string& key) const;
- framing::Uuid attrUuid(const std::string& key) const;
- framing::FieldTable attrMap(const std::string& key) const;
+ QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const;
+ QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const;
+ QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const;
+ QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const;
private:
Broker* broker;
@@ -111,7 +115,7 @@ namespace console {
void parsePresenceMasks(framing::Buffer& buffer, std::set<std::string>& excludeList);
};
- std::ostream& operator<<(std::ostream& o, const Object& object);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Object& object);
}
}
diff --git a/qpid/cpp/src/qpid/console/ObjectId.h b/qpid/cpp/src/qpid/console/ObjectId.h
index 73304ca306..ac0e8d8b03 100644
--- a/qpid/cpp/src/qpid/console/ObjectId.h
+++ b/qpid/cpp/src/qpid/console/ObjectId.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_OBJECTID_H
#include <iostream>
+#include "ConsoleImportExport.h"
#include "qpid/sys/IntegerTypes.h"
namespace qpid {
@@ -34,7 +35,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class ObjectId {
+ class QPID_CONSOLE_EXTERN ObjectId {
public:
ObjectId() : first(0), second(0) {}
ObjectId(framing::Buffer& buffer);
@@ -61,7 +62,7 @@ namespace console {
uint64_t second;
};
- std::ostream& operator<<(std::ostream& o, const ObjectId& id);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ObjectId& id);
}
}
diff --git a/qpid/cpp/src/qpid/console/Package.h b/qpid/cpp/src/qpid/console/Package.h
index 18203cb807..3cc63c8b75 100644
--- a/qpid/cpp/src/qpid/console/Package.h
+++ b/qpid/cpp/src/qpid/console/Package.h
@@ -23,6 +23,7 @@
#include <string>
#include <map>
+#include "ConsoleImportExport.h"
#include "qpid/sys/IntegerTypes.h"
namespace qpid {
diff --git a/qpid/cpp/src/qpid/console/SequenceManager.h b/qpid/cpp/src/qpid/console/SequenceManager.h
index c7a8c20fe6..5a041f530b 100644
--- a/qpid/cpp/src/qpid/console/SequenceManager.h
+++ b/qpid/cpp/src/qpid/console/SequenceManager.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_SEQUENCEMANAGER_H_
#define _QPID_CONSOLE_SEQUENCEMANAGER_H_
+#include "ConsoleImportExport.h"
#include "qpid/sys/Mutex.h"
#include <map>
#include <string>
@@ -38,8 +39,8 @@ namespace console {
typedef std::set<uint32_t> set;
SequenceManager() : sequence(0) {}
- uint32_t reserve(const std::string& context = "");
- std::string release(uint32_t seq);
+ QPID_CONSOLE_EXTERN uint32_t reserve(const std::string& context = "");
+ QPID_CONSOLE_EXTERN std::string release(uint32_t seq);
private:
sys::Mutex lock;
diff --git a/qpid/cpp/src/qpid/console/SessionManager.h b/qpid/cpp/src/qpid/console/SessionManager.h
index ab6e111caa..4341fe317c 100644
--- a/qpid/cpp/src/qpid/console/SessionManager.h
+++ b/qpid/cpp/src/qpid/console/SessionManager.h
@@ -22,6 +22,7 @@
*
*/
+#include "ConsoleImportExport.h"
#include "Broker.h"
#include "Package.h"
#include "SequenceManager.h"
@@ -80,8 +81,8 @@ class SessionManager
* and bindClass methods. If userBindings is false, the listener will receive
* updates for all object classes.
*/
- SessionManager(ConsoleListener* listener = 0,
- Settings settings = Settings());
+ QPID_CONSOLE_EXTERN SessionManager(ConsoleListener* listener = 0,
+ Settings settings = Settings());
/** Connect a broker to the console session
*
@@ -89,32 +90,33 @@ class SessionManager
*@return broker object if operation is successful
* an exception shall be thrown.
*/
- Broker* addBroker(client::ConnectionSettings& settings);
+ QPID_CONSOLE_EXTERN Broker* addBroker(client::ConnectionSettings& settings);
/** Disconnect a broker from the console session
*
*@param broker The broker object returned from an earlier call to addBroker.
*/
- void delBroker(Broker* broker);
+ QPID_CONSOLE_EXTERN void delBroker(Broker* broker);
/** Get a list of known management packages
*
*@param packages Vector of package names returned by the session manager.
*/
- void getPackages(NameVector& packages);
+ QPID_CONSOLE_EXTERN void getPackages(NameVector& packages);
/** Get a list of class keys associated with a package
*
*@param classKeys List of class keys returned by the session manager.
*@param packageName Name of package being queried.
*/
- void getClasses(KeyVector& classKeys, const std::string& packageName);
+ QPID_CONSOLE_EXTERN void getClasses(KeyVector& classKeys,
+ const std::string& packageName);
/** Get the schema of a class given its class key
*
*@param classKey Class key of the desired schema.
*/
- SchemaClass& getSchema(const ClassKey& classKey);
+ QPID_CONSOLE_EXTERN SchemaClass& getSchema(const ClassKey& classKey);
/** Request that updates be received for all classes within a package
*
@@ -123,7 +125,7 @@ class SessionManager
*
*@param packageName Name of the package to which to bind.
*/
- void bindPackage(const std::string& packageName);
+ QPID_CONSOLE_EXTERN void bindPackage(const std::string& packageName);
/** Request update to be received for a particular class
*
@@ -132,8 +134,9 @@ class SessionManager
*
*@param classKey Class key of class to which to bind.
*/
- void bindClass(const ClassKey& classKey);
- void bindClass(const std::string& packageName, const std::string& className);
+ QPID_CONSOLE_EXTERN void bindClass(const ClassKey& classKey);
+ QPID_CONSOLE_EXTERN void bindClass(const std::string& packageName,
+ const std::string& className);
/** Get a list of qmf agents known to the session manager.
*
@@ -141,7 +144,8 @@ class SessionManager
*@param broker Return agents registered with this broker only. If NULL, return agents
* from all connected brokers.
*/
- void getAgents(Agent::Vector& agents, Broker* broker = 0);
+ QPID_CONSOLE_EXTERN void getAgents(Agent::Vector& agents,
+ Broker* broker = 0);
/** Get objects from agents. There are four variants of this method with different ways of
* specifying from which class objects are being queried.
@@ -153,8 +157,10 @@ class SessionManager
*@param broker Restrict the query to this broker, or all brokers if NULL.
*@param agent Restrict the query to this agent, or all agents if NULL.
*/
- void getObjects(Object::Vector& objects, const std::string& className,
- Broker* broker = 0, Agent* agent = 0);
+ QPID_CONSOLE_EXTERN void getObjects(Object::Vector& objects,
+ const std::string& className,
+ Broker* broker = 0,
+ Agent* agent = 0);
//void getObjects(Object::Vector& objects, const ClassKey& classKey,
// Broker* broker = 0, Agent* agent = 0);
//void getObjects(Object::Vector& objects, const ObjectId& objectId,
diff --git a/qpid/cpp/src/qpid/framing/AMQBody.h b/qpid/cpp/src/qpid/framing/AMQBody.h
index 9e66b9738f..60ac2d3b7e 100644
--- a/qpid/cpp/src/qpid/framing/AMQBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQBody.h
@@ -26,6 +26,7 @@
#include "qpid/framing/BodyFactory.h"
#include <boost/intrusive_ptr.hpp>
#include <ostream>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -48,7 +49,7 @@ struct AMQBodyConstVisitor {
class AMQBody : public RefCounted {
public:
AMQBody() {}
- virtual ~AMQBody();
+ QPID_COMMON_EXTERN virtual ~AMQBody();
// Make AMQBody copyable even though RefCounted.
AMQBody(const AMQBody&) : RefCounted() {}
@@ -71,7 +72,7 @@ class AMQBody : public RefCounted {
virtual boost::intrusive_ptr<AMQBody> clone() const = 0;
};
-std::ostream& operator<<(std::ostream& out, const AMQBody& body) ;
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const AMQBody& body) ;
enum BodyTypes {
METHOD_BODY = 1,
diff --git a/qpid/cpp/src/qpid/framing/AMQContentBody.h b/qpid/cpp/src/qpid/framing/AMQContentBody.h
index a81cf36168..9606ae5ec5 100644
--- a/qpid/cpp/src/qpid/framing/AMQContentBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQContentBody.h
@@ -21,6 +21,7 @@
#include "amqp_types.h"
#include "AMQBody.h"
#include "Buffer.h"
+#include "qpid/CommonImportExport.h"
#ifndef _AMQContentBody_
#define _AMQContentBody_
@@ -33,18 +34,18 @@ class AMQContentBody : public AMQBody
string data;
public:
- AMQContentBody();
- AMQContentBody(const string& data);
+ QPID_COMMON_EXTERN AMQContentBody();
+ QPID_COMMON_EXTERN AMQContentBody(const string& data);
inline virtual ~AMQContentBody(){}
- inline uint8_t type() const { return CONTENT_BODY; };
- inline const string& getData() const { return data; }
- inline string& getData() { return data; }
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer, uint32_t size);
- void print(std::ostream& out) const;
- void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
- boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
+ QPID_COMMON_EXTERN inline uint8_t type() const { return CONTENT_BODY; };
+ QPID_COMMON_EXTERN inline const string& getData() const { return data; }
+ QPID_COMMON_EXTERN inline string& getData() { return data; }
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer, uint32_t size);
+ QPID_COMMON_EXTERN void print(std::ostream& out) const;
+ QPID_COMMON_EXTERN void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
+ QPID_COMMON_EXTERN boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
}
diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.cpp b/qpid/cpp/src/qpid/framing/AMQFrame.cpp
index 80c8e0b56d..9473b2a513 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.cpp
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.cpp
@@ -41,7 +41,7 @@ AMQFrame::AMQFrame(const boost::intrusive_ptr<AMQBody>& b) : body(b) { init(); }
AMQFrame::AMQFrame(const AMQBody& b) : body(b.clone()) { init(); }
-AMQFrame::~AMQFrame() {}
+AMQFrame::~AMQFrame() { init(); }
AMQBody* AMQFrame::getBody() {
// Non-const AMQBody* may be used to modify the body.
diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.h b/qpid/cpp/src/qpid/framing/AMQFrame.h
index 028d0c1d8a..34319e7ed4 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.h
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.h
@@ -29,6 +29,7 @@
#include "qpid/sys/LatencyMetric.h"
#include <boost/intrusive_ptr.hpp>
#include <boost/cast.hpp>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -36,15 +37,15 @@ namespace framing {
class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
{
public:
- AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0);
- AMQFrame(const AMQBody& b);
- ~AMQFrame();
+ QPID_COMMON_EXTERN AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0);
+ QPID_COMMON_EXTERN AMQFrame(const AMQBody& b);
+ QPID_COMMON_EXTERN ~AMQFrame();
ChannelId getChannel() const { return channel; }
void setChannel(ChannelId c) { channel = c; }
- AMQBody* getBody();
- const AMQBody* getBody() const;
+ QPID_COMMON_EXTERN AMQBody* getBody();
+ QPID_COMMON_EXTERN const AMQBody* getBody() const;
AMQMethodBody* getMethod() { return getBody()->getMethod(); }
const AMQMethodBody* getMethod() const { return getBody()->getMethod(); }
@@ -59,9 +60,9 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
return boost::polymorphic_downcast<const T*>(getBody());
}
- void encode(Buffer& buffer) const;
- bool decode(Buffer& buffer);
- uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN bool decode(Buffer& buffer);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
// 0-10 terminology: first/last frame (in segment) first/last segment (in assembly)
@@ -88,13 +89,10 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
void setEos(bool isEos) { eos = isEos; }
static uint16_t DECODE_SIZE_MIN;
- static uint32_t frameOverhead();
+ QPID_COMMON_EXTERN static uint32_t frameOverhead();
/** Must point to at least DECODE_SIZE_MIN bytes of data */
static uint16_t decodeSize(char* data);
- uint64_t getClusterId() const { return clusterId; }
- void setClusterId(uint64_t id) { clusterId = id; }
-
private:
void init();
@@ -106,10 +104,9 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
bool bos : 1;
bool eos : 1;
mutable uint32_t encodedSizeCache;
- uint64_t clusterId; // Used to identify frames in a clustered broekr.
};
-std::ostream& operator<<(std::ostream&, const AMQFrame&);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const AMQFrame&);
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
index 9846544949..b8099f2e51 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
@@ -26,6 +26,7 @@
#include "Buffer.h"
#include "qpid/framing/DeliveryProperties.h"
#include "qpid/framing/MessageProperties.h"
+#include "qpid/CommonImportExport.h"
#include <iostream>
#include <boost/optional.hpp>
@@ -83,12 +84,12 @@ public:
inline uint8_t type() const { return HEADER_BODY; }
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer, uint32_t size);
- uint64_t getContentLength() const;
- void print(std::ostream& out) const;
- void accept(AMQBodyConstVisitor&) const;
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer, uint32_t size);
+ QPID_COMMON_EXTERN uint64_t getContentLength() const;
+ QPID_COMMON_EXTERN void print(std::ostream& out) const;
+ QPID_COMMON_EXTERN void accept(AMQBodyConstVisitor&) const;
template <class T> T* get(bool create) {
boost::optional<T>& p=properties.OptProps<T>::props;
diff --git a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
index 3fb41c128e..5d3f633576 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
@@ -21,6 +21,7 @@
#include "amqp_types.h"
#include "AMQBody.h"
#include "Buffer.h"
+#include "qpid/CommonImportExport.h"
#ifndef _AMQHeartbeatBody_
#define _AMQHeartbeatBody_
@@ -31,12 +32,12 @@ namespace framing {
class AMQHeartbeatBody : public AMQBody
{
public:
- virtual ~AMQHeartbeatBody();
+ QPID_COMMON_EXTERN virtual ~AMQHeartbeatBody();
inline uint32_t encodedSize() const { return 0; }
inline uint8_t type() const { return HEARTBEAT_BODY; }
inline void encode(Buffer& ) const {}
inline void decode(Buffer& , uint32_t /*size*/) {}
- virtual void print(std::ostream& out) const;
+ QPID_COMMON_EXTERN virtual void print(std::ostream& out) const;
void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
diff --git a/qpid/cpp/src/qpid/framing/AMQMethodBody.h b/qpid/cpp/src/qpid/framing/AMQMethodBody.h
index cc7489ddd9..a38726b0fc 100644
--- a/qpid/cpp/src/qpid/framing/AMQMethodBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQMethodBody.h
@@ -25,7 +25,7 @@
#include "AMQBody.h"
#include "qpid/framing/ProtocolVersion.h"
#include "qpid/shared_ptr.h"
-
+#include "qpid/CommonImportExport.h"
#include <ostream>
#include <assert.h>
@@ -40,7 +40,7 @@ class MethodBodyConstVisitor;
class AMQMethodBody : public AMQBody {
public:
AMQMethodBody() {}
- virtual ~AMQMethodBody();
+ QPID_COMMON_EXTERN virtual ~AMQMethodBody();
virtual void accept(MethodBodyConstVisitor&) const = 0;
diff --git a/qpid/cpp/src/qpid/framing/AccumulatedAck.h b/qpid/cpp/src/qpid/framing/AccumulatedAck.h
index ea78b797e0..ede73897c7 100644
--- a/qpid/cpp/src/qpid/framing/AccumulatedAck.h
+++ b/qpid/cpp/src/qpid/framing/AccumulatedAck.h
@@ -27,6 +27,7 @@
#include <ostream>
#include "SequenceNumber.h"
#include "SequenceNumberSet.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -58,17 +59,17 @@ namespace qpid {
*/
std::list<Range> ranges;
- explicit AccumulatedAck(SequenceNumber r = SequenceNumber());
- void update(SequenceNumber firstTag, SequenceNumber lastTag);
- void consolidate();
- void clear();
- bool covers(SequenceNumber tag) const;
+ QPID_COMMON_EXTERN explicit AccumulatedAck(SequenceNumber r = SequenceNumber());
+ QPID_COMMON_EXTERN void update(SequenceNumber firstTag, SequenceNumber lastTag);
+ QPID_COMMON_EXTERN void consolidate();
+ QPID_COMMON_EXTERN void clear();
+ QPID_COMMON_EXTERN bool covers(SequenceNumber tag) const;
void collectRanges(SequenceNumberSet& set) const;
- void update(const SequenceNumber cumulative, const SequenceNumberSet& range);
+ QPID_COMMON_EXTERN void update(const SequenceNumber cumulative, const SequenceNumberSet& range);
void operator()(SequenceNumber first, SequenceNumber last) { update(first, last); }
};
- std::ostream& operator<<(std::ostream&, const Range&);
- std::ostream& operator<<(std::ostream&, const AccumulatedAck&);
+ QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const Range&);
+ QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const AccumulatedAck&);
}
}
diff --git a/qpid/cpp/src/qpid/framing/Array.h b/qpid/cpp/src/qpid/framing/Array.h
index 183fcb6d5c..0b6b704ed2 100644
--- a/qpid/cpp/src/qpid/framing/Array.h
+++ b/qpid/cpp/src/qpid/framing/Array.h
@@ -24,6 +24,7 @@
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <vector>
+#include "qpid/CommonImportExport.h"
#ifndef _Array_
#define _Array_
@@ -41,38 +42,38 @@ class Array
typedef ValueVector::const_iterator const_iterator;
typedef ValueVector::iterator iterator;
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer);
- int count() const;
- bool operator==(const Array& other) const;
+ QPID_COMMON_EXTERN int count() const;
+ QPID_COMMON_EXTERN bool operator==(const Array& other) const;
- Array();
- Array(TypeCode type);
- Array(uint8_t type);
+ QPID_COMMON_EXTERN Array();
+ QPID_COMMON_EXTERN Array(TypeCode type);
+ QPID_COMMON_EXTERN Array(uint8_t type);
//creates a longstr array
- Array(const std::vector<std::string>& in);
+ QPID_COMMON_EXTERN Array(const std::vector<std::string>& in);
- TypeCode getType() const { return type; }
+ QPID_COMMON_EXTERN TypeCode getType() const { return type; }
// std collection interface.
- const_iterator begin() const { return values.begin(); }
- const_iterator end() const { return values.end(); }
- iterator begin() { return values.begin(); }
- iterator end(){ return values.end(); }
-
- ValuePtr front() const { return values.front(); }
- ValuePtr back() const { return values.back(); }
- size_t size() const { return values.size(); }
-
- void insert(iterator i, ValuePtr value);
- void erase(iterator i) { values.erase(i); }
- void push_back(ValuePtr value) { values.insert(end(), value); }
- void pop_back() { values.pop_back(); }
+ QPID_COMMON_EXTERN const_iterator begin() const { return values.begin(); }
+ QPID_COMMON_EXTERN const_iterator end() const { return values.end(); }
+ QPID_COMMON_EXTERN iterator begin() { return values.begin(); }
+ QPID_COMMON_EXTERN iterator end(){ return values.end(); }
+
+ QPID_COMMON_EXTERN ValuePtr front() const { return values.front(); }
+ QPID_COMMON_EXTERN ValuePtr back() const { return values.back(); }
+ QPID_COMMON_EXTERN size_t size() const { return values.size(); }
+
+ QPID_COMMON_EXTERN void insert(iterator i, ValuePtr value);
+ QPID_COMMON_EXTERN void erase(iterator i) { values.erase(i); }
+ QPID_COMMON_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); }
+ QPID_COMMON_EXTERN void pop_back() { values.pop_back(); }
// Non-std interface
- void add(ValuePtr value) { push_back(value); }
+ QPID_COMMON_EXTERN void add(ValuePtr value) { push_back(value); }
template <class T>
void collect(std::vector<T>& out) const
@@ -86,7 +87,7 @@ class Array
TypeCode type;
ValueVector values;
- friend std::ostream& operator<<(std::ostream& out, const Array& body);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const Array& body);
};
}
diff --git a/qpid/cpp/src/qpid/framing/Buffer.h b/qpid/cpp/src/qpid/framing/Buffer.h
index 828e6e963a..57fb1e32a0 100644
--- a/qpid/cpp/src/qpid/framing/Buffer.h
+++ b/qpid/cpp/src/qpid/framing/Buffer.h
@@ -20,6 +20,7 @@
*/
#include "amqp_types.h"
#include "qpid/Exception.h"
+#include "qpid/CommonImportExport.h"
#include <boost/iterator/iterator_facade.hpp>
#ifndef _Buffer_
@@ -66,65 +67,65 @@ class Buffer
friend class Iterator;
- Buffer(char* data=0, uint32_t size=0);
+ QPID_COMMON_EXTERN Buffer(char* data=0, uint32_t size=0);
- void record();
- void restore(bool reRecord = false);
- void reset();
+ QPID_COMMON_EXTERN void record();
+ QPID_COMMON_EXTERN void restore(bool reRecord = false);
+ QPID_COMMON_EXTERN void reset();
- uint32_t available() { return size - position; }
- uint32_t getSize() { return size; }
- uint32_t getPosition() { return position; }
- Iterator getIterator() { return Iterator(*this); }
- char* getPointer() { return data; }
+ QPID_COMMON_EXTERN uint32_t available() { return size - position; }
+ QPID_COMMON_EXTERN uint32_t getSize() { return size; }
+ QPID_COMMON_EXTERN uint32_t getPosition() { return position; }
+ QPID_COMMON_EXTERN Iterator getIterator() { return Iterator(*this); }
+ QPID_COMMON_EXTERN char* getPointer() { return data; }
- void putOctet(uint8_t i);
- void putShort(uint16_t i);
- void putLong(uint32_t i);
- void putLongLong(uint64_t i);
- void putInt8(int8_t i);
- void putInt16(int16_t i);
- void putInt32(int32_t i);
- void putInt64(int64_t i);
- void putFloat(float f);
- void putDouble(double f);
- void putBin128(uint8_t* b);
-
- uint8_t getOctet();
- uint16_t getShort();
- uint32_t getLong();
- uint64_t getLongLong();
- int8_t getInt8();
- int16_t getInt16();
- int32_t getInt32();
- int64_t getInt64();
- float getFloat();
- double getDouble();
+ QPID_COMMON_EXTERN void putOctet(uint8_t i);
+ QPID_COMMON_EXTERN void putShort(uint16_t i);
+ QPID_COMMON_EXTERN void putLong(uint32_t i);
+ QPID_COMMON_EXTERN void putLongLong(uint64_t i);
+ QPID_COMMON_EXTERN void putInt8(int8_t i);
+ QPID_COMMON_EXTERN void putInt16(int16_t i);
+ QPID_COMMON_EXTERN void putInt32(int32_t i);
+ QPID_COMMON_EXTERN void putInt64(int64_t i);
+ QPID_COMMON_EXTERN void putFloat(float f);
+ QPID_COMMON_EXTERN void putDouble(double f);
+ QPID_COMMON_EXTERN void putBin128(uint8_t* b);
+
+ QPID_COMMON_EXTERN uint8_t getOctet();
+ QPID_COMMON_EXTERN uint16_t getShort();
+ QPID_COMMON_EXTERN uint32_t getLong();
+ QPID_COMMON_EXTERN uint64_t getLongLong();
+ QPID_COMMON_EXTERN int8_t getInt8();
+ QPID_COMMON_EXTERN int16_t getInt16();
+ QPID_COMMON_EXTERN int32_t getInt32();
+ QPID_COMMON_EXTERN int64_t getInt64();
+ QPID_COMMON_EXTERN float getFloat();
+ QPID_COMMON_EXTERN double getDouble();
template <int n>
- uint64_t getUInt();
+ QPID_COMMON_EXTERN uint64_t getUInt();
template <int n>
- void putUInt(uint64_t);
+ QPID_COMMON_EXTERN void putUInt(uint64_t);
- void putShortString(const string& s);
- void putMediumString(const string& s);
- void putLongString(const string& s);
- void getShortString(string& s);
- void getMediumString(string& s);
- void getLongString(string& s);
- void getBin128(uint8_t* b);
+ QPID_COMMON_EXTERN void putShortString(const string& s);
+ QPID_COMMON_EXTERN void putMediumString(const string& s);
+ QPID_COMMON_EXTERN void putLongString(const string& s);
+ QPID_COMMON_EXTERN void getShortString(string& s);
+ QPID_COMMON_EXTERN void getMediumString(string& s);
+ QPID_COMMON_EXTERN void getLongString(string& s);
+ QPID_COMMON_EXTERN void getBin128(uint8_t* b);
- void putRawData(const string& s);
- void getRawData(string& s, uint32_t size);
+ QPID_COMMON_EXTERN void putRawData(const string& s);
+ QPID_COMMON_EXTERN void getRawData(string& s, uint32_t size);
- void putRawData(const uint8_t* data, size_t size);
- void getRawData(uint8_t* data, size_t size);
+ QPID_COMMON_EXTERN void putRawData(const uint8_t* data, size_t size);
+ QPID_COMMON_EXTERN void getRawData(uint8_t* data, size_t size);
template <class T> void put(const T& data) { data.encode(*this); }
template <class T> void get(T& data) { data.decode(*this); }
- void dump(std::ostream&) const;
+ QPID_COMMON_EXTERN void dump(std::ostream&) const;
};
std::ostream& operator<<(std::ostream&, const Buffer&);
diff --git a/qpid/cpp/src/qpid/framing/FieldTable.h b/qpid/cpp/src/qpid/framing/FieldTable.h
index 9e1214a28c..a07568559f 100644
--- a/qpid/cpp/src/qpid/framing/FieldTable.h
+++ b/qpid/cpp/src/qpid/framing/FieldTable.h
@@ -23,6 +23,7 @@
#include <boost/shared_ptr.hpp>
#include <map>
#include "amqp_types.h"
+#include "qpid/CommonImportExport.h"
#ifndef _FieldTable_
#define _FieldTable_
@@ -51,45 +52,45 @@ class FieldTable
typedef std::map<std::string, ValuePtr> ValueMap;
typedef ValueMap::iterator iterator;
- FieldTable() {};
- FieldTable(const FieldTable& ft);
- ~FieldTable();
- FieldTable& operator=(const FieldTable& ft);
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer);
-
- int count() const;
- void set(const std::string& name, const ValuePtr& value);
- ValuePtr get(const std::string& name) const;
- bool isSet(const std::string& name) const { return get(name).get() != 0; }
-
- void setString(const std::string& name, const std::string& value);
- void setInt(const std::string& name, const int value);
- void setInt64(const std::string& name, const int64_t value);
- void setTimestamp(const std::string& name, const uint64_t value);
- void setUInt64(const std::string& name, const uint64_t value);
- void setTable(const std::string& name, const FieldTable& value);
- void setArray(const std::string& name, const Array& value);
- void setFloat(const std::string& name, const float value);
- void setDouble(const std::string& name, const double value);
+ QPID_COMMON_EXTERN FieldTable() {};
+ QPID_COMMON_EXTERN FieldTable(const FieldTable& ft);
+ QPID_COMMON_EXTERN ~FieldTable();
+ QPID_COMMON_EXTERN FieldTable& operator=(const FieldTable& ft);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer);
+
+ QPID_COMMON_EXTERN int count() const;
+ QPID_COMMON_EXTERN void set(const std::string& name, const ValuePtr& value);
+ QPID_COMMON_EXTERN ValuePtr get(const std::string& name) const;
+ QPID_COMMON_EXTERN bool isSet(const std::string& name) const { return get(name).get() != 0; }
+
+ QPID_COMMON_EXTERN void setString(const std::string& name, const std::string& value);
+ QPID_COMMON_EXTERN void setInt(const std::string& name, const int value);
+ QPID_COMMON_EXTERN void setInt64(const std::string& name, const int64_t value);
+ QPID_COMMON_EXTERN void setTimestamp(const std::string& name, const uint64_t value);
+ QPID_COMMON_EXTERN void setUInt64(const std::string& name, const uint64_t value);
+ QPID_COMMON_EXTERN void setTable(const std::string& name, const FieldTable& value);
+ QPID_COMMON_EXTERN void setArray(const std::string& name, const Array& value);
+ QPID_COMMON_EXTERN void setFloat(const std::string& name, const float value);
+ QPID_COMMON_EXTERN void setDouble(const std::string& name, const double value);
//void setDecimal(string& name, xxx& value);
- int getAsInt(const std::string& name) const;
- uint64_t getAsUInt64(const std::string& name) const;
- int64_t getAsInt64(const std::string& name) const;
- std::string getAsString(const std::string& name) const;
+ QPID_COMMON_EXTERN int getAsInt(const std::string& name) const;
+ QPID_COMMON_EXTERN uint64_t getAsUInt64(const std::string& name) const;
+ QPID_COMMON_EXTERN int64_t getAsInt64(const std::string& name) const;
+ QPID_COMMON_EXTERN std::string getAsString(const std::string& name) const;
- bool getTable(const std::string& name, FieldTable& value) const;
- bool getArray(const std::string& name, Array& value) const;
- bool getFloat(const std::string& name, float& value) const;
- bool getDouble(const std::string& name, double& value) const;
+ QPID_COMMON_EXTERN bool getTable(const std::string& name, FieldTable& value) const;
+ QPID_COMMON_EXTERN bool getArray(const std::string& name, Array& value) const;
+ QPID_COMMON_EXTERN bool getFloat(const std::string& name, float& value) const;
+ QPID_COMMON_EXTERN bool getDouble(const std::string& name, double& value) const;
//bool getTimestamp(const std::string& name, uint64_t& value) const;
//bool getDecimal(string& name, xxx& value);
- void erase(const std::string& name);
+ QPID_COMMON_EXTERN void erase(const std::string& name);
- bool operator==(const FieldTable& other) const;
+ QPID_COMMON_EXTERN bool operator==(const FieldTable& other) const;
// Map-like interface.
// TODO: may need to duplicate into versions that return mutable iterator
@@ -107,7 +108,7 @@ class FieldTable
private:
ValueMap values;
- friend std::ostream& operator<<(std::ostream& out, const FieldTable& body);
+ QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream& out, const FieldTable& body);
};
//class FieldNotFoundException{};
diff --git a/qpid/cpp/src/qpid/framing/FieldValue.h b/qpid/cpp/src/qpid/framing/FieldValue.h
index 29760619e5..0f27700ac8 100644
--- a/qpid/cpp/src/qpid/framing/FieldValue.h
+++ b/qpid/cpp/src/qpid/framing/FieldValue.h
@@ -25,6 +25,7 @@
#include "amqp_types.h"
#include "Buffer.h"
#include "FieldTable.h"
+#include "qpid/CommonImportExport.h"
#include "assert.h"
@@ -87,8 +88,8 @@ class FieldValue {
bool empty() const { return data.get() == 0; }
void encode(Buffer& buffer);
void decode(Buffer& buffer);
- bool operator==(const FieldValue&) const;
- bool operator!=(const FieldValue& v) const { return !(*this == v); }
+ QPID_COMMON_EXTERN bool operator==(const FieldValue&) const;
+ QPID_COMMON_EXTERN bool operator!=(const FieldValue& v) const { return !(*this == v); }
void print(std::ostream& out) const;
@@ -244,28 +245,28 @@ class EncodedValue : public FieldValue::Data {
class Str8Value : public FieldValue {
public:
- Str8Value(const std::string& v);
+ QPID_COMMON_EXTERN Str8Value(const std::string& v);
};
class Str16Value : public FieldValue {
public:
- Str16Value(const std::string& v);
+ QPID_COMMON_EXTERN Str16Value(const std::string& v);
};
class Struct32Value : public FieldValue {
public:
- Struct32Value(const std::string& v);
+ QPID_COMMON_EXTERN Struct32Value(const std::string& v);
};
class FloatValue : public FieldValue
{
public:
- FloatValue(float f);
+ QPID_COMMON_EXTERN FloatValue(float f);
};
class DoubleValue : public FieldValue
{
public:
- DoubleValue(double f);
+ QPID_COMMON_EXTERN DoubleValue(double f);
};
/*
@@ -273,32 +274,32 @@ class DoubleValue : public FieldValue
*/
class IntegerValue : public FieldValue {
public:
- IntegerValue(int v);
+ QPID_COMMON_EXTERN IntegerValue(int v);
};
class TimeValue : public FieldValue {
public:
- TimeValue(uint64_t v);
+ QPID_COMMON_EXTERN TimeValue(uint64_t v);
};
class Integer64Value : public FieldValue {
public:
- Integer64Value(int64_t v);
+ QPID_COMMON_EXTERN Integer64Value(int64_t v);
};
class Unsigned64Value : public FieldValue {
public:
- Unsigned64Value(uint64_t v);
+ QPID_COMMON_EXTERN Unsigned64Value(uint64_t v);
};
class FieldTableValue : public FieldValue {
public:
- FieldTableValue(const FieldTable&);
+ QPID_COMMON_EXTERN FieldTableValue(const FieldTable&);
};
class ArrayValue : public FieldValue {
public:
- ArrayValue(const Array&);
+ QPID_COMMON_EXTERN ArrayValue(const Array&);
};
template <class T>
diff --git a/qpid/cpp/src/qpid/framing/FrameDecoder.cpp b/qpid/cpp/src/qpid/framing/FrameDecoder.cpp
index cbdac181e9..1e73ee1e51 100644
--- a/qpid/cpp/src/qpid/framing/FrameDecoder.cpp
+++ b/qpid/cpp/src/qpid/framing/FrameDecoder.cpp
@@ -21,8 +21,9 @@
#include "FrameDecoder.h"
#include "Buffer.h"
#include "qpid/log/Statement.h"
-#include <algorithm>
#include "qpid/framing/reply_exceptions.h"
+#include <algorithm>
+#include <string.h>
namespace qpid {
namespace framing {
@@ -67,4 +68,13 @@ bool FrameDecoder::decode(Buffer& buffer) {
return false;
}
+void FrameDecoder::setFragment(const char* data, size_t size) {
+ fragment.resize(size);
+ ::memcpy(&fragment[0], data, size);
+}
+
+std::pair<const char*, size_t> FrameDecoder::getFragment() const {
+ return std::pair<const char*, size_t>(&fragment[0], fragment.size());
+}
+
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/FrameDecoder.h b/qpid/cpp/src/qpid/framing/FrameDecoder.h
index 7f974dadc3..961cc666a9 100644
--- a/qpid/cpp/src/qpid/framing/FrameDecoder.h
+++ b/qpid/cpp/src/qpid/framing/FrameDecoder.h
@@ -35,9 +35,16 @@ class FrameDecoder
{
public:
bool decode(Buffer& buffer);
- AMQFrame frame;
+ const AMQFrame& getFrame() const { return frame; }
+ AMQFrame& getFrame() { return frame; }
+
+ void setFragment(const char*, size_t);
+ std::pair<const char*, size_t> getFragment() const;
+
private:
std::vector<char> fragment;
+ AMQFrame frame;
+
};
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/FrameSet.h b/qpid/cpp/src/qpid/framing/FrameSet.h
index b13ca16e97..e3e8727600 100644
--- a/qpid/cpp/src/qpid/framing/FrameSet.h
+++ b/qpid/cpp/src/qpid/framing/FrameSet.h
@@ -23,6 +23,7 @@
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/SequenceNumber.h"
+#include "qpid/CommonImportExport.h"
#ifndef _FrameSet_
#define _FrameSet_
@@ -44,20 +45,20 @@ class FrameSet
public:
typedef boost::shared_ptr<FrameSet> shared_ptr;
- FrameSet(const SequenceNumber& id);
- void append(const AMQFrame& part);
- bool isComplete() const;
+ QPID_COMMON_EXTERN FrameSet(const SequenceNumber& id);
+ QPID_COMMON_EXTERN void append(const AMQFrame& part);
+ QPID_COMMON_EXTERN bool isComplete() const;
- uint64_t getContentSize() const;
+ QPID_COMMON_EXTERN uint64_t getContentSize() const;
- void getContent(std::string&) const;
- std::string getContent() const;
+ QPID_COMMON_EXTERN void getContent(std::string&) const;
+ QPID_COMMON_EXTERN std::string getContent() const;
bool isContentBearing() const;
- const AMQMethodBody* getMethod() const;
- const AMQHeaderBody* getHeaders() const;
- AMQHeaderBody* getHeaders();
+ QPID_COMMON_EXTERN const AMQMethodBody* getMethod() const;
+ QPID_COMMON_EXTERN const AMQHeaderBody* getHeaders() const;
+ QPID_COMMON_EXTERN AMQHeaderBody* getHeaders();
template <class T> bool isA() const {
const AMQMethodBody* method = getMethod();
diff --git a/qpid/cpp/src/qpid/framing/ProtocolInitiation.h b/qpid/cpp/src/qpid/framing/ProtocolInitiation.h
index 6584fee55c..7a82b3575f 100644
--- a/qpid/cpp/src/qpid/framing/ProtocolInitiation.h
+++ b/qpid/cpp/src/qpid/framing/ProtocolInitiation.h
@@ -22,6 +22,7 @@
#include "Buffer.h"
#include "AMQDataBlock.h"
#include "ProtocolVersion.h"
+#include "qpid/CommonImportExport.h"
#ifndef _ProtocolInitiation_
#define _ProtocolInitiation_
@@ -35,12 +36,12 @@ private:
ProtocolVersion version;
public:
- ProtocolInitiation();
- ProtocolInitiation(uint8_t major, uint8_t minor);
- ProtocolInitiation(ProtocolVersion p);
- virtual ~ProtocolInitiation();
- virtual void encode(Buffer& buffer) const;
- virtual bool decode(Buffer& buffer);
+ QPID_COMMON_EXTERN ProtocolInitiation();
+ QPID_COMMON_EXTERN ProtocolInitiation(uint8_t major, uint8_t minor);
+ QPID_COMMON_EXTERN ProtocolInitiation(ProtocolVersion p);
+ QPID_COMMON_EXTERN virtual ~ProtocolInitiation();
+ QPID_COMMON_EXTERN virtual void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN virtual bool decode(Buffer& buffer);
inline virtual uint32_t encodedSize() const { return 8; }
inline uint8_t getMajor() const { return version.getMajor(); }
inline uint8_t getMinor() const { return version.getMinor(); }
@@ -48,7 +49,7 @@ public:
bool operator==(ProtocolVersion v) const { return v == getVersion(); }
};
-std::ostream& operator<<(std::ostream& o, const framing::ProtocolInitiation& pi);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& o, const framing::ProtocolInitiation& pi);
}
diff --git a/qpid/cpp/src/qpid/framing/ProtocolVersion.h b/qpid/cpp/src/qpid/framing/ProtocolVersion.h
index 9a7ebec491..681c9daf21 100644
--- a/qpid/cpp/src/qpid/framing/ProtocolVersion.h
+++ b/qpid/cpp/src/qpid/framing/ProtocolVersion.h
@@ -22,6 +22,7 @@
#define _ProtocolVersion_
#include "amqp_types.h"
+#include "qpid/CommonImportExport.h"
namespace qpid
{
@@ -38,16 +39,16 @@ public:
explicit ProtocolVersion(uint8_t _major=0, uint8_t _minor=0)
: major_(_major), minor_(_minor) {}
- uint8_t getMajor() const { return major_; }
- void setMajor(uint8_t major) { major_ = major; }
- uint8_t getMinor() const { return minor_; }
- void setMinor(uint8_t minor) { minor_ = minor; }
- const std::string toString() const;
+ QPID_COMMON_EXTERN uint8_t getMajor() const { return major_; }
+ QPID_COMMON_EXTERN void setMajor(uint8_t major) { major_ = major; }
+ QPID_COMMON_EXTERN uint8_t getMinor() const { return minor_; }
+ QPID_COMMON_EXTERN void setMinor(uint8_t minor) { minor_ = minor; }
+ QPID_COMMON_EXTERN const std::string toString() const;
- ProtocolVersion& operator=(ProtocolVersion p);
+ QPID_COMMON_EXTERN ProtocolVersion& operator=(ProtocolVersion p);
- bool operator==(ProtocolVersion p) const;
- bool operator!=(ProtocolVersion p) const { return ! (*this == p); }
+ QPID_COMMON_EXTERN bool operator==(ProtocolVersion p) const;
+ QPID_COMMON_EXTERN bool operator!=(ProtocolVersion p) const { return ! (*this == p); }
};
} // namespace framing
diff --git a/qpid/cpp/src/qpid/framing/Proxy.h b/qpid/cpp/src/qpid/framing/Proxy.h
index 5e2c886af2..a9a6ce981e 100644
--- a/qpid/cpp/src/qpid/framing/Proxy.h
+++ b/qpid/cpp/src/qpid/framing/Proxy.h
@@ -22,6 +22,8 @@
#include "FrameHandler.h"
#include "ProtocolVersion.h"
+#include "qpid/CommonImportExport.h"
+
namespace qpid {
namespace framing {
@@ -37,19 +39,19 @@ class Proxy
{
Proxy& proxy;
public:
- ScopedSync(Proxy& p);
- ~ScopedSync();
+ QPID_COMMON_EXTERN ScopedSync(Proxy& p);
+ QPID_COMMON_EXTERN ~ScopedSync();
};
- Proxy(FrameHandler& h);
- virtual ~Proxy();
+ QPID_COMMON_EXTERN Proxy(FrameHandler& h);
+ QPID_COMMON_EXTERN virtual ~Proxy();
- void send(const AMQBody&);
+ QPID_COMMON_EXTERN void send(const AMQBody&);
- ProtocolVersion getVersion() const;
+ QPID_COMMON_EXTERN ProtocolVersion getVersion() const;
- FrameHandler& getHandler();
- void setHandler(FrameHandler&);
+ QPID_COMMON_EXTERN FrameHandler& getHandler();
+ QPID_COMMON_EXTERN void setHandler(FrameHandler&);
private:
FrameHandler* out;
bool sync;
diff --git a/qpid/cpp/src/qpid/framing/SendContent.h b/qpid/cpp/src/qpid/framing/SendContent.h
index dcd5202b3e..745c948c9e 100644
--- a/qpid/cpp/src/qpid/framing/SendContent.h
+++ b/qpid/cpp/src/qpid/framing/SendContent.h
@@ -22,6 +22,7 @@
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/FrameHandler.h"
+#include "qpid/CommonImportExport.h"
#ifndef _SendContent_
#define _SendContent_
@@ -44,8 +45,8 @@ class SendContent
void sendFragment(const AMQContentBody& body, uint32_t offset, uint16_t size, bool first, bool last) const;
void setFlags(AMQFrame& f, bool first, bool last) const;
public:
- SendContent(FrameHandler& _handler, uint16_t _maxFrameSize, uint frameCount);
- void operator()(const AMQFrame& f);
+ QPID_COMMON_EXTERN SendContent(FrameHandler& _handler, uint16_t _maxFrameSize, uint frameCount);
+ QPID_COMMON_EXTERN void operator()(const AMQFrame& f);
};
}
diff --git a/qpid/cpp/src/qpid/framing/SequenceNumber.h b/qpid/cpp/src/qpid/framing/SequenceNumber.h
index 930e146863..3b18ce1360 100644
--- a/qpid/cpp/src/qpid/framing/SequenceNumber.h
+++ b/qpid/cpp/src/qpid/framing/SequenceNumber.h
@@ -23,6 +23,7 @@
#include "amqp_types.h"
#include <iosfwd>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -37,22 +38,22 @@ class SequenceNumber
int32_t value;
public:
- SequenceNumber();
- SequenceNumber(uint32_t v);
+ QPID_COMMON_EXTERN SequenceNumber();
+ QPID_COMMON_EXTERN SequenceNumber(uint32_t v);
- SequenceNumber& operator++();//prefix ++
- const SequenceNumber operator++(int);//postfix ++
- SequenceNumber& operator--();//prefix ++
- bool operator==(const SequenceNumber& other) const;
- bool operator!=(const SequenceNumber& other) const;
- bool operator<(const SequenceNumber& other) const;
- bool operator>(const SequenceNumber& other) const;
- bool operator<=(const SequenceNumber& other) const;
- bool operator>=(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN SequenceNumber& operator++();//prefix ++
+ QPID_COMMON_EXTERN const SequenceNumber operator++(int);//postfix ++
+ QPID_COMMON_EXTERN SequenceNumber& operator--();//prefix ++
+ QPID_COMMON_EXTERN bool operator==(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator!=(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator<(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator>(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator<=(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator>=(const SequenceNumber& other) const;
uint32_t getValue() const { return (uint32_t) value; }
operator uint32_t() const { return (uint32_t) value; }
- friend int32_t operator-(const SequenceNumber& a, const SequenceNumber& b);
+ QPID_COMMON_EXTERN friend int32_t operator-(const SequenceNumber& a, const SequenceNumber& b);
void encode(Buffer& buffer) const;
void decode(Buffer& buffer);
@@ -67,7 +68,7 @@ struct Window
SequenceNumber lwm;
};
-std::ostream& operator<<(std::ostream& o, const SequenceNumber& n);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& o, const SequenceNumber& n);
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/SequenceNumberSet.h b/qpid/cpp/src/qpid/framing/SequenceNumberSet.h
index 666307f9d9..8e023ba535 100644
--- a/qpid/cpp/src/qpid/framing/SequenceNumberSet.h
+++ b/qpid/cpp/src/qpid/framing/SequenceNumberSet.h
@@ -27,6 +27,7 @@
#include "SequenceNumber.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/InlineVector.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -41,8 +42,8 @@ public:
void encode(Buffer& buffer) const;
void decode(Buffer& buffer);
uint32_t encodedSize() const;
- SequenceNumberSet condense() const;
- void addRange(const SequenceNumber& start, const SequenceNumber& end);
+ QPID_COMMON_EXTERN SequenceNumberSet condense() const;
+ QPID_COMMON_EXTERN void addRange(const SequenceNumber& start, const SequenceNumber& end);
template <class T>
void processRanges(T& t) const
@@ -58,7 +59,7 @@ public:
}
}
- friend std::ostream& operator<<(std::ostream&, const SequenceNumberSet&);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceNumberSet&);
};
diff --git a/qpid/cpp/src/qpid/framing/SequenceSet.h b/qpid/cpp/src/qpid/framing/SequenceSet.h
index 57b9c2c8e1..a5ee6cd649 100644
--- a/qpid/cpp/src/qpid/framing/SequenceSet.h
+++ b/qpid/cpp/src/qpid/framing/SequenceSet.h
@@ -23,6 +23,7 @@
#include "SequenceNumber.h"
#include "qpid/RangeSet.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -41,13 +42,13 @@ class SequenceSet : public RangeSet<SequenceNumber> {
void decode(Buffer& buffer);
uint32_t encodedSize() const;
- bool contains(const SequenceNumber& s) const;
- void add(const SequenceNumber& s);
- void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
- void add(const SequenceSet& set);
- void remove(const SequenceNumber& s);
- void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
- void remove(const SequenceSet& set);
+ QPID_COMMON_EXTERN bool contains(const SequenceNumber& s) const;
+ QPID_COMMON_EXTERN void add(const SequenceNumber& s);
+ QPID_COMMON_EXTERN void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
+ QPID_COMMON_EXTERN void add(const SequenceSet& set);
+ QPID_COMMON_EXTERN void remove(const SequenceNumber& s);
+ QPID_COMMON_EXTERN void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
+ QPID_COMMON_EXTERN void remove(const SequenceSet& set);
template <class T> void for_each(T& t) const {
for (RangeIterator i = rangesBegin(); i != rangesEnd(); i++)
@@ -59,7 +60,7 @@ class SequenceSet : public RangeSet<SequenceNumber> {
t(i->first(), i->last());
}
- friend std::ostream& operator<<(std::ostream&, const SequenceSet&);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceSet&);
};
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/StructHelper.h b/qpid/cpp/src/qpid/framing/StructHelper.h
index e3dce4f5ec..89f556ad3c 100644
--- a/qpid/cpp/src/qpid/framing/StructHelper.h
+++ b/qpid/cpp/src/qpid/framing/StructHelper.h
@@ -22,6 +22,7 @@
#define _StructHelper_
#include "qpid/Exception.h"
+#include "qpid/CommonImportExport.h"
#include "Buffer.h"
#include <stdlib.h> // For alloca
diff --git a/qpid/cpp/src/qpid/framing/TransferContent.h b/qpid/cpp/src/qpid/framing/TransferContent.h
index e3f6666fa4..236a0b6d93 100644
--- a/qpid/cpp/src/qpid/framing/TransferContent.h
+++ b/qpid/cpp/src/qpid/framing/TransferContent.h
@@ -26,6 +26,7 @@
#include "qpid/Exception.h"
#include "qpid/framing/MessageProperties.h"
#include "qpid/framing/DeliveryProperties.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -36,27 +37,27 @@ class TransferContent : public MethodContent
AMQHeaderBody header;
std::string data;
public:
- TransferContent(const std::string& data = std::string(), const std::string& key=std::string());
+ QPID_COMMON_EXTERN TransferContent(const std::string& data = std::string(), const std::string& key=std::string());
///@internal
- AMQHeaderBody getHeader() const;
+ QPID_COMMON_EXTERN AMQHeaderBody getHeader() const;
- void setData(const std::string&);
- const std::string& getData() const;
- std::string& getData();
+ QPID_COMMON_EXTERN void setData(const std::string&);
+ QPID_COMMON_EXTERN const std::string& getData() const;
+ QPID_COMMON_EXTERN std::string& getData();
- void appendData(const std::string&);
+ QPID_COMMON_EXTERN void appendData(const std::string&);
- bool hasMessageProperties() const;
- MessageProperties& getMessageProperties();
- const MessageProperties& getMessageProperties() const;
+ QPID_COMMON_EXTERN bool hasMessageProperties() const;
+ QPID_COMMON_EXTERN MessageProperties& getMessageProperties();
+ QPID_COMMON_EXTERN const MessageProperties& getMessageProperties() const;
- bool hasDeliveryProperties() const;
- DeliveryProperties& getDeliveryProperties();
- const DeliveryProperties& getDeliveryProperties() const;
+ QPID_COMMON_EXTERN bool hasDeliveryProperties() const;
+ QPID_COMMON_EXTERN DeliveryProperties& getDeliveryProperties();
+ QPID_COMMON_EXTERN const DeliveryProperties& getDeliveryProperties() const;
///@internal
- void populate(const FrameSet& frameset);
+ QPID_COMMON_EXTERN void populate(const FrameSet& frameset);
};
}}
diff --git a/qpid/cpp/src/qpid/framing/Uuid.h b/qpid/cpp/src/qpid/framing/Uuid.h
index 2fcbb5a261..fe0c32dc0b 100644
--- a/qpid/cpp/src/qpid/framing/Uuid.h
+++ b/qpid/cpp/src/qpid/framing/Uuid.h
@@ -19,7 +19,9 @@
*
*/
+#include "qpid/CommonImportExport.h"
#include "qpid/sys/uuid.h"
+#include "qpid/sys/IntegerTypes.h"
#include <boost/array.hpp>
@@ -63,12 +65,12 @@ struct Uuid : public boost::array<uint8_t, 16> {
// Default op= and copy ctor are fine.
// boost::array gives us ==, < etc.
- void encode(framing::Buffer& buf) const;
- void decode(framing::Buffer& buf);
- uint32_t encodedSize() const { return size(); }
+ QPID_COMMON_EXTERN void encode(framing::Buffer& buf) const;
+ QPID_COMMON_EXTERN void decode(framing::Buffer& buf);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const { return size(); }
/** String value in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */
- std::string str() const;
+ QPID_COMMON_EXTERN std::string str() const;
template <class S> void serialize(S& s) {
s.raw(begin(), size());
@@ -76,10 +78,10 @@ struct Uuid : public boost::array<uint8_t, 16> {
};
/** Print in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */
-std::ostream& operator<<(std::ostream&, Uuid);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, Uuid);
/** Read from format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */
-std::istream& operator>>(std::istream&, Uuid&);
+QPID_COMMON_EXTERN std::istream& operator>>(std::istream&, Uuid&);
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/log/Logger.h b/qpid/cpp/src/qpid/log/Logger.h
index 539c1c851b..0cbd7685d6 100644
--- a/qpid/cpp/src/qpid/log/Logger.h
+++ b/qpid/cpp/src/qpid/log/Logger.h
@@ -18,6 +18,7 @@
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/noncopyable.hpp>
#include <set>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace log {
@@ -48,48 +49,48 @@ class Logger : private boost::noncopyable {
*/
class Output {
public:
- Output();
- virtual ~Output();
+ QPID_COMMON_EXTERN Output();
+ QPID_COMMON_EXTERN virtual ~Output();
/** Receives the statemnt of origin and formatted message to log. */
virtual void log(const Statement&, const std::string&) =0;
};
- static Logger& instance();
+ QPID_COMMON_EXTERN static Logger& instance();
- Logger();
- ~Logger();
+ QPID_COMMON_EXTERN Logger();
+ QPID_COMMON_EXTERN ~Logger();
/** Select the messages to be logged. */
- void select(const Selector& s);
+ QPID_COMMON_EXTERN void select(const Selector& s);
/** Set the formatting flags, bitwise OR of FormatFlag values. */
- void format(int formatFlags);
+ QPID_COMMON_EXTERN void format(int formatFlags);
/** Set format flags from options object.
*@returns computed flags.
*/
- int format(const Options&);
+ QPID_COMMON_EXTERN int format(const Options&);
/** Configure logger from Options */
- void configure(const Options& o);
+ QPID_COMMON_EXTERN void configure(const Options& o);
/** Add a statement. */
- void add(Statement& s);
+ QPID_COMMON_EXTERN void add(Statement& s);
/** Log a message. */
- void log(const Statement&, const std::string&);
+ QPID_COMMON_EXTERN void log(const Statement&, const std::string&);
/** Add an output destination for messages */
- void output(std::auto_ptr<Output> out);
+ QPID_COMMON_EXTERN void output(std::auto_ptr<Output> out);
/** Set a prefix for all messages */
- void setPrefix(const std::string& prefix);
+ QPID_COMMON_EXTERN void setPrefix(const std::string& prefix);
/** Reset the logger. */
- void clear();
+ QPID_COMMON_EXTERN void clear();
/** Get the options used to configure the logger. */
- const Options& getOptions() const { return options; }
+ QPID_COMMON_EXTERN const Options& getOptions() const { return options; }
private:
diff --git a/qpid/cpp/src/qpid/log/Options.h b/qpid/cpp/src/qpid/log/Options.h
index 8a3c352d14..5e7bd433af 100644
--- a/qpid/cpp/src/qpid/log/Options.h
+++ b/qpid/cpp/src/qpid/log/Options.h
@@ -19,6 +19,7 @@
*
*/
#include "qpid/Options.h"
+#include "qpid/CommonImportExport.h"
#include "SinkOptions.h"
#include <iosfwd>
#include <memory>
@@ -29,11 +30,11 @@ namespace log {
/** Logging options for config parser. */
struct Options : public qpid::Options {
/** Pass argv[0] for use in syslog output */
- Options(const std::string& argv0_=std::string(),
+ QPID_COMMON_EXTERN Options(const std::string& argv0_=std::string(),
const std::string& name_="Logging options");
- Options(const Options &);
+ QPID_COMMON_EXTERN Options(const Options &);
- Options& operator=(const Options&);
+ QPID_COMMON_EXTERN Options& operator=(const Options&);
std::string argv0;
std::string name;
diff --git a/qpid/cpp/src/qpid/log/OstreamOutput.h b/qpid/cpp/src/qpid/log/OstreamOutput.h
index 8bbfc8c38b..8df38468ad 100644
--- a/qpid/cpp/src/qpid/log/OstreamOutput.h
+++ b/qpid/cpp/src/qpid/log/OstreamOutput.h
@@ -26,8 +26,8 @@ namespace log {
*/
class OstreamOutput : public qpid::log::Logger::Output {
public:
- OstreamOutput(std::ostream& o);
- OstreamOutput(const std::string& file);
+ QPID_COMMON_EXTERN OstreamOutput(std::ostream& o);
+ QPID_COMMON_EXTERN OstreamOutput(const std::string& file);
virtual void log(const Statement&, const std::string& m);
diff --git a/qpid/cpp/src/qpid/log/Selector.cpp b/qpid/cpp/src/qpid/log/Selector.cpp
index 4d1c5b6e0c..0a629edc3e 100644
--- a/qpid/cpp/src/qpid/log/Selector.cpp
+++ b/qpid/cpp/src/qpid/log/Selector.cpp
@@ -20,6 +20,7 @@
#include "Options.h"
#include <boost/bind.hpp>
#include <algorithm>
+#include <string.h>
namespace qpid {
namespace log {
diff --git a/qpid/cpp/src/qpid/log/Selector.h b/qpid/cpp/src/qpid/log/Selector.h
index 705abfeb5d..070ffd4abf 100644
--- a/qpid/cpp/src/qpid/log/Selector.h
+++ b/qpid/cpp/src/qpid/log/Selector.h
@@ -20,6 +20,7 @@
*/
#include "Statement.h"
+#include "qpid/CommonImportExport.h"
#include <vector>
namespace qpid {
@@ -37,7 +38,7 @@ class Selector {
Selector() {}
/** Set selector from Options */
- Selector(const Options&);
+ QPID_COMMON_EXTERN Selector(const Options&);
/** Equavlient to: Selector s; s.enable(l, s) */
Selector(Level l, const std::string& s=std::string()) {
@@ -54,10 +55,10 @@ class Selector {
}
/** Enable based on a 'level[+]:file' string */
- void enable(const std::string& enableStr);
+ QPID_COMMON_EXTERN void enable(const std::string& enableStr);
/** True if level is enabled for file. */
- bool isEnabled(Level level, const char* function);
+ QPID_COMMON_EXTERN bool isEnabled(Level level, const char* function);
private:
std::vector<std::string> substrings[LevelTraits::COUNT];
diff --git a/qpid/cpp/src/qpid/log/Statement.h b/qpid/cpp/src/qpid/log/Statement.h
index 3c67b04b20..445f635cdd 100644
--- a/qpid/cpp/src/qpid/log/Statement.h
+++ b/qpid/cpp/src/qpid/log/Statement.h
@@ -20,7 +20,7 @@
*/
#include "qpid/Msg.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/current_function.hpp>
namespace qpid {
@@ -63,10 +63,10 @@ struct Statement {
const char* function;
Level level;
- void log(const std::string& message);
+ QPID_COMMON_EXTERN void log(const std::string& message);
struct Initializer {
- Initializer(Statement& s);
+ QPID_COMMON_EXTERN Initializer(Statement& s);
Statement& statement;
};
};
diff --git a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
index 9d51358e2e..985cb32c5c 100644
--- a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
+++ b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
@@ -42,10 +42,14 @@ public:
struct NameValue { const char* name; int value; };
NameValue nameValue[] = {
{ "AUTH", LOG_AUTH },
+#ifdef HAVE_LOG_AUTHPRIV
{ "AUTHPRIV", LOG_AUTHPRIV },
+#endif
{ "CRON", LOG_CRON },
{ "DAEMON", LOG_DAEMON },
+#ifdef HAVE_LOG_FTP
{ "FTP", LOG_FTP },
+#endif
{ "KERN", LOG_KERN },
{ "LOCAL0", LOG_LOCAL0 },
{ "LOCAL1", LOG_LOCAL1 },
@@ -72,7 +76,7 @@ public:
int value(const string& name) const {
string key(name);
- transform(key.begin(), key.end(), key.begin(), ::toupper);
+ std::transform(key.begin(), key.end(), key.begin(), ::toupper);
ByName::const_iterator i = byName.find(key);
if (i == byName.end())
throw Exception("Not a valid syslog facility: " + name);
diff --git a/qpid/cpp/src/qpid/log/windows/SinkOptions.h b/qpid/cpp/src/qpid/log/windows/SinkOptions.h
index d14e9352be..605822fd46 100644
--- a/qpid/cpp/src/qpid/log/windows/SinkOptions.h
+++ b/qpid/cpp/src/qpid/log/windows/SinkOptions.h
@@ -27,20 +27,20 @@ namespace log {
namespace windows {
struct SinkOptions : public qpid::log::SinkOptions {
- SinkOptions(const std::string& argv0);
+ QPID_COMMON_EXTERN SinkOptions(const std::string& argv0);
virtual ~SinkOptions() {}
- virtual qpid::log::SinkOptions& operator=(const qpid::log::SinkOptions& rhs);
+ QPID_COMMON_EXTERN virtual qpid::log::SinkOptions& operator=(const qpid::log::SinkOptions& rhs);
// This allows the caller to indicate that there's no normal outputs
// available. For example, when running as a service. In these cases, the
// platform's "syslog"-type output should replace the default stderr
// unless some other sink has been selected.
- virtual void detached(void);
+ QPID_COMMON_EXTERN virtual void detached(void);
// The Logger acting on these options calls setup() to request any
// Sinks be set up and fed back to the logger.
- virtual void setup(qpid::log::Logger *logger);
+ QPID_COMMON_EXTERN virtual void setup(qpid::log::Logger *logger);
bool logToStderr;
bool logToStdout;
diff --git a/qpid/cpp/src/qpid/management/Manageable.h b/qpid/cpp/src/qpid/management/Manageable.h
index b4d80d8fad..ededa6141e 100644
--- a/qpid/cpp/src/qpid/management/Manageable.h
+++ b/qpid/cpp/src/qpid/management/Manageable.h
@@ -23,11 +23,12 @@
#include "ManagementObject.h"
#include "Args.h"
#include <string>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace management {
-class Manageable
+class QPID_COMMON_EXTERN Manageable
{
public:
diff --git a/qpid/cpp/src/qpid/management/ManagementBroker.cpp b/qpid/cpp/src/qpid/management/ManagementBroker.cpp
index 0f96e97fb0..19300ef1af 100644
--- a/qpid/cpp/src/qpid/management/ManagementBroker.cpp
+++ b/qpid/cpp/src/qpid/management/ManagementBroker.cpp
@@ -80,7 +80,7 @@ ManagementBroker::RemoteAgent::~RemoteAgent ()
}
ManagementBroker::ManagementBroker () :
- threadPoolSize(1), interval(10), broker(0)
+ threadPoolSize(1), interval(10), broker(0), startTime(uint64_t(Duration(now())))
{
nextObjectId = 1;
brokerBank = 1;
@@ -346,6 +346,9 @@ void ManagementBroker::periodicProcessing (void)
string routingKey;
list<pair<ObjectId, ManagementObject*> > deleteList;
+ uint64_t uptime = uint64_t(Duration(now())) - startTime;
+ static_cast<_qmf::Broker*>(broker->GetManagementObject())->set_uptime(uptime);
+
moveNewObjectsLH();
if (clientWasAdded) {
@@ -515,6 +518,7 @@ void ManagementBroker::handleMethodRequestLH (Buffer& inBuffer, string replyToKe
else
try {
outBuffer.record();
+ Mutex::ScopedUnlock u(userLock);
iter->second->doMethod(methodName, inBuffer, outBuffer);
} catch(exception& e) {
outBuffer.restore();
@@ -844,6 +848,9 @@ void ManagementBroker::handleGetQueryLH (Buffer& inBuffer, string replyToKey, ui
Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
@@ -865,6 +872,9 @@ void ManagementBroker::handleGetQueryLH (Buffer& inBuffer, string replyToKey, ui
Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
diff --git a/qpid/cpp/src/qpid/management/ManagementBroker.h b/qpid/cpp/src/qpid/management/ManagementBroker.h
index f65d6a345e..a57f73be15 100644
--- a/qpid/cpp/src/qpid/management/ManagementBroker.h
+++ b/qpid/cpp/src/qpid/management/ManagementBroker.h
@@ -182,6 +182,7 @@ private:
uint32_t nextRemoteBank;
uint32_t nextRequestSequence;
bool clientWasAdded;
+ const uint64_t startTime;
std::auto_ptr<IdAllocator> allocator;
diff --git a/qpid/cpp/src/qpid/management/ManagementObject.h b/qpid/cpp/src/qpid/management/ManagementObject.h
index fbdad347b8..498169318d 100644
--- a/qpid/cpp/src/qpid/management/ManagementObject.h
+++ b/qpid/cpp/src/qpid/management/ManagementObject.h
@@ -25,6 +25,7 @@
#include "qpid/sys/Time.h"
#include "qpid/sys/Mutex.h"
#include <qpid/framing/Buffer.h>
+#include "qpid/CommonImportExport.h"
#include <map>
namespace qpid {
@@ -41,7 +42,7 @@ private:
uint64_t first;
public:
AgentAttachment() : first(0) {}
- void setBanks(uint32_t broker, uint32_t bank);
+ QPID_COMMON_EXTERN void setBanks(uint32_t broker, uint32_t bank);
uint64_t getFirst() const { return first; }
};
@@ -53,17 +54,17 @@ protected:
uint64_t second;
void fromString(const std::string&);
public:
- ObjectId() : agent(0), first(0), second(0) {}
- ObjectId(framing::Buffer& buf) : agent(0) { decode(buf); }
- ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint32_t bank, uint64_t object);
- ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq, uint64_t object);
- ObjectId(std::istream&);
- ObjectId(const std::string&);
- bool operator==(const ObjectId &other) const;
- bool operator<(const ObjectId &other) const;
- void encode(framing::Buffer& buffer);
- void decode(framing::Buffer& buffer);
- friend std::ostream& operator<<(std::ostream&, const ObjectId&);
+ QPID_COMMON_EXTERN ObjectId() : agent(0), first(0), second(0) {}
+ QPID_COMMON_EXTERN ObjectId(framing::Buffer& buf) : agent(0) { decode(buf); }
+ QPID_COMMON_EXTERN ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint32_t bank, uint64_t object);
+ QPID_COMMON_EXTERN ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq, uint64_t object);
+ QPID_COMMON_EXTERN ObjectId(std::istream&);
+ QPID_COMMON_EXTERN ObjectId(const std::string&);
+ QPID_COMMON_EXTERN bool operator==(const ObjectId &other) const;
+ QPID_COMMON_EXTERN bool operator<(const ObjectId &other) const;
+ QPID_COMMON_EXTERN void encode(framing::Buffer& buffer);
+ QPID_COMMON_EXTERN void decode(framing::Buffer& buffer);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const ObjectId&);
};
class ManagementItem {
@@ -128,8 +129,8 @@ class ManagementObject : public ManagementItem
static int nextThreadIndex;
bool forcePublish;
- int getThreadIndex();
- void writeTimestamps(qpid::framing::Buffer& buf);
+ QPID_COMMON_EXTERN int getThreadIndex();
+ QPID_COMMON_EXTERN void writeTimestamps(qpid::framing::Buffer& buf);
public:
typedef void (*writeSchemaCall_t) (qpid::framing::Buffer&);
@@ -148,7 +149,7 @@ class ManagementObject : public ManagementItem
virtual void doMethod(std::string& methodName,
qpid::framing::Buffer& inBuf,
qpid::framing::Buffer& outBuf) = 0;
- virtual void setReference(ObjectId objectId);
+ QPID_COMMON_EXTERN virtual void setReference(ObjectId objectId);
virtual std::string& getClassName() const = 0;
virtual std::string& getPackageName() const = 0;
diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
index 2d8af3b052..60d5fffc0b 100644
--- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
+++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
@@ -21,6 +21,7 @@
#include "ReplicatingEventListener.h"
#include "constants.h"
#include "qpid/broker/Broker.h"
+#include "qpid/broker/DeliverableMessage.h"
#include "qpid/broker/QueueEvents.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/FrameHandler.h"
@@ -57,11 +58,12 @@ void ReplicatingEventListener::deliverDequeueMessage(const QueuedMessage& dequeu
{
FieldTable headers;
headers.setString(REPLICATION_TARGET_QUEUE, dequeued.queue->getName());
- headers.setInt(REPLICATION_EVENT_SEQNO, ++sequence);
headers.setInt(REPLICATION_EVENT_TYPE, DEQUEUE);
headers.setInt(DEQUEUED_MESSAGE_POSITION, dequeued.position);
boost::intrusive_ptr<Message> msg(createMessage(headers));
- queue->deliver(msg);
+ DeliveryProperties* props = msg->getFrames().getHeaders()->get<DeliveryProperties>(true);
+ props->setRoutingKey(dequeued.queue->getName());
+ route(msg);
}
void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueued)
@@ -69,11 +71,27 @@ void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueu
boost::intrusive_ptr<Message> msg(cloneMessage(*(enqueued.queue), enqueued.payload));
FieldTable& headers = msg->getProperties<MessageProperties>()->getApplicationHeaders();
headers.setString(REPLICATION_TARGET_QUEUE, enqueued.queue->getName());
- headers.setInt(REPLICATION_EVENT_SEQNO, ++sequence);
headers.setInt(REPLICATION_EVENT_TYPE, ENQUEUE);
- queue->deliver(msg);
+ route(msg);
}
+void ReplicatingEventListener::route(boost::intrusive_ptr<qpid::broker::Message> msg)
+{
+ try {
+ if (exchange) {
+ DeliverableMessage deliverable(msg);
+ exchange->route(deliverable, msg->getRoutingKey(), msg->getApplicationHeaders());
+ } else if (queue) {
+ queue->deliver(msg);
+ } else {
+ QPID_LOG(error, "Cannot route replication event, neither replication queue nor exchange configured");
+ }
+ } catch (const std::exception& e) {
+ QPID_LOG(error, "Error enqueing replication event: " << e.what());
+ }
+}
+
+
boost::intrusive_ptr<Message> ReplicatingEventListener::createMessage(const FieldTable& headers)
{
boost::intrusive_ptr<Message> msg(new Message());
@@ -129,30 +147,49 @@ Options* ReplicatingEventListener::getOptions()
void ReplicatingEventListener::initialize(Plugin::Target& target)
{
- Broker* broker = dynamic_cast<broker::Broker*>(&target);
- if (broker && !options.queue.empty()) {
- if (options.createQueue) {
- queue = broker->getQueues().declare(options.queue).first;
- } else {
- queue = broker->getQueues().find(options.queue);
- }
- if (queue) {
- QueueEvents::EventListener callback = boost::bind(&ReplicatingEventListener::handle, this, _1);
- broker->getQueueEvents().registerListener(options.name, callback);
- QPID_LOG(info, "Registered replicating queue event listener");
- } else {
- QPID_LOG(error, "Replication queue named '" << options.queue << "' does not exist; replication plugin disabled.");
- }
- }
+ Broker* broker = dynamic_cast<broker::Broker*>(&target);
+ if (broker) {
+ broker->addFinalizer(boost::bind(&ReplicatingEventListener::shutdown, this));
+ if (!options.exchange.empty()) {
+ if (!options.queue.empty()) {
+ QPID_LOG(warning, "Replication queue option ignored as replication exchange has been specified");
+ }
+ try {
+ exchange = broker->getExchanges().declare(options.exchange, options.exchangeType).first;
+ } catch (const UnknownExchangeTypeException&) {
+ QPID_LOG(error, "Replication disabled due to invalid type: " << options.exchangeType);
+ }
+ } else if (!options.queue.empty()) {
+ if (options.createQueue) {
+ queue = broker->getQueues().declare(options.queue).first;
+ } else {
+ queue = broker->getQueues().find(options.queue);
+ }
+ if (queue) {
+ queue->insertSequenceNumbers(REPLICATION_EVENT_SEQNO);
+ } else {
+ QPID_LOG(error, "Replication queue named '" << options.queue << "' does not exist; replication plugin disabled.");
+ }
+ }
+ if (queue || exchange) {
+ QueueEvents::EventListener callback = boost::bind(&ReplicatingEventListener::handle, this, _1);
+ broker->getQueueEvents().registerListener(options.name, callback);
+ QPID_LOG(info, "Registered replicating queue event listener");
+ }
+ }
}
void ReplicatingEventListener::earlyInitialize(Target&) {}
+void ReplicatingEventListener::shutdown() { queue.reset(); exchange.reset(); }
ReplicatingEventListener::PluginOptions::PluginOptions() : Options("Queue Replication Options"),
- name("replicator"),
+ exchangeType("direct"),
+ name("replicator"),
createQueue(false)
{
addOptions()
+ ("replication-exchange-name", optValue(exchange, "EXCHANGE"), "Exchange to which events for other queues are routed")
+ ("replication-exchange-type", optValue(exchangeType, "direct|topic etc"), "Type of exchange to use")
("replication-queue", optValue(queue, "QUEUE"), "Queue on which events for other queues are recorded")
("replication-listener-name", optValue(name, "NAME"), "name by which to register the replicating event listener")
("create-replication-queue", optValue(createQueue), "if set, the replication will be created if it does not exist");
diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h
index 7616c7ac8a..74418d00e6 100644
--- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h
+++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h
@@ -24,6 +24,7 @@
#include "qpid/Plugin.h"
#include "qpid/Options.h"
+#include "qpid/broker/Exchange.h"
#include "qpid/broker/Message.h"
#include "qpid/broker/Queue.h"
#include "qpid/broker/QueueEvents.h"
@@ -50,6 +51,8 @@ class ReplicatingEventListener : public Plugin
struct PluginOptions : public Options
{
std::string queue;
+ std::string exchange;
+ std::string exchangeType;
std::string name;
bool createQueue;
@@ -58,10 +61,12 @@ class ReplicatingEventListener : public Plugin
PluginOptions options;
qpid::broker::Queue::shared_ptr queue;
- qpid::framing::SequenceNumber sequence;
+ qpid::broker::Exchange::shared_ptr exchange;
void deliverDequeueMessage(const qpid::broker::QueuedMessage& enqueued);
void deliverEnqueueMessage(const qpid::broker::QueuedMessage& enqueued);
+ void route(boost::intrusive_ptr<qpid::broker::Message>);
+ void shutdown();
boost::intrusive_ptr<qpid::broker::Message> createMessage(const qpid::framing::FieldTable& headers);
boost::intrusive_ptr<qpid::broker::Message> cloneMessage(qpid::broker::Queue& queue,
diff --git a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
index 639cfb5d2e..29cdf21bc6 100644
--- a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
+++ b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
@@ -34,11 +34,13 @@ using namespace qpid::broker;
using namespace qpid::framing;
using namespace qpid::replication::constants;
+const std::string SEQUENCE_VALUE("qpid.replication-event.sequence");
ReplicationExchange::ReplicationExchange(const std::string& name, bool durable,
const FieldTable& args,
QueueRegistry& qr,
Manageable* parent)
- : Exchange(name, durable, args, parent), queues(qr), init(false) {}
+ : Exchange(name, durable, args, parent), queues(qr), sequence(args.getAsInt64(SEQUENCE_VALUE)), init(false)
+ {}
std::string ReplicationExchange::getType() const { return typeName; }
@@ -68,31 +70,39 @@ void ReplicationExchange::handleEnqueueEvent(const FieldTable* args, Deliverable
{
std::string queueName = args->getAsString(REPLICATION_TARGET_QUEUE);
Queue::shared_ptr queue = queues.find(queueName);
- FieldTable& headers = msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders();
- headers.erase(REPLICATION_TARGET_QUEUE);
- headers.erase(REPLICATION_EVENT_SEQNO);
- headers.erase(REPLICATION_EVENT_TYPE);
- msg.deliverTo(queue);
- QPID_LOG(debug, "Enqueued replicated message onto " << queue);
+ if (queue) {
+ FieldTable& headers = msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders();
+ headers.erase(REPLICATION_TARGET_QUEUE);
+ headers.erase(REPLICATION_EVENT_SEQNO);
+ headers.erase(REPLICATION_EVENT_TYPE);
+ msg.deliverTo(queue);
+ QPID_LOG(debug, "Enqueued replicated message onto " << queueName);
+ } else {
+ QPID_LOG(error, "Cannot enqueue replicated message. Queue " << queueName << " does not exist");
+ }
}
void ReplicationExchange::handleDequeueEvent(const FieldTable* args)
{
std::string queueName = args->getAsString(REPLICATION_TARGET_QUEUE);
Queue::shared_ptr queue = queues.find(queueName);
- SequenceNumber position(args->getAsInt(DEQUEUED_MESSAGE_POSITION));
-
- QueuedMessage dequeued;
- if (queue->acquireMessageAt(position, dequeued)) {
- queue->dequeue(0, dequeued);
- QPID_LOG(debug, "Processed replicated 'dequeue' event from " << queueName << " at position " << position);
+ if (queue) {
+ SequenceNumber position(args->getAsInt(DEQUEUED_MESSAGE_POSITION));
+ QueuedMessage dequeued;
+ if (queue->acquireMessageAt(position, dequeued)) {
+ queue->dequeue(0, dequeued);
+ QPID_LOG(debug, "Processed replicated 'dequeue' event from " << queueName << " at position " << position);
+ } else {
+ QPID_LOG(warning, "Could not acquire message " << position << " from " << queueName);
+ }
} else {
- QPID_LOG(warning, "Could not acquire message " << position << " from " << queueName);
+ QPID_LOG(error, "Cannot process replicated 'dequeue' event. Queue " << queueName << " does not exist");
}
}
bool ReplicationExchange::isDuplicate(const FieldTable* args)
{
+ if (!args->get(REPLICATION_EVENT_SEQNO)) return false;
SequenceNumber seqno(args->getAsInt(REPLICATION_EVENT_SEQNO));
if (!init) {
init = true;
@@ -128,6 +138,13 @@ bool ReplicationExchange::isBound(Queue::shared_ptr /*queue*/, const string* con
const std::string ReplicationExchange::typeName("replication");
+void ReplicationExchange::encode(Buffer& buffer) const
+{
+ args.setInt64(std::string(SEQUENCE_VALUE), sequence);
+ Exchange::encode(buffer);
+}
+
+
struct ReplicationExchangePlugin : Plugin
{
Broker* broker;
diff --git a/qpid/cpp/src/qpid/replication/ReplicationExchange.h b/qpid/cpp/src/qpid/replication/ReplicationExchange.h
index 897e4a954e..4cc45ed5f5 100644
--- a/qpid/cpp/src/qpid/replication/ReplicationExchange.h
+++ b/qpid/cpp/src/qpid/replication/ReplicationExchange.h
@@ -22,6 +22,7 @@
*
*/
#include "qpid/broker/Exchange.h"
+#include "qpid/framing/Buffer.h"
#include "qpid/framing/SequenceNumber.h"
namespace qpid {
@@ -58,6 +59,7 @@ class ReplicationExchange : public qpid::broker::Exchange
bool isDuplicate(const qpid::framing::FieldTable* args);
void handleEnqueueEvent(const qpid::framing::FieldTable* args, qpid::broker::Deliverable& msg);
void handleDequeueEvent(const qpid::framing::FieldTable* args);
+ void encode(framing::Buffer& buffer) const;
};
}} // namespace qpid::replication
diff --git a/qpid/cpp/src/qpid/sys/AggregateOutput.h b/qpid/cpp/src/qpid/sys/AggregateOutput.h
index 1cda4456b4..fcd0d4c2f7 100644
--- a/qpid/cpp/src/qpid/sys/AggregateOutput.h
+++ b/qpid/cpp/src/qpid/sys/AggregateOutput.h
@@ -24,6 +24,7 @@
#include "Mutex.h"
#include "OutputControl.h"
#include "OutputTask.h"
+#include "qpid/CommonImportExport.h"
#include <algorithm>
#include <vector>
@@ -42,15 +43,15 @@ namespace sys {
public:
AggregateOutput(OutputControl& c) : next(0), control(c) {};
//this may be called on any thread
- void activateOutput();
- void giveReadCredit(int32_t);
+ QPID_COMMON_EXTERN void activateOutput();
+ QPID_COMMON_EXTERN void giveReadCredit(int32_t);
//all the following will be called on the same thread
- bool doOutput();
- bool hasOutput();
- void addOutputTask(OutputTask* t);
- void removeOutputTask(OutputTask* t);
- void removeAll();
+ QPID_COMMON_EXTERN bool doOutput();
+ QPID_COMMON_EXTERN bool hasOutput();
+ QPID_COMMON_EXTERN void addOutputTask(OutputTask* t);
+ QPID_COMMON_EXTERN void removeOutputTask(OutputTask* t);
+ QPID_COMMON_EXTERN void removeAll();
/** Apply f to each OutputTask* in the tasks list */
template <class F> void eachOutput(F f) {
diff --git a/qpid/cpp/src/qpid/sys/AsynchIO.h b/qpid/cpp/src/qpid/sys/AsynchIO.h
index ffd4436c2a..fb02183359 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIO.h
+++ b/qpid/cpp/src/qpid/sys/AsynchIO.h
@@ -22,7 +22,7 @@
*/
#include "qpid/sys/IntegerTypes.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
@@ -45,9 +45,9 @@ private:
AsynchAcceptorPrivate* impl;
public:
- AsynchAcceptor(const Socket& s, Callback callback);
- ~AsynchAcceptor();
- void start(boost::shared_ptr<Poller> poller);
+ QPID_COMMON_EXTERN AsynchAcceptor(const Socket& s, Callback callback);
+ QPID_COMMON_EXTERN ~AsynchAcceptor();
+ QPID_COMMON_EXTERN void start(boost::shared_ptr<Poller> poller);
};
/*
@@ -65,7 +65,7 @@ public:
// create a correctly typed object. The platform code also manages
// deletes. To correctly manage heaps when needed, the allocate and
// delete should both be done from the same class/library.
- static AsynchConnector* create(const Socket& s,
+ QPID_COMMON_EXTERN static AsynchConnector* create(const Socket& s,
boost::shared_ptr<Poller> poller,
std::string hostname,
uint16_t port,
@@ -121,7 +121,7 @@ public:
// create a correctly typed object. The platform code also manages
// deletes. To correctly manage heaps when needed, the allocate and
// delete should both be done from the same class/library.
- static AsynchIO* create(const Socket& s,
+ QPID_COMMON_EXTERN static AsynchIO* create(const Socket& s,
ReadCallback rCb,
EofCallback eofCb,
DisconnectCallback disCb,
diff --git a/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp b/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
index 3bc05e4bf9..6b7e7b5145 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
+++ b/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
@@ -84,10 +84,11 @@ void AsynchIOHandler::giveReadCredit(int32_t credit) {
// Check whether we started in the don't about credit state
if (readCredit.boolCompareAndSwap(InfiniteCredit, credit))
return;
- else if (readCredit.fetchAndAdd(credit) != 0)
- return;
- // Lock and retest credit to make sure we don't race with decreasing credit
+ // TODO In theory should be able to use an atomic operation before taking the lock
+ // but in practice there seems to be an unexplained race in that case
ScopedLock<Mutex> l(creditLock);
+ if (readCredit.fetchAndAdd(credit) != 0)
+ return;
assert(readCredit.get() >= 0);
if (readCredit.get() != 0)
aio->startReading();
@@ -141,9 +142,10 @@ bool AsynchIOHandler::readbuff(AsynchIO& , AsynchIO::BufferBase* buff) {
}
// Check here for read credit
if (readCredit.get() != InfiniteCredit) {
+ // TODO In theory should be able to use an atomic operation before taking the lock
+ // but in practice there seems to be an unexplained race in that case
+ ScopedLock<Mutex> l(creditLock);
if (--readCredit == 0) {
- // Lock and retest credit to make sure we don't race with increasing credit
- ScopedLock<Mutex> l(creditLock);
assert(readCredit.get() >= 0);
if (readCredit.get() == 0) {
aio->stopReading();
diff --git a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
index fa020fbce4..9f1d043b62 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
+++ b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
@@ -25,6 +25,7 @@
#include "ConnectionCodec.h"
#include "AtomicValue.h"
#include "Mutex.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -52,26 +53,26 @@ class AsynchIOHandler : public OutputControl {
void write(const framing::ProtocolInitiation&);
public:
- AsynchIOHandler(std::string id, ConnectionCodec::Factory* f);
- ~AsynchIOHandler();
- void init(AsynchIO* a, int numBuffs);
+ QPID_COMMON_EXTERN AsynchIOHandler(std::string id, ConnectionCodec::Factory* f);
+ QPID_COMMON_EXTERN ~AsynchIOHandler();
+ QPID_COMMON_EXTERN void init(AsynchIO* a, int numBuffs);
- void setClient() { isClient = true; }
+ QPID_COMMON_EXTERN void setClient() { isClient = true; }
// Output side
- void close();
- void activateOutput();
- void giveReadCredit(int32_t credit);
+ QPID_COMMON_EXTERN void close();
+ QPID_COMMON_EXTERN void activateOutput();
+ QPID_COMMON_EXTERN void giveReadCredit(int32_t credit);
// Input side
- bool readbuff(AsynchIO& aio, AsynchIOBufferBase* buff);
- void eof(AsynchIO& aio);
- void disconnect(AsynchIO& aio);
+ QPID_COMMON_EXTERN bool readbuff(AsynchIO& aio, AsynchIOBufferBase* buff);
+ QPID_COMMON_EXTERN void eof(AsynchIO& aio);
+ QPID_COMMON_EXTERN void disconnect(AsynchIO& aio);
// Notifications
- void nobuffs(AsynchIO& aio);
- void idle(AsynchIO& aio);
- void closedSocket(AsynchIO& aio, const Socket& s);
+ QPID_COMMON_EXTERN void nobuffs(AsynchIO& aio);
+ QPID_COMMON_EXTERN void idle(AsynchIO& aio);
+ QPID_COMMON_EXTERN void closedSocket(AsynchIO& aio, const Socket& s);
};
}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/Codec.h b/qpid/cpp/src/qpid/sys/Codec.h
index f9645f554e..ace721fbcc 100644
--- a/qpid/cpp/src/qpid/sys/Codec.h
+++ b/qpid/cpp/src/qpid/sys/Codec.h
@@ -38,11 +38,11 @@ class Codec
* @return may be less than size if there was incomplete
* data at the end of the buffer.
*/
- virtual size_t decode(const char* buffer, size_t size) = 0;
+ virtual std::size_t decode(const char* buffer, std::size_t size) = 0;
/** Encode into buffer, return number of bytes encoded */
- virtual size_t encode(const char* buffer, size_t size) = 0;
+ virtual std::size_t encode(const char* buffer, std::size_t size) = 0;
/** Return true if we have data to encode */
virtual bool canEncode() = 0;
diff --git a/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h b/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
index df6de89982..32809d86a1 100644
--- a/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
+++ b/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
@@ -30,7 +30,7 @@ namespace sys {
/**
* A ConnectionOutputHandler that delegates to another
* ConnectionOutputHandler. Allows the "real" ConnectionOutputHandler
- * to be changed modified without updating all the pointers/references
+ * to be changed without updating all the pointers/references
* using the ConnectionOutputHandlerPtr
*/
class ConnectionOutputHandlerPtr : public ConnectionOutputHandler
diff --git a/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h b/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h
index a09ee9d441..577a475afd 100644
--- a/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h
+++ b/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h
@@ -80,7 +80,7 @@ public:
bool add_unless(T& t, F f)
{
Mutex::ScopedLock l(lock);
- if (array && find_if(array->begin(), array->end(), f) != array->end()) {
+ if (array && std::find_if(array->begin(), array->end(), f) != array->end()) {
return false;
} else {
ArrayPtr copy(array ? new std::vector<T>(*array) : new std::vector<T>());
diff --git a/qpid/cpp/src/qpid/sys/DispatchHandle.cpp b/qpid/cpp/src/qpid/sys/DispatchHandle.cpp
index cbdee7eda6..cd7dec7fa6 100644
--- a/qpid/cpp/src/qpid/sys/DispatchHandle.cpp
+++ b/qpid/cpp/src/qpid/sys/DispatchHandle.cpp
@@ -21,6 +21,8 @@
#include "DispatchHandle.h"
+#include <algorithm>
+
#include <boost/cast.hpp>
#include <assert.h>
@@ -29,7 +31,6 @@ namespace qpid {
namespace sys {
DispatchHandle::~DispatchHandle() {
- stopWatch();
}
void DispatchHandle::startWatch(Poller::shared_ptr poller0) {
@@ -37,13 +38,21 @@ void DispatchHandle::startWatch(Poller::shared_ptr poller0) {
bool w = writableCallback;
ScopedLock<Mutex> lock(stateLock);
- assert(state == IDLE);
+ assert(state == IDLE || state == DELAYED_IDLE);
// If no callbacks set then do nothing (that is what we were asked to do!)
// TODO: Maybe this should be an assert instead
if (!r && !w) {
- state = INACTIVE;
- return;
+ switch (state) {
+ case IDLE:
+ state = INACTIVE;
+ return;
+ case DELAYED_IDLE:
+ state = DELAYED_INACTIVE;
+ return;
+ default:
+ assert(state == IDLE || state == DELAYED_IDLE);
+ }
}
Poller::Direction d = r ?
@@ -53,9 +62,20 @@ void DispatchHandle::startWatch(Poller::shared_ptr poller0) {
poller = poller0;
poller->addFd(*this, d);
- state = r ?
- (w ? ACTIVE_RW : ACTIVE_R) :
- ACTIVE_W;
+ switch (state) {
+ case IDLE:
+ state = r ?
+ (w ? ACTIVE_RW : ACTIVE_R) :
+ ACTIVE_W;
+ return;
+ case DELAYED_IDLE:
+ state = r ?
+ (w ? DELAYED_RW : DELAYED_R) :
+ DELAYED_W;
+ return;
+ default:
+ assert(state == IDLE || state == DELAYED_IDLE);
+ }
}
void DispatchHandle::rewatch() {
@@ -93,6 +113,8 @@ void DispatchHandle::rewatch() {
case ACTIVE_RW:
// Don't need to do anything already waiting for readable/writable
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -130,6 +152,8 @@ void DispatchHandle::rewatchRead() {
poller->modFd(*this, Poller::INOUT);
state = ACTIVE_RW;
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -167,6 +191,8 @@ void DispatchHandle::rewatchWrite() {
case ACTIVE_RW:
// Nothing to do: already waiting for writable
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -203,6 +229,8 @@ void DispatchHandle::unwatchRead() {
case ACTIVE_W:
case INACTIVE:
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -239,6 +267,8 @@ void DispatchHandle::unwatchWrite() {
case ACTIVE_R:
case INACTIVE:
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -261,6 +291,8 @@ void DispatchHandle::unwatch() {
poller->modFd(*this, Poller::NONE);
state = INACTIVE;
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -280,47 +312,72 @@ void DispatchHandle::stopWatch() {
default:
state = IDLE;
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
assert(poller);
poller->delFd(*this);
poller.reset();
}
+// If we are already in the IDLE state we can't do the callback as we might
+// race to delete and callback at the same time
+// TODO: might be able to fix this by adding a new state, but would make
+// the state machine even more complex
void DispatchHandle::call(Callback iCb) {
assert(iCb);
ScopedLock<Mutex> lock(stateLock);
- interruptedCallbacks.push(iCb);
-
- (void) poller->interrupt(*this);
+ switch (state) {
+ case IDLE:
+ case ACTIVE_DELETE:
+ assert(false);
+ return;
+ default:
+ interruptedCallbacks.push(iCb);
+ assert(poller);
+ (void) poller->interrupt(*this);
+ }
}
// The slightly strange switch structure
// is to ensure that the lock is released before
// we do the delete
void DispatchHandle::doDelete() {
- // Ensure that we're no longer watching anything
- stopWatch();
-
- // If we're in the middle of a callback defer the delete
{
ScopedLock<Mutex> lock(stateLock);
+ // Ensure that we're no longer watching anything
switch (state) {
+ case DELAYED_R:
+ case DELAYED_W:
+ case DELAYED_RW:
+ case DELAYED_INACTIVE:
+ assert(poller);
+ poller->delFd(*this);
+ poller.reset();
+ // Fallthrough
case DELAYED_IDLE:
- case DELAYED_DELETE:
state = DELAYED_DELETE;
+ // Fallthrough
+ case DELAYED_DELETE:
+ case ACTIVE_DELETE:
return;
case IDLE:
break;
default:
- // Can only get out of stopWatch() in DELAYED_IDLE/DELAYED_DELETE/IDLE states
- assert(false);
+ state = ACTIVE_DELETE;
+ assert(poller);
+ (void) poller->interrupt(*this);
+ poller->delFd(*this);
+ return;
}
}
- // If we're not then do it right away
+ // If we're IDLE we can do this right away
delete this;
}
void DispatchHandle::processEvent(Poller::EventType type) {
+ CallbackQueue callbacks;
+
// Note that we are now doing the callbacks
{
ScopedLock<Mutex> lock(stateLock);
@@ -336,6 +393,16 @@ void DispatchHandle::processEvent(Poller::EventType type) {
case ACTIVE_RW:
state = DELAYED_RW;
break;
+ case ACTIVE_DELETE:
+ // Need to make sure we clean up any pending callbacks in this case
+ std::swap(callbacks, interruptedCallbacks);
+ goto saybyebye;
+ // Can get here in idle if we are stopped in a different thread
+ // just after we return with this handle in Poller::wait
+ case IDLE:
+ // Can get here in INACTIVE if a non connection thread unwatches
+ // whilst we were stuck in the above lock
+ case INACTIVE:
// Can only get here in a DELAYED_* state in the rare case
// that we're already here for reading and we get activated for
// writing and we can write (it might be possible the other way
@@ -348,9 +415,9 @@ void DispatchHandle::processEvent(Poller::EventType type) {
case DELAYED_IDLE:
case DELAYED_DELETE:
return;
- default:
- assert(false);
}
+
+ std::swap(callbacks, interruptedCallbacks);
}
// Do callbacks - whilst we are doing the callbacks we are prevented from processing
@@ -378,8 +445,8 @@ void DispatchHandle::processEvent(Poller::EventType type) {
break;
case Poller::INTERRUPTED:
{
- ScopedLock<Mutex> lock(stateLock);
- assert(interruptedCallbacks.size() > 0);
+ // We could only be interrupted if we also had a callback to do
+ assert(callbacks.size() > 0);
// We'll actually do the interrupt below
}
break;
@@ -387,16 +454,18 @@ void DispatchHandle::processEvent(Poller::EventType type) {
assert(false);
}
- {
- ScopedLock<Mutex> lock(stateLock);
- // If we've got a pending interrupt do it now
- while (interruptedCallbacks.size() > 0) {
- Callback cb = interruptedCallbacks.front();
+ // If we have any callbacks do them now -
+ // (because we use a copy from before the previous callbacks we won't
+ // do anything yet that was just added)
+ while (callbacks.size() > 0) {
+ Callback cb = callbacks.front();
assert(cb);
cb(*this);
- interruptedCallbacks.pop();
+ callbacks.pop();
}
+ {
+ ScopedLock<Mutex> lock(stateLock);
// If any of the callbacks re-enabled reading/writing then actually
// do it now
switch (state) {
@@ -425,7 +494,9 @@ void DispatchHandle::processEvent(Poller::EventType type) {
case DELAYED_DELETE:
break;
}
- }
+ }
+
+saybyebye:
delete this;
}
diff --git a/qpid/cpp/src/qpid/sys/DispatchHandle.h b/qpid/cpp/src/qpid/sys/DispatchHandle.h
index ffcbd80f7e..bc9f98775e 100644
--- a/qpid/cpp/src/qpid/sys/DispatchHandle.h
+++ b/qpid/cpp/src/qpid/sys/DispatchHandle.h
@@ -24,7 +24,7 @@
#include "Poller.h"
#include "Mutex.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/function.hpp>
#include <queue>
@@ -65,6 +65,7 @@ private:
Mutex stateLock;
enum {
IDLE, INACTIVE, ACTIVE_R, ACTIVE_W, ACTIVE_RW,
+ ACTIVE_DELETE,
DELAYED_IDLE, DELAYED_INACTIVE, DELAYED_R, DELAYED_W, DELAYED_RW,
DELAYED_DELETE
} state;
@@ -82,7 +83,7 @@ public:
*@param wCb Callback called when the handle is writable.
*@param dCb Callback called when the handle is disconnected.
*/
- DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) :
+ QPID_COMMON_EXTERN DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) :
PollerHandle(h),
readableCallback(rCb),
writableCallback(wCb),
@@ -90,42 +91,42 @@ public:
state(IDLE)
{}
- ~DispatchHandle();
+ QPID_COMMON_EXTERN ~DispatchHandle();
/** Add this DispatchHandle to the poller to be watched. */
- void startWatch(Poller::shared_ptr poller);
+ QPID_COMMON_EXTERN void startWatch(Poller::shared_ptr poller);
/** Resume watching for all non-0 callbacks. */
- void rewatch();
+ QPID_COMMON_EXTERN void rewatch();
/** Resume watching for read only. */
- void rewatchRead();
+ QPID_COMMON_EXTERN void rewatchRead();
/** Resume watching for write only. */
- void rewatchWrite();
+ QPID_COMMON_EXTERN void rewatchWrite();
/** Stop watching temporarily. The DispatchHandle remains
associated with the poller and can be re-activated using
rewatch. */
- void unwatch();
+ QPID_COMMON_EXTERN void unwatch();
/** Stop watching for read */
- void unwatchRead();
+ QPID_COMMON_EXTERN void unwatchRead();
/** Stop watching for write */
- void unwatchWrite();
+ QPID_COMMON_EXTERN void unwatchWrite();
/** Stop watching permanently. Disassociates from the poller. */
- void stopWatch();
+ QPID_COMMON_EXTERN void stopWatch();
/** Interrupt watching this handle and make a serialised callback that respects the
* same exclusivity guarantees as the other callbacks
*/
- void call(Callback iCb);
+ QPID_COMMON_EXTERN void call(Callback iCb);
protected:
/** Override to get extra processing done when the DispatchHandle is deleted. */
- void doDelete();
+ QPID_COMMON_EXTERN void doDelete();
private:
- void processEvent(Poller::EventType dir);
+ QPID_COMMON_EXTERN void processEvent(Poller::EventType dir);
};
class DispatchHandleRef {
diff --git a/qpid/cpp/src/qpid/sys/Dispatcher.h b/qpid/cpp/src/qpid/sys/Dispatcher.h
index f7c9e8d731..2f3ed10901 100644
--- a/qpid/cpp/src/qpid/sys/Dispatcher.h
+++ b/qpid/cpp/src/qpid/sys/Dispatcher.h
@@ -24,6 +24,7 @@
#include "Poller.h"
#include "Runnable.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
@@ -32,10 +33,10 @@ class Dispatcher : public Runnable {
const Poller::shared_ptr poller;
public:
- Dispatcher(Poller::shared_ptr poller);
- ~Dispatcher();
+ QPID_COMMON_EXTERN Dispatcher(Poller::shared_ptr poller);
+ QPID_COMMON_EXTERN ~Dispatcher();
- void run();
+ QPID_COMMON_EXTERN void run();
};
}}
diff --git a/qpid/cpp/src/qpid/sys/IOHandle.h b/qpid/cpp/src/qpid/sys/IOHandle.h
index 0bf2abbafa..656e5e1efd 100644
--- a/qpid/cpp/src/qpid/sys/IOHandle.h
+++ b/qpid/cpp/src/qpid/sys/IOHandle.h
@@ -22,6 +22,8 @@
*
*/
+#include "qpid/CommonImportExport.h"
+
namespace qpid {
namespace sys {
@@ -50,8 +52,8 @@ class IOHandle {
protected:
IOHandlePrivate* const impl;
- IOHandle(IOHandlePrivate*);
- virtual ~IOHandle();
+ IOHandle(IOHandlePrivate*);
+ QPID_COMMON_EXTERN virtual ~IOHandle();
};
}}
diff --git a/qpid/cpp/src/qpid/sys/PollableCondition.h b/qpid/cpp/src/qpid/sys/PollableCondition.h
index 56d38f90da..f49fb22cb4 100644
--- a/qpid/cpp/src/qpid/sys/PollableCondition.h
+++ b/qpid/cpp/src/qpid/sys/PollableCondition.h
@@ -22,7 +22,58 @@
*
*/
-// Currently only has a posix implementation, add #ifdefs for other platforms as needed.
-#include "posix/PollableCondition.h"
+#include "qpid/sys/Poller.h"
+#include "qpid/CommonImportExport.h"
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+
+
+namespace qpid {
+namespace sys {
+
+class PollableConditionPrivate;
+
+class PollableCondition {
+public:
+ typedef boost::function1<void, PollableCondition&> Callback;
+
+ QPID_COMMON_EXTERN PollableCondition(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller);
+
+ QPID_COMMON_EXTERN ~PollableCondition();
+
+ /**
+ * Set the condition. Triggers callback to Callback from Poller.
+ * When callback is made, condition is suspended. Call rearm() to
+ * resume reacting to the condition.
+ */
+ QPID_COMMON_EXTERN void set();
+
+ /**
+ * Get the current state of the condition, then clear it.
+ *
+ * @return The state of the condition before it was cleared.
+ */
+ QPID_COMMON_EXTERN bool clear();
+
+ /**
+ * Temporarily suspend the ability for the poller to react to the
+ * condition. It can be rearm()ed later.
+ */
+ QPID_COMMON_EXTERN void disarm();
+
+ /**
+ * Reset the ability for the poller to react to the condition.
+ */
+ QPID_COMMON_EXTERN void rearm();
+
+ private:
+ PollableConditionPrivate *impl;
+
+ Callback callback;
+ boost::shared_ptr<sys::Poller> poller;
+};
+
+}} // namespace qpid::sys
#endif /*!QPID_SYS_POLLABLECONDITION_H*/
diff --git a/qpid/cpp/src/qpid/sys/PollableQueue.h b/qpid/cpp/src/qpid/sys/PollableQueue.h
index b5ff98c2c7..f8acf0a5f6 100644
--- a/qpid/cpp/src/qpid/sys/PollableQueue.h
+++ b/qpid/cpp/src/qpid/sys/PollableQueue.h
@@ -23,8 +23,6 @@
*/
#include "qpid/sys/PollableCondition.h"
-#include "qpid/sys/Dispatcher.h"
-#include "qpid/sys/DispatchHandle.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Thread.h"
#include <boost/function.hpp>
@@ -38,9 +36,10 @@ namespace sys {
class Poller;
/**
- * A queue that can be polled by sys::Poller. Any thread can push to
- * the queue, on wakeup the poller thread processes all items on the
- * queue by passing them to a callback in a batch.
+ * A queue whose item processing is dispatched by sys::Poller.
+ * Any thread can push to the queue; items pushed trigger an event the Poller
+ * recognizes. When a Poller I/O thread dispatches the event, a
+ * user-specified callback is invoked with all items on the queue.
*/
template <class T>
class PollableQueue {
@@ -50,12 +49,21 @@ class PollableQueue {
/**
* Callback to process a batch of items from the queue.
- * @param values to process, any items remaining after call are put back on the queue.
+ *
+ * @param values Queue of values to process. Any items remaining
+ * on return from Callback are put back on the queue.
*/
- typedef boost::function<void (Queue& values)> Callback;
+ typedef boost::function<void (Queue&)> Callback;
- /** When the queue is selected by the poller, values are passed to callback cb. */
- PollableQueue(const Callback& cb, const boost::shared_ptr<sys::Poller>& poller);
+ /**
+ * Constructor; sets necessary parameters.
+ *
+ * @param cb Callback that will be called to process items on the
+ * queue. Will be called from a Poller I/O thread.
+ * @param poller Poller to use for dispatching queue events.
+ */
+ PollableQueue(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller);
~PollableQueue();
@@ -85,14 +93,12 @@ class PollableQueue {
typedef sys::Monitor::ScopedLock ScopedLock;
typedef sys::Monitor::ScopedUnlock ScopedUnlock;
- void dispatch(sys::DispatchHandle&);
+ void dispatch(PollableCondition& cond);
void process();
mutable sys::Monitor lock;
Callback callback;
- boost::shared_ptr<sys::Poller> poller;
PollableCondition condition;
- DispatchHandleRef handle;
Queue queue, batch;
Thread dispatcher;
bool stopped;
@@ -100,11 +106,10 @@ class PollableQueue {
template <class T> PollableQueue<T>::PollableQueue(
const Callback& cb, const boost::shared_ptr<sys::Poller>& p)
- : callback(cb), poller(p),
- handle(condition, boost::bind(&PollableQueue<T>::dispatch, this, _1), 0, 0), stopped(true)
+ : callback(cb),
+ condition(boost::bind(&PollableQueue<T>::dispatch, this, _1), p),
+ stopped(true)
{
- handle.startWatch(poller);
- handle.unwatch();
}
template <class T> void PollableQueue<T>::start() {
@@ -112,11 +117,10 @@ template <class T> void PollableQueue<T>::start() {
if (!stopped) return;
stopped = false;
if (!queue.empty()) condition.set();
- handle.rewatch();
+ condition.rearm();
}
template <class T> PollableQueue<T>::~PollableQueue() {
- handle.stopWatch();
}
template <class T> void PollableQueue<T>::push(const T& t) {
@@ -125,15 +129,15 @@ template <class T> void PollableQueue<T>::push(const T& t) {
queue.push_back(t);
}
-template <class T> void PollableQueue<T>::dispatch(sys::DispatchHandle& h) {
+template <class T> void PollableQueue<T>::dispatch(PollableCondition& cond) {
ScopedLock l(lock);
assert(dispatcher.id() == 0);
dispatcher = Thread::current();
process();
dispatcher = Thread();
- if (queue.empty()) condition.clear();
+ if (queue.empty()) cond.clear();
if (stopped) lock.notifyAll();
- else h.rewatch();
+ else cond.rearm();
}
template <class T> void PollableQueue<T>::process() {
@@ -159,7 +163,7 @@ template <class T> void PollableQueue<T>::shutdown() {
template <class T> void PollableQueue<T>::stop() {
ScopedLock l(lock);
if (stopped) return;
- handle.unwatch();
+ condition.disarm();
stopped = true;
// Avoid deadlock if stop is called from the dispatch thread
while (dispatcher.id() && dispatcher.id() != Thread::current().id())
diff --git a/qpid/cpp/src/qpid/sys/Poller.h b/qpid/cpp/src/qpid/sys/Poller.h
index 8e9f67fefd..825ad8bfed 100644
--- a/qpid/cpp/src/qpid/sys/Poller.h
+++ b/qpid/cpp/src/qpid/sys/Poller.h
@@ -24,7 +24,7 @@
#include "Time.h"
#include "Runnable.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/shared_ptr.hpp>
namespace qpid {
@@ -74,10 +74,10 @@ public:
void process();
};
- Poller();
- ~Poller();
+ QPID_COMMON_EXTERN Poller();
+ QPID_COMMON_EXTERN ~Poller();
/** Note: this function is async-signal safe */
- void shutdown();
+ QPID_COMMON_EXTERN void shutdown();
// Interrupt waiting for a specific poller handle
// returns true if we could interrupt the handle
@@ -86,18 +86,19 @@ public:
// with the handle and the INTERRUPTED event type
// if it returns false then the handle is not being monitored by the poller
// - This can either be because it has just received an event which has been
- // reported and has not been reenabled since. Or because it was removed
- // from the monitoring set
- bool interrupt(PollerHandle& handle);
+ // reported and has not been reenabled since.
+ // - Because it was removed from the monitoring set
+ // - Or because it is already being interrupted
+ QPID_COMMON_EXTERN bool interrupt(PollerHandle& handle);
// Poller run loop
- void run();
+ QPID_COMMON_EXTERN void run();
- void addFd(PollerHandle& handle, Direction dir);
- void delFd(PollerHandle& handle);
- void modFd(PollerHandle& handle, Direction dir);
- void rearmFd(PollerHandle& handle);
- Event wait(Duration timeout = TIME_INFINITE);
+ QPID_COMMON_EXTERN void addFd(PollerHandle& handle, Direction dir);
+ QPID_COMMON_EXTERN void delFd(PollerHandle& handle);
+ QPID_COMMON_EXTERN void modFd(PollerHandle& handle, Direction dir);
+ QPID_COMMON_EXTERN void rearmFd(PollerHandle& handle);
+ QPID_COMMON_EXTERN Event wait(Duration timeout = TIME_INFINITE);
};
/**
@@ -110,11 +111,11 @@ class PollerHandle {
friend struct Poller::Event;
PollerHandlePrivate* const impl;
- virtual void processEvent(Poller::EventType) {};
+ QPID_COMMON_EXTERN virtual void processEvent(Poller::EventType) {};
public:
- PollerHandle(const IOHandle& h);
- virtual ~PollerHandle();
+ QPID_COMMON_EXTERN PollerHandle(const IOHandle& h);
+ QPID_COMMON_EXTERN virtual ~PollerHandle();
};
inline void Poller::Event::process() {
diff --git a/qpid/cpp/src/qpid/sys/Runnable.h b/qpid/cpp/src/qpid/sys/Runnable.h
index fb3927c612..4bf43c93d1 100644
--- a/qpid/cpp/src/qpid/sys/Runnable.h
+++ b/qpid/cpp/src/qpid/sys/Runnable.h
@@ -22,6 +22,7 @@
*/
#include <boost/function.hpp>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
@@ -35,7 +36,7 @@ class Runnable
/** Type to represent a runnable as a Functor */
typedef boost::function0<void> Functor;
- virtual ~Runnable();
+ QPID_COMMON_EXTERN virtual ~Runnable();
/** Derived classes override run(). */
virtual void run() = 0;
diff --git a/qpid/cpp/src/qpid/sys/Shlib.h b/qpid/cpp/src/qpid/sys/Shlib.h
index a6d94b42d4..7f66cfec14 100644
--- a/qpid/cpp/src/qpid/sys/Shlib.h
+++ b/qpid/cpp/src/qpid/sys/Shlib.h
@@ -21,7 +21,8 @@
* under the License.
*
*/
-
+
+#include "qpid/CommonImportExport.h"
#include <boost/noncopyable.hpp>
#include <iostream>
@@ -40,10 +41,10 @@ class Shlib {
Shlib(const std::string& libname) { load(libname.c_str()); }
/** Unload shared library. */
- void unload();
+ QPID_COMMON_EXTERN void unload();
/** Look up symbol. */
- void* getSymbol(const char* symbol);
+ QPID_COMMON_EXTERN void* getSymbol(const char* symbol);
/** Look up symbol in shared library, cast it to the desired
* pointer type, void* by default.
@@ -57,7 +58,7 @@ class Shlib {
private:
void* handle;
- void load(const char* libname);
+ QPID_COMMON_EXTERN void load(const char* libname);
};
/** A shared library handle that unloads the shlib in it's dtor */
@@ -66,7 +67,7 @@ class AutoShlib : public Shlib {
/** Load shared library */
AutoShlib(const std::string& libname) : Shlib(libname) {}
/** Calls unload() */
- ~AutoShlib() throw();
+ QPID_COMMON_EXTERN ~AutoShlib() throw();
};
diff --git a/qpid/cpp/src/qpid/sys/Socket.h b/qpid/cpp/src/qpid/sys/Socket.h
index ae48b8104d..e6555f5774 100644
--- a/qpid/cpp/src/qpid/sys/Socket.h
+++ b/qpid/cpp/src/qpid/sys/Socket.h
@@ -24,11 +24,9 @@
#include "IOHandle.h"
#include "qpid/sys/IntegerTypes.h"
-
+#include "qpid/CommonImportExport.h"
#include <string>
-struct sockaddr;
-
namespace qpid {
namespace sys {
@@ -38,7 +36,7 @@ class Socket : public IOHandle
{
public:
/** Create a socket wrapper for descriptor. */
- Socket();
+ QPID_COMMON_EXTERN Socket();
/** Create an initialized TCP socket */
void createTcp() const;
@@ -49,21 +47,21 @@ public:
/** Set socket non blocking */
void setNonblocking() const;
- void connect(const std::string& host, uint16_t port) const;
+ QPID_COMMON_EXTERN void connect(const std::string& host, uint16_t port) const;
- void close() const;
+ QPID_COMMON_EXTERN void close() const;
/** Bind to a port and start listening.
*@param port 0 means choose an available port.
*@param backlog maximum number of pending connections.
*@return The bound port.
*/
- int listen(uint16_t port = 0, int backlog = 10) const;
+ QPID_COMMON_EXTERN int listen(uint16_t port = 0, int backlog = 10) const;
/** Returns the "socket name" ie the address bound to
* the near end of the socket
*/
- std::string getSockname() const;
+ QPID_COMMON_EXTERN std::string getSockname() const;
/** Returns the "peer name" ie the address bound to
* the remote end of the socket
@@ -74,14 +72,14 @@ public:
* Returns an address (host and port) for the remote end of the
* socket
*/
- std::string getPeerAddress() const;
+ QPID_COMMON_EXTERN std::string getPeerAddress() const;
/**
* Returns an address (host and port) for the local end of the
* socket
*/
std::string getLocalAddress() const;
- uint16_t getLocalPort() const;
+ QPID_COMMON_EXTERN uint16_t getLocalPort() const;
uint16_t getRemotePort() const;
/**
@@ -93,13 +91,13 @@ public:
/** Accept a connection from a socket that is already listening
* and has an incoming connection
*/
- Socket* accept(struct sockaddr *addr, socklen_t *addrlen) const;
+ QPID_COMMON_EXTERN Socket* accept() const;
// TODO The following are raw operations, maybe they need better wrapping?
- int read(void *buf, size_t count) const;
- int write(const void *buf, size_t count) const;
+ QPID_COMMON_EXTERN int read(void *buf, size_t count) const;
+ QPID_COMMON_EXTERN int write(const void *buf, size_t count) const;
- void setTcpNoDelay(bool nodelay) const;
+ QPID_COMMON_EXTERN void setTcpNoDelay(bool nodelay) const;
private:
Socket(IOHandlePrivate*);
diff --git a/qpid/cpp/src/qpid/sys/StrError.h b/qpid/cpp/src/qpid/sys/StrError.h
index 3843f2abe1..69cc7e714c 100644
--- a/qpid/cpp/src/qpid/sys/StrError.h
+++ b/qpid/cpp/src/qpid/sys/StrError.h
@@ -23,12 +23,13 @@
*/
#include <string>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
/** Get the error message for a system number err, e.g. errno. */
-std::string strError(int err);
+QPID_COMMON_EXTERN std::string strError(int err);
}} // namespace qpid
diff --git a/qpid/cpp/src/qpid/sys/SystemInfo.h b/qpid/cpp/src/qpid/sys/SystemInfo.h
index d43fe34b04..6e97022b36 100644
--- a/qpid/cpp/src/qpid/sys/SystemInfo.h
+++ b/qpid/cpp/src/qpid/sys/SystemInfo.h
@@ -23,6 +23,7 @@
#include "qpid/sys/IntegerTypes.h"
#include "qpid/Address.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
@@ -36,15 +37,15 @@ namespace SystemInfo {
* Estimate available concurrency, e.g. number of CPU cores.
* -1 means estimate not available on this platform.
*/
- long concurrency();
+ QPID_COMMON_EXTERN long concurrency();
/**
* Get the local host name and set it in the specified TcpAddress.
* Returns false if it can't be obtained and sets errno to any error value.
*/
- bool getLocalHostname (TcpAddress &address);
+ QPID_COMMON_EXTERN bool getLocalHostname (TcpAddress &address);
- void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
+ QPID_COMMON_EXTERN void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
/**
* Retrieve system identifiers and versions. This is information that can
@@ -57,7 +58,7 @@ namespace SystemInfo {
* @param version Receives the OS release version (kernel, build, sp, etc.)
* @param machine Receives the hardware type.
*/
- void getSystemId (std::string &osName,
+ QPID_COMMON_EXTERN void getSystemId (std::string &osName,
std::string &nodeName,
std::string &release,
std::string &version,
@@ -66,12 +67,17 @@ namespace SystemInfo {
/**
* Get the process ID of the current process.
*/
- uint32_t getProcessId();
+ QPID_COMMON_EXTERN uint32_t getProcessId();
/**
* Get the process ID of the parent of the current process.
*/
- uint32_t getParentProcessId();
+ QPID_COMMON_EXTERN uint32_t getParentProcessId();
+
+ /**
+ * Get the name of the current process (i.e. the name of the executable)
+ */
+ QPID_COMMON_EXTERN std::string getProcessName();
}}} // namespace qpid::sys::SystemInfo
diff --git a/qpid/cpp/src/qpid/sys/Thread.h b/qpid/cpp/src/qpid/sys/Thread.h
index e2b904aa1a..b532d4d80a 100644
--- a/qpid/cpp/src/qpid/sys/Thread.h
+++ b/qpid/cpp/src/qpid/sys/Thread.h
@@ -22,11 +22,14 @@
*
*/
#include <boost/shared_ptr.hpp>
+#include "qpid/CommonImportExport.h"
#ifdef _WIN32
# define QPID_TSS __declspec(thread)
#elif defined (__GNUC__)
# define QPID_TSS __thread
+#elif defined (__SUNPRO_CC)
+# define QPID_TSS __thread
#else
# error "Dont know how to define QPID_TSS for this platform"
#endif
@@ -42,15 +45,15 @@ class Thread
boost::shared_ptr<ThreadPrivate> impl;
public:
- Thread();
- explicit Thread(qpid::sys::Runnable*);
- explicit Thread(qpid::sys::Runnable&);
+ QPID_COMMON_EXTERN Thread();
+ QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable*);
+ QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable&);
- void join();
+ QPID_COMMON_EXTERN void join();
- unsigned long id();
+ QPID_COMMON_EXTERN unsigned long id();
- static Thread current();
+ QPID_COMMON_EXTERN static Thread current();
/** ID of current thread for logging.
* Workaround for broken Thread::current() in APR
diff --git a/qpid/cpp/src/qpid/sys/Time.h b/qpid/cpp/src/qpid/sys/Time.h
index d39be95434..b7173406ca 100644
--- a/qpid/cpp/src/qpid/sys/Time.h
+++ b/qpid/cpp/src/qpid/sys/Time.h
@@ -33,6 +33,8 @@
# include "posix/Time.h"
#endif
+#include "qpid/CommonImportExport.h"
+
#include <limits>
#include <iosfwd>
@@ -86,23 +88,23 @@ class AbsTime {
TimePrivate timepoint;
public:
- inline AbsTime() {}
- AbsTime(const AbsTime& time0, const Duration& duration);
+ QPID_COMMON_EXTERN inline AbsTime() {}
+ QPID_COMMON_EXTERN AbsTime(const AbsTime& time0, const Duration& duration);
// Default assignment operation fine
// Default copy constructor fine
- static AbsTime now();
- static AbsTime FarFuture();
+ QPID_COMMON_EXTERN static AbsTime now();
+ QPID_COMMON_EXTERN static AbsTime FarFuture();
const TimePrivate& getPrivate(void) const { return timepoint; }
bool operator==(const AbsTime& t) const { return t.timepoint == timepoint; }
template <class S> void serialize(S& s) { s(timepoint); }
friend bool operator<(const AbsTime& a, const AbsTime& b);
friend bool operator>(const AbsTime& a, const AbsTime& b);
- friend std::ostream& operator << (std::ostream&, const AbsTime&);
+ QPID_COMMON_EXTERN friend std::ostream& operator << (std::ostream&, const AbsTime&);
};
-std::ostream& operator << (std::ostream&, const AbsTime&);
+QPID_COMMON_EXTERN std::ostream& operator << (std::ostream&, const AbsTime&);
/**
* @class Duration
@@ -120,9 +122,9 @@ class Duration {
friend class AbsTime;
public:
- inline Duration(int64_t time0);
- explicit Duration(const AbsTime& time0);
- explicit Duration(const AbsTime& start, const AbsTime& finish);
+ QPID_COMMON_EXTERN inline Duration(int64_t time0);
+ QPID_COMMON_EXTERN explicit Duration(const AbsTime& time0);
+ QPID_COMMON_EXTERN explicit Duration(const AbsTime& start, const AbsTime& finish);
inline operator int64_t() const;
};
@@ -158,10 +160,10 @@ const Duration TIME_INFINITE = std::numeric_limits<int64_t>::max();
const AbsTime FAR_FUTURE = AbsTime::FarFuture();
/** Portable sleep for a number of seconds */
-void sleep(int secs);
+QPID_COMMON_EXTERN void sleep(int secs);
/** Portable sleep for a number of microseconds */
-void usleep(uint64_t usecs);
+QPID_COMMON_EXTERN void usleep(uint64_t usecs);
}}
diff --git a/qpid/cpp/src/qpid/sys/Timer.h b/qpid/cpp/src/qpid/sys/Timer.h
index 2561e41034..dab2f55edb 100644
--- a/qpid/cpp/src/qpid/sys/Timer.h
+++ b/qpid/cpp/src/qpid/sys/Timer.h
@@ -25,7 +25,7 @@
#include "qpid/sys/Thread.h"
#include "qpid/sys/Runnable.h"
#include "qpid/RefCounted.h"
-
+#include "qpid/CommonImportExport.h"
#include <memory>
#include <queue>
@@ -49,15 +49,15 @@ class TimerTask : public RefCounted {
void fireTask();
public:
- TimerTask(Duration period);
- TimerTask(AbsTime fireTime);
- virtual ~TimerTask();
+ QPID_COMMON_EXTERN TimerTask(Duration period);
+ QPID_COMMON_EXTERN TimerTask(AbsTime fireTime);
+ QPID_COMMON_EXTERN virtual ~TimerTask();
- void setupNextFire();
- void restart();
- void delayTill(AbsTime fireTime);
- void cancel();
- bool isCancelled() const;
+ QPID_COMMON_EXTERN void setupNextFire();
+ QPID_COMMON_EXTERN void restart();
+ QPID_COMMON_EXTERN void delayTill(AbsTime fireTime);
+ QPID_COMMON_EXTERN void cancel();
+ QPID_COMMON_EXTERN bool isCancelled() const;
protected:
// Must be overridden with callback
@@ -78,12 +78,12 @@ class Timer : private Runnable {
void run();
public:
- Timer();
- ~Timer();
+ QPID_COMMON_EXTERN Timer();
+ QPID_COMMON_EXTERN ~Timer();
- void add(boost::intrusive_ptr<TimerTask> task);
- void start();
- void stop();
+ QPID_COMMON_EXTERN void add(boost::intrusive_ptr<TimerTask> task);
+ QPID_COMMON_EXTERN void start();
+ QPID_COMMON_EXTERN void stop();
};
diff --git a/qpid/cpp/src/qpid/sys/alloca.h b/qpid/cpp/src/qpid/sys/alloca.h
new file mode 100644
index 0000000000..e989670e4f
--- /dev/null
+++ b/qpid/cpp/src/qpid/sys/alloca.h
@@ -0,0 +1,39 @@
+#ifndef QPID_SYS_ALLOCA_H
+#define QPID_SYS_ALLOCA_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.
+ *
+ */
+
+#if (defined(_WINDOWS) || defined (WIN32)) && defined(_MSC_VER)
+#include <malloc.h>
+#ifdef alloc
+# undef alloc
+#endif
+#define alloc _alloc
+#ifdef alloca
+# undef alloca
+#endif
+#define alloca _alloca
+#endif
+#if !defined _WINDOWS && !defined WIN32
+#include <alloca.h>
+#endif
+
+#endif /*!QPID_SYS_ALLOCA_H*/
diff --git a/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp b/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp
index 10705e12da..42b5d8b1aa 100644
--- a/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp
+++ b/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp
@@ -54,17 +54,20 @@ class PollerHandlePrivate {
INACTIVE,
HUNGUP,
MONITORED_HUNGUP,
+ INTERRUPTED,
DELETED
};
int fd;
::__uint32_t events;
+ PollerHandle* pollerHandle;
FDStat stat;
Mutex lock;
- PollerHandlePrivate(int f) :
+ PollerHandlePrivate(int f, PollerHandle* p) :
fd(f),
events(0),
+ pollerHandle(p),
stat(ABSENT) {
}
@@ -101,6 +104,14 @@ class PollerHandlePrivate {
stat = HUNGUP;
}
+ bool isInterrupted() const {
+ return stat == INTERRUPTED;
+ }
+
+ void setInterrupted() {
+ stat = INTERRUPTED;
+ }
+
bool isDeleted() const {
return stat == DELETED;
}
@@ -111,7 +122,7 @@ class PollerHandlePrivate {
};
PollerHandle::PollerHandle(const IOHandle& h) :
- impl(new PollerHandlePrivate(toFd(h.impl)))
+ impl(new PollerHandlePrivate(toFd(h.impl), this))
{}
PollerHandle::~PollerHandle() {
@@ -120,6 +131,10 @@ PollerHandle::~PollerHandle() {
if (impl->isDeleted()) {
return;
}
+ if (impl->isInterrupted()) {
+ impl->setDeleted();
+ return;
+ }
if (impl->isActive()) {
impl->setDeleted();
}
@@ -243,23 +258,21 @@ class PollerPrivate {
::close(epollFd);
}
- void interrupt(bool all=false) {
+ void interrupt() {
::epoll_event epe;
- if (all) {
- // Not EPOLLONESHOT, so we eventually get all threads
- epe.events = ::EPOLLIN;
- epe.data.u64 = 0; // Keep valgrind happy
- } else {
- // Use EPOLLONESHOT so we only wake a single thread
- epe.events = ::EPOLLIN | ::EPOLLONESHOT;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &static_cast<PollerHandle&>(interruptHandle);
- }
+ // Use EPOLLONESHOT so we only wake a single thread
+ epe.events = ::EPOLLIN | ::EPOLLONESHOT;
+ epe.data.u64 = 0; // Keep valgrind happy
+ epe.data.ptr = &static_cast<PollerHandle&>(interruptHandle);
QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe));
}
void interruptAll() {
- interrupt(true);
+ ::epoll_event epe;
+ // Not EPOLLONESHOT, so we eventually get all threads
+ epe.events = ::EPOLLIN;
+ epe.data.u64 = 0; // Keep valgrind happy
+ QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe));
}
};
@@ -281,7 +294,7 @@ void Poller::addFd(PollerHandle& handle, Direction dir) {
epe.events = eh.events | PollerPrivate::directionToEpollEvent(dir);
}
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &handle;
+ epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, op, eh.fd, &epe));
@@ -312,7 +325,7 @@ void Poller::modFd(PollerHandle& handle, Direction dir) {
::epoll_event epe;
epe.events = PollerPrivate::directionToEpollEvent(dir) | ::EPOLLONESHOT;
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &handle;
+ epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe));
@@ -329,7 +342,7 @@ void Poller::rearmFd(PollerHandle& handle) {
::epoll_event epe;
epe.events = eh.events;
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &handle;
+ epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe));
@@ -355,15 +368,14 @@ bool Poller::interrupt(PollerHandle& handle) {
{
PollerHandlePrivate& eh = *handle.impl;
ScopedLock<Mutex> l(eh.lock);
- if (eh.isInactive()) {
+ if (!eh.isActive()) {
return false;
}
::epoll_event epe;
epe.events = 0;
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe));
- eh.setInactive();
+ eh.setInterrupted();
}
PollerPrivate::InterruptHandle& ih = impl->interruptHandle;
@@ -422,37 +434,54 @@ Poller::Event Poller::wait(Duration timeout) {
#else
int rc = ::epoll_pwait(impl->epollFd, &epe, 1, timeoutMs, &impl->sigMask);
#endif
- // Check for shutdown
- if (impl->isShutdown) {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- return Event(0, SHUTDOWN);
- }
if (rc ==-1 && errno != EINTR) {
QPID_POSIX_CHECK(rc);
} else if (rc > 0) {
assert(rc == 1);
- PollerHandle* handle = static_cast<PollerHandle*>(epe.data.ptr);
+ void* dataPtr = epe.data.ptr;
+
+ // Check if this is an interrupt
+ PollerPrivate::InterruptHandle& interruptHandle = impl->interruptHandle;
+ if (dataPtr == &interruptHandle) {
+ PollerHandle* wrappedHandle = 0;
+ {
+ ScopedLock<Mutex> l(interruptHandle.impl->lock);
+ if (interruptHandle.impl->isActive()) {
+ wrappedHandle = interruptHandle.getHandle();
+ // If there is an interrupt queued behind this one we need to arm it
+ // We do it this way so that another thread can pick it up
+ if (interruptHandle.queuedHandles()) {
+ impl->interrupt();
+ interruptHandle.impl->setActive();
+ } else {
+ interruptHandle.impl->setInactive();
+ }
+ }
+ }
+ if (wrappedHandle) {
+ ScopedLock<Mutex> l(wrappedHandle->impl->lock);
+ if (!wrappedHandle->impl->isDeleted()) {
+ wrappedHandle->impl->setInactive();
+ return Event(wrappedHandle, INTERRUPTED);
+ }
+ PollerHandleDeletionManager.markForDeletion(wrappedHandle->impl);
+ }
+ continue;
+ }
+
+ // Check for shutdown
+ if (impl->isShutdown) {
+ PollerHandleDeletionManager.markAllUnusedInThisThread();
+ return Event(0, SHUTDOWN);
+ }
- PollerHandlePrivate& eh = *handle->impl;
+ PollerHandlePrivate& eh = *static_cast<PollerHandlePrivate*>(dataPtr);
ScopedLock<Mutex> l(eh.lock);
// the handle could have gone inactive since we left the epoll_wait
if (eh.isActive()) {
-
- // Check if this is an interrupt
- if (handle == &impl->interruptHandle) {
- PollerHandle* wrappedHandle = impl->interruptHandle.getHandle();
- // If there is an interrupt queued behind this one we need to arm it
- // We do it this way so that another thread can pick it up
- if (impl->interruptHandle.queuedHandles()) {
- impl->interrupt();
- eh.setActive();
- } else {
- eh.setInactive();
- }
- return Event(wrappedHandle, INTERRUPTED);
- }
+ PollerHandle* handle = eh.pollerHandle;
// If the connection has been hungup we could still be readable
// (just not writable), allow us to readable until we get here again
diff --git a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
index a356a72650..a914dc817a 100644
--- a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
@@ -123,7 +123,7 @@ void AsynchAcceptorPrivate::readable(DispatchHandle& h) {
// TODO: Currently we ignore the peers address, perhaps we should
// log it or use it for connection acceptance.
try {
- s = socket.accept(0, 0);
+ s = socket.accept();
if (s) {
acceptedCallback(*s);
} else {
@@ -474,7 +474,7 @@ void AsynchIO::readable(DispatchHandle& h) {
break;
} else {
// Report error then just treat as a socket disconnect
- QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(rc) << "(" << rc << ")" );
+ QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(errno) << "(" << errno << ")" );
eofCallback(*this);
h.unwatchRead();
break;
diff --git a/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp b/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp
index 0c55fd3c0d..0991e5fd76 100644
--- a/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp
@@ -22,17 +22,46 @@
*
*/
-#include "PollableCondition.h"
+#include "qpid/sys/PollableCondition.h"
+#include "qpid/sys/DispatchHandle.h"
+#include "qpid/sys/IOHandle.h"
#include "qpid/sys/posix/PrivatePosix.h"
#include "qpid/Exception.h"
+#include <boost/bind.hpp>
+
#include <unistd.h>
#include <fcntl.h>
namespace qpid {
namespace sys {
-PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) {
+class PollableConditionPrivate : public sys::IOHandle {
+ friend class PollableCondition;
+
+private:
+ PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller);
+ ~PollableConditionPrivate();
+
+ void dispatch(sys::DispatchHandle& h);
+ void rewatch();
+ void unwatch();
+
+private:
+ PollableCondition::Callback cb;
+ PollableCondition& parent;
+ boost::shared_ptr<sys::Poller> poller;
+ int writeFd;
+ std::auto_ptr<DispatchHandleRef> handle;
+};
+
+PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : IOHandle(new sys::IOHandlePrivate), cb(cb), parent(parent)
+{
int fds[2];
if (::pipe(fds) == -1)
throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
@@ -42,22 +71,71 @@ PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) {
throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
if (::fcntl(writeFd, F_SETFL, O_NONBLOCK) == -1)
throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
+ handle.reset (new DispatchHandleRef(*this,
+ boost::bind(&sys::PollableConditionPrivate::dispatch, this, _1),
+ 0, 0));
+ handle->startWatch(poller);
+ handle->unwatch();
+}
+
+PollableConditionPrivate::~PollableConditionPrivate()
+{
+ handle->stopWatch();
+ close(writeFd);
+}
+
+void PollableConditionPrivate::dispatch(sys::DispatchHandle& /*h*/)
+{
+ cb(parent);
+}
+
+void PollableConditionPrivate::rewatch()
+{
+ handle->rewatch();
+}
+
+void PollableConditionPrivate::unwatch()
+{
+ handle->unwatch();
+}
+
+ /* PollableCondition */
+
+PollableCondition::PollableCondition(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : impl(new PollableConditionPrivate(cb, *this, poller))
+{
+}
+
+PollableCondition::~PollableCondition()
+{
+ delete impl;
+}
+
+void PollableCondition::set() {
+ static const char dummy=0;
+ ssize_t n = ::write(impl->writeFd, &dummy, 1);
+ if (n == -1 && errno != EAGAIN)
+ throw ErrnoException("Error setting PollableCondition");
}
bool PollableCondition::clear() {
char buf[256];
ssize_t n;
bool wasSet = false;
- while ((n = ::read(impl->fd, buf, sizeof(buf))) > 0)
+ while ((n = ::read(impl->impl->fd, buf, sizeof(buf))) > 0)
wasSet = true;
- if (n == -1 && errno != EAGAIN) throw ErrnoException(QPID_MSG("Error clearing PollableCondition"));
+ if (n == -1 && errno != EAGAIN)
+ throw ErrnoException(QPID_MSG("Error clearing PollableCondition"));
return wasSet;
}
-void PollableCondition::set() {
- static const char dummy=0;
- ssize_t n = ::write(writeFd, &dummy, 1);
- if (n == -1 && errno != EAGAIN) throw ErrnoException("Error setting PollableCondition");
+void PollableCondition::disarm() {
+ impl->unwatch();
+}
+
+void PollableCondition::rearm() {
+ impl->rewatch();
}
@@ -71,22 +149,35 @@ void PollableCondition::set() {
namespace qpid {
namespace sys {
-PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) {
+PollableConditionPrivate::PollableConditionPrivate(const PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : cb(cb), parent(parent), poller(poller),
+ IOHandle(new sys::IOHandlePrivate) {
impl->fd = ::eventfd(0, 0);
if (impl->fd < 0) throw ErrnoException("conditionfd() failed");
}
+void PollableCondition::set() {
+ static const uint64_t value=1;
+ ssize_t n = ::write(impl->impl->fd,
+ reinterpret_cast<const void*>(&value), 8);
+ if (n != 8) throw ErrnoException("write failed on conditionfd");
+}
+
bool PollableCondition::clear() {
char buf[8];
- ssize_t n = ::read(impl->fd, buf, 8);
+ ssize_t n = ::read(impl->impl->fd, buf, 8);
if (n != 8) throw ErrnoException("read failed on conditionfd");
return *reinterpret_cast<uint64_t*>(buf);
}
-void PollableCondition::set() {
- static const uint64_t value=1;
- ssize_t n = ::write(impl->fd, reinterpret_cast<const void*>(&value), 8);
- if (n != 8) throw ErrnoException("write failed on conditionfd");
+void PollableCondition::disarm() {
+ // ????
+}
+
+void PollableCondition::rearm() {
+ // ????
}
#endif
diff --git a/qpid/cpp/src/qpid/sys/posix/Socket.cpp b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
index 415d5293ef..ab0c28c48c 100644
--- a/qpid/cpp/src/qpid/sys/posix/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
@@ -108,7 +108,7 @@ void Socket::createTcp() const
{
int& socket = impl->fd;
if (socket != -1) Socket::close();
- int s = ::socket (PF_INET, SOCK_STREAM, 0);
+ int s = ::socket (AF_INET, SOCK_STREAM, 0);
if (s < 0) throw QPID_POSIX_ERROR(errno);
socket = s;
}
@@ -138,25 +138,30 @@ const char* h_errstr(int e) {
}
}
-void Socket::connect(const std::string& host, uint16_t port) const
+void Socket::connect(const std::string& host, uint16_t p) const
{
- std::stringstream namestream;
- namestream << host << ":" << port;
- connectname = namestream.str();
+ std::stringstream portstream;
+ portstream << p;
+ std::string port = portstream.str();
+ connectname = host + ":" + port;
const int& socket = impl->fd;
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_port = htons(port);
- // TODO: Be good to make this work for IPv6 as well as IPv4
- // Use more modern lookup functions
- struct hostent* hp = gethostbyname ( host.c_str() );
- if (hp == 0)
- throw Exception(QPID_MSG("Cannot resolve " << host << ": " << h_errstr(h_errno)));
- ::memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length);
- if ((::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0) &&
- (errno != EINPROGRESS))
+
+ ::addrinfo *res;
+ ::addrinfo hints;
+ ::memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET; // In order to allow AF_INET6 we'd have to change createTcp() as well
+ hints.ai_socktype = SOCK_STREAM;
+ int n = ::getaddrinfo(host.c_str(), port.c_str(), &hints, &res);
+ if (n != 0)
+ throw Exception(QPID_MSG("Cannot resolve " << host << ": " << ::gai_strerror(n)));
+ // TODO the correct thing to do here is loop on failure until you've used all the returned addresses
+ if ((::connect(socket, res->ai_addr, res->ai_addrlen) < 0) &&
+ (errno != EINPROGRESS)) {
+ ::freeaddrinfo(res);
throw qpid::Exception(QPID_MSG(strError(errno) << ": " << host << ":" << port));
+ }
+ ::freeaddrinfo(res);
}
void
@@ -189,9 +194,9 @@ int Socket::listen(uint16_t port, int backlog) const
return ntohs(name.sin_port);
}
-Socket* Socket::accept(struct sockaddr *addr, socklen_t *addrlen) const
+Socket* Socket::accept() const
{
- int afd = ::accept(impl->fd, addr, addrlen);
+ int afd = ::accept(impl->fd, 0, 0);
if ( afd >= 0)
return new Socket(new IOHandlePrivate(afd));
else if (errno == EAGAIN)
@@ -238,7 +243,7 @@ uint16_t Socket::getLocalPort() const
uint16_t Socket::getRemotePort() const
{
- return atoi(getService(impl->fd, true).c_str());
+ return std::atoi(getService(impl->fd, true).c_str());
}
int Socket::getError() const
diff --git a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
index 938d4861c4..5d9eda605d 100755
--- a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
@@ -27,6 +27,9 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX 256
@@ -104,6 +107,27 @@ uint32_t SystemInfo::getParentProcessId()
return (uint32_t) ::getppid();
}
+string SystemInfo::getProcessName()
+{
+ uint32_t pid = getProcessId();
+ string value;
+
+ stringstream pathStream;
+ pathStream << "/proc/" << pid << "/status";
+ ifstream input(pathStream.str().c_str());
+ if (input.good()) {
+ while (!input.eof()) {
+ string key;
+ input >> key;
+ if (key == "Name:") {
+ input >> value;
+ break;
+ }
+ }
+ input.close();
+ }
+ return value;
+}
}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp b/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp
index 783f84576b..f12012cbb0 100644
--- a/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp
+++ b/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp
@@ -30,9 +30,11 @@
#include <port.h>
#include <poll.h>
#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
#include <assert.h>
-#include <vector>
+#include <queue>
#include <exception>
@@ -43,11 +45,11 @@ namespace qpid {
namespace sys {
// Deletion manager to handle deferring deletion of PollerHandles to when they definitely aren't being used
-DeletionManager<PollerHandle> PollerHandleDeletionManager;
+DeletionManager<PollerHandlePrivate> PollerHandleDeletionManager;
// Instantiate (and define) class static for DeletionManager
template <>
-DeletionManager<PollerHandle>::AllThreadsStatuses DeletionManager<PollerHandle>::allThreadsStatuses(0);
+DeletionManager<PollerHandlePrivate>::AllThreadsStatuses DeletionManager<PollerHandlePrivate>::allThreadsStatuses(0);
class PollerHandlePrivate {
friend class Poller;
@@ -58,7 +60,8 @@ class PollerHandlePrivate {
MONITORED,
INACTIVE,
HUNGUP,
- MONITORED_HUNGUP
+ MONITORED_HUNGUP,
+ DELETED
};
int fd;
@@ -104,6 +107,14 @@ class PollerHandlePrivate {
assert(stat == MONITORED);
stat = HUNGUP;
}
+
+ bool isDeleted() const {
+ return stat == DELETED;
+ }
+
+ void setDeleted() {
+ stat = DELETED;
+ }
};
PollerHandle::PollerHandle(const IOHandle& h) :
@@ -111,11 +122,16 @@ PollerHandle::PollerHandle(const IOHandle& h) :
{}
PollerHandle::~PollerHandle() {
- delete impl;
-}
-
-void PollerHandle::deferDelete() {
- PollerHandleDeletionManager.markForDeletion(this);
+ {
+ ScopedLock<Mutex> l(impl->lock);
+ if (impl->isDeleted()) {
+ return;
+ }
+ if (impl->isActive()) {
+ impl->setDeleted();
+ }
+ }
+ PollerHandleDeletionManager.markForDeletion(impl);
}
/**
@@ -125,35 +141,82 @@ void PollerHandle::deferDelete() {
class PollerPrivate {
friend class Poller;
- const int portId;
+ class InterruptHandle: public PollerHandle {
+ std::queue<PollerHandle*> handles;
+
+ void processEvent(Poller::EventType) {
+ PollerHandle* handle = handles.front();
+ handles.pop();
+ assert(handle);
+
+ //Synthesise event
+ Poller::Event event(handle, Poller::INTERRUPTED);
+
+ //Process synthesised event
+ event.process();
+ }
+ public:
+ InterruptHandle() : PollerHandle(DummyIOHandle) {}
+
+ void addHandle(PollerHandle& h) {
+ handles.push(&h);
+ }
+
+ PollerHandle *getHandle() {
+ PollerHandle* handle = handles.front();
+ handles.pop();
+ return handle;
+ }
+
+ bool queuedHandles() {
+ return handles.size() > 0;
+ }
+ };
+
+ const int portId;
+ bool isShutdown;
+ InterruptHandle interruptHandle;
+
static uint32_t directionToPollEvent(Poller::Direction dir) {
switch (dir) {
- case Poller::INPUT: return POLLIN;
- case Poller::OUTPUT: return POLLOUT;
- case Poller::INOUT: return POLLIN | POLLOUT;
- default: return 0;
+ case Poller::INPUT: return POLLIN;
+ case Poller::OUTPUT: return POLLOUT;
+ case Poller::INOUT: return POLLIN | POLLOUT;
+ default: return 0;
}
}
static Poller::EventType pollToDirection(uint32_t events) {
uint32_t e = events & (POLLIN | POLLOUT);
switch (e) {
- case POLLIN: return Poller::READABLE;
- case POLLOUT: return Poller::WRITABLE;
- case POLLIN | POLLOUT: return Poller::READ_WRITABLE;
- default:
- return (events & (POLLHUP | POLLERR)) ?
- Poller::DISCONNECTED : Poller::INVALID;
+ case POLLIN: return Poller::READABLE;
+ case POLLOUT: return Poller::WRITABLE;
+ case POLLIN | POLLOUT: return Poller::READ_WRITABLE;
+ default:
+ return (events & (POLLHUP | POLLERR)) ?
+ Poller::DISCONNECTED : Poller::INVALID;
}
}
-
+
PollerPrivate() :
- portId(::port_create()) {
+ portId(::port_create()),
+ isShutdown(false) {
+ QPID_POSIX_CHECK(portId);
+ QPID_LOG(trace, "port_create returned port Id: " << portId);
}
~PollerPrivate() {
}
+
+ void interrupt() {
+ //Send an Alarm to the port
+ //We need to send a nonzero event mask, using POLLHUP,
+ //nevertheless the wait method will only look for a PORT_ALERT_SET
+ QPID_LOG(trace, "Sending a port_alert to " << portId);
+ QPID_POSIX_CHECK(::port_alert(portId, PORT_ALERT_SET, POLLHUP,
+ &static_cast<PollerHandle&>(interruptHandle)));
+ }
};
void Poller::addFd(PollerHandle& handle, Direction dir) {
@@ -177,7 +240,6 @@ void Poller::addFd(PollerHandle& handle, Direction dir) {
QPID_LOG(trace, "Poller::addFd(handle=" << &handle
<< "[" << typeid(&handle).name()
<< "], fd=" << eh.fd << ")");
- //assert(dynamic_cast<DispatchHandle*>(&handle));
}
void Poller::delFd(PollerHandle& handle) {
@@ -223,17 +285,56 @@ void Poller::rearmFd(PollerHandle& handle) {
}
void Poller::shutdown() {
- //Send an Alarm to the port
- //We need to send a nonzero event mask, using POLLHUP, but
- //The wait method will only look for a PORT_ALERT_SET
- QPID_POSIX_CHECK(::port_alert(impl->portId, PORT_ALERT_SET, POLLHUP, NULL));
- QPID_LOG(trace, "Poller::shutdown");
+ //Allow sloppy code to shut us down more than once
+ if (impl->isShutdown)
+ return;
+
+ impl->isShutdown = true;
+ impl->interrupt();
+}
+
+bool Poller::interrupt(PollerHandle& handle) {
+ PollerPrivate::InterruptHandle& ih = impl->interruptHandle;
+ PollerHandlePrivate& eh = *static_cast<PollerHandle&>(ih).impl;
+ ScopedLock<Mutex> l(eh.lock);
+ ih.addHandle(handle);
+ impl->interrupt();
+ eh.setActive();
+ return true;
+}
+
+void Poller::run() {
+ // Make sure we can't be interrupted by signals at a bad time
+ ::sigset_t ss;
+ ::sigfillset(&ss);
+ ::pthread_sigmask(SIG_SETMASK, &ss, 0);
+
+ do {
+ Event event = wait();
+
+ // If can read/write then dispatch appropriate callbacks
+ if (event.handle) {
+ event.process();
+ } else {
+ // Handle shutdown
+ switch (event.type) {
+ case SHUTDOWN:
+ return;
+ default:
+ // This should be impossible
+ assert(false);
+ }
+ }
+ } while (true);
}
Poller::Event Poller::wait(Duration timeout) {
timespec_t tout;
timespec_t* ptout = NULL;
port_event_t pe;
+
+ AbsTime targetTimeout = (timeout == TIME_INFINITE) ? FAR_FUTURE :
+ AbsTime(now(), timeout);
if (timeout != TIME_INFINITE) {
tout.tv_sec = 0;
@@ -243,12 +344,21 @@ Poller::Event Poller::wait(Duration timeout) {
do {
PollerHandleDeletionManager.markAllUnusedInThisThread();
- QPID_LOG(trace, "About to enter port_get. Thread "
- << pthread_self()
+ QPID_LOG(trace, "About to enter port_get on " << impl->portId
+ << ". Thread " << pthread_self()
<< ", timeout=" << timeout);
-
+
+
int rc = ::port_get(impl->portId, &pe, ptout);
+ QPID_LOG(trace, "port_get on " << impl->portId
+ << " returned " << rc);
+
+ if (impl->isShutdown) {
+ PollerHandleDeletionManager.markAllUnusedInThisThread();
+ return Event(0, SHUTDOWN);
+ }
+
if (rc < 0) {
switch (errno) {
case EINTR:
@@ -259,33 +369,61 @@ Poller::Event Poller::wait(Duration timeout) {
QPID_POSIX_CHECK(rc);
}
} else {
- //We use alert mode to notify the shutdown of the Poller
- if (pe.portev_source == PORT_SOURCE_ALERT) {
- return Event(0, SHUTDOWN);
- }
- if (pe.portev_source == PORT_SOURCE_FD) {
- PollerHandle *handle = static_cast<PollerHandle*>(pe.portev_user);
- PollerHandlePrivate& eh = *handle->impl;
- ScopedLock<Mutex> l(eh.lock);
- QPID_LOG(trace, "About to send handle: " << handle);
+ PollerHandle* handle = static_cast<PollerHandle*>(pe.portev_user);
+ PollerHandlePrivate& eh = *handle->impl;
+ ScopedLock<Mutex> l(eh.lock);
+
+ if (eh.isActive()) {
+ QPID_LOG(trace, "Handle is active");
+ //We use alert mode to notify interrupts
+ if (pe.portev_source == PORT_SOURCE_ALERT &&
+ handle == &impl->interruptHandle) {
+ QPID_LOG(trace, "Interrupt notified");
+
+ PollerHandle* wrappedHandle = impl->interruptHandle.getHandle();
+
+ if (impl->interruptHandle.queuedHandles()) {
+ impl->interrupt();
+ eh.setActive();
+ } else {
+ eh.setInactive();
+ }
+ return Event(wrappedHandle, INTERRUPTED);
+ }
- if (eh.isActive()) {
- if (pe.portev_events & POLLHUP) {
- if (eh.isHungup()) {
- return Event(handle, DISCONNECTED);
+ if (pe.portev_source == PORT_SOURCE_FD) {
+ QPID_LOG(trace, "About to send handle: " << handle);
+ if (pe.portev_events & POLLHUP) {
+ if (eh.isHungup()) {
+ return Event(handle, DISCONNECTED);
+ }
+ eh.setHungup();
+ } else {
+ eh.setInactive();
}
- eh.setHungup();
- } else {
- eh.setInactive();
- }
- QPID_LOG(trace, "Sending event (thread: "
- << pthread_self() << ") for handle " << handle
- << ", direction= "
- << PollerPrivate::pollToDirection(pe.portev_events));
- return Event(handle, PollerPrivate::pollToDirection(pe.portev_events));
+ QPID_LOG(trace, "Sending event (thread: "
+ << pthread_self() << ") for handle " << handle
+ << ", direction= "
+ << PollerPrivate::pollToDirection(pe.portev_events));
+ return Event(handle, PollerPrivate::pollToDirection(pe.portev_events));
+ }
+ } else if (eh.isDeleted()) {
+ //Remove the handle from the poller
+ int rc = ::port_dissociate(impl->portId, PORT_SOURCE_FD,
+ (uintptr_t) eh.fd);
+ if (rc == -1 && errno != EBADFD) {
+ QPID_POSIX_CHECK(rc);
}
}
}
+
+ if (timeout == TIME_INFINITE) {
+ continue;
+ }
+ if (rc == 0 && now() > targetTimeout) {
+ PollerHandleDeletionManager.markAllUnusedInThisThread();
+ return Event(0, TIMEOUT);
+ }
} while (true);
}
diff --git a/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp
new file mode 100755
index 0000000000..0075a89021
--- /dev/null
+++ b/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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/sys/SystemInfo.h"
+
+#define BSD_COMP
+#include <sys/ioctl.h>
+#include <netdb.h>
+#undef BDS_COMP
+
+
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+#include <procfs.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+using namespace std;
+
+namespace qpid {
+namespace sys {
+
+long SystemInfo::concurrency() {
+ return sysconf(_SC_NPROCESSORS_ONLN);
+}
+
+bool SystemInfo::getLocalHostname(TcpAddress &address) {
+ char name[MAXHOSTNAMELEN];
+ if (::gethostname(name, sizeof(name)) != 0)
+ return false;
+ address.host = name;
+ return true;
+}
+
+static const string LOCALHOST("127.0.0.1");
+
+void SystemInfo::getLocalIpAddresses(uint16_t port,
+ std::vector<Address> &addrList) {
+ int s = socket(PF_INET, SOCK_STREAM, 0);
+ for (int i=1;;i++) {
+ struct lifreq ifr;
+ ifr.lifr_index = i;
+ if (::ioctl(s, SIOCGIFADDR, &ifr) < 0) {
+ break;
+ }
+ struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.lifr_addr;
+ std::string addr(inet_ntoa(sin->sin_addr));
+ if (addr != LOCALHOST)
+ addrList.push_back(TcpAddress(addr, port));
+ }
+ if (addrList.empty()) {
+ addrList.push_back(TcpAddress(LOCALHOST, port));
+ }
+ close (s);
+}
+
+void SystemInfo::getSystemId(std::string &osName,
+ std::string &nodeName,
+ std::string &release,
+ std::string &version,
+ std::string &machine) {
+ struct utsname _uname;
+ if (uname (&_uname) == 0) {
+ osName = _uname.sysname;
+ nodeName = _uname.nodename;
+ release = _uname.release;
+ version = _uname.version;
+ machine = _uname.machine;
+ }
+}
+
+uint32_t SystemInfo::getProcessId()
+{
+ return (uint32_t) ::getpid();
+}
+
+uint32_t SystemInfo::getParentProcessId()
+{
+ return (uint32_t) ::getppid();
+}
+
+string SystemInfo::getProcessName()
+{
+ psinfo processInfo;
+ char procfile[PATH_MAX];
+ int fd;
+ string value;
+
+ snprintf(procfile, PATH_MAX, "/proc/%d/psinfo", getProcessId());
+ if ((fd = open(procfile, O_RDONLY)) >= 0) {
+ if (read(fd, (void *) &processInfo, sizeof(processInfo)) == sizeof(processInfo)) {
+ value = processInfo.pr_fname;
+ }
+ }
+ return value;
+}
+
+}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
index 9be75af47d..624683ae7d 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
@@ -90,7 +90,7 @@ void SslAcceptor::readable(DispatchHandle& h) {
// TODO: Currently we ignore the peers address, perhaps we should
// log it or use it for connection acceptance.
try {
- s = socket.accept(0, 0);
+ s = socket.accept();
if (s) {
acceptedCallback(*s);
} else {
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
index 597fbe57db..dc816b403b 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
@@ -201,9 +201,9 @@ int SslSocket::listen(uint16_t port, int backlog, const std::string& certName, b
return ntohs(name.sin_port);
}
-SslSocket* SslSocket::accept(struct sockaddr *addr, socklen_t *addrlen) const
+SslSocket* SslSocket::accept() const
{
- int afd = ::accept(impl->fd, addr, addrlen);
+ int afd = ::accept(impl->fd, 0, 0);
if ( afd >= 0) {
return new SslSocket(new IOHandlePrivate(afd), prototype);
} else if (errno == EAGAIN) {
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
index a82e9133e8..7434667b78 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
@@ -64,7 +64,7 @@ public:
* Accept a connection from a socket that is already listening
* and has an incoming connection
*/
- SslSocket* accept(struct sockaddr *addr, socklen_t *addrlen) const;
+ SslSocket* accept() const;
// TODO The following are raw operations, maybe they need better wrapping?
int read(void *buf, size_t count) const;
diff --git a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
index 37d87947a2..0a3c36452c 100644
--- a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
@@ -690,10 +690,9 @@ void AsynchIO::writeComplete(AsynchWriteResult *result) {
}
}
- // If there are no writes outstanding, the priority is to write any
- // remaining buffers first (either queued or via idle), then close the
- // socket if that's queued.
- // opsInProgress handled in completion()
+ // If there are no writes outstanding, check for more writes to initiate
+ // (either queued or via idle). The opsInProgress count is handled in
+ // completion()
if (!writeInProgress) {
bool writing = false;
{
@@ -706,11 +705,8 @@ void AsynchIO::writeComplete(AsynchWriteResult *result) {
writing = true;
}
}
- if (!writing) {
- if (queuedClose)
- close();
- else
- notifyIdle();
+ if (!writing && !queuedClose) {
+ notifyIdle();
}
}
return;
@@ -757,9 +753,11 @@ void AsynchIO::completion(AsynchIoResult *result) {
}
working = false;
}
- // Lock released; ok to delete if all is done.
- if (opsInProgress == 0 && queuedDelete)
- delete this;
+ // Lock released; ok to close if ops are done and close requested.
+ // Layer above will call back to queueForDeletion()
+ if (opsInProgress == 0 && queuedClose) {
+ close();
+ }
}
} // namespace windows
diff --git a/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h b/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h
index 80168fab88..47b1d16a76 100755
--- a/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h
+++ b/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h
@@ -32,8 +32,6 @@ typedef __int64 int64_t;
// Visual Studio doesn't define other common types, so set them up here too.
typedef int pid_t;
-typedef int socklen_t;
-typedef unsigned int size_t;
typedef int ssize_t;
typedef unsigned int uint;
diff --git a/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp b/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp
new file mode 100644
index 0000000000..ed0f7c3917
--- /dev/null
+++ b/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp
@@ -0,0 +1,125 @@
+#ifndef QPID_SYS_WINDOWS_POLLABLECONDITION_CPP
+#define QPID_SYS_WINDOWS_POLLABLECONDITION_CPP
+
+/*
+ *
+ * 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/sys/PollableCondition.h"
+#include "qpid/sys/IOHandle.h"
+#include "AsynchIoResult.h"
+#include "IoHandlePrivate.h"
+
+#include <boost/bind.hpp>
+#include <windows.h>
+
+namespace qpid {
+namespace sys {
+
+// PollableConditionPrivate will reuse the IocpPoller's ability to queue
+// a completion to the IOCP and have it dispatched to the completer callback
+// noted in the IOHandlePrivate when the request is queued. The
+// AsynchCallbackRequest object is not really used - we already have the
+// desired callback for the user of PollableCondition.
+class PollableConditionPrivate : private IOHandle {
+ friend class PollableCondition;
+
+private:
+ PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller);
+ ~PollableConditionPrivate();
+
+ void poke();
+ void dispatch(AsynchIoResult *result);
+
+private:
+ PollableCondition::Callback cb;
+ PollableCondition& parent;
+ boost::shared_ptr<sys::Poller> poller;
+ LONG isSet;
+ LONG armed;
+};
+
+PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : IOHandle(new sys::IOHandlePrivate(INVALID_SOCKET,
+ boost::bind(&PollableConditionPrivate::dispatch, this, _1))),
+ cb(cb), parent(parent), poller(poller), isSet(0), armed(0)
+{
+}
+
+PollableConditionPrivate::~PollableConditionPrivate()
+{
+}
+
+void PollableConditionPrivate::poke()
+{
+ if (!armed)
+ return;
+
+ // addFd will queue a completion for the IOCP; when it's handled, a
+ // poller thread will call back to dispatch() below.
+ PollerHandle ph(*this);
+ poller->addFd(ph, Poller::INPUT);
+}
+
+void PollableConditionPrivate::dispatch(AsynchIoResult *result)
+{
+ delete result; // Poller::addFd() allocates this
+ cb(parent);
+}
+
+ /* PollableCondition */
+
+PollableCondition::PollableCondition(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : impl(new PollableConditionPrivate(cb, *this, poller))
+{
+}
+
+PollableCondition::~PollableCondition()
+{
+ delete impl;
+}
+
+void PollableCondition::set() {
+ // Add one to the set count and poke it to provoke a callback
+ ::InterlockedIncrement(&impl->isSet);
+ impl->poke();
+}
+
+bool PollableCondition::clear() {
+ return (0 != ::InterlockedExchange(&impl->isSet, 0));
+}
+
+void PollableCondition::disarm() {
+ ::InterlockedExchange(&impl->armed, 0);
+}
+
+void PollableCondition::rearm() {
+ if (0 == ::InterlockedExchange(&impl->armed, 1) && impl->isSet)
+ impl->poke();
+}
+
+}} // namespace qpid::sys
+
+#endif /*!QPID_SYS_WINDOWS_POLLABLECONDITION_CPP*/
diff --git a/qpid/cpp/src/qpid/sys/windows/Socket.cpp b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
index a9959bf43e..93059d03ef 100755
--- a/qpid/cpp/src/qpid/sys/windows/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
@@ -262,9 +262,9 @@ int Socket::listen(uint16_t port, int backlog) const
return ntohs(name.sin_port);
}
-Socket* Socket::accept(struct sockaddr *addr, socklen_t *addrlen) const
+Socket* Socket::accept() const
{
- SOCKET afd = ::accept(impl->fd, addr, addrlen);
+ SOCKET afd = ::accept(impl->fd, 0, 0);
if (afd != INVALID_SOCKET)
return new Socket(new IOHandlePrivate(afd));
else if (WSAGetLastError() == EAGAIN)
diff --git a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
index b887cac58b..3e2fcb1517 100755
--- a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
@@ -29,6 +29,7 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
+#include <tlhelp32.h>
#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX 256
@@ -157,4 +158,41 @@ void SystemInfo::getSystemId (std::string &osName,
}
}
+uint32_t SystemInfo::getProcessId()
+{
+ return static_cast<uint32_t>(::GetCurrentProcessId());
+}
+
+uint32_t SystemInfo::getParentProcessId()
+{
+ // Only want info for the current process, so ask for something specific.
+ // The module info won't be used here but it keeps the snapshot limited to
+ // the current process so a search through all processes is not needed.
+ HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
+ if (snap == INVALID_HANDLE_VALUE)
+ return 0;
+ PROCESSENTRY32 entry;
+ entry.dwSize = sizeof(entry);
+ if (!Process32First(snap, &entry))
+ entry.th32ParentProcessID = 0;
+ CloseHandle(snap);
+ return static_cast<uint32_t>(entry.th32ParentProcessID);
+}
+
+std::string SystemInfo::getProcessName()
+{
+ // Only want info for the current process, so ask for something specific.
+ // The module info won't be used here but it keeps the snapshot limited to
+ // the current process so a search through all processes is not needed.
+ HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
+ if (snap == INVALID_HANDLE_VALUE)
+ return 0;
+ PROCESSENTRY32 entry;
+ entry.dwSize = sizeof(entry);
+ if (!Process32First(snap, &entry))
+ entry.szExeFile[0] = '\0';
+ CloseHandle(snap);
+ return std::string(entry.szExeFile);
+}
+
}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/windows/uuid.h b/qpid/cpp/src/qpid/sys/windows/uuid.h
index a44ef2e9a3..7d003c3739 100644
--- a/qpid/cpp/src/qpid/sys/windows/uuid.h
+++ b/qpid/cpp/src/qpid/sys/windows/uuid.h
@@ -23,6 +23,7 @@
*/
#include <Rpc.h>
+#include "qpid/CommonImportExport.h"
#ifdef uuid_t /* Done in rpcdce.h */
# undef uuid_t
@@ -31,11 +32,11 @@
namespace qpid { namespace sys { const size_t UuidSize = 16; }}
typedef uint8_t uuid_t[qpid::sys::UuidSize];
-void uuid_clear (uuid_t uu);
-void uuid_copy (uuid_t dst, const uuid_t src);
-void uuid_generate (uuid_t out);
-int uuid_is_null (const uuid_t uu); // Returns 1 if null, else 0
-int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1
-void uuid_unparse (const uuid_t uu, char *out);
+QPID_COMMON_EXTERN void uuid_clear (uuid_t uu);
+QPID_COMMON_EXTERN void uuid_copy (uuid_t dst, const uuid_t src);
+QPID_COMMON_EXTERN void uuid_generate (uuid_t out);
+QPID_COMMON_EXTERN int uuid_is_null (const uuid_t uu); // Returns 1 if null, else 0
+QPID_COMMON_EXTERN int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1
+QPID_COMMON_EXTERN void uuid_unparse (const uuid_t uu, char *out);
#endif /*!_sys_windows_uuid_h*/
diff --git a/qpid/cpp/src/qpid/xml/XmlExchange.cpp b/qpid/cpp/src/qpid/xml/XmlExchange.cpp
index 5197b239d0..4e9de49ad5 100644
--- a/qpid/cpp/src/qpid/xml/XmlExchange.cpp
+++ b/qpid/cpp/src/qpid/xml/XmlExchange.cpp
@@ -33,6 +33,9 @@
#include "qpid/Plugin.h"
#include <xercesc/framework/MemBufInputSource.hpp>
+
+#include <xqilla/ast/XQGlobalVariable.hpp>
+
#include <xqilla/context/ItemFactory.hpp>
#include <xqilla/xqilla-simple.hpp>
@@ -62,17 +65,6 @@ XmlExchange::XmlExchange(const std::string& _name, bool _durable,
mgmtExchange->set_type (typeName);
}
-/*
- * Use the name of the query as the binding key.
- *
- * The first time a given name is used in a binding, the query body
- * must be provided.After that, no query body should be present.
- *
- * To modify an installed query, the user must first unbind the
- * existing query, then replace it by binding again with the same
- * name.
- *
- */
// #### TODO: The Binding should take the query text
// #### only. Consider encapsulating the entire block, including
@@ -94,6 +86,21 @@ bool XmlExchange::bind(Queue::shared_ptr queue, const string& routingKey, const
bindings.add(binding);
QPID_LOG(trace, "Bound successfully with query: " << queryText );
+ binding->parse_message_content = false;
+
+ if (query->getQueryBody()->getStaticAnalysis().areContextFlagsUsed()) {
+ binding->parse_message_content = true;
+ }
+ else {
+ GlobalVariables &vars = const_cast<GlobalVariables&>(query->getVariables());
+ for(GlobalVariables::iterator it = vars.begin(); it != vars.end(); ++it) {
+ if ((*it)->getStaticAnalysis().areContextFlagsUsed()) {
+ binding->parse_message_content = true;
+ break;
+ }
+ }
+ }
+
if (mgmtExchange != 0) {
mgmtExchange->inc_bindingCount();
((_qmf::Queue*) queue->GetManagementObject())->inc_bindingCount();
@@ -126,59 +133,74 @@ bool XmlExchange::unbind(Queue::shared_ptr queue, const string& routingKey, cons
}
}
-bool XmlExchange::matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args)
+bool XmlExchange::matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args, bool parse_message_content)
{
- // ### TODO: Need istream for frameset
- // Hack alert - the following code does not work for really large messages
-
string msgContent;
try {
- msg.getMessage().getFrames().getContent(msgContent);
-
- QPID_LOG(trace, "matches: query is [" << UTF8(query->getQueryText()) << "]");
- QPID_LOG(trace, "matches: message content is [" << msgContent << "]");
-
- boost::scoped_ptr<DynamicContext> context(query->createDynamicContext());
- if (!context.get()) {
- throw InternalErrorException(QPID_MSG("Query context looks munged ..."));
- }
-
- XERCES_CPP_NAMESPACE::MemBufInputSource xml((const XMLByte*) msgContent.c_str(),
- msgContent.length(), "input" );
- Sequence seq(context->parseDocument(xml));
-
- if (args) {
- FieldTable::ValueMap::const_iterator v = args->begin();
- for(; v != args->end(); ++v) {
- // ### TODO: Do types properly
- if (v->second->convertsTo<std::string>()) {
- QPID_LOG(trace, "XmlExchange, external variable: " << v->first << " = " << v->second->getData().getString().c_str());
- Item::Ptr value = context->getItemFactory()->createString(X(v->second->getData().getString().c_str()), context.get());
- context->setExternalVariable(X(v->first.c_str()), value);
- }
- }
- }
-
- if(!seq.isEmpty() && seq.first()->isNode()) {
- context->setContextItem(seq.first());
- context->setContextPosition(1);
- context->setContextSize(1);
- }
- Result result = query->execute(context.get());
- return result->getEffectiveBooleanValue(context.get(), 0);
+ QPID_LOG(trace, "matches: query is [" << UTF8(query->getQueryText()) << "]");
+
+ boost::scoped_ptr<DynamicContext> context(query->createDynamicContext());
+ if (!context.get()) {
+ throw InternalErrorException(QPID_MSG("Query context looks munged ..."));
+ }
+
+ if (parse_message_content) {
+
+ msg.getMessage().getFrames().getContent(msgContent);
+
+ QPID_LOG(trace, "matches: message content is [" << msgContent << "]");
+
+ XERCES_CPP_NAMESPACE::MemBufInputSource xml((const XMLByte*) msgContent.c_str(),
+ msgContent.length(), "input" );
+
+ // This will parse the document using either Xerces or FastXDM, depending
+ // on your XQilla configuration. FastXDM can be as much as 10x faster.
+
+ Sequence seq(context->parseDocument(xml));
+
+ if(!seq.isEmpty() && seq.first()->isNode()) {
+ context->setContextItem(seq.first());
+ context->setContextPosition(1);
+ context->setContextSize(1);
+ }
+ }
+
+ if (args) {
+ FieldTable::ValueMap::const_iterator v = args->begin();
+ for(; v != args->end(); ++v) {
+ // ### TODO: Do types properly
+ if (v->second->convertsTo<std::string>()) {
+ QPID_LOG(trace, "XmlExchange, external variable: " << v->first << " = " << v->second->getData().getString().c_str());
+ Item::Ptr value = context->getItemFactory()->createString(X(v->second->getData().getString().c_str()), context.get());
+ context->setExternalVariable(X(v->first.c_str()), value);
+ }
+ }
+ }
+
+ Result result = query->execute(context.get());
+ return result->getEffectiveBooleanValue(context.get(), 0);
}
catch (XQException& e) {
- QPID_LOG(warning, "Could not parse XML content (or message headers):" << msgContent);
- return 0;
+ QPID_LOG(warning, "Could not parse XML content (or message headers):" << msgContent);
}
catch (...) {
- QPID_LOG(warning, "Unexpected error routing message: " << msgContent);
- return 0;
+ QPID_LOG(warning, "Unexpected error routing message: " << msgContent);
}
return 0;
}
+// Future optimization: If any query in a binding for a given routing key requires
+// message content, parse the message once, and use that parsed form for all bindings.
+//
+// Future optimization: XQilla does not currently do document projection for data
+// accessed via the context item. If there is a single query for a given routing key,
+// and it accesses document data, this could be a big win.
+//
+// Document projection often is not a win if you have multiple queries on the same data.
+// But for very large messages, if all these queries are on the first part of the data,
+// it could still be a big win.
+
void XmlExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* args)
{
PreRoute pr(msg, this);
@@ -192,7 +214,7 @@ void XmlExchange::route(Deliverable& msg, const string& routingKey, const FieldT
int count(0);
for (std::vector<XmlBinding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); i++) {
- if ((*i)->xquery && matches((*i)->xquery, msg, args)) { // Overly defensive? There should always be a query ...
+ if (matches((*i)->xquery, msg, args, (*i)->parse_message_content)) {
msg.deliverTo((*i)->queue);
count++;
QPID_LOG(trace, "Delivered to queue" );
diff --git a/qpid/cpp/src/qpid/xml/XmlExchange.h b/qpid/cpp/src/qpid/xml/XmlExchange.h
index 066a26489d..7bec480bde 100644
--- a/qpid/cpp/src/qpid/xml/XmlExchange.h
+++ b/qpid/cpp/src/qpid/xml/XmlExchange.h
@@ -46,9 +46,10 @@ class XmlExchange : public virtual Exchange {
typedef qpid::sys::CopyOnWriteArray<XmlBinding::shared_ptr> vector;
boost::shared_ptr<XQQuery> xquery;
+ bool parse_message_content;
XmlBinding(const std::string& key, const Queue::shared_ptr queue, Exchange* parent, Query query):
- Binding(key, queue, parent), xquery(query) {}
+ Binding(key, queue, parent), xquery(query), parse_message_content(true) {}
};
@@ -58,7 +59,7 @@ class XmlExchange : public virtual Exchange {
XQilla xqilla;
qpid::sys::RWlock lock;
- bool matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args);
+ bool matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args, bool parse_message_content);
public:
static const std::string typeName;
diff --git a/qpid/cpp/src/replication.mk b/qpid/cpp/src/replication.mk
index 6830f99d36..c65a7ae3b9 100644
--- a/qpid/cpp/src/replication.mk
+++ b/qpid/cpp/src/replication.mk
@@ -29,6 +29,9 @@ replicating_listener_la_SOURCES = \
qpid/replication/ReplicatingEventListener.h
replicating_listener_la_LIBADD = libqpidbroker.la
+if SUNOS
+ replicating_listener_la_LIBADD += libqpidcommon.la -lboost_program_options -luuid $(SUNCC_RUNTIME_LIBS)
+endif
replicating_listener_la_LDFLAGS = $(PLUGINLDFLAGS)
@@ -43,4 +46,7 @@ replication_exchange_la_SOURCES = \
replication_exchange_la_LIBADD = libqpidbroker.la
+if SUNOS
+ replication_exchange_la_LIBADD += libqpidcommon.la -lboost_program_options -lCrun -luuid
+endif
replication_exchange_la_LDFLAGS = $(PLUGINLDFLAGS)
diff --git a/qpid/cpp/src/tests/ClientSessionTest.cpp b/qpid/cpp/src/tests/ClientSessionTest.cpp
index 1658f3d4ec..589e1154e1 100644
--- a/qpid/cpp/src/tests/ClientSessionTest.cpp
+++ b/qpid/cpp/src/tests/ClientSessionTest.cpp
@@ -428,8 +428,8 @@ QPID_AUTO_TEST_CASE(testConcurrentSenders)
for (size_t i = 0; i < 5; i++) {
publishers.push_back(new Publisher(connection, message, 100));
}
- for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::start, _1));
- for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::join, _1));
+ std::for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::start, _1));
+ std::for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::join, _1));
connection.close();
}
@@ -564,6 +564,24 @@ QPID_AUTO_TEST_CASE(testSessionManagerSetFlowControl) {
BOOST_CHECK_EQUAL("my-message", got.getData());
}
+QPID_AUTO_TEST_CASE(testGetThenSubscribe) {
+ ClientSessionFixture fix;
+ std::string name("myqueue");
+ fix.session.queueDeclare(arg::queue=name, arg::exclusive=true, arg::autoDelete=true);
+ fix.session.messageTransfer(arg::content=Message("one", name));
+ fix.session.messageTransfer(arg::content=Message("two", name));
+ Message got;
+ BOOST_CHECK(fix.subs.get(got, name));
+ BOOST_CHECK_EQUAL("one", got.getData());
+
+ DummyListener listener(fix.session, name, 1);
+ listener.run();
+ BOOST_CHECK_EQUAL(1u, listener.messages.size());
+ if (!listener.messages.empty()) {
+ BOOST_CHECK_EQUAL("two", listener.messages[0].getData());
+ }
+}
+
QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/ClusterFixture.cpp b/qpid/cpp/src/tests/ClusterFixture.cpp
index 3a0ea74098..5658957b48 100644
--- a/qpid/cpp/src/tests/ClusterFixture.cpp
+++ b/qpid/cpp/src/tests/ClusterFixture.cpp
@@ -109,7 +109,7 @@ void ClusterFixture::addLocal() {
Args args(makeArgs(prefix));
vector<const char*> argv(args.size());
transform(args.begin(), args.end(), argv.begin(), boost::bind(&string::c_str, _1));
- qpid::log::Logger::instance().setPrefix(os.str());
+ qpid::log::Logger::instance().setPrefix(prefix);
localBroker.reset(new BrokerFixture(parseOpts(argv.size(), &argv[0])));
push_back(localBroker->getPort());
forkedBrokers.push_back(shared_ptr<ForkedBroker>());
diff --git a/qpid/cpp/src/tests/DispatcherTest.cpp b/qpid/cpp/src/tests/DispatcherTest.cpp
index c2f6bca12a..c619a36438 100644
--- a/qpid/cpp/src/tests/DispatcherTest.cpp
+++ b/qpid/cpp/src/tests/DispatcherTest.cpp
@@ -78,9 +78,6 @@ void reader(DispatchHandle& h, int fd) {
h.rewatch();
}
-DispatchHandle* rh = 0;
-DispatchHandle* wh = 0;
-
void rInterrupt(DispatchHandle&) {
cerr << "R";
}
@@ -92,9 +89,27 @@ void wInterrupt(DispatchHandle&) {
DispatchHandle::Callback rcb = rInterrupt;
DispatchHandle::Callback wcb = wInterrupt;
+DispatchHandleRef *volatile rh = 0;
+DispatchHandleRef *volatile wh = 0;
+
+volatile bool stopWait = false;
+volatile bool phase1finished = false;
+
+timer_t timer;
+
+void stop_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) {
+ stopWait = true;
+}
+
void timer_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) {
- rh->call(rcb);
- wh->call(wcb);
+ static int count = 0;
+ if (count++ < 10) {
+ rh->call(rcb);
+ wh->call(wcb);
+ } else {
+ phase1finished = true;
+ assert(::timer_delete(timer) == 0);
+ }
}
int main(int /*argc*/, char** /*argv*/)
@@ -114,7 +129,7 @@ int main(int /*argc*/, char** /*argv*/)
// Setup sender and receiver
int sv[2];
- int rc = ::socketpair(AF_LOCAL, SOCK_STREAM, 0, sv);
+ int rc = ::socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
assert(rc >= 0);
// Set non-blocking
@@ -132,8 +147,8 @@ int main(int /*argc*/, char** /*argv*/)
PosixIOHandle f0(sv[0]);
PosixIOHandle f1(sv[1]);
- rh = new DispatchHandle(f0, boost::bind(reader, _1, sv[0]), 0, 0);
- wh = new DispatchHandle(f1, 0, boost::bind(writer, _1, sv[1], testString), 0);
+ rh = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0);
+ wh = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0);
rh->startWatch(poller);
wh->startWatch(poller);
@@ -155,10 +170,9 @@ int main(int /*argc*/, char** /*argv*/)
assert(rc == 0);
::sigevent se;
+ ::memset(&se, 0, sizeof(se)); // Clear to make valgrind happy (this *is* the neatest way to do this portably - sigh)
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGRTMIN;
- se.sigev_value.sival_ptr = 0;
- timer_t timer;
rc = ::timer_create(CLOCK_REALTIME, &se, &timer);
assert(rc == 0);
@@ -169,11 +183,52 @@ int main(int /*argc*/, char** /*argv*/)
rc = ::timer_settime(timer, 0, &ts, 0);
assert(rc == 0);
- // wait 2 minutes then shutdown
- ::sleep(60);
+ // wait
+ while (!phase1finished) {
+ ::sleep(1);
+ }
+
+ // Now test deleting/creating DispatchHandles in tight loop, so that we are likely to still be using the
+ // attached PollerHandles after deleting the DispatchHandle
+ DispatchHandleRef* t = wh;
+ wh = 0;
+ delete t;
+ t = rh;
+ rh = 0;
+ delete t;
+
+ sa.sa_sigaction = stop_handler;
+ rc = ::sigaction(SIGRTMIN, &sa,0);
+ assert(rc == 0);
+
+ itimerspec nts = {
+ /*.it_value = */ {30, 0}, // s, ns
+ /*.it_interval = */ {30, 0}}; // s, ns
+
+ rc = ::timer_create(CLOCK_REALTIME, &se, &timer);
+ assert(rc == 0);
+ rc = ::timer_settime(timer, 0, &nts, 0);
+ assert(rc == 0);
+
+ DispatchHandleRef* rh1;
+ DispatchHandleRef* wh1;
+
+ struct timespec w = {0, 1000000};
+ while (!stopWait) {
+ rh1 = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0);
+ wh1 = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0);
+ rh1->startWatch(poller);
+ wh1->startWatch(poller);
+
+ ::nanosleep(&w, 0);
+
+ delete wh1;
+ delete rh1;
+ }
rc = ::timer_delete(timer);
assert(rc == 0);
+
poller->shutdown();
dt.join();
dt1.join();
diff --git a/qpid/cpp/src/tests/FieldTable.cpp b/qpid/cpp/src/tests/FieldTable.cpp
index 6b364723cf..9f2fd45b73 100644
--- a/qpid/cpp/src/tests/FieldTable.cpp
+++ b/qpid/cpp/src/tests/FieldTable.cpp
@@ -22,7 +22,7 @@
#include "qpid/framing/Array.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/framing/FieldValue.h"
-#include <alloca.h>
+#include "qpid/sys/alloca.h"
#include "unit_test.h"
diff --git a/qpid/cpp/src/tests/ForkedBroker.cpp b/qpid/cpp/src/tests/ForkedBroker.cpp
index 2b90068549..f90f76aeb2 100644
--- a/qpid/cpp/src/tests/ForkedBroker.cpp
+++ b/qpid/cpp/src/tests/ForkedBroker.cpp
@@ -22,6 +22,9 @@
#include "ForkedBroker.h"
#include <boost/bind.hpp>
#include <algorithm>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
ForkedBroker::ForkedBroker(const Args& args) { init(args); }
@@ -41,9 +44,9 @@ void ForkedBroker::kill(int sig) {
if (::kill(savePid, sig) < 0)
throw ErrnoException("kill failed");
int status;
- if (::waitpid(savePid, &status, 0) < 0)
+ if (::waitpid(savePid, &status, 0) < 0 && sig != 9)
throw ErrnoException("wait for forked process failed");
- if (WEXITSTATUS(status) != 0)
+ if (WEXITSTATUS(status) != 0 && sig != 9)
throw qpid::Exception(QPID_MSG("Forked broker exited with: " << WEXITSTATUS(status)));
}
diff --git a/qpid/cpp/src/tests/FrameDecoder.cpp b/qpid/cpp/src/tests/FrameDecoder.cpp
new file mode 100644
index 0000000000..f5db66d5fe
--- /dev/null
+++ b/qpid/cpp/src/tests/FrameDecoder.cpp
@@ -0,0 +1,73 @@
+/*
+ *
+ * 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 "unit_test.h"
+#include "qpid/framing/AMQFrame.h"
+#include "qpid/framing/FrameDecoder.h"
+#include "qpid/framing/AMQContentBody.h"
+#include "qpid/framing/Buffer.h"
+#include <string>
+
+
+QPID_AUTO_TEST_SUITE(FrameDecoderTest)
+
+using namespace std;
+using namespace qpid::framing;
+
+
+string makeData(int size) {
+ string data;
+ data.resize(size);
+ for (int i =0; i < size; ++i)
+ data[i] = 'a' + (i%26);
+ return data;
+}
+string encodeFrame(string data) {
+ AMQFrame f((AMQContentBody(data)));
+ string encoded;
+ encoded.resize(f.encodedSize());
+ Buffer b(&encoded[0], encoded.size());
+ f.encode(b);
+ return encoded;
+}
+
+string getData(const AMQFrame& frame) {
+ const AMQContentBody* content = dynamic_cast<const AMQContentBody*>(frame.getBody());
+ BOOST_CHECK(content);
+ return content->getData();
+}
+
+QPID_AUTO_TEST_CASE(testByteFragments) {
+ string data = makeData(42);
+ string encoded = encodeFrame(data);
+ FrameDecoder decoder;
+ for (size_t i = 0; i < encoded.size()-1; ++i) {
+ Buffer buf(&encoded[i], 1);
+ BOOST_CHECK(!decoder.decode(buf));
+ }
+ Buffer buf(&encoded[encoded.size()-1], 1);
+ BOOST_CHECK(decoder.decode(buf));
+ BOOST_CHECK_EQUAL(data, getData(decoder.getFrame()));
+}
+
+
+
+QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am
index 9da85eaad4..9a81ef18b3 100644
--- a/qpid/cpp/src/tests/Makefile.am
+++ b/qpid/cpp/src/tests/Makefile.am
@@ -94,7 +94,9 @@ unit_test_SOURCES= unit_test.cpp unit_test.h \
QueueEvents.cpp \
ProxyTest.cpp \
RetryList.cpp \
- RateFlowcontrolTest.cpp
+ RateFlowcontrolTest.cpp \
+ FrameDecoder.cpp \
+ ReplicationTest.cpp
if HAVE_XML
unit_test_SOURCES+= XmlClientSessionTest.cpp
@@ -163,7 +165,7 @@ header_test_LDADD=$(lib_client)
check_PROGRAMS+=failover_soak
failover_soak_SOURCES=failover_soak.cpp ForkedBroker.h ForkedBroker.cpp
-failover_soak_LDADD=$(lib_client)
+failover_soak_LDADD=$(lib_client) $(lib_broker)
check_PROGRAMS+=declare_queues
declare_queues_SOURCES=declare_queues.cpp
@@ -195,11 +197,11 @@ sender_LDADD=$(lib_client)
check_PROGRAMS+=PollerTest
PollerTest_SOURCES=PollerTest.cpp
-PollerTest_LDADD=$(lib_common)
+PollerTest_LDADD=$(lib_common) $(SOCKLIBS)
check_PROGRAMS+=DispatcherTest
DispatcherTest_SOURCES=DispatcherTest.cpp
-DispatcherTest_LDADD=$(lib_common)
+DispatcherTest_LDADD=$(lib_common) $(SOCKLIBS)
TESTS_ENVIRONMENT = VALGRIND=$(VALGRIND) srcdir=$(srcdir) QPID_DATA_DIR= BOOST_TEST_SHOW_PROGRESS=yes $(srcdir)/run_test
@@ -255,9 +257,11 @@ CLEANFILES+=valgrind.out *.log *.vglog* dummy_test $(unit_wrappers)
# Longer running stability tests, not run by default check: target.
# Not run under valgrind, too slow
-LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak stop_broker reliable_replication_test
+LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak stop_broker \
+ reliable_replication_test federated_cluster_test_with_node_failure
-EXTRA_DIST+=fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak reliable_replication_test
+EXTRA_DIST+=fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak reliable_replication_test \
+ federated_cluster_test_with_node_failure
check-long:
$(MAKE) check TESTS="$(LONG_TESTS)" VALGRIND=
diff --git a/qpid/cpp/src/tests/MessageTest.cpp b/qpid/cpp/src/tests/MessageTest.cpp
index 8fd9a53c7c..cd63f64a37 100644
--- a/qpid/cpp/src/tests/MessageTest.cpp
+++ b/qpid/cpp/src/tests/MessageTest.cpp
@@ -24,13 +24,12 @@
#include "qpid/framing/MessageTransferBody.h"
#include "qpid/framing/FieldValue.h"
#include "qpid/framing/Uuid.h"
+#include "qpid/sys/alloca.h"
#include "unit_test.h"
#include <iostream>
-#include <alloca.h>
-using namespace boost;
using namespace qpid::broker;
using namespace qpid::framing;
@@ -44,7 +43,7 @@ QPID_AUTO_TEST_CASE(testEncodeDecode)
string data1("abcdefg");
string data2("hijklmn");
- intrusive_ptr<Message> msg(new Message());
+ boost::intrusive_ptr<Message> msg(new Message());
AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
AMQFrame header((AMQHeaderBody()));
diff --git a/qpid/cpp/src/tests/MessageUtils.h b/qpid/cpp/src/tests/MessageUtils.h
index 67a852aa10..6a12c72007 100644
--- a/qpid/cpp/src/tests/MessageUtils.h
+++ b/qpid/cpp/src/tests/MessageUtils.h
@@ -33,7 +33,7 @@ struct MessageUtils
static boost::intrusive_ptr<Message> createMessage(const string& exchange="", const string& routingKey="",
const Uuid& messageId=Uuid(true), uint64_t contentSize = 0)
{
- boost::intrusive_ptr<Message> msg(new Message());
+ boost::intrusive_ptr<broker::Message> msg(new broker::Message());
AMQFrame method(( MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
AMQFrame header((AMQHeaderBody()));
diff --git a/qpid/cpp/src/tests/PollerTest.cpp b/qpid/cpp/src/tests/PollerTest.cpp
index 4f11dc5901..5b6b09ef65 100644
--- a/qpid/cpp/src/tests/PollerTest.cpp
+++ b/qpid/cpp/src/tests/PollerTest.cpp
@@ -74,7 +74,7 @@ int main(int /*argc*/, char** /*argv*/)
try
{
int sv[2];
- int rc = ::socketpair(AF_LOCAL, SOCK_STREAM, 0, sv);
+ int rc = ::socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
assert(rc >= 0);
// Set non-blocking
diff --git a/qpid/cpp/src/tests/ProxyTest.cpp b/qpid/cpp/src/tests/ProxyTest.cpp
index 9007f3dc97..4ea10f7be9 100644
--- a/qpid/cpp/src/tests/ProxyTest.cpp
+++ b/qpid/cpp/src/tests/ProxyTest.cpp
@@ -23,7 +23,6 @@
#include "qpid/framing/AMQMethodBody.h"
#include "qpid/framing/ExecutionSyncBody.h"
#include "qpid/framing/Proxy.h"
-#include <alloca.h>
#include "unit_test.h"
diff --git a/qpid/cpp/src/tests/QueueEvents.cpp b/qpid/cpp/src/tests/QueueEvents.cpp
index 3e377d04b3..cd9439355e 100644
--- a/qpid/cpp/src/tests/QueueEvents.cpp
+++ b/qpid/cpp/src/tests/QueueEvents.cpp
@@ -27,6 +27,7 @@
#include "qpid/broker/QueueEvents.h"
#include "qpid/client/QueueOptions.h"
#include "qpid/framing/SequenceNumber.h"
+#include "qpid/sys/Dispatcher.h"
#include <boost/bind.hpp>
#include <boost/format.hpp>
@@ -37,7 +38,7 @@ using namespace qpid::broker;
using namespace qpid::sys;
using qpid::framing::SequenceNumber;
-struct DummyListener
+struct EventChecker
{
typedef std::deque<QueueEvents::Event> Events;
@@ -70,9 +71,9 @@ QPID_AUTO_TEST_CASE(testBasicEventProcessing)
sys::Dispatcher dispatcher(poller);
Thread dispatchThread(dispatcher);
QueueEvents events(poller);
- DummyListener listener;
+ EventChecker listener;
listener.poller = poller;
- events.registerListener("dummy", boost::bind(&DummyListener::handle, &listener, _1));
+ events.registerListener("dummy", boost::bind(&EventChecker::handle, &listener, _1));
//signal occurence of some events:
Queue queue("queue1");
SequenceNumber id;
diff --git a/qpid/cpp/src/tests/QueuePolicyTest.cpp b/qpid/cpp/src/tests/QueuePolicyTest.cpp
index 6c650169c7..7c7f8b7a10 100644
--- a/qpid/cpp/src/tests/QueuePolicyTest.cpp
+++ b/qpid/cpp/src/tests/QueuePolicyTest.cpp
@@ -158,6 +158,15 @@ QPID_AUTO_TEST_CASE(testRingPolicy)
BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
}
BOOST_CHECK(!f.subs.get(msg, q));
+
+ for (int i = 10; i < 20; i++) {
+ f.session.messageTransfer(arg::content=client::Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), q));
+ }
+ for (int i = 15; i < 20; i++) {
+ BOOST_CHECK(f.subs.get(msg, q, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+ BOOST_CHECK(!f.subs.get(msg, q));
}
QPID_AUTO_TEST_CASE(testStrictRingPolicy)
diff --git a/qpid/cpp/src/tests/ReplicationTest.cpp b/qpid/cpp/src/tests/ReplicationTest.cpp
new file mode 100644
index 0000000000..7bd585639d
--- /dev/null
+++ b/qpid/cpp/src/tests/ReplicationTest.cpp
@@ -0,0 +1,129 @@
+ /*
+ *
+ * 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 "unit_test.h"
+#include "test_tools.h"
+#include "BrokerFixture.h"
+
+#include "qpid/Plugin.h"
+#include "qpid/broker/Broker.h"
+#include "qpid/client/QueueOptions.h"
+#include "qpid/framing/reply_exceptions.h"
+#include "qpid/framing/SequenceNumber.h"
+#include "qpid/replication/constants.h"
+#include "qpid/sys/Shlib.h"
+
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+
+using namespace qpid::client;
+using namespace qpid::framing;
+using namespace qpid::replication::constants;
+using boost::assign::list_of;
+
+QPID_AUTO_TEST_SUITE(ReplicationTestSuite)
+
+qpid::sys::Shlib plugin("../.libs/replicating_listener.so");
+
+qpid::broker::Broker::Options getBrokerOpts(const std::vector<std::string>& args)
+{
+ std::vector<const char*> argv(args.size());
+ transform(args.begin(), args.end(), argv.begin(), boost::bind(&string::c_str, _1));
+
+ qpid::broker::Broker::Options opts;
+ qpid::Plugin::addOptions(opts);
+ opts.parse(argv.size(), &argv[0], "", true);
+ return opts;
+}
+
+QPID_AUTO_TEST_CASE(testReplicationExchange)
+{
+ qpid::broker::Broker::Options brokerOpts(getBrokerOpts(list_of<string>("qpidd")
+ ("--replication-exchange-name=qpid.replication")));
+ ProxySessionFixture f(brokerOpts);
+
+
+ std::string dataQ("queue-1");
+ std::string eventQ("event-queue-1");
+ std::string dataQ2("queue-2");
+ std::string eventQ2("event-queue-2");
+ FieldTable eventQopts;
+ eventQopts.setString("qpid.insert_sequence_numbers", REPLICATION_EVENT_SEQNO);
+
+ f.session.queueDeclare(arg::queue=eventQ, arg::exclusive=true, arg::autoDelete=true, arg::arguments=eventQopts);
+ f.session.exchangeBind(arg::exchange="qpid.replication", arg::queue=eventQ, arg::bindingKey=dataQ);
+
+ f.session.queueDeclare(arg::queue=eventQ2, arg::exclusive=true, arg::autoDelete=true, arg::arguments=eventQopts);
+ f.session.exchangeBind(arg::exchange="qpid.replication", arg::queue=eventQ2, arg::bindingKey=dataQ2);
+
+ QueueOptions args;
+ args.enableQueueEvents(false);
+ f.session.queueDeclare(arg::queue=dataQ, arg::exclusive=true, arg::autoDelete=true, arg::arguments=args);
+ f.session.queueDeclare(arg::queue=dataQ2, arg::exclusive=true, arg::autoDelete=true, arg::arguments=args);
+ for (int i = 0; i < 10; i++) {
+ f.session.messageTransfer(arg::content=Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), dataQ));
+ f.session.messageTransfer(arg::content=Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), dataQ2));
+ }
+ Message msg;
+ LocalQueue incoming;
+ Subscription sub = f.subs.subscribe(incoming, dataQ);
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+ BOOST_CHECK(!f.subs.get(msg, dataQ));
+
+ sub.cancel();
+ sub = f.subs.subscribe(incoming, eventQ);
+ //check that we received enqueue events for first queue:
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), ENQUEUE);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+1));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+ //check that we received dequeue events for first queue:
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), DEQUEUE);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(DEQUEUED_MESSAGE_POSITION), (i+1));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+11));
+ }
+
+ sub.cancel();
+ sub = f.subs.subscribe(incoming, eventQ2);
+ //check that we received enqueue events for second queue:
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ2);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), ENQUEUE);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+1));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+}
+
+
+QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/SocketProxy.h b/qpid/cpp/src/tests/SocketProxy.h
index 9722359d82..d2a93c902b 100644
--- a/qpid/cpp/src/tests/SocketProxy.h
+++ b/qpid/cpp/src/tests/SocketProxy.h
@@ -94,7 +94,7 @@ class SocketProxy : private qpid::sys::Runnable
throwIf(!(event.type == qpid::sys::Poller::READABLE && event.handle == &listenerHandle), "SocketProxy: Accept failed");
poller.delFd(listenerHandle);
- server.reset(listener.accept(0, 0));
+ server.reset(listener.accept());
// Pump data between client & server sockets
qpid::sys::PollerHandle clientHandle(client);
diff --git a/qpid/cpp/src/tests/TimerTest.cpp b/qpid/cpp/src/tests/TimerTest.cpp
index 50712ff79c..f8ab9fb2f3 100644
--- a/qpid/cpp/src/tests/TimerTest.cpp
+++ b/qpid/cpp/src/tests/TimerTest.cpp
@@ -75,7 +75,11 @@ class TestTask : public TimerTask
BOOST_CHECK(fired);
BOOST_CHECK_EQUAL(expected_position, position);
Duration actual(start, end);
+#ifdef _WIN32
+ uint64_t difference = _abs64(expected - actual);
+#else
uint64_t difference = abs(expected - actual);
+#endif
std::string msg(boost::lexical_cast<std::string>(boost::format("tolerance = %1%, difference = %2%") % tolerance % difference));
BOOST_CHECK_MESSAGE(difference < tolerance, msg);
}
diff --git a/qpid/cpp/src/tests/Uuid.cpp b/qpid/cpp/src/tests/Uuid.cpp
index ee86d75a26..ea2e80b63b 100644
--- a/qpid/cpp/src/tests/Uuid.cpp
+++ b/qpid/cpp/src/tests/Uuid.cpp
@@ -18,11 +18,11 @@
#include "qpid/framing/Uuid.h"
#include "qpid/framing/Buffer.h"
+#include "qpid/sys/alloca.h"
#include "unit_test.h"
#include <set>
-#include <alloca.h>
QPID_AUTO_TEST_SUITE(UuidTestSuite)
diff --git a/qpid/cpp/src/tests/client_test.vcproj b/qpid/cpp/src/tests/client_test.vcproj
index 0f9a50cdf0..1623c2961e 100644
--- a/qpid/cpp/src/tests/client_test.vcproj
+++ b/qpid/cpp/src/tests/client_test.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="client_test"
- ProjectGUID="{9A95F0E4-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="client_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\client_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\client_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\client_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\client_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\client_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\client_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\client_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\client_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/cluster.mk b/qpid/cpp/src/tests/cluster.mk
index c3100ac968..5d115de5a5 100644
--- a/qpid/cpp/src/tests/cluster.mk
+++ b/qpid/cpp/src/tests/cluster.mk
@@ -29,8 +29,9 @@ if HAVE_LIBCPG
# ais_check checks pre-requisites for cluster tests and runs them if ok.
-TESTS+=ais_check federated_cluster_test
-EXTRA_DIST+=ais_check start_cluster stop_cluster restart_cluster cluster_python_tests cluster_python_tests_failing.txt federated_cluster_test
+TESTS+=ais_check federated_cluster_test clustered_replication_test
+EXTRA_DIST+=ais_check start_cluster stop_cluster restart_cluster cluster_python_tests cluster_python_tests_failing.txt \
+ federated_cluster_test clustered_replication_test
check_PROGRAMS+=cluster_test
cluster_test_SOURCES=unit_test.cpp cluster_test.cpp ClusterFixture.cpp ClusterFixture.h ForkedBroker.h ForkedBroker.cpp
diff --git a/qpid/cpp/src/tests/cluster_test.cpp b/qpid/cpp/src/tests/cluster_test.cpp
index c880f30e6b..eee2df58cc 100644
--- a/qpid/cpp/src/tests/cluster_test.cpp
+++ b/qpid/cpp/src/tests/cluster_test.cpp
@@ -27,6 +27,7 @@
#include "qpid/client/ConnectionAccess.h"
#include "qpid/client/Session.h"
#include "qpid/client/FailoverListener.h"
+#include "qpid/client/FailoverManager.h"
#include "qpid/cluster/Cluster.h"
#include "qpid/cluster/Cpg.h"
#include "qpid/cluster/UpdateClient.h"
@@ -35,6 +36,8 @@
#include "qpid/framing/reply_exceptions.h"
#include "qpid/framing/enum.h"
#include "qpid/log/Logger.h"
+#include "qpid/sys/Monitor.h"
+#include "qpid/sys/Thread.h"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
@@ -148,49 +151,65 @@ vector<string> browse(Client& c, const string& q, int n) {
c.subs.subscribe(lq, q, browseSettings);
vector<string> result;
for (int i = 0; i < n; ++i) {
- result.push_back(lq.get(TIMEOUT).getData());
+ Message m;
+ if (!lq.get(m, TIMEOUT))
+ break;
+ result.push_back(m.getData());
}
c.subs.getSubscription(q).cancel();
return result;
}
+ConnectionSettings aclSettings(int port, const std::string& id) {
+ ConnectionSettings settings;
+ settings.port = port;
+ settings.mechanism = "PLAIN";
+ settings.username = id;
+ settings.password = id;
+ return settings;
+}
+
+#if 0
+// FIXME aconway 2009-03-10: This test passes but exposes a memory leak in the SASL client code.
+// Enable it when the leak is fixed.
+
+QPID_AUTO_TEST_CASE(testAcl) {
+ ofstream policyFile("cluster_test.acl");
+ // FIXME aconway 2009-02-12: guest -> qpidd?
+ policyFile << "acl allow foo@QPID create queue name=foo" << endl
+ << "acl allow foo@QPID create queue name=foo2" << endl
+ << "acl deny foo@QPID create queue name=bar" << endl
+ << "acl allow all all" << endl;
+ policyFile.close();
+ char cwd[1024];
+ BOOST_CHECK(::getcwd(cwd, sizeof(cwd)));
+ ClusterFixture cluster(2,-1, list_of<string>
+ ("--no-data-dir")
+ ("--auth=no")
+ ("--acl-file="+string(cwd)+"/cluster_test.acl")
+ ("--cluster-mechanism=PLAIN")
+ ("--cluster-username=cluster")
+ ("--cluster-password=cluster")
+ ("--load-module=../.libs/acl.so"));
+
+ Client c0(aclSettings(cluster[0], "c0"), "c0");
+ Client c1(aclSettings(cluster[1], "c1"), "c1");
+ Client foo(aclSettings(cluster[1], "foo"), "foo");
+
+ foo.session.queueDeclare("foo");
+ BOOST_CHECK_EQUAL(c0.session.queueQuery("foo").getQueue(), "foo");
+
+ BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), framing::NotAllowedException);
+ BOOST_CHECK(c0.session.queueQuery("bar").getQueue().empty());
+ BOOST_CHECK(c1.session.queueQuery("bar").getQueue().empty());
-// FIXME aconway 2009-02-12: need to figure out how to test this properly.
-// Current problems:
-// - all brokers share the same data-dir (set ACL without data dir?)
-// - updater's user name not making it through to updatee for ACL checks.
-//
-// QPID_AUTO_TEST_CASE(testAcl) {
-// ofstream policyFile("cluster_test.acl");
-// // FIXME aconway 2009-02-12: guest -> qpidd?
-// policyFile << "acl allow guest@QPID all all" << endl
-// << "acl allow foo@QPID create queue name=foo" << endl
-// << "acl allow bar@QPID create queue name=bar" << endl
-// << "acl deny all create queue" << endl
-// << "acl allow all all" << endl;
-// policyFile.close();
-// ClusterFixture cluster(2,-1, list_of<string>
-// ("--data-dir=.") ("--auth=no")
-// ("--acl-file=cluster_test.acl")
-// ("--cluster-mechanism=PLAIN")
-// ("--load-module=../.libs/acl.so"));
-// Client c0(cluster[0], "c0");
-// Client c1(cluster[1], "c1");
-
-// ConnectionSettings settings;
-// settings.port = cluster[0];
-// settings.username = "foo";
-// Client foo(settings, "foo");
-
-// foo.session.queueDeclare("foo");
-// BOOST_CHECK_EQUAL(c0.session.queueQuery("foo").getQueue(), "foo");
-// BOOST_CHECK_EQUAL(c1.session.queueQuery("foo").getQueue(), "foo");
-
-// BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), int);
-// BOOST_CHECK_EQUAL(c0.session.queueQuery("bar").getQueue(), "");
-// BOOST_CHECK_EQUAL(c1.session.queueQuery("bar").getQueue(), "");
-// }
+ cluster.add();
+ Client c2(aclSettings(cluster[2], "c2"), "c2");
+ BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), framing::NotAllowedException);
+ BOOST_CHECK(c2.session.queueQuery("bar").getQueue().empty());
+}
+#endif
QPID_AUTO_TEST_CASE(testMessageTimeToLive) {
// Note: this doesn't actually test for cluster race conditions around TTL,
@@ -199,13 +218,23 @@ QPID_AUTO_TEST_CASE(testMessageTimeToLive) {
ClusterFixture cluster(2);
Client c0(cluster[0], "c0");
Client c1(cluster[1], "c1");
+ c0.session.queueDeclare("p");
c0.session.queueDeclare("q");
c0.session.messageTransfer(arg::content=ttlMessage("a", "q", 200));
c0.session.messageTransfer(arg::content=Message("b", "q"));
- BOOST_CHECK_EQUAL(browse(c1, "q", 2), list_of<string>("a")("b"));
- sys::usleep(300*1000);
+ c0.session.messageTransfer(arg::content=ttlMessage("x", "p", 10000));
+ c0.session.messageTransfer(arg::content=Message("y", "p"));
+ cluster.add();
+ Client c2(cluster[1], "c2");
+
+ BOOST_CHECK_EQUAL(browse(c0, "p", 2), list_of<string>("x")("y"));
+ BOOST_CHECK_EQUAL(browse(c1, "p", 2), list_of<string>("x")("y"));
+ BOOST_CHECK_EQUAL(browse(c2, "p", 2), list_of<string>("x")("y"));
+
+ sys::usleep(200*1000);
BOOST_CHECK_EQUAL(browse(c0, "q", 1), list_of<string>("b"));
BOOST_CHECK_EQUAL(browse(c1, "q", 1), list_of<string>("b"));
+ BOOST_CHECK_EQUAL(browse(c2, "q", 1), list_of<string>("b"));
}
QPID_AUTO_TEST_CASE(testSequenceOptions) {
@@ -506,10 +535,11 @@ QPID_AUTO_TEST_CASE(testCatchupSharedState) {
c0.session.queueDeclare("q");
c0.session.messageTransfer(arg::content=Message("foo","q"));
c0.session.messageTransfer(arg::content=Message("bar","q"));
+
while (c0.session.queueQuery("q").getMessageCount() != 2)
sys::usleep(1000); // Wait for message to show up on broker 0.
- // Add a new broker, it should catch up.
+ // Add a new broker, it will catch up.
cluster.add();
// Do some work post-add
@@ -527,6 +557,7 @@ QPID_AUTO_TEST_CASE(testCatchupSharedState) {
BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT));
BOOST_CHECK_EQUAL(m.getData(), "foo");
+ BOOST_CHECK_EQUAL(m.getDeliveryProperties().getExchange(), "");
BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT));
BOOST_CHECK_EQUAL(m.getData(), "bar");
BOOST_CHECK_EQUAL(c1.session.queueQuery("q").getMessageCount(), 0u);
@@ -628,4 +659,86 @@ QPID_AUTO_TEST_CASE(testDequeueWaitingSubscription) {
BOOST_CHECK_EQUAL(0u, c2.session.queueQuery("q").getMessageCount());
}
+QPID_AUTO_TEST_CASE(testHeartbeatCancelledOnFailover)
+{
+ struct Sender : FailoverManager::Command
+ {
+ std::string queue;
+ std::string content;
+
+ Sender(const std::string& q, const std::string& c) : queue(q), content(c) {}
+
+ void execute(AsyncSession& session, bool)
+ {
+ session.messageTransfer(arg::content=Message(content, queue));
+ }
+ };
+
+ struct Receiver : FailoverManager::Command, MessageListener, qpid::sys::Runnable
+ {
+ FailoverManager& mgr;
+ std::string queue;
+ std::string expectedContent;
+ qpid::client::Subscription subscription;
+ qpid::sys::Monitor lock;
+ bool ready;
+
+ Receiver(FailoverManager& m, const std::string& q, const std::string& c) : mgr(m), queue(q), expectedContent(c), ready(false) {}
+
+ void received(Message& message)
+ {
+ BOOST_CHECK_EQUAL(expectedContent, message.getData());
+ subscription.cancel();
+ }
+
+ void execute(AsyncSession& session, bool)
+ {
+ session.queueDeclare(arg::queue=queue);
+ SubscriptionManager subs(session);
+ subscription = subs.subscribe(*this, queue);
+ session.sync();
+ setReady();
+ subs.run();
+ //cleanup:
+ session.queueDelete(arg::queue=queue);
+ }
+
+ void run()
+ {
+ mgr.execute(*this);
+ }
+
+ void waitForReady()
+ {
+ qpid::sys::Monitor::ScopedLock l(lock);
+ while (!ready) {
+ lock.wait();
+ }
+ }
+
+ void setReady()
+ {
+ qpid::sys::Monitor::ScopedLock l(lock);
+ ready = true;
+ lock.notify();
+ }
+ };
+
+ ClusterFixture cluster(2);
+ ConnectionSettings settings;
+ settings.port = cluster[1];
+ settings.heartbeat = 1;
+ FailoverManager fmgr(settings);
+ Sender sender("my-queue", "my-data");
+ Receiver receiver(fmgr, "my-queue", "my-data");
+ qpid::sys::Thread runner(receiver);
+ receiver.waitForReady();
+ cluster.kill(1);
+ //sleep for 2 secs to allow the heartbeat task to fire on the now dead connection:
+ ::usleep(2*1000*1000);
+ fmgr.execute(sender);
+ runner.join();
+ fmgr.close();
+}
+
QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/clustered_replication_test b/qpid/cpp/src/tests/clustered_replication_test
new file mode 100755
index 0000000000..2a3e742632
--- /dev/null
+++ b/qpid/cpp/src/tests/clustered_replication_test
@@ -0,0 +1,127 @@
+#!/bin/sh
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Test reliability of the replication feature in the face of link
+# failures:
+srcdir=`dirname $0`
+PYTHON_DIR=$srcdir/../../../python
+
+trap stop_brokers INT EXIT
+
+fail() {
+ echo $1
+ exit 1
+}
+with_ais_group() {
+ id -nG | grep '\<ais\>' >/dev/null || { echo "You are not a member of the ais group." 1>&2; exit 1; }
+ echo $* | newgrp ais
+}
+
+stop_brokers() {
+ if [[ $PRIMARY1 ]] ; then
+ ../qpidd -q --port $PRIMARY1
+ unset PRIMARY1
+ fi
+ if [[ $PRIMARY2 ]] ; then
+ ../qpidd -q --port $PRIMARY2
+ unset PRIMARY2
+ fi
+ if [[ $DR1 ]] ; then
+ ../qpidd -q --port $DR1
+ unset DR1
+ fi
+ if [[ $DR2 ]] ; then
+ ../qpidd -q --port $DR2
+ unset DR2
+ fi
+}
+
+if test -d ${PYTHON_DIR}; then
+ id -nG | grep '\<ais\>' >/dev/null || \
+ NOGROUP="You are not a member of the ais group."
+ ps -u root | grep 'aisexec\|corosync' >/dev/null || \
+ NOAISEXEC="The aisexec or corosync daemon is not running as root"
+
+ if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then
+ cat <<EOF
+Not running federation to cluster test because:
+ $NOGROUP
+ $NOAISEXEC
+EOF
+ exit 0;
+ fi
+
+ #todo: these cluster names need to be unique to prevent clashes
+ PRIMARY_CLUSTER=PRIMARY_$(hostname)_$(pwd)
+ DR_CLUSTER=DR_$(hostname)_$(pwd)
+
+ GENERAL_OPTS="--auth no --no-module-dir --no-data-dir --daemon --port 0 --log-enable notice+ --log-to-stderr false"
+ PRIMARY_OPTS="--load-module ../.libs/replicating_listener.so --create-replication-queue true --replication-queue REPLICATION_QUEUE --load-module ../.libs/cluster.so --cluster-name $PRIMARY_CLUSTER"
+ DR_OPTS="--load-module ../.libs/replication_exchange.so --load-module ../.libs/cluster.so --cluster-name $DR_CLUSTER"
+
+ rm -f repl*.tmp #cleanup any files left from previous run
+
+ #start first node of primary cluster and set up test queue
+ echo Starting primary cluster
+ PRIMARY1=$(with_ais_group ../qpidd $GENERAL_OPTS $PRIMARY_OPTS --log-to-file repl.primary.1.tmp) || fail "Could not start node"
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue test-queue --generate-queue-events 2
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue control-queue --generate-queue-events 1
+
+ #send 10 messages, consume 5 of them
+ for i in `seq 1 10`; do echo Message$i; done | ./sender --port $PRIMARY1
+ ./receiver --port $PRIMARY1 --messages 5 > /dev/null
+
+ #add new node to primary cluster, testing correct transfer of state:
+ echo Adding node to primary cluster
+ PRIMARY2=$(with_ais_group ../qpidd $GENERAL_OPTS $PRIMARY_OPTS --log-to-file repl.primary.2.tmp)
+
+ #start DR cluster, set up test queue there and establish replication bridge
+ echo Starting DR cluster
+ DR1=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.1.tmp)
+ DR2=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.2.tmp)
+
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue test-queue
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue control-queue
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add exchange replication REPLICATION_EXCHANGE
+ $PYTHON_DIR/commands/qpid-route queue add localhost:$DR2 localhost:$PRIMARY2 REPLICATION_EXCHANGE REPLICATION_QUEUE
+
+ #send more messages to primary
+ for i in `seq 11 20`; do echo Message$i; done | ./sender --port $PRIMARY1 --send-eos 1
+
+ #wait for replication events to all be processed:
+ echo Waiting for replication to complete
+ echo Done | ./sender --port $PRIMARY1 --routing-key control-queue --send-eos 1
+ ./receiver --queue control-queue --port $DR1 > /dev/null
+
+ #verify contents of test queue on dr cluster:
+ echo Verifying...
+ ./receiver --port $DR2 > repl.out.tmp
+ for i in `seq 6 20`; do echo Message$i; done | diff repl.out.tmp - || FAIL=1
+
+ if [[ $FAIL ]]; then
+ echo Clustered replication test failed: expectations not met!
+ exit 1
+ else
+ echo Clustered replication test passed
+ rm -f repl*.tmp
+ fi
+
+fi
diff --git a/qpid/cpp/src/tests/consume.vcproj b/qpid/cpp/src/tests/consume.vcproj
index ecf7b2df08..2e1f8e3e56 100644
--- a/qpid/cpp/src/tests/consume.vcproj
+++ b/qpid/cpp/src/tests/consume.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="consume"
- ProjectGUID="{7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="consume"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\consume\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\consume\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\consume\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\consume\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\consume\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\consume\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\consume\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\consume\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/echotest.vcproj b/qpid/cpp/src/tests/echotest.vcproj
index 0048dde85f..2848894228 100644
--- a/qpid/cpp/src/tests/echotest.vcproj
+++ b/qpid/cpp/src/tests/echotest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="echotest"
- ProjectGUID="{0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="echotest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\echotest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\echotest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\echotest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\echotest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\echotest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\echotest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\echotest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\echotest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/failover_soak.cpp b/qpid/cpp/src/tests/failover_soak.cpp
index 6149e845e4..4f16e469b8 100644
--- a/qpid/cpp/src/tests/failover_soak.cpp
+++ b/qpid/cpp/src/tests/failover_soak.cpp
@@ -26,18 +26,32 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <string.h>
+#include <sys/types.h>
+#include <signal.h>
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
+#include <boost/assign.hpp>
+
+#include "qpid/framing/Uuid.h"
+
#include <ForkedBroker.h>
+#include <qpid/client/Connection.h>
+
+
using namespace std;
+using boost::assign::list_of;
+using namespace qpid::framing;
+using namespace qpid::client;
+
+
typedef vector<ForkedBroker *> brokerVector;
@@ -51,11 +65,34 @@ typedef enum
childStatus;
+typedef enum
+{
+ NO_TYPE,
+ DECLARING_CLIENT,
+ SENDING_CLIENT,
+ RECEIVING_CLIENT
+}
+childType;
+
+
+ostream& operator<< ( ostream& os, const childType& ct ) {
+ switch ( ct ) {
+ case DECLARING_CLIENT: os << "Declaring Client"; break;
+ case SENDING_CLIENT: os << "Sending Client"; break;
+ case RECEIVING_CLIENT: os << "Receiving Client"; break;
+ default: os << "No Client"; break;
+ }
+
+ return os;
+}
+
+
+
struct child
{
- child ( string & name, pid_t pid )
- : name(name), pid(pid), retval(-999), status(RUNNING)
+ child ( string & name, pid_t pid, childType type )
+ : name(name), pid(pid), retval(-999), status(RUNNING), type(type)
{
gettimeofday ( & startTime, 0 );
}
@@ -70,10 +107,18 @@ struct child
}
+ void
+ setType ( childType t )
+ {
+ type = t;
+ }
+
+
string name;
pid_t pid;
int retval;
childStatus status;
+ childType type;
struct timeval startTime,
stopTime;
};
@@ -83,10 +128,11 @@ struct child
struct children : public vector<child *>
{
+
void
- add ( string & name, pid_t pid )
+ add ( string & name, pid_t pid, childType type )
{
- push_back(new child ( name, pid ));
+ push_back ( new child ( name, pid, type ) );
}
@@ -108,7 +154,7 @@ struct children : public vector<child *>
child * kid = get ( pid );
if(! kid)
{
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
{
cerr << "children::exited warning: Can't find child with pid "
<< pid
@@ -138,10 +184,15 @@ struct children : public vector<child *>
int
checkChildren ( )
{
- vector<child *>::iterator i;
+ vector<child *>::iterator i;
for ( i = begin(); i != end(); ++ i )
if ( (COMPLETED == (*i)->status) && (0 != (*i)->retval) )
- return (*i)->retval;
+ {
+ cerr << "checkChildren: error on child of type "
+ << (*i)->type
+ << endl;
+ return (*i)->retval;
+ }
return 0;
}
@@ -176,22 +227,43 @@ struct children : public vector<child *>
If it has been at least that long since a shild stopped
running, we judge the system to have hung.
*/
- bool
+ int
hanging ( int hangTime )
{
struct timeval now,
duration;
gettimeofday ( &now, 0 );
+ int how_many_hanging = 0;
+
vector<child *>::iterator i;
for ( i = begin(); i != end(); ++ i )
{
- timersub ( & now, &((*i)->startTime), & duration );
- if ( duration.tv_sec >= hangTime )
- return true;
+ //Not in POSIX
+ //timersub ( & now, &((*i)->startTime), & duration );
+ duration.tv_sec = now.tv_sec - (*i)->startTime.tv_sec;
+ duration.tv_usec = now.tv_usec - (*i)->startTime.tv_usec;
+ if (duration.tv_usec < 0) {
+ --duration.tv_sec;
+ duration.tv_usec += 1000000;
+ }
+
+ if ( (COMPLETED != (*i)->status) // child isn't done running
+ &&
+ ( duration.tv_sec >= hangTime ) // it's been too long
+ )
+ {
+ std::cerr << "Child of type "
+ << (*i)->type
+ << " hanging. "
+ << "PID is "
+ << (*i)->pid
+ << endl;
+ ++ how_many_hanging;
+ }
}
- return false;
+ return how_many_hanging;
}
@@ -206,9 +278,8 @@ children allMyChildren;
void
-childExit ( int signalNumber )
+childExit ( int )
{
- signalNumber ++; // Now maybe the compiler willleave me alone?
int childReturnCode;
pid_t pid = waitpid ( 0, & childReturnCode, WNOHANG);
@@ -235,10 +306,9 @@ mrand ( int minDesiredVal, int maxDesiredVal ) {
void
-makeClusterName ( string & s, int & num ) {
- num = mrand(1000);
+makeClusterName ( string & s ) {
stringstream ss;
- ss << "soakTestCluster_" << num;
+ ss << "soakTestCluster_" << Uuid(true).str();
s = ss.str();
}
@@ -263,66 +333,136 @@ printBrokers ( brokerVector & brokers )
+ForkedBroker * newbie = 0;
+int newbie_port = 0;
+
+
+
+bool
+wait_for_newbie ( )
+{
+ if ( ! newbie )
+ return true;
+
+ try
+ {
+ Connection connection;
+ connection.open ( "127.0.0.1", newbie_port );
+ connection.close();
+ newbie = 0; // He's no newbie anymore!
+ return true;
+ }
+ catch ( const std::exception& error )
+ {
+ std::cerr << "wait_for_newbie error: "
+ << error.what()
+ << endl;
+ return false;
+ }
+}
+
+
+
void
startNewBroker ( brokerVector & brokers,
char const * srcRoot,
char const * moduleDir,
- string const clusterName )
+ string const clusterName,
+ int verbosity )
{
static int brokerId = 0;
stringstream path, prefix, module;
module << moduleDir << "/cluster.so";
path << srcRoot << "/qpidd";
- prefix << "soak-" << brokerId++;
-
- const char * const argv[] =
- {
- "qpidd",
- "-p0",
- "--load-module=cluster.so",
- "--cluster-name",
- clusterName.c_str(),
- "--auth=no",
- "--no-data-dir",
- "--no-module-dir",
- "--mgmt-enable=no",
- "--log-prefix", prefix.str().c_str(),
- 0
- };
-
- size_t argc = sizeof(argv)/sizeof(argv[0]);
- brokers.push_back ( new ForkedBroker ( argc, argv ) );
+ prefix << "soak-" << brokerId;
+ std::vector<std::string> argv = list_of<string>
+ ("qpidd")
+ ("--no-module-dir")
+ ("--load-module=cluster.so")
+ ("--cluster-name")
+ (clusterName)
+ ("--auth=no")
+ ("--no-data-dir")
+ ("--mgmt-enable=no")
+ ("--log-prefix")
+ (prefix.str())
+ ("--log-to-file")
+ (prefix.str()+".log");
+
+ newbie = new ForkedBroker ( argv );
+ newbie_port = newbie->getPort();
+ ForkedBroker * broker = newbie;
+
+ if ( verbosity > 0 )
+ std::cerr << "new broker created: pid == "
+ << broker->getPID()
+ << " log-prefix == "
+ << "soak-" << brokerId
+ << endl;
+ brokers.push_back ( broker );
+
+ ++ brokerId;
}
-void
+bool
killFrontBroker ( brokerVector & brokers, int verbosity )
{
+ cerr << "killFrontBroker: waiting for newbie sync...\n";
+ if ( ! wait_for_newbie() )
+ return false;
+ cerr << "killFrontBroker: newbie synced.\n";
+
if ( verbosity > 0 )
cout << "killFrontBroker pid: " << brokers[0]->getPID() << " on port " << brokers[0]->getPort() << endl;
try { brokers[0]->kill(9); }
catch ( const exception& error ) {
if ( verbosity > 0 )
- cout << "error killing broker: " << error.what() << endl;
+ {
+ cout << "error killing broker: "
+ << error.what()
+ << endl;
+ }
+
+ return false;
}
delete brokers[0];
brokers.erase ( brokers.begin() );
+ return true;
}
+/*
+ * The optional delay is to avoid killing newbie brokers that have just
+ * been added and are still in the process of updating. This causes
+ * spurious, test-generated errors that scare everybody.
+ */
void
-killAllBrokers ( brokerVector & brokers )
+killAllBrokers ( brokerVector & brokers, int delay )
{
+ if ( delay > 0 )
+ {
+ std::cerr << "Killing all brokers after delay of " << delay << endl;
+ sleep ( delay );
+ }
+
for ( uint i = 0; i < brokers.size(); ++ i )
try { brokers[i]->kill(9); }
- catch ( ... ) { }
+ catch ( const exception& error )
+ {
+ std::cerr << "killAllBrokers Warning: exception during kill on broker "
+ << i
+ << " "
+ << error.what()
+ << endl;
+ }
}
@@ -339,7 +479,7 @@ runDeclareQueuesClient ( brokerVector brokers,
string name("declareQueues");
int port = brokers[0]->getPort ( );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "startDeclareQueuesClient: host: "
<< host
<< " port: "
@@ -357,11 +497,11 @@ runDeclareQueuesClient ( brokerVector brokers,
if ( ! pid ) {
execv ( path, const_cast<char * const *>(&argv[0]) );
- perror ( "error executing dq: " );
+ perror ( "error executing declareQueues: " );
return 0;
}
- allMyChildren.add ( name, pid );
+ allMyChildren.add ( name, pid, DECLARING_CLIENT );
return pid;
}
@@ -380,12 +520,16 @@ startReceivingClient ( brokerVector brokers,
string name("receiver");
int port = brokers[0]->getPort ( );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "startReceivingClient: port " << port << endl;
+
+ // verbosity has to be > 1 to let clients talk.
+ int client_verbosity = (verbosity > 1 ) ? 1 : 0;
+
char portStr[100];
char verbosityStr[100];
sprintf(portStr, "%d", port);
- sprintf(verbosityStr, "%d", verbosity);
+ sprintf(verbosityStr, "%d", client_verbosity);
vector<const char*> argv;
@@ -404,7 +548,7 @@ startReceivingClient ( brokerVector brokers,
return 0;
}
- allMyChildren.add ( name, pid );
+ allMyChildren.add ( name, pid, RECEIVING_CLIENT );
return pid;
}
@@ -424,13 +568,16 @@ startSendingClient ( brokerVector brokers,
string name("sender");
int port = brokers[0]->getPort ( );
- if ( verbosity )
+ if ( verbosity > 1)
cout << "startSenderClient: port " << port << endl;
char portStr[100];
char verbosityStr[100];
+ //
+ // verbosity has to be > 1 to let clients talk.
+ int client_verbosity = (verbosity > 1 ) ? 1 : 0;
sprintf ( portStr, "%d", port);
- sprintf ( verbosityStr, "%d", verbosity);
+ sprintf ( verbosityStr, "%d", client_verbosity);
vector<const char*> argv;
argv.push_back ( "replayingSender" );
@@ -449,19 +596,21 @@ startSendingClient ( brokerVector brokers,
return 0;
}
- allMyChildren.add ( name, pid );
+ allMyChildren.add ( name, pid, SENDING_CLIENT );
return pid;
}
-#define HUNKY_DORY 0
-#define BAD_ARGS 1
-#define CANT_FORK_DQ 2
-#define CANT_FORK_RECEIVER 3
-#define DQ_FAILED 4
-#define ERROR_ON_CHILD 5
-#define HANGING 6
+#define HUNKY_DORY 0
+#define BAD_ARGS 1
+#define CANT_FORK_DQ 2
+#define CANT_FORK_RECEIVER 3
+#define CANT_FORK_SENDER 4
+#define DQ_FAILED 5
+#define ERROR_ON_CHILD 6
+#define HANGING 7
+#define ERROR_KILLING_BROKER 8
int
@@ -489,16 +638,15 @@ main ( int argc, char const ** argv )
allMyChildren.verbosity = verbosity;
- int clusterNum;
string clusterName;
srand ( getpid() );
- makeClusterName ( clusterName, clusterNum );
+ makeClusterName ( clusterName );
brokerVector brokers;
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "Starting initial cluster...\n";
int nBrokers = 3;
@@ -506,7 +654,8 @@ main ( int argc, char const ** argv )
startNewBroker ( brokers,
srcRoot,
moduleDir,
- clusterName );
+ clusterName,
+ verbosity );
}
@@ -518,14 +667,14 @@ main ( int argc, char const ** argv )
pid_t dqClientPid =
runDeclareQueuesClient ( brokers, host, declareQueuesPath, verbosity );
if ( -1 == dqClientPid ) {
- cerr << "failoverSoak error: Couldn't fork declareQueues.\n";
+ cerr << "END_OF_TEST ERROR_START_DECLARE_1\n";
return CANT_FORK_DQ;
}
// Don't continue until declareQueues is finished.
pid_t retval = waitpid ( dqClientPid, & childStatus, 0);
if ( retval != dqClientPid) {
- cerr << "failoverSoak error: waitpid on declareQueues returned value " << retval << endl;
+ cerr << "END_OF_TEST ERROR_START_DECLARE_2\n";
return DQ_FAILED;
}
allMyChildren.exited ( dqClientPid, childStatus );
@@ -540,7 +689,7 @@ main ( int argc, char const ** argv )
reportFrequency,
verbosity );
if ( -1 == receivingClientPid ) {
- cerr << "failoverSoak error: Couldn't fork receiver.\n";
+ cerr << "END_OF_TEST ERROR_START_RECEIVER\n";
return CANT_FORK_RECEIVER;
}
@@ -554,13 +703,13 @@ main ( int argc, char const ** argv )
reportFrequency,
verbosity );
if ( -1 == sendingClientPid ) {
- cerr << "failoverSoak error: Couldn't fork sender.\n";
- return CANT_FORK_RECEIVER;
+ cerr << "END_OF_TEST ERROR_START_SENDER\n";
+ return CANT_FORK_SENDER;
}
- int minSleep = 3,
- maxSleep = 6;
+ int minSleep = 2,
+ maxSleep = 4;
for ( int totalBrokers = 3;
@@ -578,11 +727,16 @@ main ( int argc, char const ** argv )
sleep ( sleepyTime );
// Kill the oldest broker. --------------------------
- killFrontBroker ( brokers, verbosity );
+ if ( ! killFrontBroker ( brokers, verbosity ) )
+ {
+ allMyChildren.killEverybody();
+ std::cerr << "END_OF_TEST ERROR_BROKER\n";
+ return ERROR_KILLING_BROKER;
+ }
// Sleep for a while. -------------------------
sleepyTime = mrand ( minSleep, maxSleep );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cerr << "Sleeping for " << sleepyTime << " seconds.\n";
sleep ( sleepyTime );
@@ -593,22 +747,33 @@ main ( int argc, char const ** argv )
startNewBroker ( brokers,
srcRoot,
moduleDir,
- clusterName );
+ clusterName,
+ verbosity );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
printBrokers ( brokers );
// If all children have exited, quit.
int unfinished = allMyChildren.unfinished();
if ( ! unfinished ) {
- killAllBrokers ( brokers );
+ killAllBrokers ( brokers, 5 );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "failoverSoak: all children have exited.\n";
int retval = allMyChildren.checkChildren();
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
std::cerr << "failoverSoak: checkChildren: " << retval << endl;
- return retval ? ERROR_ON_CHILD : HUNKY_DORY;
+
+ if ( retval )
+ {
+ std::cerr << "END_OF_TEST ERROR_CLIENT\n";
+ return ERROR_ON_CHILD;
+ }
+ else
+ {
+ std::cerr << "END_OF_TEST SUCCESSFUL\n";
+ return HUNKY_DORY;
+ }
}
// Even if some are still running, if there's an error, quit.
@@ -617,35 +782,38 @@ main ( int argc, char const ** argv )
if ( verbosity > 0 )
cout << "failoverSoak: error on child.\n";
allMyChildren.killEverybody();
- killAllBrokers ( brokers );
+ killAllBrokers ( brokers, 5 );
+ std::cerr << "END_OF_TEST ERROR_CLIENT\n";
return ERROR_ON_CHILD;
}
// If one is hanging, quit.
if ( allMyChildren.hanging ( 120 ) )
{
- if ( verbosity > 0 )
- cout << "failoverSoak: child hanging.\n";
- allMyChildren.killEverybody();
- killAllBrokers ( brokers );
+ /*
+ * Don't kill any processes. Leave alive for questioning.
+ * */
+ std::cerr << "END_OF_TEST ERROR_HANGING\n";
return HANGING;
}
- if ( verbosity > 0 ) {
+ if ( verbosity > 1 ) {
std::cerr << "------- next kill-broker loop --------\n";
allMyChildren.print();
}
}
retval = allMyChildren.checkChildren();
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
std::cerr << "failoverSoak: checkChildren: " << retval << endl;
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "failoverSoak: maxBrokers reached.\n";
allMyChildren.killEverybody();
- killAllBrokers ( brokers );
+ killAllBrokers ( brokers, 5 );
+
+ std::cerr << "END_OF_TEST SUCCESSFUL\n";
return retval ? ERROR_ON_CHILD : HUNKY_DORY;
}
diff --git a/qpid/cpp/src/tests/federated_cluster_test b/qpid/cpp/src/tests/federated_cluster_test
index d4549738b2..575a5d9c9b 100755
--- a/qpid/cpp/src/tests/federated_cluster_test
+++ b/qpid/cpp/src/tests/federated_cluster_test
@@ -21,8 +21,8 @@
# Test reliability of the replication feature in the face of link
# failures:
-MY_DIR=`dirname \`which $0\``
-PYTHON_DIR=${MY_DIR}/../../../python
+srcdir=`dirname $0`
+PYTHON_DIR=$srcdir/../../../python
trap stop_brokers EXIT
@@ -37,9 +37,14 @@ stop_brokers() {
unset BROKER_A
fi
if [[ $NODE_1 ]] ; then
- ./stop_cluster
+ ../qpidd -q --port $NODE_1
unset NODE_1
fi
+ if [[ $NODE_2 ]] ; then
+ ../qpidd -q --port $NODE_2
+ unset NODE_2
+ fi
+ rm cluster.ports
}
start_brokers() {
@@ -48,19 +53,20 @@ start_brokers() {
BROKER_A=`cat fed.port.tmp`
#...and start cluster
- ./start_cluster 2 || fail "Could not start cluster"
+ $srcdir/start_cluster 2 || fail "Could not start cluster"
NODE_1=$(head -1 cluster.ports)
NODE_2=$(tail -1 cluster.ports)
}
setup() {
+ export PYTHONPATH=$PYTHON_DIR
#create exchange on both cluster and single broker
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add exchange direct test-exchange
$PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add exchange direct test-exchange
#create dynamic routes for test exchange
- $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$NODE_1" "localhost:$BROKER_A" test-exchange
- $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_1" test-exchange
+ $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$NODE_2" "localhost:$BROKER_A" test-exchange
+ $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_2" test-exchange
#create test queue on cluster and bind it to the test exchange
$PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add queue test-queue
@@ -71,7 +77,7 @@ setup() {
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" bind test-exchange test-queue from-cluster
}
-run_test_pull_to_cluster() {
+run_test_pull_to_cluster_two_consumers() {
#start consumers on each of the two nodes of the cluster
./receiver --port $NODE_1 --queue test-queue --credit-window 1 > fed1.out.tmp &
./receiver --port $NODE_2 --queue test-queue --credit-window 1 > fed2.out.tmp &
@@ -88,6 +94,20 @@ run_test_pull_to_cluster() {
rm -f fed*.tmp #cleanup
}
+run_test_pull_to_cluster() {
+ #send stream of messages to test exchange on single broker
+ for i in `seq 1 1000`; do echo Message $i >> fed.in.tmp; done
+ ./sender --port $BROKER_A --exchange test-exchange --routing-key to-cluster --send-eos 1 < fed.in.tmp
+
+ #consume from remaining node of the cluster
+ ./receiver --port $NODE_2 --queue test-queue > fed.out.tmp
+
+ #verify all messages are received
+ diff fed.in.tmp fed.out.tmp || fail "federated link to cluster failed: expectations not met!"
+
+ rm -f fed*.tmp #cleanup
+}
+
run_test_pull_from_cluster() {
#start consumer on single broker
./receiver --port $BROKER_A --queue test-queue --credit-window 1 > fed.out.tmp &
@@ -124,8 +144,19 @@ EOF
echo "brokers started"
setup
echo "setup completed"
- run_test_pull_to_cluster
+ run_test_pull_to_cluster_two_consumers
echo "federated link to cluster verified"
run_test_pull_from_cluster
echo "federated link from cluster verified"
+ if [[ $TEST_NODE_FAILURE ]] ; then
+ #kill first cluster node and retest
+ kill -9 $(../qpidd --check --port $NODE_1) && unset NODE_1
+ echo "killed first cluster node; waiting for links to re-establish themselves..."
+ sleep 5
+ echo "retesting..."
+ run_test_pull_to_cluster
+ echo "federated link to cluster verified"
+ run_test_pull_from_cluster
+ echo "federated link from cluster verified"
+ fi
fi
diff --git a/qpid/cpp/src/tests/federated_cluster_test_with_node_failure b/qpid/cpp/src/tests/federated_cluster_test_with_node_failure
new file mode 100755
index 0000000000..f144a676de
--- /dev/null
+++ b/qpid/cpp/src/tests/federated_cluster_test_with_node_failure
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+srcdir=`dirname $0`
+TEST_NODE_FAILURE=1 $srcdir/federated_cluster_test
diff --git a/qpid/cpp/src/tests/header_test.vcproj b/qpid/cpp/src/tests/header_test.vcproj
index 9a1da958cc..da761a6edb 100644
--- a/qpid/cpp/src/tests/header_test.vcproj
+++ b/qpid/cpp/src/tests/header_test.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="header_test"
- ProjectGUID="{1B23F05D-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="header_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\header_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\header_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\header_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\header_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\header_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\header_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\header_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\header_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/latencytest.vcproj b/qpid/cpp/src/tests/latencytest.vcproj
index eb9741a1e1..758302029a 100644
--- a/qpid/cpp/src/tests/latencytest.vcproj
+++ b/qpid/cpp/src/tests/latencytest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="latencytest"
- ProjectGUID="{4A809018-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{4A809018-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="latencytest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\latencytest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\latencytest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\latencytest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\latencytest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\latencytest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\latencytest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\latencytest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\latencytest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/logging.cpp b/qpid/cpp/src/tests/logging.cpp
index 051722e7c8..00e1d7de85 100644
--- a/qpid/cpp/src/tests/logging.cpp
+++ b/qpid/cpp/src/tests/logging.cpp
@@ -23,6 +23,7 @@
#include "qpid/memory.h"
#include "qpid/Options.h"
#if defined (_WIN32)
+# include "qpid/log/windows/SinkOptions.h"
#else
# include "qpid/log/posix/SinkOptions.h"
#endif
@@ -172,7 +173,7 @@ QPID_AUTO_TEST_CASE(testLoggerFormat) {
l.format(Logger::FUNCTION);
QPID_LOG(critical, "foo");
- BOOST_CHECK_REGEX("void .*testLoggerFormat.*\\(\\): foo\n", out->last());
+ BOOST_CHECK_EQUAL(string(BOOST_CURRENT_FUNCTION) + ": foo\n", out->last());
l.format(Logger::LEVEL);
QPID_LOG(critical, "foo");
@@ -270,7 +271,11 @@ QPID_AUTO_TEST_CASE(testOptionsParse) {
"--log-function", "YES"
};
qpid::log::Options opts("");
+#ifdef _WIN32
+ qpid::log::windows::SinkOptions sinks("test");
+#else
qpid::log::posix::SinkOptions sinks("test");
+#endif
opts.parse(ARGC(argv), const_cast<char**>(argv));
sinks = *opts.sinkOptions;
vector<string> expect=list_of("error+:foo")("debug:bar")("info");
@@ -286,7 +291,11 @@ QPID_AUTO_TEST_CASE(testOptionsParse) {
QPID_AUTO_TEST_CASE(testOptionsDefault) {
Options opts("");
+#ifdef _WIN32
+ qpid::log::windows::SinkOptions sinks("test");
+#else
qpid::log::posix::SinkOptions sinks("test");
+#endif
sinks = *opts.sinkOptions;
BOOST_CHECK(sinks.logToStderr);
BOOST_CHECK(!sinks.logToStdout);
@@ -345,8 +354,13 @@ QPID_AUTO_TEST_CASE(testQuoteNonPrintable) {
ScopedSuppressLogging ls(l);
Options opts("test");
opts.time=false;
+#ifdef _WIN32
+ qpid::log::windows::SinkOptions *sinks =
+ dynamic_cast<qpid::log::windows::SinkOptions *>(opts.sinkOptions.get());
+#else
qpid::log::posix::SinkOptions *sinks =
dynamic_cast<qpid::log::posix::SinkOptions *>(opts.sinkOptions.get());
+#endif
sinks->logToStderr = false;
sinks->logFile = "logging.tmp";
l.configure(opts);
diff --git a/qpid/cpp/src/tests/perftest.cpp b/qpid/cpp/src/tests/perftest.cpp
index 6456bc8304..18491d72a0 100644
--- a/qpid/cpp/src/tests/perftest.cpp
+++ b/qpid/cpp/src/tests/perftest.cpp
@@ -38,7 +38,6 @@
#include <sstream>
#include <numeric>
#include <algorithm>
-#include <unistd.h>
#include <math.h>
@@ -238,8 +237,10 @@ struct Client : public Runnable {
~Client() {
try {
- session.close();
- connection->close();
+ if (connection->isOpen()) {
+ session.close();
+ connection->close();
+ }
} catch (const std::exception& e) {
std::cerr << "Error in shutdown: " << e.what() << std::endl;
}
@@ -523,7 +524,8 @@ struct PublishThread : public Client {
sync(session).txCommit();
}
}
- if (opts.intervalPub) ::usleep(opts.intervalPub*1000);
+ if (opts.intervalPub)
+ qpid::sys::usleep(opts.intervalPub*1000);
}
if (opts.confirm) session.sync();
AbsTime end=now();
@@ -613,7 +615,8 @@ struct SubscribeThread : public Client {
if (opts.commitAsync) session.txCommit();
else sync(session).txCommit();
}
- if (opts.intervalSub) ::usleep(opts.intervalSub*1000);
+ if (opts.intervalSub)
+ qpid::sys::usleep(opts.intervalSub*1000);
// TODO aconway 2007-11-23: check message order for.
// multiple publishers. Need an array of counters,
// one per publisher and a publisher ID in the
diff --git a/qpid/cpp/src/tests/perftest.vcproj b/qpid/cpp/src/tests/perftest.vcproj
index c9132bac03..3a2397ac9b 100644
--- a/qpid/cpp/src/tests/perftest.vcproj
+++ b/qpid/cpp/src/tests/perftest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="perftest"
- ProjectGUID="{1F2066BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="perftest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\perftest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\perftest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\perftest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\perftest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\perftest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\perftest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\perftest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\perftest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/publish.vcproj b/qpid/cpp/src/tests/publish.vcproj
index a205337ecd..7422606a32 100644
--- a/qpid/cpp/src/tests/publish.vcproj
+++ b/qpid/cpp/src/tests/publish.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="publish"
- ProjectGUID="{AE773E7F-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="publish"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\publish\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\publish\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\publish\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\publish\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\publish\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\publish\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\publish\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\publish\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/receiver.cpp b/qpid/cpp/src/tests/receiver.cpp
index 1ecaece51e..49f7ff0338 100644
--- a/qpid/cpp/src/tests/receiver.cpp
+++ b/qpid/cpp/src/tests/receiver.cpp
@@ -23,7 +23,7 @@
#include <qpid/client/Session.h>
#include <qpid/client/Message.h>
#include <qpid/client/SubscriptionManager.h>
-#include <qpid/client/SubscriptionManager.h>
+#include <qpid/client/SubscriptionSettings.h>
#include "TestOptions.h"
#include <iostream>
@@ -43,15 +43,17 @@ struct Args : public qpid::TestOptions
bool ignoreDuplicates;
uint creditWindow;
uint ackFrequency;
+ bool browse;
- Args() : queue("test-queue"), messages(0), ignoreDuplicates(false), creditWindow(0), ackFrequency(1)
+ Args() : queue("test-queue"), messages(0), ignoreDuplicates(false), creditWindow(0), ackFrequency(1), browse(false)
{
addOptions()
("queue", qpid::optValue(queue, "QUEUE NAME"), "Queue from which to request messages")
("messages", qpid::optValue(messages, "N"), "Number of messages to receive; 0 means receive indefinitely")
("ignore-duplicates", qpid::optValue(ignoreDuplicates), "Detect and ignore duplicates (by checking 'sn' header)")
("credit-window", qpid::optValue(creditWindow, "N"), "Credit window (0 implies infinite window)")
- ("ack-frequency", qpid::optValue(ackFrequency, "N"), "Ack frequency (0 implies none of the messages will get accepted)");
+ ("ack-frequency", qpid::optValue(ackFrequency, "N"), "Ack frequency (0 implies none of the messages will get accepted)")
+ ("browse", qpid::optValue(browse), "Browse rather than consuming");
}
};
@@ -60,7 +62,7 @@ const string EOS("eos");
class Receiver : public MessageListener, public FailoverManager::Command
{
public:
- Receiver(const string& queue, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency);
+ Receiver(const string& queue, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency, bool browse);
void received(Message& message);
void execute(AsyncSession& session, bool isRetry);
private:
@@ -75,9 +77,10 @@ class Receiver : public MessageListener, public FailoverManager::Command
bool isDuplicate(Message& message);
};
-Receiver::Receiver(const string& q, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency) :
+Receiver::Receiver(const string& q, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency, bool browse) :
queue(q), count(messages), skipDups(ignoreDuplicates), processed(0), lastSn(0)
{
+ if (browse) settings.acquireMode = ACQUIRE_MODE_NOT_ACQUIRED;
if (creditWindow) settings.flowControl = FlowControl::messageWindow(creditWindow);
settings.autoAck = ackFrequency;
}
@@ -107,6 +110,9 @@ void Receiver::execute(AsyncSession& session, bool /*isRetry*/)
SubscriptionManager subs(session);
subscription = subs.subscribe(*this, queue, settings);
subs.run();
+ if (settings.autoAck) {
+ subscription.accept(subscription.getUnaccepted());
+ }
}
int main(int argc, char ** argv)
@@ -115,7 +121,7 @@ int main(int argc, char ** argv)
try {
opts.parse(argc, argv);
FailoverManager connection(opts.con);
- Receiver receiver(opts.queue, opts.messages, opts.ignoreDuplicates, opts.creditWindow, opts.ackFrequency);
+ Receiver receiver(opts.queue, opts.messages, opts.ignoreDuplicates, opts.creditWindow, opts.ackFrequency, opts.browse);
connection.execute(receiver);
connection.close();
return 0;
diff --git a/qpid/cpp/src/tests/receiver.vcproj b/qpid/cpp/src/tests/receiver.vcproj
index 824b75d7d9..ce6fad366e 100644
--- a/qpid/cpp/src/tests/receiver.vcproj
+++ b/qpid/cpp/src/tests/receiver.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="receiver"
- ProjectGUID="{7D314A98-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7D314A98-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="receiver"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\receiver\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\receiver\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\receiver\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\receiver\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\receiver\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\receiver\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\receiver\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\receiver\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/replaying_sender.cpp b/qpid/cpp/src/tests/replaying_sender.cpp
index 7e148e277f..ea2a13bd54 100644
--- a/qpid/cpp/src/tests/replaying_sender.cpp
+++ b/qpid/cpp/src/tests/replaying_sender.cpp
@@ -60,6 +60,8 @@ Sender::Sender(const std::string& queue, uint count_, uint reportFreq ) : sender
void Sender::execute(AsyncSession& session, bool isRetry)
{
+ if (verbosity > 0)
+ std::cout << "replaying_sender " << (isRetry ? "first " : "re-") << "connect." << endl;
if (isRetry) sender.replay(session);
else sender.init(session);
while (sent < count) {
@@ -70,7 +72,7 @@ void Sender::execute(AsyncSession& session, bool isRetry)
sender.send(message);
if (count > reportFrequency && !(sent % reportFrequency)) {
if ( verbosity > 0 )
- std::cout << "sent " << sent << " of " << count << std::endl;
+ std::cout << "Sender sent " << sent << " of " << count << std::endl;
}
}
message.setData("That's all, folks!");
diff --git a/qpid/cpp/src/tests/replication_test b/qpid/cpp/src/tests/replication_test
index 9b6e5cfb29..6e0c1c8d3b 100755
--- a/qpid/cpp/src/tests/replication_test
+++ b/qpid/cpp/src/tests/replication_test
@@ -22,21 +22,20 @@
# Run a test of the replication feature
MY_DIR=`dirname \`which $0\``
PYTHON_DIR=${MY_DIR}/../../../python
-
trap stop_brokers INT TERM QUIT
stop_brokers() {
- if [[ $BROKER_A ]] ; then
+ if [ x$BROKER_A != x ]; then
../qpidd -q --port $BROKER_A
unset BROKER_A
fi
- if [[ $BROKER_B ]] ; then
+ if [ x$BROKER_B != x ]; then
../qpidd -q --port $BROKER_B
unset BROKER_B
fi
}
-if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e ../.libs/replication_exchange.so ; then
+if test -d ${PYTHON_DIR} && test -f ../.libs/replicating_listener.so && test -f ../.libs/replication_exchange.so; then
rm -f queue-*.repl replication-*.log #cleanup from any earlier runs
../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replicating_listener.so --replication-queue replication --create-replication-queue true --log-enable info+ --log-to-file replication-source.log --log-to-stderr 0 > qpidd.port
@@ -44,7 +43,8 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e
../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replication_exchange.so --log-enable info+ --log-to-file replication-dest.log --log-to-stderr 0 > qpidd.port
BROKER_B=`cat qpidd.port`
- export PYTHONPATH=$PYTHON_DIR
+ PYTHONPATH=$PYTHON_DIR
+ export PYTHONPATH
echo "Running replication test between localhost:$BROKER_A and localhost:$BROKER_B"
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add exchange replication replication
@@ -55,23 +55,39 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-a --generate-queue-events 2
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-b --generate-queue-events 2
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-c --generate-queue-events 1
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-d --generate-queue-events 2
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-a
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-b
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-c
-
- #publish and consume from test queus on broker A:
- for i in `seq 1 10`; do echo Message $i for A >> queue-a-input.repl; done
- for i in `seq 1 20`; do echo Message $i for B >> queue-b-input.repl; done
- for i in `seq 1 15`; do echo Message $i for C >> queue-c-input.repl; done
+ #queue-d deliberately not declared on DR; this error case should be handled
+
+ #publish and consume from test queues on broker A:
+ i=1
+ while [ $i -le 10 ]; do
+ echo Message $i for A >> queue-a-input.repl
+ i=`expr $i + 1`
+ done
+ i=1
+ while [ $i -le 20 ]; do
+ echo Message $i for B >> queue-b-input.repl
+ i=`expr $i + 1`
+ done
+ i=1
+ while [ $i -le 15 ]; do
+ echo Message $i for C >> queue-c-input.repl
+ i=`expr $i + 1`
+ done
./sender --port $BROKER_A --routing-key queue-a --send-eos 1 < queue-a-input.repl
./sender --port $BROKER_A --routing-key queue-b --send-eos 1 < queue-b-input.repl
./sender --port $BROKER_A --routing-key queue-c --send-eos 1 < queue-c-input.repl
+ echo dummy | ./sender --port $BROKER_A --routing-key queue-d --send-eos 1
./receiver --port $BROKER_A --queue queue-a --messages 5 > /dev/null
./receiver --port $BROKER_A --queue queue-b --messages 10 > /dev/null
./receiver --port $BROKER_A --queue queue-c --messages 10 > /dev/null
+ ./receiver --port $BROKER_A --queue queue-d > /dev/null
#shutdown broker A then check that broker Bs versions of the queues are as expected
../qpidd -q --port $BROKER_A
@@ -90,7 +106,9 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e
diff queue-b-backup.repl queue-b-expected.repl || FAIL=1
diff queue-c-backup.repl queue-c-input.repl || FAIL=1
- if [[ $FAIL ]]; then
+ grep 'queue-d does not exist' replication-dest.log > /dev/null || echo "WARNING: Expected error to be logged!"
+
+ if [ x$FAIL != x ]; then
echo replication test failed: expectations not met!
exit 1
else
diff --git a/qpid/cpp/src/tests/resuming_receiver.cpp b/qpid/cpp/src/tests/resuming_receiver.cpp
index f49a115e1e..ef559a009d 100644
--- a/qpid/cpp/src/tests/resuming_receiver.cpp
+++ b/qpid/cpp/src/tests/resuming_receiver.cpp
@@ -53,6 +53,7 @@ class Listener : public MessageListener,
bool gaps;
uint reportFrequency;
int verbosity;
+ bool done;
};
@@ -62,7 +63,8 @@ Listener::Listener(int freq, int verbosity)
lastSn(0),
gaps(false),
reportFrequency(freq),
- verbosity(verbosity)
+ verbosity(verbosity),
+ done(false)
{}
@@ -70,6 +72,7 @@ void Listener::received(Message & message)
{
if (message.getData() == "That's all, folks!")
{
+ done = true;
if(verbosity > 0 )
{
std::cout << "Shutting down listener for "
@@ -111,14 +114,14 @@ void Listener::check()
if (gaps) throw Exception("Detected gaps in sequence; messages appear to have been lost.");
}
-void Listener::execute(AsyncSession& session, bool isRetry)
-{
- if (isRetry) {
- // std::cout << "Resuming from " << count << std::endl;
+void Listener::execute(AsyncSession& session, bool isRetry) {
+ if (verbosity > 0)
+ std::cout << "resuming_receiver " << (isRetry ? "first " : "re-") << "connect." << endl;
+ if (!done) {
+ SubscriptionManager subs(session);
+ subscription = subs.subscribe(*this, "message_queue");
+ subs.run();
}
- SubscriptionManager subs(session);
- subscription = subs.subscribe(*this, "message_queue");
- subs.run();
}
void Listener::editUrlList(std::vector<Url>& urls)
diff --git a/qpid/cpp/src/tests/run_failover_soak b/qpid/cpp/src/tests/run_failover_soak
index 9dddf59cf1..36dfed79a6 100755
--- a/qpid/cpp/src/tests/run_failover_soak
+++ b/qpid/cpp/src/tests/run_failover_soak
@@ -22,8 +22,8 @@
# Check AIS requirements and run tests if found.
id -ng | grep '\<ais\>' >/dev/null || \
NOGROUP="The ais group is not your primary group."
-ps -u root | grep aisexec >/dev/null || \
- NOAISEXEC="The aisexec daemon is not running as root"
+ps -u root | grep 'aisexec\|corosync' >/dev/null || \
+ NOAISEXEC="The aisexec/corosync daemon is not running as root"
if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then
cat <<EOF
@@ -47,10 +47,10 @@ host=127.0.0.1
src_root=..
module_dir=$src_root/.libs
-n_messages=300000
-report_frequency=10000
-verbosity=1
+MESSAGES=${MESSAGES:-300000}
+REPORT_FREQUENCY=${REPORT_FREQUENCY:-`expr $MESSAGES / 20`}
+VERBOSITY=${VERBOSITY:-1}
-exec `dirname $0`/failover_soak $src_root $module_dir $host ./declare_queues ./replaying_sender ./resuming_receiver $n_messages $report_frequency $verbosity
+exec ./failover_soak $src_root $module_dir $host ./declare_queues ./replaying_sender ./resuming_receiver $MESSAGES $REPORT_FREQUENCY $VERBOSITY
diff --git a/qpid/cpp/src/tests/run_header_test b/qpid/cpp/src/tests/run_header_test
index 39d4a24f84..414fecd28f 100755
--- a/qpid/cpp/src/tests/run_header_test
+++ b/qpid/cpp/src/tests/run_header_test
@@ -29,7 +29,8 @@ test -f qpidd.port && QPID_PORT=`cat qpidd.port`
if test -d ${PYTHON_DIR} ; then
./header_test -p $QPID_PORT
- export PYTHONPATH=$PYTHON_DIR:$PYTHONPATH
+ PYTHONPATH=$PYTHON_DIR:$PYTHONPATH
+ export PYTHONPATH
$srcdir/header_test.py "localhost" $QPID_PORT
else
echo "Skipping header test as python libs not found"
diff --git a/qpid/cpp/src/tests/sender.cpp b/qpid/cpp/src/tests/sender.cpp
index 48062315fe..9d9e5be99d 100644
--- a/qpid/cpp/src/tests/sender.cpp
+++ b/qpid/cpp/src/tests/sender.cpp
@@ -24,6 +24,7 @@
#include <qpid/client/AsyncSession.h>
#include <qpid/client/Message.h>
#include <qpid/client/MessageReplayTracker.h>
+#include <qpid/client/QueueOptions.h>
#include <qpid/Exception.h>
#include "TestOptions.h"
@@ -40,13 +41,17 @@ struct Args : public qpid::TestOptions
string destination;
string key;
uint sendEos;
+ bool durable;
+ string lvqMatchValue;
- Args() : key("test-queue"), sendEos(0)
+ Args() : key("test-queue"), sendEos(0), durable(false)
{
- addOptions()
+ addOptions()
("exchange", qpid::optValue(destination, "EXCHANGE"), "Exchange to send messages to")
("routing-key", qpid::optValue(key, "KEY"), "Routing key to add to messages")
- ("send-eos", qpid::optValue(sendEos, "N"), "Send N EOS messages to mark end of input");
+ ("send-eos", qpid::optValue(sendEos, "N"), "Send N EOS messages to mark end of input")
+ ("durable", qpid::optValue(durable, "true|false"), "Mark messages as durable.")
+ ("lvq-match-value", qpid::optValue(lvqMatchValue, "KEY"), "The value to set for the LVQ match key property");
}
};
@@ -55,7 +60,7 @@ const string EOS("eos");
class Sender : public FailoverManager::Command
{
public:
- Sender(const std::string& destination, const std::string& key, uint sendEos);
+ Sender(const std::string& destination, const std::string& key, uint sendEos, bool durable, const std::string& lvqMatchValue);
void execute(AsyncSession& session, bool isRetry);
private:
const std::string destination;
@@ -65,8 +70,17 @@ class Sender : public FailoverManager::Command
uint sent;
};
-Sender::Sender(const std::string& dest, const std::string& key, uint eos) :
- destination(dest), sender(10), message("", key), sendEos(eos), sent(0) {}
+Sender::Sender(const std::string& dest, const std::string& key, uint eos, bool durable, const std::string& lvqMatchValue) :
+ destination(dest), sender(10), message("", key), sendEos(eos), sent(0)
+{
+ if (durable){
+ message.getDeliveryProperties().setDeliveryMode(framing::PERSISTENT);
+ }
+
+ if (!lvqMatchValue.empty()) {
+ message.getHeaders().setString(QueueOptions::strLVQMatchProperty, lvqMatchValue);
+ }
+}
void Sender::execute(AsyncSession& session, bool isRetry)
{
@@ -90,7 +104,7 @@ int main(int argc, char ** argv)
try {
opts.parse(argc, argv);
FailoverManager connection(opts.con);
- Sender sender(opts.destination, opts.key, opts.sendEos);
+ Sender sender(opts.destination, opts.key, opts.sendEos, opts.durable, opts.lvqMatchValue);
connection.execute(sender);
connection.close();
return 0;
diff --git a/qpid/cpp/src/tests/sender.vcproj b/qpid/cpp/src/tests/sender.vcproj
index 7ae9081332..616b665406 100644
--- a/qpid/cpp/src/tests/sender.vcproj
+++ b/qpid/cpp/src/tests/sender.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="sender"
- ProjectGUID="{09714CB8-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{09714CB8-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="sender"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\sender\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\sender\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\sender\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\sender\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\sender\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\sender\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\sender\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\sender\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/shlibtest.vcproj b/qpid/cpp/src/tests/shlibtest.vcproj
index b30ce30b3a..4a139a2cb5 100644
--- a/qpid/cpp/src/tests/shlibtest.vcproj
+++ b/qpid/cpp/src/tests/shlibtest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="shlibtest"
- ProjectGUID="{37AB26B9-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="shlibtest"
Keyword="Win32Proj"
SignManifests="true"
@@ -22,8 +22,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\shlibtest\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\shlibtest\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -52,10 +52,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -74,8 +74,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtestsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtestd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\shlibtestd.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -96,8 +104,8 @@
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\shlibtest\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\shlibtest\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -126,8 +134,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -145,8 +153,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtests.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtest.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\shlibtest.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -167,8 +185,8 @@
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\shlibtest\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\shlibtest\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -197,10 +215,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -219,8 +237,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtestsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtestd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\shlibtestd.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -241,8 +268,8 @@
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\shlibtest\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\shlibtest\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -271,8 +298,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -290,8 +317,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtests.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtest.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\shlibtest.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -336,6 +374,9 @@
RelativePath="BrokerFixture.h">
</File>
<File
+ RelativePath="ClusterFixture.h">
+ </File>
+ <File
RelativePath="ConnectionOptions.h">
</File>
<File
diff --git a/qpid/cpp/src/tests/ssl_test b/qpid/cpp/src/tests/ssl_test
index c7b59b62ef..13965f3a03 100755
--- a/qpid/cpp/src/tests/ssl_test
+++ b/qpid/cpp/src/tests/ssl_test
@@ -39,8 +39,7 @@ create_certs() {
}
start_broker() {
- ../qpidd --daemon --transport ssl --port 0 --ssl-port 0 --no-data-dir --no-module-dir --auth no --config $CONFIG --load-module ../.libs/ssl.so --ssl-cert-db $CERT_DIR --ssl-cert-password-file $CERT_PW_FILE > qpidd.port
- PORT=`cat qpidd.port`
+ PORT=`../qpidd --daemon --transport ssl --port 0 --ssl-port 0 --no-data-dir --no-module-dir --auth no --config $CONFIG --load-module ../.libs/ssl.so --ssl-cert-db $CERT_DIR --ssl-cert-password-file $CERT_PW_FILE`
}
stop_broker() {
diff --git a/qpid/cpp/src/tests/start_cluster b/qpid/cpp/src/tests/start_cluster
index 4f0516500c..053b23da33 100755
--- a/qpid/cpp/src/tests/start_cluster
+++ b/qpid/cpp/src/tests/start_cluster
@@ -28,11 +28,10 @@ with_ais_group() {
echo $* | newgrp ais
}
-test -f cluster.ports && { echo "cluster.ports file already exists" ; exit 1; }
rm -f cluster*.log
SIZE=${1:-1}; shift
CLUSTER=`pwd` # Cluster name=pwd, avoid clashes.
-OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --no-data-dir --auth=no $*"
+OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --no-data-dir --auth=no $@"
for (( i=0; i<SIZE; ++i )); do
PORT=`with_ais_group ../qpidd -p0 --log-to-file=cluster$i.log $OPTS` || exit 1
diff --git a/qpid/cpp/src/tests/tests.sln b/qpid/cpp/src/tests/tests.sln
index cee1a45292..273e90d1c8 100644
--- a/qpid/cpp/src/tests/tests.sln
+++ b/qpid/cpp/src/tests/tests.sln
@@ -7,38 +7,38 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# this file will be lost the next time it is generated.
#
# MPC Command:
-# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 -static tests.mwc
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_test", "client_test.vcproj", "{9A95F0E4-FECA-1BAD-2235-047BCDC7409E}"
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 tests.mwc
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_test", "client_test.vcproj", "{9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "consume", "consume.vcproj", "{7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "consume", "consume.vcproj", "{7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echotest", "echotest.vcproj", "{0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echotest", "echotest.vcproj", "{0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "header_test", "header_test.vcproj", "{1B23F05D-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "header_test", "header_test.vcproj", "{1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "latencytest", "latencytest.vcproj", "{4A809018-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "latencytest", "latencytest.vcproj", "{4A809018-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perftest", "perftest.vcproj", "{1F2066BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perftest", "perftest.vcproj", "{1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "publish", "publish.vcproj", "{AE773E7F-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "publish", "publish.vcproj", "{AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "receiver", "receiver.vcproj", "{7D314A98-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "receiver", "receiver.vcproj", "{7D314A98-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sender", "sender.vcproj", "{09714CB8-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sender", "sender.vcproj", "{09714CB8-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shlibtest", "shlibtest.vcproj", "{37AB26B9-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shlibtest", "shlibtest.vcproj", "{37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_listener", "topic_listener.vcproj", "{9392D1EE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_listener", "topic_listener.vcproj", "{9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_publisher", "topic_publisher.vcproj", "{7D66FE10-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_publisher", "topic_publisher.vcproj", "{7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txjob", "txjob.vcproj", "{09034A53-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txjob", "txjob.vcproj", "{09034A53-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txshift", "txshift.vcproj", "{6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txshift", "txshift.vcproj", "{6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txtest", "txtest.vcproj", "{697786BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txtest", "txtest.vcproj", "{697786BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_test", "unit_test.vcproj", "{51E5F6B9-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_test", "unit_test.vcproj", "{51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -48,134 +48,134 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/qpid/cpp/src/tests/topic_listener.cpp b/qpid/cpp/src/tests/topic_listener.cpp
index 7bdc2c32de..1f0b3f5377 100644
--- a/qpid/cpp/src/tests/topic_listener.cpp
+++ b/qpid/cpp/src/tests/topic_listener.cpp
@@ -37,6 +37,7 @@
#include "qpid/client/MessageListener.h"
#include "qpid/client/Session.h"
#include "qpid/client/SubscriptionManager.h"
+#include "qpid/sys/SystemInfo.h"
#include "qpid/sys/Time.h"
#include "qpid/framing/FieldValue.h"
#include <iostream>
@@ -132,7 +133,7 @@ int main(int argc, char** argv){
if( args.statusqueue.length() > 0 ) {
stringstream msg_str;
- msg_str << "topic_listener: " << (int)getpid();
+ msg_str << "topic_listener: " << qpid::sys::SystemInfo::getProcessId();
session.messageTransfer(arg::content=Message(msg_str.str(), args.statusqueue));
cout << "Ready status put on queue '" << args.statusqueue << "'" << endl;
}
diff --git a/qpid/cpp/src/tests/topic_listener.vcproj b/qpid/cpp/src/tests/topic_listener.vcproj
index eedfe14687..0be31b8348 100644
--- a/qpid/cpp/src/tests/topic_listener.vcproj
+++ b/qpid/cpp/src/tests/topic_listener.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="topic_listener"
- ProjectGUID="{9392D1EE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="topic_listener"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_listener\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_listener\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_listener\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_listener\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_listener\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_listener\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_listener\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_listener\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/topic_publisher.vcproj b/qpid/cpp/src/tests/topic_publisher.vcproj
index a059adb398..016c6d4a38 100644
--- a/qpid/cpp/src/tests/topic_publisher.vcproj
+++ b/qpid/cpp/src/tests/topic_publisher.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="topic_publisher"
- ProjectGUID="{7D66FE10-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="topic_publisher"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_publisher\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_publisher\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_publisher\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_publisher\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_publisher\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_publisher\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_publisher\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_publisher\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txjob.vcproj b/qpid/cpp/src/tests/txjob.vcproj
index 69bdff2e8d..19fe3fba12 100644
--- a/qpid/cpp/src/tests/txjob.vcproj
+++ b/qpid/cpp/src/tests/txjob.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="txjob"
- ProjectGUID="{09034A53-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{09034A53-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txjob"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txjob\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txjob\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txjob\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txjob\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txjob\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txjob\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txjob\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txjob\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txshift.cpp b/qpid/cpp/src/tests/txshift.cpp
index 5db08d7a53..dd67710526 100644
--- a/qpid/cpp/src/tests/txshift.cpp
+++ b/qpid/cpp/src/tests/txshift.cpp
@@ -155,6 +155,7 @@ struct Worker : FailoverManager::Command, Runnable
SubscriptionManager subs(session);
transfer.subscribeToControl(subs);
subs.run();
+ session.txCommit();//commit accept of control messages
}
};
@@ -173,8 +174,8 @@ int main(int argc, char** argv)
for (size_t i = 0; i < opts.workers; i++) {
workers.push_back(new Worker(connection, opts.workQueue));
}
- for_each(workers.begin(), workers.end(), boost::bind(&Worker::start, _1));
- for_each(workers.begin(), workers.end(), boost::bind(&Worker::join, _1));
+ std::for_each(workers.begin(), workers.end(), boost::bind(&Worker::start, _1));
+ std::for_each(workers.begin(), workers.end(), boost::bind(&Worker::join, _1));
}
return 0;
diff --git a/qpid/cpp/src/tests/txshift.vcproj b/qpid/cpp/src/tests/txshift.vcproj
index aa7d6ca303..3212881351 100644
--- a/qpid/cpp/src/tests/txshift.vcproj
+++ b/qpid/cpp/src/tests/txshift.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="txshift"
- ProjectGUID="{6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txshift"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txshift\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txshift\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txshift\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txshift\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txshift\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txshift\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txshift\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txshift\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txtest.vcproj b/qpid/cpp/src/tests/txtest.vcproj
index a56e820dc0..663291a9d5 100644
--- a/qpid/cpp/src/tests/txtest.vcproj
+++ b/qpid/cpp/src/tests/txtest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="txtest"
- ProjectGUID="{697786BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{697786BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txtest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txtest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txtest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txtest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txtest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txtest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txtest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txtest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txtest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/unit_test.h b/qpid/cpp/src/tests/unit_test.h
index df3ebfb1fe..fc542e62ad 100644
--- a/qpid/cpp/src/tests/unit_test.h
+++ b/qpid/cpp/src/tests/unit_test.h
@@ -61,7 +61,14 @@
namespace { struct test_name { void test_method(); }; } \
void test_name::test_method()
-#endif // Workaround for BOOST_AUTO_TEST_SUITE_EXPECTED_FAILURES
+#endif // Workaround for BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES
+
+// Correct syntax for boost > 1.36
+#if (BOOST_VERSION > 103500)
+# define QPID_AUTO_TEST_CASE_EXPECTED_FAILURES(name,n) \
+ BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(name,n) \
+ BOOST_AUTO_TEST_CASE(name)
+#endif // Correct syntax for boost > 1.36
//
// Default definitions for latest version of boost.
diff --git a/qpid/cpp/src/tests/unit_test.vcproj b/qpid/cpp/src/tests/unit_test.vcproj
index ab6d13cd62..8710b617f8 100644
--- a/qpid/cpp/src/tests/unit_test.vcproj
+++ b/qpid/cpp/src/tests/unit_test.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="unit_test"
- ProjectGUID="{51E5F6B9-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="unit_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\unit_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\unit_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -52,22 +52,22 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qpidbrokerd.lib qmfconsoled.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\unit_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\unit_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -134,19 +134,19 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qpidbroker.lib qmfconsole.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\unit_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\unit_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -215,22 +215,22 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qpidbrokerd.lib qmfconsoled.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\unit_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\unit_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -298,19 +298,19 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qpidbroker.lib qmfconsole.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -361,15 +361,33 @@
RelativePath="Array.cpp">
</File>
<File
+ RelativePath="AsyncCompletion.cpp">
+ </File>
+ <File
RelativePath="AtomicValue.cpp">
</File>
<File
RelativePath="Blob.cpp">
</File>
<File
+ RelativePath="ClientSessionTest.cpp">
+ </File>
+ <File
RelativePath="ConsoleTest.cpp">
</File>
<File
+ RelativePath="DeliveryRecordTest.cpp">
+ </File>
+ <File
+ RelativePath="DtxWorkRecordTest.cpp">
+ </File>
+ <File
+ RelativePath="exception_test.cpp">
+ </File>
+ <File
+ RelativePath="ExchangeTest.cpp">
+ </File>
+ <File
RelativePath="FieldTable.cpp">
</File>
<File
@@ -379,9 +397,15 @@
RelativePath="FramingTest.cpp">
</File>
<File
+ RelativePath="HeadersExchangeTest.cpp">
+ </File>
+ <File
RelativePath="HeaderTest.cpp">
</File>
<File
+ RelativePath="IncompleteMessageList.cpp">
+ </File>
+ <File
RelativePath="InlineAllocator.cpp">
</File>
<File
@@ -394,6 +418,15 @@
RelativePath="ManagementTest.cpp">
</File>
<File
+ RelativePath="MessageBuilderTest.cpp">
+ </File>
+ <File
+ RelativePath="MessageReplayTracker.cpp">
+ </File>
+ <File
+ RelativePath="MessageTest.cpp">
+ </File>
+ <File
RelativePath="ProxyTest.cpp">
</File>
<File
@@ -403,6 +436,15 @@
RelativePath="QueueOptionsTest.cpp">
</File>
<File
+ RelativePath="QueuePolicyTest.cpp">
+ </File>
+ <File
+ RelativePath="QueueRegistryTest.cpp">
+ </File>
+ <File
+ RelativePath="QueueTest.cpp">
+ </File>
+ <File
RelativePath="RangeSet.cpp">
</File>
<File
@@ -430,6 +472,18 @@
RelativePath="StringUtils.cpp">
</File>
<File
+ RelativePath="TimerTest.cpp">
+ </File>
+ <File
+ RelativePath="TopicExchangeTest.cpp">
+ </File>
+ <File
+ RelativePath="TxBufferTest.cpp">
+ </File>
+ <File
+ RelativePath="TxPublishTest.cpp">
+ </File>
+ <File
RelativePath="unit_test.cpp">
</File>
<File