Hi!
Is there any way to make Gambit's scheduler trig an event when there is activity on external file descriptors, for instance as provided by curl_multi_fdset ( http://curl.haxx.se/libcurl/c/curl_multi_fdset.html ) of libCurl multi ( http://curl.haxx.se/libcurl/c/libcurl-multi.html )?
The question was raised in 2004 ( https://webmail.iro.umontreal.ca/pipermail/gambit-list/2004-November/000023....), at that time without answer.
What is the current answer to this question, is there any elegant way to have Gambit monitor a set of external file descriptors, and trig an event handler on event?
( There has been a quite extensive related discussion over the years, and one interesting instance was when Allan Langley published a libevent patch for Gambit, https://webmail.iro.umontreal.ca/pipermail/gambit-list/2005-August/000382.ht.... Allan has personally not continued developing this respect of Gambit. Has someone else? Ought Allan's code work in the current Gambit version? )
Regards Mikael
Afficher les réponses par date
Mikael More wrote:
Hi!
Is there any way to make Gambit's scheduler trig an event when there is activity on external file descriptors, for instance as provided by curl_multi_fdset ( http://curl.haxx.se/libcurl/c/curl_multi_fdset.html ) of libCurl multi ( http://curl.haxx.se/libcurl/c/libcurl-multi.html )?
The question was raised in 2004 ( https://webmail.iro.umontreal.ca/pipermail/gambit-list/2004-November/000023....), at that time without answer.
What is the current answer to this question, is there any elegant way to have Gambit monitor a set of external file descriptors, and trig an event handler on event?
I guess it was just missing setting the fd to nonblocking? See |fd->port| and |fd-nonblock-set!| in http://scheme.mine.nu/gambit/scratch/cj-posix/2006-12-06/cj-posix.scm
Christian.
Christian Jaeger wrote:
Mikael More wrote:
Hi!
Is there any way to make Gambit's scheduler trig an event when there is activity on external file descriptors, for instance as provided by curl_multi_fdset ( http://curl.haxx.se/libcurl/c/curl_multi_fdset.html ) of libCurl multi ( http://curl.haxx.se/libcurl/c/libcurl-multi.html )?
The question was raised in 2004 ( https://webmail.iro.umontreal.ca/pipermail/gambit-list/2004-November/000023....), at that time without answer.
What is the current answer to this question, is there any elegant way to have Gambit monitor a set of external file descriptors, and trig an event handler on event?
I guess it was just missing setting the fd to nonblocking? See |fd->port| and |fd-nonblock-set!| in http://scheme.mine.nu/gambit/scratch/cj-posix/2006-12-06/cj-posix.scm
Wait, I think I get what you want: you want to block your Gambit thread just as in a read or write operation but not actually carry out any read or write, correct? Just kind of peek-char that doesn't read into a buffer etc.; or basically, you want that this blocks until there is data to be read or there is the possibility to write data (pardon my shell syntax):
({read,write}-subu8vector (u8vector) 0 0 port)
That's a question for Marc I guess.
Christian.
Christian Jaeger wrote:
Wait, I think I get what you want: you want to block your Gambit thread just as in a read or write operation but not actually carry out any read or write, correct? Just kind of peek-char that doesn't read into a buffer etc.; or basically, you want that this blocks until there is data to be read or there is the possibility to write data (pardon my shell syntax):
({read,write}-subu8vector (u8vector) 0 0 port)
That's a question for Marc I guess.
Ok it didn't let me calm so... check out:
http://scheme.mine.nu/gambit/experimental/wait-for-io/
(git clone http://scheme.mine.nu/gambit/experimental/wait-for-io/.git)
Christian.
So this is it, a mechanism that waits for external fd:s? I.e. it adds an external fd to Gambit's select() call in the Scheduler, and then returns when there's data (or one can write)?
So for X external fd:s, one spawns X threads and calls port-wait-for-input with the port as parameter, and the port in turn is the result of fd->port?
Mikael
2008/9/3 Christian Jaeger christian@pflanze.mine.nu
Christian Jaeger wrote:
Wait, I think I get what you want: you want to block your Gambit thread just as in a read or write operation but not actually carry out any read or write, correct? Just kind of peek-char that doesn't read into a buffer etc.; or basically, you want that this blocks until there is data to be read or there is the possibility to write data (pardon my shell syntax):
({read,write}-subu8vector (u8vector) 0 0 port)
That's a question for Marc I guess.
Ok it didn't let me calm so... check out:
http://scheme.mine.nu/gambit/experimental/wait-for-io/
(git clone http://scheme.mine.nu/gambit/experimental/wait-for-io/.git)
Christian.
Mikael More wrote:
So this is it, a mechanism that waits for external fd:s? I.e. it adds an external fd to Gambit's select() call in the Scheduler,
No, this is just the functionality that waits for input or output on a port without actually reading from it or writing to it. If you've got an fd from your library, you need the |fd->port| first.
and then returns when there's data (or one can write)?
Yes, if there is no timeout set then those block until input is there or the OS output buffer can take output. If a timeout is set, they return with #f instead of with #t, as it seems.
So for X external fd:s, one spawns X threads and calls port-wait-for-input with the port as parameter, and the port in turn is the result of fd->port?
Yes, you usually want one Gambit thread per port / fd.
Christian.
On 2-Sep-08, at 8:04 PM, Christian Jaeger wrote:
Wait, I think I get what you want: you want to block your Gambit thread just as in a read or write operation but not actually carry out any read or write, correct? Just kind of peek-char that doesn't read into a buffer etc.; or basically, you want that this blocks until there is data to be read or there is the possibility to write data (pardon my shell syntax):
({read,write}-subu8vector (u8vector) 0 0 port)
That's a question for Marc I guess.
That will not do what you expect. If you ask for zero bytes then it will return immediately. I don't think it is a good idea to give a special meaning to the zero-bytes case.
What you want is (peek-u8 port). It isn't defined but would be easy to add. An alternative would be a (wait-until-available-u8 n port) which blocks until at least n bytes are available to be read, and returns the number of bytes actually available to be read. The implementation would have a reasonable upper limit on n. So you would say (wait-until-available-u8 1 port) to block until at least one byte is available, and (wait-until-available-u8 0 port) to get how many bytes are available (without blocking).
What exactly do you need this for?
Marc
Marc Feeley wrote:
On 2-Sep-08, at 8:04 PM, Christian Jaeger wrote:
Wait, I think I get what you want: you want to block your Gambit thread just as in a read or write operation but not actually carry out any read or write, correct? Just kind of peek-char that doesn't read into a buffer etc.; or basically, you want that this blocks until there is data to be read or there is the possibility to write data (pardon my shell syntax):
({read,write}-subu8vector (u8vector) 0 0 port)
That's a question for Marc I guess.
That will not do what you expect. If you ask for zero bytes then it will return immediately.
Yes, I wasn't clear about this: I *did* try the above and found it to return immediately, which is why I then said so it's a question for you to answer, and yes I was thinking that maybe making this case block would possibly be a sensible way to offer what Mikael needs.
I don't think it is a good idea to give a special meaning to the zero-bytes case.
Probably true.
What you want is (peek-u8 port). It isn't defined but would be easy to add. An alternative would be a (wait-until-available-u8 n port) which blocks until at least n bytes are available to be read,
But the point is that Mikael does not want any bytes end up in Gambit's I/O buffers; he just wants to make the Gambit scheduler report when I/O is ready on a filehandle, on the OS level, so that his thread will unblock and then call into an FFI function which then does the read(2) system call on that fd. At least that's what I understood: i.e. that libcurl allows one to call some proceed-reading and proceed-writing procedures which will call read and write (or recv and send) on some previously opened tcp sockets; and lets one take care of event handling oneself; so Mikael needed a way to add those fd's to the bitmasks used in the select call done by the Gambit scheduler and get some Scheme code to run when such an fd is ready, but never wants Gambit to carry out an actual read or write operation on those fd's.
Christian.
P.S. I've now reworded the description in the file a bit to make the intent clearer. I'm attaching the diff and the files here to make sure they stay available in the archive and since the diff would only be seen when actually using the Git checkout.
Maybe Mikael could confirm some time whether this solution was what he needed and whether it worked.
Christian.