From: dizzy (dizzy_at_[hidden])
Date: 2008-08-07 06:57:13
On Thursday 07 August 2008 11:52:37 Felipe Magno de Almeida wrote:
> On Thu, Aug 7, 2008 at 5:33 AM, dizzy <dizzy_at_[hidden]> wrote:
> > On Thursday 07 August 2008 04:00:39 Felipe Magno de Almeida wrote:
> >> I'm writing a GUI library, and I wanted to use the asio concepts in it.
> >> For example, I find it very compelling that every window has a
> >> member-function that returns a io_service::strand to which one
> >> can post messages to the window thread.
> >> This would work well with all mainstream toolkits and the win32 API.
> >> But how would this work with asio implementation?
> >> Can a service be appended to a io_service, and have its own
> >> demultiplexer function control the thread running the run member
> >> function?
> > You can make your own service that has a thread of its own (like the
> > resolver service does) and from it you can post() events to the
> > io_service event queue so that the thread(s) that perform run() on the
> > io_service will handle them.
> > This is a pretty generic way one can handle any asynchronous sources to
> > asio (by using additional threads).
> That won't work. I have to wait for events on the thread that run is
> running in, which
> is the user thread and is the same that creates the windows.
Is this a limitation of the GUI framework? You only need to _wait_ for the
events in this internal thread, the actual dispatching still happens through
normal asio mechanisms to the threads that execute run(). If your GUI somehow
assigns some kind of ownership of the window creator thread so only that
thread can wait/query for events then this is a serious limitation because it
won't allow you to easily in the future have multiple threads execute run()
for scalability reasons.
You won't be able to _really_ wait events in the same thread since that
already blocks using some OS dependent I/O notification mechanism (say it
blocks in select()) which may not permit notification of GUI events anyways
(not to mention this does not seem to be a configurable part of asio without
depending on "detail" stuff). A workaround is to get all events be some sort
of I/O events (ex using socketpair) but then you need the GUI to use the
socketpair or you need that separate thread to wait for GUI events and post to
the socketpair (but then the socketpair is not needed since you can directly
post() events on the io_service).
Another general solution but that has its own shortcomings is to have your own
event loop that calls run_one() and on each iteration you "peek" into the
other event source (the GUI event source you want to integrate with asio).
This works fine if asio is busy but if not you can also program a timer with
asio so it will make run_one() return at least once per the time configured in
the timer. It obviously has the problem that if asio is not busy GUI events
will be handled at this timer granularity. If GUI events are more important
than asio generated ones then you could do the reverse (make an event loop
that calls some sort of run_one() function for the GUI events, a function that
waits for at least an event and dispatches it and returns and then you use
io_service.peek() to execute possible asio queued events).
-- Mihai RUSU Email: dizzy_at_[hidden] "Linux is obsolete" -- AST