6 Dec 2004 05:19
Re: UDP sockets and sendto
Dave Roberts <ldave <at> droberts.com>
2004-12-06 04:19:40 GMT
2004-12-06 04:19:40 GMT
On Sun, 2004-12-05 at 20:56 +0000, Icarus Sparry wrote: > I posted this to USENET (comp.lang.lisp) and it was suggested to me that I > should email this list instead. It is a little long. Summary > I have something which works, but I would like it improved. It adds missing > funcuntionality to sb-bsd-sockets, but it is not very general. I attempted the same thing a few months ago. I had something that worked with 0.8.10 or so, but then something changed in the depths of sb-bsd- sockets relating to the FFI interface and the way sb-grovel was working, and my patches weren't good after 0.8.10.56 or thereabouts. I got busy with some other stuff and haven't been able to get back to it. Let me see if I can dig up the code. A few comments on your code: 1. You should not use sb-grovel::define-foreign-routine directly, but rather hack a definition for sendto into constants.lisp. 2. As you say, you shouldn't declare things as strings that are really buffers of unsigned octets. You can make your socket-sendto interface smart and "do the right thing," depending on the type of buffer passed to it. This obviously requires more code to special case a few interesting data types (strings, arrays, lists, etc.). 3. Your current solution has some subtle bugs, I believe. In particular, you haven't accounted for blocking in the socket layer, multiple threads, and garbage collection. Depending on how the OS implements its networking and threading, there *may* exist a case where the first thread gets blocked while in the sockets layer, but before the network stack copies the data out of the heap. If another SBCL thread runs and triggers a GC which causes the buffer to move on the heap, the network stack may end up with a bogus pointer. This may only happen on some ports where the GC moves things around (do all versions of the SBCL GC copy/compact?) and where a UDP sendto would block (not very likely, but potentially still possible, depending on the OS/stack implementation). To get around this, you can do one of a couple of things. In the 0.8.10 timeframe, the code used to lock the buffer on the heap so that it couldn't be moved. I'm guessing this interfered with GC at some level and the new code (0.8.10.56+) seems to use an alien copy buffer (see socket-receive in sockets.lisp, for instance, where the probability of blocking in the call is very high). This is not a very efficient solution, obviously, because you're copying data around within the Lisp process, and then the stack will likely copy it to kernel buffers, too. That said, I'm not a good enough SBCL hacker to know what the Right Thing(TM) is to do here. -- -- Dave Roberts <ldave <at> droberts.com> ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://productguide.itmanagersjournal.com/
RSS Feed