Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::asio blocking socket read with timeout with multiple threads
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2018-03-20 04:07:14


On 16/03/2018 08:04, Thomas Quarendon wrote:
> I've got a boost::asio based server, and generally it's working well.
> The server runs multiple threads, each simply running the
> io_service::run method on the same io_service object. It accepts
> multiple connections and processes multiple concurrent sockets. It
> uses a strand per connection to ensure that the data for each
> connection is processed strictly sequentially.
>
> For various reasons it uses a mixture of async and sync reads. The
> trouble I'm having is implementing a timeout on the synchronous
> (blocking) reads. I want to protect the server in the case of a
> client sending an erroneous or malicious packet for example, and make
> sure a read doesn't block forever.
This is probably going to seem like an overly flippant answer, but I do
firmly believe that it is the *only* correct answer.

Don't mix async and sync. Once you go async, you have to go async "all
the way down".

This means that your async handlers must never make blocking calls
themselves.

If your sync and async operations are both on the same socket, then you
must convert them all to async -- if you don't like the async-callback
code style that results, look into the coroutine style instead, which
looks more like sync code while still behaving like async code.

If your sync calls operate on different objects and you can't convert
those blocking calls to async calls (eg. they're calling some library
API that doesn't provide async), then you should make a "sync worker
thread" that has its own separate io_service, and have your async
workers post jobs to this service, then post back completions to the
original io_service once the task is done.

It's up to you how many of these sync worker threads to create, ranging
from one global one (easy but will make everything wait for everyone
else's blocking operations), through to a small threadpool, through to
one per connection (also easy but risks thread explosion). There's no
One True Answerâ„¢, it will depend on your application's expected workload
and connection count.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net