GithubHelp home page GithubHelp logo

asio's People

Contributors

beman avatar brycelelbach avatar chriskohlhoff avatar danieljames avatar ecatmur avatar eldiener avatar grafikrobot avatar hkaiser avatar imikejackson avatar jessicah avatar jzmaddock avatar klemens-morgenstern avatar nmusatti avatar pdimov avatar steveire avatar straszheim avatar swatanabe avatar viboes avatar vprus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asio's Issues

Noncopyable (move-only) completion handlers are unsupported

Example:

#include <boost/asio/io_context.hpp>
#include <memory>
int main()
{
    boost::asio::io_context ctx;
    struct op
    {
        std::unique_ptr<int> data;
        void operator()() { }
    };
    ctx.post(op{});
}

fails to compile:

/usr/local/include/boost/asio/impl/io_context.hpp:174:3: error: use of deleted function ‘main()::op::op(const main()::op&)’

Some sections of ASIO (and others?) documentation lack an "index"

No idea how Quickbook is supposed to work. But from the perspective of somebody reading the docs:

And here I would have expected an index. It took me ages to notice that I can now click on the right arrow to reach https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio/reference/asynchronous_operations/general_asynchronous_operation_concepts.html (AFAIK the only way to reach it).

Not sure if it's an issue with Quickbook (so affecting others?) or with the way ASIO uses Quickbook.

clang 7.0 <experimental/string_view> has been moved to <string_view>

I've been trying out clang 7.0 and it seems they moved experimenta/string_view to string_view:

In file included from /usr/local/include/boost/asio/ip/address.hpp:21:
In file included from /usr/local/include/boost/asio/detail/string_view.hpp:23:
/usr/local/include/c++/v1/experimental/string_view:11:2: error: "<experimental/string_view> has been removed. Use <string_view> instead."
#error "<experimental/string_view> has been removed. Use <string_view> instead."

This quick fix in boost/asio/detail/config.hpp fixes my issue, but I'm not sure how it interplays with AppleClang.

--- config.hpp	2018-02-11 13:41:39.000000000 +0100
+++ config.hpp.mine	2018-02-11 13:41:21.000000000 +0100
@@ -775,7 +775,11 @@
 #   if (__cplusplus >= 201402)
 #    if __has_include(<experimental/string_view>)
 #     define BOOST_ASIO_HAS_STD_STRING_VIEW 1
-#     define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
+#     if __clang_major__ >= 7
+#      undef BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW
+#     else
+#      define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
+#     endif // __clang_major__ >= 7
 #    endif // __has_include(<experimental/string_view>)
 #   endif // (__cplusplus >= 201402)
 #  endif // defined(__clang__)

1.66 API breaking change in io_context constructor

Hello,

1.66 introduced an API breaking change in the constructor of io_context.

io_context takes an int while io_service took a std::size_t. Compare v1.66 and v1.65. This change breaks all code that stored a std::size_t which later got passed to the io_service constructor due to a now narrowing conversion.

I think this should either be fixed or noted on http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/net_ts.html as io_service is not a strict typedef but a different type.

For example, see microsoft/cpprestsdk#654.

thanks,
Stephan

Stack smashing in boost::asio::detail::task_io_service::do_run_one

I have a stripped down PoC and some more info here:

https://pastebin.com/raw/GVK8PJRe

Looking at the function in question, I don't see anything that immediately stands out, but I'm not familiar with all the internal processes going on within it.

Build/Test (Boost 1.62.0, g++ 7.2.0, Linux 4.13.0-32-generic x86_64):

Start echo server
ncat -vvlp 9001 -e /bin/cat

Run
g++ main.cpp -lboost_system -lpthread
./a.out 127.0.0.1 9001

*** stack smashing detected ***: terminated
Aborted (core dumped)

Backtrace:
1 __GI_raise
2 __GI_abort
3 __libc_message
4 __GI___fortify_fail_abort
5 __stack_chk_fail
6 boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lockboost::asio::detail::posix_mutex&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&)
7 boost::asio::detail::task_io_service::run_one(boost::system::error_code&)
8 boost::asio::io_service::run_one()
9 tcp::send(std::vector const&)
10 main

Experimental redirect error token not working with initiating functions

If a user of Asio attempts to use a custom initiating function, it fails to compile when using the redirect error token type.

We can easily recreate this using Win10's Windows Subystem for Linux with clang-6.

Code:

#include <boost/asio.hpp>
#include <boost/asio/experimental.hpp>
#include <boost/system/error_code.hpp>
#include <utility>

namespace asio = boost::asio;

template <typename Handler>
auto initiating_function(
  asio::io_context& io,
  Handler&& handler
) {
  asio::async_completion<
    Handler, void(boost::system::error_code)
  >
  init(handler);

  co_spawn(
    io,
    [handler = std::move(init.completion_handler)]
    () mutable -> asio::experimental::awaitable<void> {
       co_return handler(boost::system::error_code());
    },
    asio::experimental::detached);

  return init.result.get();
}

auto coro_test(
  asio::io_context& io
) -> asio::experimental::awaitable<void> {

  auto token = co_await asio::experimental::this_coro::token();

  auto ec = boost::system::error_code();

  auto error_token = asio::experimental::redirect_error(token, ec);

  co_await initiating_function(io, error_token);

  co_return;
}

int main() {
  asio::io_context io;

  asio::experimental::co_spawn(
    io,
    [&]() mutable { return coro_test(io); },
    asio::experimental::detached);

  io.run();

  return 0;
}

