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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top