[Vala] Documenting 'async' / WAS: Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala
- From: Jim Peters <jim uazu net>
- To: Alexandre Rosenfeld <alexandre rosenfeld gmail com>
- Cc: Serge Hulne <serge hulne gmail com>, vala-list <vala-list gnome org>
- Subject: [Vala] Documenting 'async' / WAS: Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala
- Date: Thu, 14 Jul 2011 16:52:52 -0500
Alexandre Rosenfeld wrote:
Async methods were created primarily for GIO to do non-blocking
IO. Doing IO usually blocks the application and so freezes the UI,
so the GLib answer is to provide callbacks to be called when the IO
is done and the program can keep executing while IO is done in the
background (note here that background does not necessarily mean
another thread, the IO can be done by the kernel and notify the
process when it's complete).
Async methods have nothing to do with threads, so none of these
points are valid. However, what async methods allow is to stop the
processing of a function in the middle and resume it after the async
method returns, by the means of the callbacks. So, what the async
method can do is spawn a thread to do background processing and
later call the callback to resume the operation of the method that
Which means async methods can be just as blocking as any other
method if it does sequential processing and at the end calls the
callback. But also means it can be designed to use any other way to
provide background processing (including threads) without blocking
the main program (especially the UI) and thus can take advantage of
This is helpful, thanks.
There seems to be special stuff associated with an async method which
I haven't found documented well anywhere. For async method 'method',
there are all these ways to use it:
- Call 'method' from non-async code, starts it running until its first
'yield', at which point it returns to the caller. (Correct?)
- Get callback (from within method itself). This is the callback to
resume execution after the following 'yield'. (Correct?)
SourceFunc callback = method.callback;
- Use the resume callback from elsewhere. 'method' resumes and takes
control again, running until its next 'yield', at which point it
returns from this call. (Correct?)
- Give up control and return to the caller. This doesn't guarantee in
any way that the method will be resumed, i.e. callback() must be
called somewhere else. (Correct?)
- Give up control but arrange for a resume callback when idle. This
requires the main loop to be running. (Correct?)
- Call async method 'other_method' from 'method'. This automatically
sets up a callback for 'method' to resume itself and collect the
return value when 'other_method' completes. (Correct?)
Question: At the C level, I guess this first calls forwards to
'other_method' to start it before returning to the caller due to the
'yield'. If the 'other_method' also yields, then there is no
problem, but if 'other_method' finishes without yielding (e.g. if it
can return the result right away without doing any asynchronous
work), then the 'method' callback would be called again, only a few
stack frames lower. In theory if 'method' called 'other_method'
repeatedly like this, the stack could overflow. Is this correct?
If so maybe that needs documenting.
- Call with .begin(). Question: Is this just like the 'method()' call
but adding a callback request for when method() finishes? If so
will it also just run until the first 'yield' and then return?
- Call with .end(). For use within the 'begin' callback, to get
method return value and clean up. Question: Is an .end() call
required for plain 'method()' style invocation?
- Are there any other special features associated with async methods?
(Any other .<identifier> features, for example.)
- When it is necessary to have a main loop running? Some of the
generated C code requests an idle callback. I guess this won't work
without a main loop running. But the Generator, for example, seems
to run through fine without a main loop.
- The docs say "The .callback call is used to implicitly register a
_finish method for the async method". What does this mean? Also:
"end() is a syntax for the *_finish method". I'm confused.
If someone can say RIGHT or WRONG to some of the points in this list
I'd be happy to document this on the wiki somewhere.
Jim Peters (_)/=\~/_(_) jim uazu net
(_) /=\ ~/_ (_)
Uazú (_) /=\ ~/_ (_) http://
in Peru (_) ____ /=\ ____ ~/_ ____ (_) uazu.net
] [Thread Prev