Post by m***@nokia.comPost by Thiago MacieiraBTW, if anyone has suggestions on how to write cancellable synchronous code
that is also non-blocking (co-threads?), I'd love to read some more. Vala
(the language) has some concepts in that area, but I don't know how
they're implemented.
I've been toying around with a new API for QtConcurrent that supports the
"threaded synchronous" style with cancellation. If using futures it could
future f = run([]{
contents = QFile::readAll(fileName);
process(contents);
});
f.cancel() // cancels the task at any point.
QFile:readAll() would register itself with the future and be implemented on
top of a suitable async API that supports cancellation. How does it return
from the readAll() call? By throwing a QCancelledException.
When I said cancellable, I think I used the wrong term. I didn't mean
cancelling it programmatically, though it of course makes sense (the user may
press the Cancel button).
I was thinking of operations that might fail with bad results. For example,
when you read a file, you expect the operation to succeed. Most file APIs do not
deal with errors like EIO and cannot recover from it since they are quite
rare. On a network scenario, such calls can and will fail often.
I was thinking of something like the async client example in
http://live.gnome.org/Vala/GIONetworkingSample. You simply write a bunch of
code that would be otherwise blocking, but at suitable points where it might
block, the execution yields to something else. It helps that Vala is a C code
generator, so it can simply split up the function into chunks and set the next
chunk as callback to the previous one.
That's why I thought of co-threads. Whenever we run into a blocking call
(EWOULDBLOCK), the execution suspends and something else takes over. until
we're asynchronously notified that the blocking call can now succeed. At that
point, it resumes from where it left off. Co-threads could be implemented using
setjmp/longjmp, for example.
I imagine though that this would make all hell break loose. You'd write:
1 QNetworkReply reply = manager.get(...);
2 QByteArray line = synchronous reply.readLine();
3 process(line);
Between lines 2 and 3, the execution might be suspended and other code would
run, which means the rest of the program's state could completely change.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358