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