Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions src/Communication/AsioCompatibility.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) 2009, 2010, 2011 Object Computing, Inc.
// All rights reserved.
// See the file license.txt for licensing information.
//
#ifdef _MSC_VER
# pragma once
#endif
#ifndef ASIOCOMPATIBILITY_H
#define ASIOCOMPATIBILITY_H
#ifndef QUICKFAST_HEADERS
#error Please include <Application/QuickFAST.h> preferably as a precompiled header file.
#endif //QUICKFAST_HEADERS

#include "AsioService_fwd.h"
#include <boost/version.hpp>
#include <boost/asio.hpp>

namespace QuickFAST
{
namespace Communication
{
// Boost 1.66 replaced several of the Asio interfaces QuickFAST is written
// against, and Boost 1.87 removed the originals. Each helper below spells
// its operation the way the Boost release being compiled against expects,
// so that the call sites do not have to.

/// @brief Convert a dotted IP address to an asio address
/// @param address is the address in dotted notation
inline boost::asio::ip::address makeAddress(const std::string & address)
{
#if BOOST_VERSION >= 106600
return boost::asio::ip::make_address(address);
#else
return boost::asio::ip::address::from_string(address);
#endif
}

/// @brief Post a completion handler to an io service
/// @param ioService is the service that will run the handler
/// @param handler is the handler to be posted
template<typename CompletionHandler>
inline void postHandler(
boost::asio::io_service & ioService,
CompletionHandler handler)
{
#if BOOST_VERSION >= 106600
boost::asio::post(ioService, handler);
#else
ioService.post(handler);
#endif
}

/// @brief Keeps an io service running while it has no work to do
///
/// io_service::work was replaced by executor_work_guard in Boost 1.66 and
/// removed in Boost 1.87.
#if BOOST_VERSION >= 106600
typedef boost::asio::executor_work_guard<
boost::asio::io_context::executor_type> WorkGuard;
#else
typedef boost::asio::io_service::work WorkGuard;
#endif

/// @brief Create a work guard for an io service
/// @param ioService is the service to be kept alive
/// @returns a new work guard; the caller owns it
inline WorkGuard * makeWorkGuard(boost::asio::io_service & ioService)
{
#if BOOST_VERSION >= 106600
return new WorkGuard(boost::asio::make_work_guard(ioService));
#else
return new WorkGuard(ioService);
#endif
}

/// @brief Prepare an io service to be run again after it has stopped
/// @param ioService is the service to be restarted
inline void restartService(boost::asio::io_service & ioService)
{
#if BOOST_VERSION >= 106600
ioService.restart();
#else
ioService.reset();
#endif
}
}
}
#endif // ASIOCOMPATIBILITY_H
20 changes: 17 additions & 3 deletions src/Communication/AsioService.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#endif
#ifndef ASIOSERVICE_H
#define ASIOSERVICE_H
#include "AsioService_fwd.h"
#include "AsioCompatibility.h"
#include <Common/QuickFAST_Export.h>
#include <Common/Logger_fwd.h>
#include <Common/AtomicCounter.h>
Expand Down Expand Up @@ -87,7 +87,7 @@ namespace QuickFAST
/// should be called after joinThreads before calling run*, poll*, etc. again.
void resetService()
{
ioService_.reset();
restartService(ioService_);
stopping_ = false;
}

Expand All @@ -100,12 +100,26 @@ namespace QuickFAST
return ioService_;
}

#if BOOST_VERSION >= 106600
/// @brief the executor of the underlying io_service
///
/// Boost 1.66 replaced the io_service& constructors of the Asio I/O
/// objects with a template that asks its argument for an executor. The
/// implicit cast above is no longer enough for an AsioService to be
/// passed where an io_service used to be accepted, so the question is
/// forwarded to the io_service being wrapped.
boost::asio::io_context::executor_type get_executor()
{
return ioService_.get_executor();
}
#endif // BOOST_VERSION >= 106600

///@brief Post a completion handler for later processing (usually in a different thread)
/// @param handler is the handler to be posted
template<typename CompletionHandler>
void post(CompletionHandler handler)
{
ioService_.post(handler);
postHandler(ioService_, handler);
}

/// @brief Attempt to determine how many threads are available to ASIO
Expand Down
19 changes: 19 additions & 0 deletions src/Communication/AsioService_fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@
#error Please include <Application/QuickFAST.h> preferably as a precompiled header file.
#endif //QUICKFAST_HEADERS

// Boost 1.66 turned io_service into a typedef for io_context, so the class
// declaration QuickFAST used to make here now conflicts with the one Asio
// provides. From that release on, take the declaration from Boost itself;
// io_service.hpp only pulls in io_context, not all of Asio.
#include <boost/version.hpp>
#if BOOST_VERSION >= 108700
// Boost 1.87 removed the io_service name altogether.
# include <boost/asio/io_context.hpp>
namespace boost
{
namespace asio
{
typedef io_context io_service;
}
}
#elif BOOST_VERSION >= 106600
# include <boost/asio/io_service.hpp>
#else
// forward declare io_service without including
// boost header
namespace boost
Expand All @@ -20,6 +38,7 @@ namespace boost
class io_service;
}
}
#endif // BOOST_VERSION >= 106600