Compile command:

chris@DESKTOP-752NP2V:~/cpp$ ~/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang++ -I/home/chris/boosts/i
nstall-ftw/include -I/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/ -L/home/chris/cl
ang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/lib/ -lc++ -lc++abi -pthread -std=c++17 -nostdinc++ -fcoroutines-ts
 asio-fail.cpp /home/chris/boosts/install-ftw/lib/libboost_system.a

Output:

asio-fail.cpp:39:3: warning: expression result unused [-Wunused-value]
  co_await initiating_function(io, error_token);
  ^~~~~~~~
In file included from asio-fail.cpp:2:
In file included from /home/chris/boosts/install-ftw/include/boost/asio/experimental.hpp:18:
In file included from /home/chris/boosts/install-ftw/include/boost/asio/experimental/co_spawn.hpp:224:
/home/chris/boosts/install-ftw/include/boost/asio/experimental/impl/co_spawn.hpp:341:20: error: no matching
      constructor for initialization of 'std::__1::tuple<>'
    new (&result_) T(std::forward<U>(u));
                   ^ ~~~~~~~~~~~~~~~~~~
/home/chris/boosts/install-ftw/include/boost/asio/experimental/impl/co_spawn.hpp:606:21: note: in instantiation of
      function template specialization 'boost::asio::experimental::detail::awaitee<std::__1::tuple<>,
      boost::asio::strand<boost::asio::executor> >::return_value<std::__1::tuple<boost::system::error_code &&> >'
      requested here
    this->awaitee_->return_value(
                    ^
/home/chris/boosts/install-ftw/include/boost/asio/experimental/impl/redirect_error.hpp:53:5: note: in instantiation of
      function template specialization
      'boost::asio::experimental::detail::await_handler<boost::asio::strand<boost::asio::executor>>::operator()<boost:
:system::error_code>'
      requested here
    handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
    ^
asio-fail.cpp:22:18: note: in instantiation of function template specialization
      'boost::asio::experimental::detail::redirect_error_handler<boost::asio::experimental::detail::await_handler<boos
t::asio::strand<boost::asio::executor>>
      >::operator()<boost::system::error_code>' requested here
       co_return handler(boost::system::error_code());
                 ^
/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/tuple:911:28: note: candidate
      constructor (the implicit copy constructor) not viable: no known conversion from
      'tuple<boost::system::error_code &&>' to 'const tuple<(no argument)>' for 1st argument
class _LIBCPP_TEMPLATE_VIS tuple<>
                           ^
/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/tuple:911:28: note: candidate
      constructor (the implicit move constructor) not viable: no known conversion from
      'tuple<boost::system::error_code &&>' to 'tuple<(no argument)>' for 1st argument
/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/tuple:924:9: note: candidate template
      ignored: could not match 'array' against 'tuple'
        tuple(array<_Up, 0>) _NOEXCEPT {}
        ^
/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/tuple:918:9: note: candidate
      constructor template not viable: requires 2 arguments, but 1 was provided
        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
        ^
/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/tuple:921:9: note: candidate
      constructor template not viable: requires 3 arguments, but 1 was provided
        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
        ^
/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/tuple:927:9: note: candidate
      constructor template not viable: requires 3 arguments, but 1 was provided
        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
        ^
/home/chris/clang/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/include/c++/v1/tuple:915:23: note: candidate
      constructor not viable: requires 0 arguments, but 1 was provided
    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
                      ^
1 warning and 1 error generated.

The code compiles perfectly when using token in lieu of error_token.

Is there a way to get this fixed? It makes using Asio's coros with Beast impossible or any other custom code.

visual studio reports memory leak for asio::buffer

{214747} normal block at 0x03B52E90, 8 bytes long.
Data: < N > 88 D3 4E 00 00 00 00 00
{214746} normal block at 0x03B53210, 8 bytes long.
Data: 6C D3 4E 00 00 00 00 00
{214745} normal block at 0x03B53130, 8 bytes long.
Data:

50 D3 4E 00 00 00 00 00
{214744} normal block at 0x03B53168, 8 bytes long.
Data: <4 N > 34 D3 4E 00 00 00 00 00
{214743} normal block at 0x03B52950, 8 bytes long.
Data: < N > EC D2 4E 00 00 00 00 00
{214742} normal block at 0x03B535C8, 8 bytes long.
Data: < N > D0 D2 4E 00 00 00 00 00
{214741} normal block at 0x03B52FA8, 8 bytes long.
Data: < N > B4 D2 4E 00 00 00 00 00
{214740} normal block at 0x03B529F8, 8 bytes long.
Data: < N > 98 D2 4E 00 00 00 00 00
{214739} normal block at 0x004ED298, 288 bytes long.
Data: < ) promux-651 > F8 29 B5 03 70 72 6F 6D 75 78 2D 36 35 31 00 CD

My code is here. Visual studio 2015.
buffer_ contents shows as memory leak.

class MulticastSocket 
{
public:
	MulticastSocket();
	virtual ~MulticastSocket();
	virtual void open(int port_num, const char* network_type="ipv4", const char* ip_address="", uint32_t listen_interface=0);
	virtual void send(u8* message, u32 size);
	virtual void close();
	virtual bool isOpen();
	//virtual void onReceived(u8*, u32);

private:
	void write();
	void strand_push(std::string str);

