El uso de sintéticos filehandle con EV (perl)
Pregunta
Tengo un filehandle objeto que se crea, por tanto (ligeramente editado para mayor claridad):
sub TIEHANDLE
{
return $_[0] if ref($_[0]);
my $class = shift;
my $self = bless Symbol::gensym(), $class;
return $self;
}
sub new
{
my ($class, $fh, $chunk, $interval, $cb) = @_;
my $self = bless Symbol::gensym(), ref($class) || $class;
tie *$self, $self;
my $data = {
fh => $fh,
};
${*$self}{'data'} = $data;
return $self;
}
sub fileno
{
my $self = $_[0];
return ${*$self}{'data'}->{'fh'}->fileno();
}
*FILENO = \&fileno;
Quiero usar este con AnyEvent
.Funciona bien con AnyEvent::Impl::Perl
pero no con
AnyEvent::Impl::EV
.Creo que he seguido a este método de EV
:
static int
s_fileno (SV *fh, int wr)
{
dTHX;
SvGETMAGIC (fh);
if (SvROK (fh))
{
fh = SvRV (fh);
SvGETMAGIC (fh);
}
if (SvTYPE (fh) == SVt_PVGV)
return PerlIO_fileno (wr ? IoOFP (sv_2io (fh)) : IoIFP (sv_2io (fh)));
if (SvOK (fh) && (SvIV (fh) >= 0) && (SvIV (fh) < 0x7fffffffL))
return SvIV (fh);
return -1;
}
Creo que está fallando la SvTYPE (fh) == SVt_PVGV
prueba.El uso de Devel::Peek
's método Dump() obtengo:
SV = PVMG(0x9c98460) at 0x44313b0
REFCNT = 1
FLAGS = (PADMY,ROK)
IV = 0
NV = 0
RV = 0x9c21d00
SV = PVGV(0x9c35510) at 0x9c21d00
REFCNT = 1
FLAGS = (OBJECT,RMG,MULTI)
MAGIC = 0x9a68ee0
MG_VIRTUAL = &PL_vtbl_backref
MG_TYPE = PERL_MAGIC_backref(<)
MG_OBJ = 0x9c217a8
STASH = 0x4374440 "MetadataStream"
NAME = "GEN5"
NAMELEN = 4
GvSTASH = 0x25d01c8 "Symbol"
GP = 0x9a43d50
SV = 0x0
REFCNT = 1
IO = 0x9c214a8
FORM = 0x0
AV = 0x0
HV = 0x9c21ce8
CV = 0x0
CVGEN = 0x0
LINE = 102
FILE = "/usr/share/perl5/Symbol.pm"
FLAGS = 0x2
EGV = 0x9c21d00 "GEN5"
PV = 0x9c21d00 ""
CUR = 0
LEN = 0
Cualquier ayuda en cuanto a cómo podría ajustar la creación de mi mango de tal manera que puede pasar esta prueba será apreciada.
Solución
atado identificadores de archivo son sólo parcialmente implementado en perl, y no funcionan con EV.Atado controla no se puede hacer funcionar con una biblioteca de eventos en general:Mientras que algunos casos específicos podría funcionar, en la mayoría de los casos donde atados utilizan controladores, que no puede trabajar debido a la preparación de la notificación de una subyacente descriptor de archivo no se refieren a la preparación de las notificaciones de el atado de manejar.
Si su objetivo es simplemente tener una cosa envoltura alrededor de un archivo real descriptor, entonces una forma de hacerlo es copiar lo que IO::Handle y/o FileHandle hacer (muy feo, pero la única manera que funciona en perl), o el uso como clases base.Esto no te permite hacer cosas muy interesantes como enganchar lee y escribe, pero lo más probable es que se enganche a ellos les hace incompatible con el evento de las bibliotecas.
Otra forma es aplicar un perlio capa (PerlIO::via).En mi experiencia, este módulo es un poco frágil, pero le da todas las opciones.De nuevo, si se introduce el almacenamiento en búfer o cosas más interesantes que desacoplar el archivo descriptor de la e/S real, entonces no puede ser hecho a trabajo.
Por último, si desea agregar un nuevo tipo de mango, entonces usted puede crear un nuevo tipo de observador.Esto puede ser tan simple como tener una función my_handle_io_watcher que toma su nombre de usuario, los controles para la preparación y crea el tipo de bajo nivel observador que se requiere.