From c1ea6a47a57c2d9142706e7fca8e745412b12750 Mon Sep 17 00:00:00 2001 From: Steven Geddis Date: Wed, 31 Jan 2018 16:42:19 +0100 Subject: [PATCH 1/9] add gcc5 support --- .travis.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3be12c..49caa01 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,14 @@ matrix: # Linux / GCC ################ + - os: linux + compiler: gcc + env: + - COMPILER_PACKAGE=g++-5 + - C_COMPILER=gcc-5 + - CXX_COMPILER=g++-5 + - CXXFLAGS=-std=c++11 + - os: linux env: - COMPILER_PACKAGE=g++-6 @@ -86,6 +94,6 @@ script: export CC=/usr/bin/$C_COMPILER && export CXX=/usr/bin/$CXX_COMPILER && mkdir build.release && cd build.release && - cmake .. ${CMAKE_OPTIONS} -DAMQP-CPP_BUILD_EXAMPLES=ON -DAMQP-CPP_LINUX_TCP=ON -GNinja && - cmake --build . --config Release && + cmake ${CMAKE_OPTIONS} -DAMQP-CPP_BUILD_EXAMPLES=ON -DAMQP-CPP_LINUX_TCP=ON -GNinja .. && + cmake --config Release --build . && cd .." From b713d48bb97cd674ed145414733ee8cead54f90c Mon Sep 17 00:00:00 2001 From: Steven Geddis Date: Thu, 1 Feb 2018 12:44:48 +0100 Subject: [PATCH 2/9] add second constructor with heartbeat interval; apply modern cpp typedefs; Add comments; --- include/amqpcpp/libboostasio.h | 40 +++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/include/amqpcpp/libboostasio.h b/include/amqpcpp/libboostasio.h index 18b2a10..2ba7918 100644 --- a/include/amqpcpp/libboostasio.h +++ b/include/amqpcpp/libboostasio.h @@ -62,7 +62,7 @@ private: */ boost::asio::io_service & _ioservice; - typedef std::weak_ptr strand_weak_ptr; + using strand_weak_ptr = std::weak_ptr; /** * The boost asio io_service::strand managed pointer. @@ -77,7 +77,6 @@ private: */ boost::asio::posix::stream_descriptor _socket; - /** * A boolean that indicates if the watcher is monitoring for read events. * @var _read True if reads are being monitored else false. @@ -315,7 +314,7 @@ private: */ boost::asio::io_service & _ioservice; - typedef std::weak_ptr strand_weak_ptr; + using strand_weak_ptr = std::weak_ptr; /** * The boost asio io_service::strand managed pointer. @@ -330,6 +329,7 @@ private: boost::asio::deadline_timer _timer; using handler_fn = boost::function; + /** * Binds and returns a lamba function handler for the io operation. * @param connection The connection being watched. @@ -457,7 +457,7 @@ private: */ boost::asio::io_service & _ioservice; - typedef std::shared_ptr strand_shared_ptr; + using strand_shared_ptr = std::shared_ptr; /** * The boost asio io_service::strand managed pointer. @@ -465,16 +465,23 @@ private: */ strand_shared_ptr _strand; - /** * All I/O watchers that are active, indexed by their filedescriptor * @var std::map */ std::map > _watchers; - + /** + * The boost asio io_service::deadline_timer managed pointer. + * @var class std::shared_ptr + */ std::shared_ptr _timer; + /** + * The heartbeat timer interval (in seconds). + * @var uint16_t + */ + uint16_t _timer_interval; /** * Method that is called by AMQP-CPP to register a filedescriptor for readability or writability @@ -528,6 +535,9 @@ protected: // skip if no heartbeats are needed if (interval == 0) return 0; + // use the most frequent heartbeat interval (user-specified or rabbit server default). + interval = (_timer_interval > 0 && _timer_interval < interval) ? _timer_interval : interval; + // set the timer _timer->set(connection, interval); @@ -551,7 +561,22 @@ public: explicit LibBoostAsioHandler(boost::asio::io_service &io_service) : _ioservice(io_service), _strand(std::make_shared(_ioservice)), - _timer(std::make_shared(_ioservice,_strand)) + _timer(std::make_shared(_ioservice,_strand)), + _timer_interval(0) + { + + } + + /** + * Constructor + * @param io_service The boost io_service to wrap + * @param interval The interval to use when negotiating heartbeat with rabbit server. + */ + explicit LibBoostAsioHandler(boost::asio::io_service &io_service, uint16_t interval) : + _ioservice(io_service), + _strand(std::make_shared(_ioservice)), + _timer(std::make_shared(_ioservice,_strand)), + _timer_interval(interval) { } @@ -584,4 +609,3 @@ public: * End of namespace */ } - From ae3b94fe92b3e5b39b29ff57b33cc9ee7d3b5803 Mon Sep 17 00:00:00 2001 From: Steven Geddis Date: Thu, 1 Feb 2018 13:05:41 +0100 Subject: [PATCH 3/9] use custom heartbeat interval outright, if set. --- include/amqpcpp/libboostasio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/amqpcpp/libboostasio.h b/include/amqpcpp/libboostasio.h index 2ba7918..fcc0705 100644 --- a/include/amqpcpp/libboostasio.h +++ b/include/amqpcpp/libboostasio.h @@ -536,7 +536,7 @@ protected: if (interval == 0) return 0; // use the most frequent heartbeat interval (user-specified or rabbit server default). - interval = (_timer_interval > 0 && _timer_interval < interval) ? _timer_interval : interval; + interval = (_timer_interval > 0) ? _timer_interval : interval; // set the timer _timer->set(connection, interval); From 33c8e76a7ea73a5595002e74ad4be80ccd3f5ba8 Mon Sep 17 00:00:00 2001 From: Steven Geddis Date: Thu, 1 Feb 2018 13:11:23 +0100 Subject: [PATCH 4/9] correct comment --- include/amqpcpp/libboostasio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/amqpcpp/libboostasio.h b/include/amqpcpp/libboostasio.h index fcc0705..56f73d4 100644 --- a/include/amqpcpp/libboostasio.h +++ b/include/amqpcpp/libboostasio.h @@ -535,7 +535,7 @@ protected: // skip if no heartbeats are needed if (interval == 0) return 0; - // use the most frequent heartbeat interval (user-specified or rabbit server default). + // choose heartbeat interval to use (user-specified or rabbit server default). interval = (_timer_interval > 0) ? _timer_interval : interval; // set the timer From 5a853134aae2b26cc36618c641bcf655e1cb3448 Mon Sep 17 00:00:00 2001 From: Steven Geddis Date: Thu, 1 Feb 2018 15:27:59 +0100 Subject: [PATCH 5/9] remove second ctor with heartbeat interval (extend class instead). Change private to protected to allow LibBoostAsioHandler to be extended. --- include/amqpcpp/libboostasio.h | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/include/amqpcpp/libboostasio.h b/include/amqpcpp/libboostasio.h index 56f73d4..9c09645 100644 --- a/include/amqpcpp/libboostasio.h +++ b/include/amqpcpp/libboostasio.h @@ -47,7 +47,7 @@ namespace AMQP { */ class LibBoostAsioHandler : public virtual TcpHandler { -private: +protected: /** * Helper class that wraps a boost io_service socket monitor. @@ -477,12 +477,6 @@ private: */ std::shared_ptr _timer; - /** - * The heartbeat timer interval (in seconds). - * @var uint16_t - */ - uint16_t _timer_interval; - /** * Method that is called by AMQP-CPP to register a filedescriptor for readability or writability * @param connection The TCP connection object that is reporting @@ -535,9 +529,6 @@ protected: // skip if no heartbeats are needed if (interval == 0) return 0; - // choose heartbeat interval to use (user-specified or rabbit server default). - interval = (_timer_interval > 0) ? _timer_interval : interval; - // set the timer _timer->set(connection, interval); @@ -567,20 +558,6 @@ public: } - /** - * Constructor - * @param io_service The boost io_service to wrap - * @param interval The interval to use when negotiating heartbeat with rabbit server. - */ - explicit LibBoostAsioHandler(boost::asio::io_service &io_service, uint16_t interval) : - _ioservice(io_service), - _strand(std::make_shared(_ioservice)), - _timer(std::make_shared(_ioservice,_strand)), - _timer_interval(interval) - { - - } - /** * Handler cannot be copied or moved * From accc1810a07e9871cc1c3b299ab5e14b9e40a216 Mon Sep 17 00:00:00 2001 From: Steven Geddis Date: Thu, 1 Feb 2018 15:31:19 +0100 Subject: [PATCH 6/9] remove timer interval from ctor init list --- include/amqpcpp/libboostasio.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/amqpcpp/libboostasio.h b/include/amqpcpp/libboostasio.h index 9c09645..c6fb532 100644 --- a/include/amqpcpp/libboostasio.h +++ b/include/amqpcpp/libboostasio.h @@ -552,8 +552,7 @@ public: explicit LibBoostAsioHandler(boost::asio::io_service &io_service) : _ioservice(io_service), _strand(std::make_shared(_ioservice)), - _timer(std::make_shared(_ioservice,_strand)), - _timer_interval(0) + _timer(std::make_shared(_ioservice,_strand)) { } From f5540e9af2d44211159cf5067a5cc0f199064a12 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Tue, 6 Feb 2018 21:54:56 +0100 Subject: [PATCH 7/9] fixed autodelete flag for declaring an exchange and added support for internal exchange. this fixes #183 --- include/amqpcpp/channel.h | 3 ++- include/amqpcpp/flags.h | 3 ++- src/channelimpl.cpp | 11 +++++++++-- src/exchangedeclareframe.h | 31 +++++++++++++++++++++++++------ src/flags.cpp | 3 ++- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/include/amqpcpp/channel.h b/include/amqpcpp/channel.h index bff4085..c41e0aa 100644 --- a/include/amqpcpp/channel.h +++ b/include/amqpcpp/channel.h @@ -1,7 +1,7 @@ /** * Class describing a (mid-level) AMQP channel implementation * - * @copyright 2014 - 2017 Copernica BV + * @copyright 2014 - 2018 Copernica BV */ /** @@ -170,6 +170,7 @@ public: * - durable exchange survives a broker restart * - autodelete exchange is automatically removed when all connected queues are removed * - passive only check if the exchange exist + * - internal create an internal exchange * * @param name name of the exchange * @param type exchange type diff --git a/include/amqpcpp/flags.h b/include/amqpcpp/flags.h index 3a4a2c3..37779af 100644 --- a/include/amqpcpp/flags.h +++ b/include/amqpcpp/flags.h @@ -3,7 +3,7 @@ * * The various flags that are supported * - * @copyright 2014 Copernica BV + * @copyright 2014 - 2018 Copernica BV */ /** @@ -38,6 +38,7 @@ extern const int multiple; extern const int requeue; extern const int readable; extern const int writable; +extern const int internal; /** * End of namespace diff --git a/src/channelimpl.cpp b/src/channelimpl.cpp index 9d32874..e655657 100644 --- a/src/channelimpl.cpp +++ b/src/channelimpl.cpp @@ -252,7 +252,7 @@ Deferred &ChannelImpl::close() Deferred &ChannelImpl::declareExchange(const std::string &name, ExchangeType type, int flags, const Table &arguments) { // convert exchange type - std::string exchangeType; + const char *exchangeType = ""; // convert the exchange type into a string if (type == ExchangeType::fanout) exchangeType = "fanout"; @@ -261,8 +261,15 @@ Deferred &ChannelImpl::declareExchange(const std::string &name, ExchangeType typ else if (type == ExchangeType::headers) exchangeType = "headers"; else if (type == ExchangeType::consistent_hash) exchangeType = "x-consistent-hash"; + // the boolean options + bool passive = flags & AMQP::passive; + bool durable = flags & AMQP::durable; + bool autodelete = flags & AMQP::autodelete; + bool internal = flags & AMQP::internal; + bool nowait = flags & AMQP::nowait; + // send declare exchange frame - return push(ExchangeDeclareFrame(_id, name, exchangeType, (flags & passive) != 0, (flags & durable) != 0, false, arguments)); + return push(ExchangeDeclareFrame(_id, name, exchangeType, passive, durable, autodelete, internal, nowait, arguments)); } /** diff --git a/src/exchangedeclareframe.h b/src/exchangedeclareframe.h index cb45f01..5e02b2c 100644 --- a/src/exchangedeclareframe.h +++ b/src/exchangedeclareframe.h @@ -1,7 +1,7 @@ /** * Class describing an AMQP exchange declare frame * - * @copyright 2014 Copernica BV + * @copyright 2014 - 2018 Copernica BV */ /** @@ -77,16 +77,17 @@ public: * @param type exchange type * @param passive do not create exchange if it does not exist * @param durable durable exchange + * @param autodelete is this an auto-delete exchange? + * @param internal is this an internal exchange * @param noWait do not wait on response * @param arguments additional arguments */ - ExchangeDeclareFrame(uint16_t channel, const std::string& name, const std::string& type, bool passive, bool durable, bool noWait, const Table& arguments) : - ExchangeFrame(channel, (uint32_t)(name.length() + type.length() + arguments.size() + 5)), // size of name, type and arguments + 1 (all booleans are stored in 1 byte) + 2 (deprecated short) + 2 (string sizes) + ExchangeDeclareFrame(uint16_t channel, const std::string& name, const char *type, bool passive, bool durable, bool autodelete, bool internal, bool nowait, const Table& arguments) : + ExchangeFrame(channel, (uint32_t)(name.length() + strlen(type) + arguments.size() + 5)), // size of name, type and arguments + 1 (all booleans are stored in 1 byte) + 2 (deprecated short) + 2 (string sizes) _name(name), _type(type), - _bools(passive, durable, false, false, noWait), - _arguments(arguments) - {} + _bools(passive, durable, autodelete, internal, nowait), + _arguments(arguments) {} /** * Construct parsing a declare frame from a received frame @@ -162,6 +163,24 @@ public: { return _bools.get(1); } + + /** + * Is this an autodelete exchange? + * @return bool + */ + bool autoDelete() const + { + return _bools.get(2); + } + + /** + * Is this an internal exchange? + * @return bool + */ + bool internal() const + { + return _bools.get(3); + } /** * Do not wait for a response diff --git a/src/flags.cpp b/src/flags.cpp index 946b51c..24351cb 100644 --- a/src/flags.cpp +++ b/src/flags.cpp @@ -3,7 +3,7 @@ * * The various flags that are supported * - * @copyright 2014 Copernica BV + * @copyright 2014 - 2018 Copernica BV */ #include "includes.h" @@ -32,6 +32,7 @@ const int immediate = 0x1000; const int redelivered = 0x2000; const int multiple = 0x4000; const int requeue = 0x8000; +const int internal = 0x10000; /** * Flags for event loops From ec327de3961547b752d0dda3cbc421568ef86212 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Wed, 7 Feb 2018 10:08:32 +0100 Subject: [PATCH 8/9] less conservative caching of outgoing data. This fixes #184 --- include/amqpcpp/channelimpl.h | 12 +++++++++--- src/channelimpl.cpp | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/amqpcpp/channelimpl.h b/include/amqpcpp/channelimpl.h index 1ba6130..3d90266 100644 --- a/include/amqpcpp/channelimpl.h +++ b/include/amqpcpp/channelimpl.h @@ -5,7 +5,7 @@ * that has a private constructor so that it can not be used from outside * the AMQP library * - * @copyright 2014 - 2017 Copernica BV + * @copyright 2014 - 2018 Copernica BV */ /** @@ -122,7 +122,8 @@ private: std::queue> _queue; /** - * Are we currently operating in synchronous mode? + * Are we currently operating in synchronous mode? Meaning: do we first have + * to wait for the answer to previous instructions before we send a new instruction? * @var bool */ bool _synchronous = false; @@ -567,6 +568,9 @@ public: // if we are still in connected state we are now ready if (_state == state_connected) _state = state_ready; + + // the last (possibly synchronous) operation was received, so we're no longer in synchronous mode + if (_synchronous && _queue.empty()) _synchronous = false; // inform handler if (_readyCallback) _readyCallback(); @@ -586,7 +590,6 @@ public: { // change state _state = state_closed; - _synchronous = false; // create a monitor, because the callbacks could destruct the current object Monitor monitor(this); @@ -620,6 +623,9 @@ public: { // skip if there is no oldest callback if (!_oldestCallback) return true; + + // the last (possibly synchronous) operation was received, so we're no longer in synchronous mode + if (_synchronous && _queue.empty()) _synchronous = false; // we are going to call callbacks that could destruct the channel Monitor monitor(this); diff --git a/src/channelimpl.cpp b/src/channelimpl.cpp index e655657..a498864 100644 --- a/src/channelimpl.cpp +++ b/src/channelimpl.cpp @@ -3,7 +3,7 @@ * * Implementation for a channel * - * @copyright 2014 - 2017 Copernica BV + * @copyright 2014 - 2018 Copernica BV */ #include "includes.h" #include "basicdeliverframe.h" @@ -693,7 +693,7 @@ bool ChannelImpl::send(const Frame &frame) // added to the list of deferred objects. it will be notified about // the error when the close operation succeeds if (_state == state_closing) return true; - + // are we currently in synchronous mode or are there // other frames waiting for their turn to be sent? if (_synchronous || !_queue.empty()) From 65da35d4643c58f023ee3ab0bfbf4f7845f4fea8 Mon Sep 17 00:00:00 2001 From: Aart Stuurman Date: Mon, 19 Feb 2018 12:07:07 +0100 Subject: [PATCH 9/9] Fix documentation to contain correct build options. README.md contained incorrectly named build options. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ef0178e..715e6a5 100644 --- a/README.md +++ b/README.md @@ -82,14 +82,14 @@ The CMake file supports both building and installing. You can choose not to use ``` bash mkdir build cd build -cmake .. [-DBUILD_SHARED] [-DLINUX_TCP] +cmake .. [-DAMQP-CPP_AMQBUILD_SHARED] [-DAMQP-CPP_LINUX_TCP] cmake --build .. --target install ``` Option|Default|Meaning ------|-------|------- -BUILD_SHARED|OFF|Static lib(ON) or shared lib(OFF)? Shared is not supported on Windows. -LINUX_TCP|OFF|Should the Linux-only TCP module be built? +AMQP-CPP_BUILD_SHARED|OFF|Static lib(ON) or shared lib(OFF)? Shared is not supported on Windows. +AMQP-CPP_LINUX_TCP|OFF|Should the Linux-only TCP module be built? ## Make Installing the library is as easy