	void startReceive();
	void handleReceive(const boost::system::error_code&, std::size_t);
	void handleSend(const boost::system::error_code& error, std::size_t bytes_transferred);

private:
	boost::asio::io_service send_ios_;
	boost::asio::io_service::strand strand_;
	std::unique_ptr<boost::asio::io_service::work> send_worker_;
	
	boost::asio::io_service receive_ios_;
	std::unique_ptr<boost::asio::io_service::work> receive_worker_;

	boost::thread send_thread_;
	boost::thread receive_thread_;
	boost::array<char, 1024> buffer_;
	boost::asio::ip::udp::endpoint mcast_endpoint_;
	boost::asio::ip::udp::endpoint sender_endpoint_;
	boost::asio::ip::udp::endpoint listen_endpoint_;

	std::unique_ptr<boost::asio::ip::udp::socket> send_udp_socket_;
	std::unique_ptr<boost::asio::ip::udp::socket> receive_udp_socket_;
	std::deque<std::string>  write_queue_;
};


MulticastSocket::MulticastSocket()
	: send_ios_()
	, strand_(send_ios_)
{
}
MulticastSocket::~MulticastSocket()
{
}

/***************************************************************************//**
\brief			
\details		
\note			
\param[in]		
*******************************************************************************/
void MulticastSocket::open(int port_num, const char* network_type, const char* multicastAddress, uint32_t listen_interface)
{
	if (listen_interface == 0) {
		return;
	}
	
	try
	{
		struct in_addr in;
		in.S_un.S_addr = listen_interface;
		char* address_listen = inet_ntoa(in);
		std::string address_mcast = multicastAddress;
		unsigned short address_port = port_num;

		boost::system::error_code ec;

		boost::asio::ip::address listen_addr = boost::asio::ip::address::from_string(address_listen, ec);
		boost::asio::ip::address mcast_addr = boost::asio::ip::address::from_string(address_mcast, ec);

		
		if (strcmp(network_type, "ipv4") == 0)
		{
			listen_endpoint_ = udp::endpoint(listen_addr, port_num);
			mcast_endpoint_ =  udp::endpoint(mcast_addr, port_num);
		}
		else if (strcmp(network_type, "ipv6") == 0)
		{
			listen_endpoint_ = udp::endpoint(listen_addr, port_num);
			mcast_endpoint_ = udp::endpoint(mcast_addr, port_num);
		}
		else
			return;

		send_udp_socket_.reset(new boost::asio::ip::udp::socket(send_ios_));
		receive_udp_socket_.reset(new boost::asio::ip::udp::socket(receive_ios_));

		send_udp_socket_->open(boost::asio::ip::udp::v4());
		receive_udp_socket_->open(listen_endpoint_.protocol());
		send_udp_socket_->set_option(boost::asio::ip::udp::socket::reuse_address(true));
		receive_udp_socket_->set_option(boost::asio::ip::udp::socket::reuse_address(true));
		
		boost::asio::ip::address_v4 local_interface =
			boost::asio::ip::address_v4::from_string(address_listen);
		boost::asio::ip::multicast::outbound_interface option(local_interface);
		
		receive_udp_socket_->bind(listen_endpoint_);
		
		// Join the multicast group.
		receive_udp_socket_->set_option(boost::asio::ip::multicast::join_group(mcast_addr.to_v4(), listen_addr.to_v4()), ec);
		
		send_udp_socket_->set_option(option);
		receive_udp_socket_->set_option(option);

		send_udp_socket_->set_option(asio::ip::multicast::enable_loopback(false));

		//boost::asio::ip::multicast::hops hops_option(3);
		//send_udp_socket_->set_option(hops_option);
		//receive_udp_socket_->set_option(hops_option);

		receive_worker_.reset(new boost::asio::io_service::work(receive_ios_));
		send_worker_.reset(new boost::asio::io_service::work(send_ios_));

		startReceive();

		receive_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &receive_ios_));
		send_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &send_ios_));


		return;
	}
	catch (std::exception& exp)
	{
		exp;
		return;
	}
}

/***************************************************************************//**
\brief			
\details		
*******************************************************************************/
ARLErrorCode_e MulticastSocket::close(void)
{
	try {
		boost::system::error_code ec;
		if (send_udp_socket_) {
			//send_udp_socket_->cancel();
			send_udp_socket_->shutdown(socket_base::shutdown_both, ec);
		}
		if (receive_udp_socket_) {
			//receive_udp_socket_->cancel();
			receive_udp_socket_->shutdown(socket_base::shutdown_both, ec);
		}
		if (ec) 
		{
			return;
		}
		if (send_udp_socket_ && send_udp_socket_->is_open())
		{
			send_udp_socket_->close();
		}
		if (receive_udp_socket_ && receive_udp_socket_->is_open())
		{
			receive_udp_socket_->close();
		}

		receive_worker_.reset();
		send_worker_.reset();

		receive_udp_socket_.reset();
		send_udp_socket_.reset();

		if (send_thread_.joinable()) {
			send_thread_.join();
		}
		if (receive_thread_.joinable()) {
			receive_thread_.join();
		}

	}
	catch (std::exception& e)
	{
		e;
		return;
	}
	
}
/***************************************************************************//**
\brief			
\details		
*******************************************************************************/
bool MulticastSocket::isOpen()
{
	bool sender = send_udp_socket_ && send_udp_socket_->is_open();
	bool receive = receive_udp_socket_ && receive_udp_socket_->is_open();
	return sender && receive;
}

