Question

J'ai un objet filehandle qui est créé ainsi (légèrement modifié pour plus de clarté) :

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;

Je veux l'utiliser avec AnyEvent.Cela fonctionne bien avec AnyEvent::Impl::Perl mais échoue avecAnyEvent::Impl::EV.Je pense que je l'ai retracé jusqu'à cette méthode depuis 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;
}

Je pense que c'est un échec SvTYPE (fh) == SVt_PVGV test.En utilisant Devel::PeekLa méthode Dump() de j'obtiens :

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

Toute aide sur la façon dont je pourrais ajuster la création de mon handle afin qu'il puisse réussir ce test serait appréciée.

Était-ce utile?

La solution

Les poignées de fichiers liées ne sont que partiellement implémentées dans Perl et ne fonctionnent pas avec EV.Les poignées liées ne peuvent pas être faites pour fonctionner avec une bibliothèque d'événements en général:Bien que certains cas spécifiques puissent fonctionner, dans la plupart des cas où des poignées liées sont utilisées, elles ne peuvent pas fonctionner car la notification de préparation à un descripteur de fichiers sous-jacente ne se rapporte pas aux notifications de préparation de la poignée liée.

Si votre objectif est d'avoir simplement une chose enroulée autour d'un descripteur de fichiers réel, alors une façon de le faire est de copier ce que IO :: Handle et / ou FileHandle fait (très moche, mais la seule façon qui fonctionne dans Perl), ou Utilisez-les comme classes de base.Cela ne vous permet pas de faire des choses intéressantes telles que l'accrochage des lectures et des écritures, mais les chances les accrochent les rend incompatibles avec les bibliothèques d'événements.

Une autre façon consiste à implémenter une couche Perlio (PerlIO :: via).D'après mon expérience, ce module est un peu fragile, mais vous offre toutes les options.Encore une fois, si vous introduisez des choses tampon ou plus intéressantes qui découplent le descripteur de fichier à partir des E / S réelles, il ne peut pas être fait pour fonctionner.

Enfin, si vous souhaitez ajouter un nouveau type de poignée, vous pouvez créer un nouveau type d'observateur.Cela peut être aussi simple que d'avoir une fonction my_handle_io_watcher qui prend votre poignée, vérifie la préparation et crée le type d'observateur de bas niveau requis.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top