From: simon meiklejohn (simon_at_[hidden])
Date: 2005-12-02 21:57:39


Hi Chris,

>> The asio::demuxer gives
>> a guarantee that the task will execute in a thread that has
>> called demuxer::run, which may include the thread which is doing
>> the requesting - implication being that the call may take place
>> immediately.
>
> Immediate execution can only occur if demuxer::dispatch() is used.

Ok, i hadnt picked that up.

>> This is an excellent performance optimisation, but
>> the programmer may require stronger guarantees, perhaps against
>> that very optimisation.
>
> Hence the distinction between demuxer::dispatch() which allows the
> optimisation, and demuxer::post() which does not. The decision about
> which is appropriate needs to be made at the point where the function
> object is invoked, so the two functions are provided.

I see the distinction and appreciate the usefulness. I keep coming across
situations though where i'd prefer the decision to hidden behind a defer
object provided by some part of the code with a better context for the
decision. (i.e. main() populating my network callback library with a defer
object appropriate to the application).

As an example, lets say i have a library component that parses data from
a socket into some higher level application message. At the time it
finds a complete message it wants to notify its client code.
- In some applications its appropriate to call immediately in the same
thread.
(e.g. if the app has only one thread which is blocking in the network layer)
- In other cases its appropriate to defer to a single different thread (eg.
one with particular thread affinity, or the single thread that services all
calls into a particular group of application objects thus providing
protection against deadlocks)
- in a third case its better to pass the message off to a pool of threads
for performance/responsiveness reasons (e.g. the task involves
accesses to a database which take time and can be done in parallel).

The message parse library can be built to support all these scenarios.
Just supply it with a different defer object when constructing and
connecting the application objects. Hide the decision behind
a polymorphically implemented demuxer::post().

Do these seem like useful general scenarios, and can they be supported
with the demuxer interface as it stands?

Many thanks

Simon