1

I am using asio for tcp server and I plan to use C++11 std for thread as well. My final goal is to have this application on Linux but I am testing it on Windows first using Visual Studio 2015.

First I am using blocking so I found there were discussion on how to stop a thread waiting on accept. There were pre-C++11 solutions such as pipe, and select. I am looking for the asio way.

    asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));
    backAcceptor = &acceptor;
    tcp::socket socket(io_service);

    asio::error_code ec;
    acceptor.accept(socket, &ec);

Second way is to use asynchronous, but I prefer to use the asio header only. The compile complained that the asio::placeholder doesn't have this member but according to the comment, the solution is applied:

    asio::async_write(socket_, asio::buffer(message_),
        std::bind(&tcp_connection::handle_write, shared_from_this(),
            std::placeholders::_1,
            std::placeholders::_2
            ));

run() still block there. And I am looking for method to resume this thread from main.

    asio::io_service io_service;
    tcp_server server(io_service);
    io_service.run();

The third way is, to set a timeout here. But it doesn't stop my accept. Plus, the answer was in 2012. I hope there is new was to solve this by now.

Update

To test the scenarios, I first have a thread to either blocks at synchronous accept() or at asynchronous run(). When the thread is running, the main then waits for 2 seconds, and tries to stop the thread. Then I wait for the thread to complete using join.

For the first method "Synchronous", I tried to use acceptor.cancel() and the thread arrived at the join. Is this the correct way?

Second method "Async", although I am still not clear how to stop this thread officially, I succeeded using io_service.stop() to actually cancel it.

Please let me know whether my solutions is correct and I will continue to try different solutions.

Community
  • 1
  • 1
Splash
  • 1,288
  • 2
  • 18
  • 36
  • Just use std::placeholders::_2 for the second placeholder? – Ralf Nov 01 '15 at 07:39
  • got it compiled. So now I realized the example from asio pdf still uses run() which blocks. – Splash Nov 01 '15 at 22:45
  • You can use run_one and poll_one if you don't want to block in cases where you have an external event loop. See http://stackoverflow.com/questions/8727568/whats-the-difference-between-boostio-service-poll-one-and-run-one – Ralf Nov 02 '15 at 09:36
  • Need a better error indicator than "complained here". `::run()` only blocks while an outstanding operation is in the cue, unless you create a `io_service::work` object. Your question is unclear because you're asking 3 questions in one. Anyway, running the io_service is going to take just as long manually as it is using `::run()` and you're going to block. Blocking has to happen somewhere, which will end up happening at `::run()`, which is typically why you designate a separate thread or thread pool to run the io_service. –  Nov 02 '15 at 22:48
  • @Ralf, from the name, poll_one looks like the one I need. I will try. – Splash Nov 03 '15 at 03:09

1 Answers1

1

I happen to have played around with a non-typical approach with run_one and no threading, that specifically allows you timeout individual "non-asynch" operations:

In fact, you do post the asynch operations, but then you call await_operation with a timeout:

async_connect(socket, ip::tcp::resolver(ioservice).resolve({address, port}), raise());
await_socket(std::chrono::seconds(6));

This is the equivalent of doing a synchronous connect but with the possibility to timeout. No threads, blocking run() or other puppies were harmed.

See the linked answer for demos


PS. Use deadline_timer with posix_time if you don't want the high_resolution_timer which works nicely with std::chrono

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • is your suggestion on server side? Your link points to a client example. – Splash Nov 03 '15 at 02:08
  • @splash my technique applies to any operation that could be lengthy. As such you can apply it wherever asynchronous operations are used, but a semi synchronous work flow is preferred, like in this case the OP has. – sehe Nov 03 '15 at 02:16
  • can you provide example of stop the accept for the server side? – Splash Nov 03 '15 at 02:47