namespace QuickFAST
{
Expand Down
4 changes: 2 additions & 2 deletions src/Communication/AsynchSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ AsynchSender::AsynchSender(
: Sender(recycler)
, name_(name)
, ioService_()
, keepAlive_(new boost::asio::io_service::work(ioService_))
, keepAlive_(makeWorkGuard(ioService_))
{
//std::cout << "Asynch Sender {" << (void *)this << "} keeping ioService " << (void*) &ioService_ << " alive." << std::endl;
}
Expand All @@ -27,7 +27,7 @@ AsynchSender::AsynchSender(
: Sender(recycler)
, name_(name)
, ioService_(ioService)
, keepAlive_(new boost::asio::io_service::work(ioService_))
, keepAlive_(makeWorkGuard(ioService_))
{
// std::cout << "Asynch Sender {" << (void *)this << "} keeping shared ioService " << (void*) &ioService_ << " alive." << std::endl;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Communication/AsynchSender.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ namespace QuickFAST
/// needed for output-type service which may have nothing to write at the moment, unlike
/// input-type services which should always have an outstanding read or an active handler
/// callback.
boost::scoped_ptr<boost::asio::io_service::work> keepAlive_;
boost::scoped_ptr<WorkGuard> keepAlive_;
};
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Communication/MulticastReceiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ namespace QuickFAST
)
: parent_(parent)
, name_(name)
, listenInterface_(boost::asio::ip::address::from_string(listenInterfaceIP))
, listenInterface_(makeAddress(listenInterfaceIP))
, portNumber_(portNumber)
, multicastGroup_(boost::asio::ip::address::from_string(multicastGroupIP))
, bindAddress_(boost::asio::ip::address::from_string(bindIP))
, multicastGroup_(makeAddress(multicastGroupIP))
, bindAddress_(makeAddress(bindIP))
, endpoint_(listenInterface_, portNumber)
, socket_(ioService)
, joined_(false)
Expand Down
2 changes: 1 addition & 1 deletion src/Communication/MulticastSender.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ namespace QuickFAST
///@brief Prepare the sender to be used
bool initializeSender()
{
multicastAddress_ = boost::asio::ip::address::from_string(sendAddress_);
multicastAddress_ = makeAddress(sendAddress_);
endpoint_ = boost::asio::ip::udp::endpoint(multicastAddress_, portNumber_);
socket_.open(endpoint_.protocol());
return true;
Expand Down
14 changes: 14 additions & 0 deletions src/Communication/TCPReceiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,26 @@ namespace QuickFAST
bool ok = true;
// generate a collection of possible endpoints for this host:port
boost::asio::ip::tcp::resolver resolver(ioService_);
#if BOOST_VERSION >= 106600
// resolver::query and the iterator-returning resolve() were replaced
// in Boost 1.66 and removed in Boost 1.87.
boost::asio::ip::tcp::resolver::results_type endpoints =
resolver.resolve(hostName_, port_);
boost::asio::ip::tcp::resolver::results_type::const_iterator iterator =
endpoints.begin();
boost::asio::ip::tcp::resolver::results_type::const_iterator endIterator =
endpoints.end();

// then iterate thru the collection until we find one that works.
boost::system::error_code error;
#else
boost::asio::ip::tcp::resolver::query query( hostName_, port_);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);

// then iterate thru the collection until we find one that works.
boost::system::error_code error;
boost::asio::ip::tcp::resolver::iterator endIterator;
#endif // BOOST_VERSION >= 106600
bool connected = false;
while(!connected && iterator != endIterator)
{
Expand Down
20 changes: 20 additions & 0 deletions src/Examples/FileToMulticast/FileToMulticast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,18 @@ FileToMulticast::run()
<< "Largest is " << bufferSize_ << " bytes." << std::endl;
}

#if BOOST_VERSION >= 106600
// strand::wrap and strand::dispatch were replaced in Boost 1.66.
boost::asio::dispatch(strand_, boost::bind(&FileToMulticast::sendBurst, this));
#else
#if BOOST_VERSION >= 106600
// strand::dispatch now takes the handler itself, already bound.
boost::asio::dispatch(strand_, boost::bind(&FileToMulticast::sendBurst, this));
#else
strand_.dispatch(
strand_.wrap(boost::bind(&FileToMulticast::sendBurst, this)));
#endif // BOOST_VERSION >= 106600
#endif // BOOST_VERSION >= 106600
StopWatch lapse;
this->ioService_.run();
unsigned long sendLapse = lapse.freeze();
Expand Down Expand Up @@ -302,9 +312,19 @@ FileToMulticast::sendBurst()
// set the next timeout
if(sendMicroseconds_ != 0)
{
#if BOOST_VERSION >= 106600
timer_.expires_after(std::chrono::microseconds(sendMicroseconds_));
#else
timer_.expires_from_now(boost::posix_time::microseconds(sendMicroseconds_));
#endif // BOOST_VERSION >= 106600
timer_.async_wait(
#if BOOST_VERSION >= 106600
// strand::wrap was replaced by bind_executor in Boost 1.66.
boost::asio::bind_executor(
strand_, boost::bind(&FileToMulticast::sendBurst, this))
#else
strand_.wrap(boost::bind(&FileToMulticast::sendBurst, this))
#endif // BOOST_VERSION >= 106600
);
}

Expand Down
11 changes: 10 additions & 1 deletion src/Examples/FileToMulticast/FileToMulticast.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <Communication/MulticastSender_fwd.h>
#include <Communication/BufferRecycler.h>
#include <stdio.h>
#include <chrono>

namespace QuickFAST{
namespace Examples{
Expand Down Expand Up @@ -64,8 +65,16 @@ namespace QuickFAST{
bool verbose_;

Communication::AsioService ioService_;
boost::asio::strand strand_;
// boost::asio::strand became a template in Boost 1.66; the class this
// example uses is spelled io_service::strand in every release.
boost::asio::io_service::strand strand_;
#if BOOST_VERSION >= 106600
// Asio's date_time based timers became opt-in, so the example uses the
// chrono based timer that is always available.
boost::asio::steady_timer timer_;
#else
boost::asio::deadline_timer timer_;
#endif // BOOST_VERSION >= 106600

Application::CommandArgParser commandArgParser_;
FILE * dataFile_;
Expand Down
9 changes: 8 additions & 1 deletion src/Examples/FileToTCP/FileToTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,19 @@ FileToTCP::run()

for (size_t count = 0; count < sendCount_ || sendCount_ == 0; ++count)
{
tcp::iostream stream;
if(verbose_)
{
std::cout << "Listening" << std::endl;
}
#if BOOST_VERSION >= 106600
// Boost 1.66 made basic_socket a private base of the stream buffer, so
// the accepted socket is moved into the stream instead of accepted into
// the stream's buffer.
tcp::iostream stream(acceptor.accept());
#else
tcp::iostream stream;
acceptor.accept(*stream.rdbuf());
#endif // BOOST_VERSION >= 106600
if(verbose_)
{
std::cout << "Accepting" << std::endl;
Expand Down
1 change: 1 addition & 0 deletions src/Examples/FileToTCP/FileToTCP.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef FILETOTCP_H
#define FILETOTCP_H
#include <Application/CommandArgParser.h>
#include <Communication/AsioCompatibility.h>
#include <boost/asio.hpp>
#include <stdio.h>

Expand Down
2 changes: 1 addition & 1 deletion src/Examples/InterpretApplication/InterpretApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ InterpretApplication::run()
"r"
#endif
);
if(bufferFile <= 0)
if(bufferFile == 0)
{
std::cerr << "Can't open file " << bufferFilename_ << std::endl;
return -1;
Expand Down
17 changes: 16 additions & 1 deletion src/Examples/PCapToMulticast/PCapToMulticast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ PCapToMulticast::applyArgs()
}
ok = ok && pcapReader_.open(dataFileName_.c_str());// for debugging dump to->, &std::cout);

multicastAddress_ = boost::asio::ip::address::from_string(sendAddress_);
multicastAddress_ = Communication::makeAddress(sendAddress_);
endpoint_ = boost::asio::ip::udp::endpoint(multicastAddress_, portNumber_);
socket_.open(endpoint_.protocol());
std::cout << "Opening multicast group: " << endpoint_.address().to_string() << ':' << endpoint_.port() << std::endl;
Expand All @@ -189,8 +189,13 @@ PCapToMulticast::run()
std::cout << " Configuring multicast: " << multicastAddress_ << '|' << sendAddress_ << ':' << portNumber_ << std::endl;
}

#if BOOST_VERSION >= 106600
// strand::dispatch now takes the handler itself, already bound.
boost::asio::dispatch(strand_, boost::bind(&PCapToMulticast::sendBurst, this));
#else
strand_.dispatch(
strand_.wrap(boost::bind(&PCapToMulticast::sendBurst, this)));
#endif // BOOST_VERSION >= 106600
StopWatch lapse;
this->ioService_.run();
unsigned long sendLapse = lapse.freeze();
Expand Down Expand Up @@ -228,9 +233,19 @@ PCapToMulticast::sendBurst()
// set the next timeout
if(sendMicroseconds_ != 0)
{
#if BOOST_VERSION >= 106600
timer_.expires_after(std::chrono::microseconds(sendMicroseconds_));
#else
timer_.expires_from_now(boost::posix_time::microseconds(sendMicroseconds_));
#endif // BOOST_VERSION >= 106600
timer_.async_wait(
#if BOOST_VERSION >= 106600
// strand::wrap was replaced by bind_executor in Boost 1.66.
boost::asio::bind_executor(
strand_, boost::bind(&PCapToMulticast::sendBurst, this))
#else
strand_.wrap(boost::bind(&PCapToMulticast::sendBurst, this))
#endif // BOOST_VERSION >= 106600
);
}

Expand Down
Loading