On Sun 25 Mar 2012 22:17, Neil Jerram <n...@ossau.homelinux.net> writes:
> Andy Wingo <wi...@pobox.com> writes: > >> How about, you write your code in such a way that it deals with eports. >> You could surround your code in a prompt that if an eport operation >> aborts because it would block, you save the continuation and ask your >> main loop to call you again when the port is readable / writable. When >> it calls you again you resume the partial continuation. > > Thanks for the ideas. I unfortunately have a bit of a cognitive deficit > backlog before I can understand them fully. I haven't yet understand > prompts properly, and I see that ethreads are built on top of those. > But I'll continue working at it! Heh, sorry for the brevity! The problem is that we don't explain them very well. Let's consider you have a d-bus callback with fd FD. You want to do write some bytes to that FD, then do something else. You can: (define (call/resumable thunk) (let ((suspend-tag (make-prompt-tag "suspend"))) (parameterize ((current-read-waiter (lambda (fd) (abort-to-prompt suspend-tag fd)))) (call-with-prompt suspend-tag thunk (lambda (k fd) (reschedule! fd (lamdbda () (call/resumable k)))))))) In the case of glib, you would implement reschedule! as some wrapper that adds fd as a gsource to the current main loop. When the gsource fires, you would arrange to call the associated thunk -- in this case a thunk that calls the captured continuation, within another call/resumable block. This assumes you are using (ice-9 eports) from wip-ethreads. Please take a look at that code. It is a ports implementation, written in Scheme, which uses non-blocking read and write primitives when it needs to fill / flush its buffers. If the I/O would block, it calls the current-read-waiter / current-write-waiter. Here we parameterize that waiter to capture the continuation and reschedule. Let me know if I can muddy^Hclarify things more for you ;-) Cheers, Andy -- http://wingolog.org/