Boost logo

Boost :

From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2005-12-13 07:27:42


Hi Cory,

--- Cory Nelson <phrosty_at_[hidden]> wrote:
> Perhaps asio::error could be changed to assert() that it is
> checked before it goes out of scope. It is important to make
> sure the user checks it as inconsistent application states can
> be a big problem to track.

Hmmm, I dunno. What constitutes checking? What if the
application simply wants to post (i.e. via a demuxer::post()
call) a copy of the error to another function object where the
real work is to be performed? This is likely to occur when you
start composing asynchronous operations to create higher levels
of abstraction. The mechanism to then keep track of whether the
error has been checked could start to be quite heavy.

<snip>
> > I see this as a layer of abstraction that can be added on
> > top of asio. For example, one could write a free function
> > async_connect that used a URL-style encoding of the target
> > endpoint. I don't see it as in scope for asio _for_now_.
>
> It would definately be an abstraction and it could certainly
> be written by the user. But what I was getting at is that
> nearly all client apps would make good use of a function like
> this, so why not prevent such remaking of the wheel and put it
> right in asio?

I think at this point I'd rather give it time to allow the
interface to grow out of common use cases. I.e. see where more
experience in the field takes it and then put it into a library.

> > - What happens if you need to perform per-thread
> > initialisation before any other code runs in the thread? For
> > example on Windows you might be using COM, and so need to
> > call CoInitializeEx in each thread.
>
> I don't use COM. I'm not sure of what it would entail.

The issue of exceptions that escape from handlers also just
occurred to me. The current design in asio lets these exceptions
propagate through demuxer::run() so that the application can
handle them. Correctly handling exceptions presents a problem for
an internally managed thread pool.

<snip>
> Having heard your reasons - how feasible would it be to
> include a threaded_demuxer type, which would be built with
> high-perf scalability in mind?

Well, I don't see it as impossible, but I also don't see it as
necessary to writing scalable, high-performance apps.

Today I was thinking that it should be possible to develop a
(possibly portable) thread-pooling solution to this external to
asio. The hard part is having a way of detecting that an
additional thread is required. Once you've decided you need an
additional thread, then you just spawn it and have it call
demuxer::run() to donate itself to the pool.

<snip>
> This is true. It will awake another thread if an active one
> blocks. However if all of your threads decide to block you
> will have a dead cpu.

My advice is to avoid blocking ;) Seriously, my experience to
date leads me to believe that long running blocking operations
should be abstracted behind an asynchronous interface, so that
the "main" thread of an application does not block.

<snip>
> You have two threads running seperate demuxers. Suppose the
> sockets in one of them gets a heavy workload and the other has
> nothing to do?
>
> This might be an unlikely scenario, but it's also an
> unacceptable and easily avoidable one.
>
> Spreading the workload between threads (without forcing a
> socket to always be on one thread) will always be the optimal
> way to go, and the only way to do this sanely on multiple
> platforms is to have the demuxer do the threading.

I just present the demuxer-per-cpu idea as a possible design
alternative that asio permits. It may be suitable for some
applications but not others. My point is that it is not
necessarily unacceptable -- I think it is entirely reasonable to
choose to trade off some potential performance in favour of
avoiding the development complexity introduced by
synchronisation.

Oh BTW, I forgot to mention ConnectEx. I was planning to do it
before the review but as time was running short I didn't want to
risk introducing instability. I intend to enable it for builds
that target Windows XP or later. I'm still of two minds as to
whether Windows 2000 targeted builds should try to dynamically
load it and use it, since that increases the amount of code
generated and the complexity of the implementation. Is it worth
it?

Cheers,
Chris


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