/***************************************************************************//**
\brief		Send a message.		
\details	The message is sent asynchronously.	
\param		message
\param		message size
*******************************************************************************/
void MulticastSocket::send(u8* message, u32 size)
{
	if (!isOpen()) {
		return;
	}

	strand_.post(boost::bind(&MulticastSocket::strand_push, this, std::string((char*)message, size)));
	
	return;
}
/***************************************************************************//**
\brief			
\details		
*******************************************************************************/
void MulticastSocket::strand_push(std::string str)
{
	write_queue_.push_front(str);
	write();
}
/***************************************************************************//**
\brief			
\details		
*******************************************************************************/
void MulticastSocket::write()
{
	std::string buffer = write_queue_.front();
	write_queue_.pop_front();

	std::string send_to_address = mcast_endpoint_.address().to_string();

	if (send_udp_socket_) {
		send_udp_socket_->async_send_to(
			boost::asio::buffer(buffer.c_str(), buffer.size()),
			mcast_endpoint_,
			bind(
				&MulticastSocket::handleSend,
				this,
				asio::placeholders::error,
				asio::placeholders::bytes_transferred));
	}
}

void MulticastSocket::handleSend(const system::error_code& error, size_t)
{
	if (error) 
	{
	}
}
/***************************************************************************//**
\brief	Start an asynchronous receiver.			
*******************************************************************************/
void NetLib::MulticastSocket::startReceive()
{
	if (receive_udp_socket_) {
		receive_udp_socket_->async_receive_from(
			boost::asio::buffer(buffer_),
			sender_endpoint_,
			bind(
				&MulticastSocket::handleReceive,
				this,
				asio::placeholders::error,
				asio::placeholders::bytes_transferred));

		std::string sender_address = sender_endpoint_.address().to_string();
	}
}

void NetLib::MulticastSocket::handleReceive(const system::error_code& error, size_t size)
{
	if (!error || error == error::message_size)
	{
		startReceive();
	}
	else 		
	{
	}
}

dynamic buffer design cannot support the strong exception guarantee

Dynamic buffer adapters such as dynamic_string_buffer remember the previous size of the input sequence so that the implementation of commit can identify which part of the underlying storage corresponds to the input sequence versus the output sequence. This prevents dynamic buffer implementations from offering the strong exception guarantee, as this code snippet demonstrates:

std::string s;
try
{
    dynamic_buffer(s).prepare(50);
    throw std::exception("oops");
}
catch(std::exception const&)
{
    assert(s.empty()); // fails
}

Note that even without exceptions, traditional idioms which use error_code can still leave the underlying storage in an invalid state:

void f(socket& sock, DynamicBuffer&& b_, error_code& ec)
{
  typename std::decay<DynamicBuffer>::type b{b_};
  auto const bytes_transferred = sock.read_some(b.prepare(50), ec);
  if(ec)
  {
    // at this point, if b_ is a dynamic_string_buffer, the underlying string will
    // have 50 surplus default-initialized characters
    return;
   }
  ...

One solution is to adjust the size of the underlying storage in the destructor of the dynamic buffer, but this fails if the dynamic buffer is copied rather than moved, where the destructor of a moved-from object performs no actions.

ASIO always requires threading to be enabled

#include <boost/asio/io_context.hpp>

int main()
{
    boost::asio::io_context srv;
    srv.post([](){});
    srv.run();
}

Requires -pthread compiler switch. The equivalent snippet compiled just fine without threading before 1.66.
I believe this is caused by the associated_executor<> trait having system_executor as the fallback executor.

Hardware flow control for serial ports falsely claims not to be supported.

I am using linux and whenever I try to enable hardware flow control on a serial port I get a boost::asio::error::operation_not_supported. If I enable flow control manually using termios everything works fine.

Some sifting through the source code has gotten me to the assumption that _BSD_SOURCE is not defined on my system which appears to gate the standard unix flow control setup in the asio code. According to this website, http://man7.org/tlpi/code/faq.html#use_default_source, use of _BSD_SOURCE is depricated and maybe was removed in glibc, but I'm not really sure what the correct fix is.

I am using Linux 4.9.48 with glibc 2.25. Please let me know if more information is needed.

boost::asio::buffer includes null character when used with string literal

When using boost::asio::buffer with a string literal, the buffer includes the terminating null character, which is not what one would expect.

This could be solved with something like this:

/// Create a new non-modifiable buffer that represents the given character array.
/**
  * @returns A const_buffer value equivalent to:
  * @code const_buffer(
  *     static_cast<const void*>(data),
  *     N * sizeof(char)); @endcode
  */
template <std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(
    const char (&data)[N]) BOOST_ASIO_NOEXCEPT
{
  return BOOST_ASIO_CONST_BUFFER(data, (N - 1) * sizeof(char));
}

But this might cause trouble when using a const char array that is not null-terminated, since we then basically drop the last character.

WSAAsyncGetHostByName ?

I noticed that Asio does not use WSAAsyncGetHostByName on Windows, any particular reason?

std::allocator<void> deprecated in C++17

This warning appears when building with MSVC and /std:c++17

1>c:\users\vinnie\lib\boost_1_67_0\boost\asio\associated_allocator.hpp(103): warning C4996: 'std::allocator': warning STL4009: std::allocator is deprecated in C++17. You can define _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.

Header dependency cycle (system_context.hpp)

This does not compile:

#include <boost/asio/system_context.hpp>

int main() {
    return 0;
}

boost/asio/system_context.hpp includes boost/asio/system_executor.hpp which uses system_contex in its implementation file (boost/asio/impl/system_context.hpp).

Examples are not complete (and or missing docs)

The examples for asio do not contain the cleanup code and the correct shutdown of the application. You can report to me that this is beyond the scope of demonstrating the possibilities of asio, but you will be wrong for three reasons:

1. The program (even the one that runs on the server) needs to be stopped correctly. After all, you are stopping the Apache process, the SQL server and so on and do not kill it. At least because the program must perform some actions before it is unloaded.

2. You can not argue that your library (engine) is working correctly in all cases if you did not check it under stopping. You can not convince the Big Boss that this works, because the Big Boss may ask you to stop the program (not to kill the process) during the demonstration. And what do you say? I can not, because the library (or example) does not allow it? How will you look in the eyes of the Big Boss?
You provided examples of "echo-server". Have you checked how it works with 10,000 connections and the user makes a stop program? If you append some lines of code in your examples - users will do these checks for you. Possible errors identified will be written in the bug reports, after correcting them the library will become more stable.

3. If I understand correctly, the basic idea of ​​asio is to use 1 io_service object and a number of processing threads to the entire application. This implicitly involves the use of std :: enable_shared_from_this. Programs written with this technology are more difficult to correctly stop than ordinary programs. And of course in your examples this is not done :). I did not find any mention of this problem in the documentation. But the problem exists, Google says that I'm not the only one who worries about this question - how correctly to stop the boost / asio program that uses the model "1 io_service + several threads + many objects inherited from std :: enable_shared_from_this"? There are very few good and correct answers. You can report to me that each program is unique - you can not describe all the cases in the documentation. Yes it is. But boost was developed to ensure that programmers around the world did not "invent bicycles", but used ready-made foreign developments. You could provide the page in the documentation with the basics - how to write the correct stopping, or do it in a particular case - in the examples. This would be a good starting point for other programmers that use boost, would greatly save time on "inventing bicycles".
That's all I wanted to say.

Documentation doesn't build

See the log at https://circleci.com/gh/boostorg/boost/5493:

Generating Output File: /home/ubuntu/build/boost/bin.v2/libs/asio/doc/gcc-gnu-4.8/debug/threadapi-pthread/asio_doc.xml
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:32: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:32: warning: line breaks generate invalid boostbook (will only note first occurrence).
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:33: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:36: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:37: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:41: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:42: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:43: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:44: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:45: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:46: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:47: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessReadDevice.qbk:48: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:32: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:33: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:37: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:38: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:42: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:43: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:44: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:45: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:46: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:47: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:48: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncRandomAccessWriteDevice.qbk:49: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncReadStream.qbk:34: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncReadStream.qbk:35: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncReadStream.qbk:42: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncReadStream.qbk:43: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncWriteStream.qbk:34: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncWriteStream.qbk:35: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncWriteStream.qbk:40: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/requirements/AsyncWriteStream.qbk:41: warning: '\n' is deprecated, pleases use '[br]' instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:20: error: Unable to find file: requirements/ComposedConnectHandler.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:23: error: Unable to find file: requirements/ConvertibleToConstBuffer.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:24: error: Unable to find file: requirements/ConvertibleToMutableBuffer.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:25: error: Unable to find file: requirements/DatagramSocketService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:26: error: Unable to find file: requirements/DescriptorService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:31: error: Unable to find file: requirements/HandleService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:37: error: Unable to find file: requirements/ObjectHandleService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:39: error: Unable to find file: requirements/RandomAccessHandleService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:40: error: Unable to find file: requirements/RawSocketService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:43: error: Unable to find file: requirements/ResolverService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:44: error: Unable to find file: requirements/SeqPacketSocketService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:45: error: Unable to find file: requirements/SerialPortService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:51: error: Unable to find file: requirements/SignalSetService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:52: error: Unable to find file: requirements/SocketAcceptorService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:53: error: Unable to find file: requirements/SocketService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:54: error: Unable to find file: requirements/StreamDescriptorService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:55: error: Unable to find file: requirements/StreamHandleService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:56: error: Unable to find file: requirements/StreamSocketService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:62: error: Unable to find file: requirements/TimerService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:63: error: Unable to find file: requirements/WaitableTimerService.qbk
/home/ubuntu/boost/libs/asio/doc/reference.qbk:72: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:126: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:182: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:211: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:307: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:350: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:862: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:1231: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:1610: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:2173: error: Invalid number of arguments passed. Expecting: 3 argument(s), got: 2 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:2190: error: Invalid number of arguments passed. Expecting: 3 argument(s), got: 2 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:2204: error: Invalid number of arguments passed. Expecting: 3 argument(s), got: 2 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:2227: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:2568: error: Invalid number of arguments passed. Expecting: 2 argument(s), got: 1 argument(s) instead.
/home/ubuntu/boost/libs/asio/doc/reference.qbk:3362: error: Invalid number of arguments passed. Expecting: 3 argument(s), got: 2 argument(s) instead.

and many more of the same.

ssl::stream writes inefficient when buffer sequences have length > 1

The write algorithms for ssl::stream end up performing a separate call to the underlying stream's write_some or async_write_some function for each individual buffer in a buffer sequence. This has performance implications when the buffer sequence has more than one element. These are related:

