Re: convert fd to IO object in extension?
- From: Toby DiPasquale <toby@xxxxxxxx>
- Date: Mon, 17 Oct 2005 07:30:39 +0900
On Mon, Oct 17, 2005 at 06:31:04AM +0900, ES wrote:
> ><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?
--
Toby DiPasquale
.
- References:
- Re: convert fd to IO object in extension?
- From: ES
- Re: convert fd to IO object in extension?
- From: Toby DiPasquale
- Re: convert fd to IO object in extension?
- From: ES
- Re: convert fd to IO object in extension?
- Prev by Date: Re: how to create a hash from 2 arrays?
- Next by Date: Re: how to create a hash from 2 arrays?
- Previous by thread: Re: convert fd to IO object in extension?
- Next by thread: RubyConf 2005 Audio - Now Podcasts at Odeo
- Index(es):
Relevant Pages
|