Utilizzo di file syntheticHandle con EV (Perl)
Domanda
Ho un oggetto FileHandle creato così (modificato leggermente per chiarezza):
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;
.
Voglio usarlo con AnyEvent
.Funziona bene con AnyEvent::Impl::Perl
ma fallisce con
AnyEvent::Impl::EV
.Penso di averlo rintracciato fino a questo metodo da 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;
}
.
Penso che sia in mancanza del test SvTYPE (fh) == SVt_PVGV
.Usando Devel::Peek
's Dump () Metodo Io ottengo:
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
.
Qualsiasi aiuto su come potrei regolare la creazione della mia maniglia in modo tale da poter passare questo test sarebbe apprezzato.
Soluzione
Le maniglie dei file legate sono implementate solo parzialmente in Perl e non funzionano con ev. Le maniglie legate non possono essere fatte per funzionare con una libreria di eventi in Generale: mentre alcuni casi specifici potrebbero funzionare, nella maggior parte dei casi in cui legato vengono utilizzati maniglie, non possono funzionare perché la notifica di prontezza di un Il descrittore di file sottostante non si riferisce alle notifiche di prontezza di la maniglia legata.
Se il tuo obiettivo è semplicemente avere un wrapper di cosa attorno a un vero file Descrittore, quindi un modo per farlo è copiare ciò che io :: maniglia e / o FileHandle Do (molto brutto, ma l'unico modo che funziona in Perl) o uso loro come classi di base. Questo non ti consente di fare cose interessanti come agganciare letture e scrive, ma le probabilità li stanno agganciandole li rende incompatibile con le librerie di eventi.
Un altro modo è implementare uno strato del Perlio (Perlio :: tramite). Nel mio Esperienza, questo modulo è un po 'fragile, ma ti dà tutto il opzioni. Di nuovo, se si introduce cose buffering o più interessanti disaccoppia il descrittore del file dall'i / o effettivo, quindi non può essere fatto lavoro.
Infine, se si desidera aggiungere un nuovo tipo di maniglia, è possibile creare Un nuovo tipo di osservatore. Questo può essere semplice come avere una funzione my_handle_io_watcher che prende la maniglia, controlla la prontezza e crea il tipo di osservatore di basso livello richiesto.