https://stackoverflow.com/questions/38198638/openssl-ssl-write-from-multiple-buffers-ssl-writev
https://stackoverflow.com/questions/50026167/performance-drop-on-port-from-beast-1-0-0-b66-to-boost-1-67-0-beast
boostorg/beast#1108

Is there any example for chunked transfer encoding ?

I'm developing a client that receive HTTPS response by chunked transfer encoding , I found the example

// client.cpp
very useful unfortunately it does not use the Chunked transfer encoding protocol. Do you know if there is an example of a client, made with asio that support this protocol ?
I have tried to play with boost::asio::transfer_exactly by providing the received chunk size without success.
Thanks,
Malick

Edit: in short I'm looking for an example that receive asynchronously a response and that can disentangle the chuck size from the chunk body.

async_resolve endpoint overload is blocking on Windows

I ran into this problem while trying to do multiple reverse lookups simultaneously. Each lookup is using a unique instance of endpoint::resolver. However, the resolution did not happen asynchronously. A similar problem has been posted on the user list back in 2014: https://lists.boost.org/boost-users/2014/12/83445.php

May I suggest that we update the documentation so that software engineers are aware of such issues in the future?
http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/reference/ip__basic_resolver/async_resolve/overload2.html

FR: read_until CompletionCondition

One of the most common problems I see mentioned in mailing lists and other support sites whenever anyone tries to use read_until or async_read_until for the first time is when they try to combine it with read/async_read and are surprised when this waits for new bytes instead of returning bytes already contained in the streambuf, the way that read_until itself operates.

A step towards making this simpler is if read_until had an additional overload that took a CompletionCondition (exactly like read), which has the following behaviour:

  • if the condition is satisfied by (some subset of) the bytes already in the streambuf, it returns immediately with those bytes.
  • if the condition is not satisfied by the current streambuf contents, it performs a read operation to collect the minimum number of additional bytes required to satisfy the condition, then returns those on completion. As usual, multiple read_some operations may be required before the condition is satisfied.

Once this exists, the advice can simply be to always use read_until or always use read and never mix the two, without losing functionality.

