><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).
Works.
rb_io_get_io() is not available to extensions, so just get rid of that call
(leaving the io_obj part) since you've already verified that its an IO instance
by then (and thus GetOpenFile() and the rest will succeed). I discovered this
after writing the email 
Ah, I see.. I am still somewhat curious. I am assuming that you are already
storing those IO instances somewhere you can reach them. That being the case
and the IO instance *already referencing the FD*, why do you need explicit
mapping?
Yeah, I wasn't 
I was asking the original question in order to _avoid_ having to build up
such a store of IO instances. Here's what happens now:
0. Caller creates an instance of Epoll
1. Caller opens IO object of some sort
2. Caller calls Epoll#update on the new IO object, which will internally
add the IO object to a Hash and also call epoll_ctl( EPOLL_CTL_ADD) to add
it to the epoll device.
3. Caller calls Epoll#poll which internally calls epoll_wait(2) and when
that returns, builds an array of 2-cell arrays, the first cell containing
the IO object that matched the fd returned from epoll_wait(2) (resolved
with the help of the Hash above) and the second cell containing the event
bitmask returned for that fd. For every fd returned by epoll_wait(2),
there will be a 2-cell array in the returned array from Epoll#poll.
I thought I could avoid having to store all active IO objects if two things
were true:
a) epoll removes the fd from its device when its close(2)'d
b) Ruby had a way to reverse-map a fd to an active IO instance
I knew a) was true, but b) is not. Thus, I am now using a Hash, just like
Zed in Ruby/Event. Consequently, this is why I want to hook into IO#close,
so I can call Epoll#delete in order to remove the IO instance from the
Hash (which is now necessary, since I'm keeping track of them all).
If for some reason you need to work with the sockets separately from the
IO instances (though I can not imagine why), you should still be able to
use the IO to read and write data normally. Any other socket manipulation
you can do independently of the IO, just with the sockets themselves and
then just have the IO reference its FD. Perhaps I am missing some crucial
insight to your architecture, though?
No I don't need to do this. My only concern was to take the fd that
epoll_wait(2) returns and somehow map it back to the IO instance so that
it would be usable in the calling Ruby script.
>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.
You can use the hook method Module#included.
This isn't working for me when I use Object#extend instead of
Module#include.
adidas~> irb
irb(main):001:0> module A
irb(main):002:1> def A.included( mod)
irb(main):003:2> puts "#{self} included in #{mod}"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> x = "String"
=> "String"
irb(main):007:0> x.extend A
=> "String"
irb(main):008:0> module Enumerable
irb(main):009:1> include A
irb(main):010:1> end
A included in Enumerable
=> Enumerable
irb(main):011:0> quit
adidas~>
Any thoughts on making it work with Object#extend?
···
On Mon, Oct 17, 2005 at 06:31:04AM +0900, ES wrote:
--
Toby DiPasquale