Boost logo

Boost :

Subject: Re: [boost] Should pass boost::asio::io_service by raw pointer or smart pointer?
From: hh h (jupiter.hce_at_[hidden])
Date: 2018-12-20 10:32:59


Thanks Richard and Vinnie, that was indeed comprehensive.

> * Many people keep shared_ptr's to sockets, deadline_timers and so on. This
> is an error. All ASIO io objects are moveable. Store by value.

That is the crux of clarifying to my post, so the io_service, context,
sockets, deadline_times should all be stored by value not the shared
pointer.

> * SSL contexts are similar to io_contexts. There should be one (or perhaps
> two if you're both accepting inbound connections and making outbound
> connections) per application. Pass them by reference to your client/server
> objects. Storing an ssl::context in an object makes it non-moveable and is
> an error.

In my server, there are mixed connections per application, the ssl is
used for applications provided services and connections via the
Internet, and non-ssl connections are used for applications provided
internal services withing the could (I believe it should not have
security issues). I am going to use one global io_service and one
global context for both ssl and non-ssl (which did nothing about ssl
context) applications, I think it should be fine, but appreciate your
inside opinion.

Thank you very much and appreciate it.

- JHH

On 12/20/18, Richard Hodges via Boost <boost_at_[hidden]> wrote:
> Adding some lessons learned over the years to Vinnie's answer, because it's
> not immediately obvious from the ASIO documentation...
>
> You should normally think of an io_context as a global dependency of the
> application. Create it in (or near) main() and pass a reference to it to
> every component of your application that needs access to an io_context.
>
> There are a couple of models for using ASIO:
>
> * one io_service, one thread - initialise your io_service with an argument
> of (1) to hint to ASIO that it can optimise for singfle-threaded code
> * one io_service, N threads - default-initialise your io_service and use
> strands to prevent contention in handlers.
> * N threads with one io_service per thread - a very efficient model, which
> will require you to manually load-balance connections by allocating them to
> the io_context associated with the least current load. This should probably
> not be attempted on your first try with ASIO.
>
> There are some other things that are not always obvious:
>
> * Many people keep shared_ptr's to sockets, deadline_timers and so on. This
> is an error. All ASIO io objects are moveable. Store by value.
>
> * SSL contexts are similar to io_contexts. There should be one (or perhaps
> two if you're both accepting inbound connections and making outbound
> connections) per application. Pass them by reference to your client/server
> objects. Storing an ssl::context in an object makes it non-moveable and is
> an error.
>
> * Good ASIO development is aided by the principle of dependency injection.
>
> * ASIO is easy to test - look at the methods io_context::poll(),
> io_context::run_one(), io_context::stopped(), io_context::restart() and
> io_context::strand::running_in_this_thread(). You can essentially
> single-step ASIO in your unit tests. This is a strong reason for using
> dependency injection (i.e. pass configuration data, contexts and executors
> by reference).
>
> * If you're multi-threading you'll either want to protect your objects with
> mutexes (not so efficient) or strands (really efficient). However, don't
> mix the models. If you're using strands then all access to your object from
> outside should be via an async function which takes a closure and posts an
> implementation of itself to the current object's strand. This ensures that
> everything runs in the correct thread (which you can assert with
> strand::running_in_this_thread() in your handler functions).
>
>
>
> On Thu, 20 Dec 2018 at 11:14, Vinnie Falco via Boost
> <boost_at_[hidden]>
> wrote:
>
>> On Wed, Dec 19, 2018 at 4:30 PM hh h via Boost <boost_at_[hidden]>
>> wrote:
>> > In many examples and even implementations, programmers like to pass
>> > boost::asio::io_service by raw pointer:
>>
>> Those examples are wrong. `io_context` should be passed by reference.
>>
>> > Will this cause issues to pass raw pointer for large size of classes,
>> > should it be replaced by passing smart pointer:
>>
>> A smart pointer is less efficient than a pointer, all else equal. But
>> you shouldn't be using any form of pointer, the io_context (legacy
>> name: io_service) is passed by reference. All of the Beast and Asio
>> examples demonstrate this:
>>
>> <https://github.com/boostorg/beast/tree/develop/example>
>> <https://github.com/boostorg/asio/tree/develop/example>
>>
>> Regards
>>
>> _______________________________________________
>> Unsubscribe & other changes:
>> http://lists.boost.org/mailman/listinfo.cgi/boost
>>
>
>
> --
> Richard Hodges
> hodges.r_at_[hidden]
> office: +442032898513
> home: +376841522
> mobile: +376380212 (this will be *expensive* outside Andorra!)
> skype: madmongo
> facebook: hodges.r
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk