On Mon, Oct 17, 2005 at 01:43:16AM +0900, ES wrote: > You can use IO#for_fd to create an IO object for a given file descriptor; > scour the source for the C function or just use rb_funcall. This, of > course, should only be done once after which you refer to the socket > using the IO object (you can get the FD again with IO#to_i). In a C extension, this is suboptimal. You can instead use: <code> #include "ruby.h" [...] int fd; OpenFile *fptr; if (!rb_respond_to( io_obj, rb_intern( "sysread"))) rb_raise( rb_eTypeError, "instance of IO needed"); GetOpenFile( rb_io_get_io( io_obj), fptr); fd = fileno( fptr->f); </code> Since both Socket and File are subclasses of IO, this will work for both network sockets and disk file I/O. The above is correct because sysread is currently only implemented by instances of IO. Caching the return value of the rb_intern( "sysread") call is also preferable (see ruby-1.8.3/marshal.c). > I am not sure what you mean by maintaining a Hash; while an explicit > data structure is by no means necessary, you (presumably) have to have > some means of referring back to the sockets. This is what the IO object > would provide, however you store it. Please clarify if I am understanding > incorrectly. What I meant was that I'd have to maintain a Hash mapping fd's to IO instances. This Hash would be inserted into when the caller wanted to insert an IO object into the epoll device. Sorry for the confusion. At any rate, it turns out that a) Ruby/Event is dead, and b) Zed was maintaining just such a Hash for the same reason in Ruby/Event. I'll just build a Hash that maps fd's to IO instances and take the memory hit. > If you find you need to do some special processing on the FD for each > read/write/update, you might do well to just subclass IO and augment > it with that functionality. Speaking of that, that brings me to another question I had. I was trying to extend IO as follows: module EpollExt attr_accessor :epoller alias_method :old_close, :close def close @epoller.delete( self) old_close end end So, then the user of the library would have to extend their IO instances with that module before they could be used with the Epoll object, like so: my_epoll = Epoll.new [...] x = File.open( "/tmp/my-tmp", "w") x.extend( EpollExt) x.epoller = my_epoll [...] However, this fails because at the time of definition, the module doesn't have a close method. I want to shadow the close method of IO in order to automatically call the cleanup method in the associated Epoll object. Anybody know a way of doing that? I feel like I've seen this kind of thing before, but I can't remember where. -- Toby DiPasquale