In some respects this is like the existing MatchCondition overload, but has the advantage that a CompletionCondition can avoid over-reading, and the existing standard completion conditions (typically transfer_exactly) can be re-used instead of inventing a new match condition (which have more complex signatures and there don't appear to be any standard ones provided).

An alternate idea that would probably be sufficient for this case is to accept a size_t of total bytes to return as a direct parameter rather than wrapped in transfer_exactly.

Another possibility is to provide a standard match condition which is the equivalent of transfer_exactly -- however I suspect this would be an inferior solution as you would not be able to avoid over-reads that way.

(Related: MatchCondition does not appear to be documented at the top level reference of the Boost docs, while CompletionCondition is.)

warning: 'BOOST_ASIO_HAS_STD_STRING_VIEW' macro redefined

Z:>type t.cpp
#include <boost/asio/io_context.hpp>
int main(){}

Z:>"clang++" -std=c++17 t.cpp -Iboost
In file included from t.cpp:1:
In file included from boost\boost/asio/io_context.hpp:18:
boost\boost/asio/detail/config.hpp:795:13: warning: 'BOOST_ASIO_HAS_STD_STRING_VIEW' macro redefined [-Wmacro-redefined]
# define BOOST_ASIO_HAS_STD_STRING_VIEW
^
boost\boost/asio/detail/config.hpp:782:14: note: previous definition is here
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
^

boost::asio::bind_executor( strand_instance, handler ) result stored in the std::function

Hi colleagues,

Very often it could be useful to store wrapped by boost::asio:io_server::strand function object in the std::function instance.

In the last boost 1.66 version there are a lot on methods became deprecated.

Asio documentation suggests to use wrap_executor(strand_instance, func_obj) instead of strand_instance.wrap( func_obj ).
But the returned result of suggested function behaves differently and breaks my multithreading code.

Please, see bellow provided usage example and pay attention on third failed case.
The strand is just bypassed. It's easy to see in the call stack from the wrapped handler.
Hence no expected serialization is performed in multithreading code.

The questions are:

  1. Is observed new behavior a bug or feature?
  2. If it is a feature, what is a recommended way to store result of wrap_executor(...) in the std::function instance keeping strand doing the serialization job?
#include <boost/test/unit_test.hpp>

#include <boost/asio.hpp>

#include <thread>
#include <atomic>
#include <functional>
#include <condition_variable>

namespace ba = boost::asio;

enum kind { new_lambda_in_wrapper, deprecated_wrapper_in_function, new_wrapper_in_function };
//----------------------------------------------------------------------------------------------------------------------
static void strand_usage( kind k, std::atomic_int & in_strand_cnt, std::atomic_int & call_cnt )
{
    auto const num_msg = 42;

    ba::io_context ioc;
    auto work = ba::make_work_guard( ioc );
    ba::io_context::strand  strand( ioc );
    std::condition_variable cond_var;
    std::mutex              mtx;

    auto lambda = [&]()
    {
        in_strand_cnt += strand.running_in_this_thread();
        ++call_cnt == num_msg ? cond_var.notify_one(),0 : 0;
    };
    using vfunc = std::function<void()>;

    for ( auto i = num_msg; i--; )
    {
        switch ( k )
        {
            case new_lambda_in_wrapper:
                ba::post( ioc, ba::bind_executor( strand, lambda ) ); // Works!
            break;
            case deprecated_wrapper_in_function:
            {
                vfunc event_handler{ strand.wrap( lambda ) }; // Works fine! But deprecated.
                ba::post( ioc, event_handler );
            }
            break;
            case new_wrapper_in_function:
            {
                vfunc event_handler{ ba::bind_executor( strand, lambda ) }; // Fail!
                // Q: How we can store a wrapped by strand handler in the std::function<> ?
                // A: ???
                ba::post( ioc, event_handler );
            }
            break;
        }
    }

    std::thread worker_thread( [&ioc]() { ioc.run(); } );

    std::unique_lock<std::mutex> l( mtx );
    cond_var.wait( l, [&](){ return call_cnt == num_msg; } );
    work.reset();
    worker_thread.join();
}
//----------------------------------------------------------------------------------------------------------------------
BOOST_AUTO_TEST_SUITE( strand )
//----------------------------------------------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( test_deprecated_wrapper_in_function )
{
    std::atomic_int in_strand_cnt{ 0 }; // counter of execution in strand context
    std::atomic_int call_cnt{ 0 };  // counter of total handler execution

    strand_usage( deprecated_wrapper_in_function, in_strand_cnt, call_cnt );
    BOOST_CHECK_EQUAL( call_cnt, in_strand_cnt );
}
//----------------------------------------------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( test_new_lambda_in_wrapper )
{
    std::atomic_int in_strand_cnt{ 0 };
    std::atomic_int call_cnt{ 0 };

    strand_usage( new_lambda_in_wrapper, in_strand_cnt, call_cnt );
    BOOST_CHECK_EQUAL( call_cnt, in_strand_cnt );
}
//----------------------------------------------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( test_new_wrapper_in_function )
{
    std::atomic_int in_strand_cnt{ 0 };
    std::atomic_int call_cnt{ 0 };

    strand_usage( new_wrapper_in_function, in_strand_cnt, call_cnt );
    // This test fails with boost 1.66!
    BOOST_CHECK_EQUAL( call_cnt, in_strand_cnt );
}
//----------------------------------------------------------------------------------------------------------------------
BOOST_AUTO_TEST_SUITE_END()

Thanks beforehand for help.

build error when openssl is used with no-comp

the cleanup method SSL_COMP_free_compression_methods does not exist when openssl has been built with no-comp

::SSL_COMP_free_compression_methods();

and generates the following error:

In file included from c:\sesteksdk/include\boost/asio/ssl/detail/openssl_init.hpp:100 : c:\sesteksdk/include\boost/asio/ssl/detail/impl/openssl_init.ipp:84:7: error: no member named
'SSL_COMP_free_compression_methods' in the global namespace; did you mean 'SSL_COMP_get_compression_methods'?
::SSL_COMP_free_compression_methods();
~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

inside the same method sk_SSL_COMP_free call has been called only if SSL_OP_NO_COMPRESSION has not been defined. Would doing the same here be a good idea? Would it affect anything else?

AF_UNIX support for Windows 10

The April update of Windows 10 includes AF_UNIX (domain sockets) support, and asio should support it.

BOOST_ASIO_HAS_LOCAL_SOCKETS would thus be true on recent Windows 10 hosts.

[OPEN] Missing header files or incorrect path?

Hi - I just cloned the current master version and am trying a test compile of a "Hello world", just to check my basic installation is ok before i start working through the tutorial.

My problem is that a number of sub-include header files can not be found by asio.hpp 😕

Pre-compile error thrown
cannot open source file "boost/config.hpp" (dependency of "boost/asio/associated_allocator.hpp")

The only config.hpp file that I can find resides in
<project root dir>\asio\include\boost\asio\detail\config.hpp

Set up process
I added latest master boostorg/asio.git following github instuctions on how work with submodules

git submodule add https://github.com/boostorg/asio.git asio

and recursively added the submodule beneath my project root directory

git submodule update --init --recursive

This has created the directory structure

<project root dir>/asio/include/boost/...

DynamicBuffer does not allow the mutation of the input sequence

DynamicBuffer does not allow the mutation of the input sequence, which is useful for protocols, which require it to be modified to extract payloads. While users may just copy the data, it might be useful to consider allowing the execution of such algorithms in place, for performance reasons.

This would require adding a non-const qualified overload of data() to the DynamicBuffer concept:

mutable_buffer_type data();
const_buffer_type data() const;

What do _WIN32_WINNT and _WIN32_WINDOWS mean, and which should I use?

Basically the title. I'm working on a project which uses boost.asio, and every build outputs the following.

13>         Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
13>         - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
13>         - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
13>         Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
13>         Generating Code...

Which tells me I need to do something, but not what either of the macros represent. Google is useless, mostly leading to people asking how to add preprocessor definitions.

I'm on windows 7, which I assume should mean Windows NT-based kernel, but _WIN32_WINNT=0x0501 (i.e. Windows XP target). implies that this macro is for windows XP.

Basically, does _WIN32_WINNT=0x0501 mean XP or later? What does the magic 0x0501 mean?

Maybe update the compiler warnings since XP has been End-of-Life for several years now, too?

Timers do not work.

Hello.
My colleague showed me that the asio timers do not work as intended.
This was tested on the OS Windows 10 64 bit .
The following combinations are used (32-bit compilation):
VS2008 SP1 + boost 1.65.1
VS2017 + boost 1.66

Tested timers - deadline_timer, steady_timer (for std / boost :: chrono). Everyone has problems.

Below I put the source code, which raises questions about the behavior of timers.

The error is often provoked when "long" processing in the timers handlers.

The same error can be found on fewer timers (we managed to get an error with 2 timers and several tens of program starts/stops).

The program works in one thread, this should exclude "racing".

The output of the program leads to strange thoughts - how can a cancel () operation on a activated timer return 0?

detail/consuming_buffers.hpp triggers a g++-5 parsing error

While trying to compile Domoticz, I ran into a strange parsing error with g++5 in detail/consuming_buffers.hpp.

     while (next != end && max_size > 0 && result.count < result.max_buffers)
                                                  ^

The code compiles fine with g++6.
I'm no c++ programmer, so excuse me if my explanation is not accurate, but apparently g++ thinks this is a template invocation and chokes.
Even though this seems to be a g++ error, adding parenthesis around result.count will allow compilation to proceed.

--- a/boost/asio/detail/consuming_buffers.hpp
+++ b/boost/asio/detail/consuming_buffers.hpp
@@ -102,7 +102,7 @@ public:

     std::advance(next, next_elem_);
     std::size_t elem_offset = next_elem_offset_;
-    while (next != end && max_size > 0 && result.count < result.max_buffers)
+    while (next != end && max_size > 0 && (result.count) < result.max_buffers)
     {
       Buffer next_buf = Buffer(*next) + elem_offset;
       result.elems[result.count] = boost::asio::buffer(next_buf, max_size);

extraneous value_type requirement on buffer sequences

The implementation of buffer sequence type checks requires the nested value_type, but the documented requirements for buffer sequences omits this requirement. This should be resolved by removing the requirement for a nested value_type in the metafunction.

basic_resolver_results::empty() on empty object leads to access violation

Hi,

this small program:

#include <cassert>
#include <boost/asio.hpp>

void main() {
	boost::asio::ip::tcp::resolver::results_type results;
	assert(results.empty());
}

leads to a access violation.

Possible solution:

change line 248 in basic_resolver_results.hpp from

return this->values_->empty();

to

return this->values_ ? this->values_->empty() : true;

And maybe similar for basic_resolver_results::size() and basic_resolver_results::max_size(), etc...

thank you

NULL deference exception in boost::asio::ip::tcp::resolver::results_type

boost::asio::ip::tcp::resolver::results_type type triggers a NULL dereference exception when calling empty() on a default-initialized instance.

How to reproduce:

  • instantiate a new boost::asio::ip::tcp::resolver::results_type class instance with the default parameterless constructor
  • call the empty() method, it should return true
  • notice the access violation crash triggered

Code example:

#include <boost/asio/ip/tcp.hpp>

int main(int /*argc*/, char** /*argv*/)
{
  boost::asio::ip::tcp::resolver::results_type test = boost::asio::ip::tcp::resolver::results_type();
  if (test.empty())
    printf("ok");
}

Boost version: 1.66 Windows x64 vc141

Issue analysis: empty() is implemented as

bool empty() const BOOST_ASIO_NOEXCEPT
{
  return this->values_->empty();
}

but this->values_ returns NULL when the class is empty. A possible fix could be to NULL-check this->values_ and then call ->empty() (if still needed at all)

bool empty() const BOOST_ASIO_NOEXCEPT
{
  return !this->values_ || this->values_->empty();
}

Current workaround: I would suggest not to use .empty() at all currently but to rely on .begin() == .end() .

Note that even if the code example above looks quite meaningless, .empty() crashes causes issue for example when checking if an address can be resolved using ip::basic_resolver::resolve function. The documentation states "An empty range is returned if an error occurs" so one expects to be able to check if the range is empty.

boost::coroutines2 integration?

I see there's an existing pull request for this (#55), but it's been languishing in limbo for more almost six months. Is the submitted code considered incomplete or subpar or do you simply have no interest in it?

need SNI support

It's good to be able to have a library that can provide such a simple network development.This makes the job very simple.But the support for SSL is not yet perfect.like SNI,and more.

Documentation refers to copying handlers

Documentation for async operations states that copies of the handler will be made as needed but this is not always correct, the handlers are moved when possible.

boost-1.66 regression in ssl socket wrapper

I'm wrapping my custom socket type in the boost::asio::ssl::stream wrapper. Building with boost-1.66-rc1 I get a compilation error caused by the way the ssl wrapper use read_some().

According to the documentation the function takes a MutableBufferSequence, defined here
to have a const_iterator type and begin() and end() functions, to iterate the buffer sequence.

However, in the boost-1.66-rc1 version of asio's ssl stream wrapper, it calls read_some() (here) with a boost::asio::mutable_buffer (i.e. not a sequence). It passes core.input_buffer_ which is defined here.

As far as I can tell, core.input_buffer should be of type boost::asio::mutable_buffers_1. Making this change makes my program build again.

basic_resolver_results has a wrong typedef to basic_resolver_entry

ip::basic_resolver_results has a wrong typedef
instead of typedef basic_resolver_entry<endpoint_type> value_type; it should be corrected to
typedef basic_resolver_entry<protocol_type> value_type;

typedef basic_resolver_entry<endpoint_type> value_type;

the ip::basic_resolver_iterator got it right
typedef basic_resolver_entry<InternetProtocol> value_type;

basic_resolver_entry doesn't need an endpoint as template parameter
template <typename InternetProtocol>

boost 1.66

If I can be any more help, pls let me know
Have fun
Markus

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.