AnyEvent-FDpasser

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    descriptor, receive the descriptor from the sending process, and then
    attempt to dup another descriptor. Because we just cleared a descriptor
    table entry, there should always be a free descriptor to create.

    If duping fails, we stop trying to receive any further descriptors and
    instead retry at regular intervals (while not interrupting the event
    loop). Hopefully eventually the full descriptor table issue will clear
    up and we will be able to resume receiving descriptors.

    Note that a descriptor could be created between closing and receiving if
    your program uses asynchronous signal handlers or threads that create
    descriptors, so don't do that. Signals that are handled synchronously
    (like normal AnyEvent signal watchers) are fine.

    This trick is similar to a trick described in Marc Lehmann's libev POD
    document, section "special problem of accept()ing when you can't,"
    although the purpose of employing the trick in this module is somewhat
    different.

TESTS AND SYSTEM ASSUMPTIONS
    All the following tests should work with BSD4.4, BSD4.3, and SysV

README.pod  view on Meta::CPAN

In order to pass a file descriptor between processes, a new descriptor needs to be allocated in the receiving process. Therefore, the C<recvmsg> and C<ioctl> system calls used to implement descriptor passing can fail unexpectedly. Failing to create a...

So what should we do? We could silently ignore it when a descriptor fails to transfer, but then we run the risk of desynchronising the descriptor stream. Another possibility is indicating to the application that this descriptor has failed to transfer...

None of the above "solutions" are very appealing so this module uses a trick known as the "close-dup slot reservation" trick. Actually I just made that name up now but it sounds pretty cool don't you think? The idea is that when the passer object is ...

When it comes time to receive a descriptor, we close the sentinel descriptor, receive the descriptor from the sending process, and then attempt to dup another descriptor. Because we just cleared a descriptor table entry, there should always be a free...

If duping fails, we stop trying to receive any further descriptors and instead retry at regular intervals (while not interrupting the event loop). Hopefully eventually the full descriptor table issue will clear up and we will be able to resume receiv...

Note that a descriptor could be created between closing and receiving if your program uses asynchronous signal handlers or threads that create descriptors, so don't do that. Signals that are handled synchronously (like normal AnyEvent signal watchers...

This trick is similar to a trick described in Marc Lehmann's libev POD document, section "special problem of accept()ing when you can't," although the purpose of employing the trick in this module is somewhat different.




=head1 TESTS AND SYSTEM ASSUMPTIONS

All the following tests should work with BSD4.4, BSD4.3, and SysV interfaces (where available).

lib/AnyEvent/FDpasser.pm  view on Meta::CPAN

  return if defined $self->{iwatcher};
  return if defined $self->{full_descriptor_table_state};

  $self->{iwatcher} = AE::io $self->{fh}, 0, sub {

    my $cb = shift @{$self->{ibuf}};

    POSIX::close($self->{fh_duped});
    delete $self->{fh_duped};

    ## Race condition: If another thread or a signal handler creates a new descriptor at this
    ## exact point in time, it could cause the descriptor table to fill up and the following
    ## to error.

    my $rv = recv_fd(fileno($self->{fh}));

    if ($rv == -1) {
      if ($!{EAGAIN} || $!{EWOULDBLOCK} || $!{EINTR}) {
        ## Spurious ready notification or signal: put the cb back on the queue
        unshift @{$self->{ibuf}}, $cb;
      } elsif ($!{EMSGSIZE} || $!{EMFILE} || $!{ENFILE}) {

lib/AnyEvent/FDpasser.pm  view on Meta::CPAN

In order to pass a file descriptor between processes, a new descriptor needs to be allocated in the receiving process. Therefore, the C<recvmsg> and C<ioctl> system calls used to implement descriptor passing can fail unexpectedly. Failing to create a...

So what should we do? We could silently ignore it when a descriptor fails to transfer, but then we run the risk of desynchronising the descriptor stream. Another possibility is indicating to the application that this descriptor has failed to transfer...

None of the above "solutions" are very appealing so this module uses a trick known as the "close-dup slot reservation" trick. Actually I just made that name up now but it sounds pretty cool don't you think? The idea is that when the passer object is ...

When it comes time to receive a descriptor, we close the sentinel descriptor, receive the descriptor from the sending process, and then attempt to dup another descriptor. Because we just cleared a descriptor table entry, there should always be a free...

If duping fails, we stop trying to receive any further descriptors and instead retry at regular intervals (while not interrupting the event loop). Hopefully eventually the full descriptor table issue will clear up and we will be able to resume receiv...

Note that a descriptor could be created between closing and receiving if your program uses asynchronous signal handlers or threads that create descriptors, so don't do that. Signals that are handled synchronously (like normal AnyEvent signal watchers...

This trick is similar to a trick described in Marc Lehmann's libev POD document, section "special problem of accept()ing when you can't," although the purpose of employing the trick in this module is somewhat different.




=head1 TESTS AND SYSTEM ASSUMPTIONS

All the following tests should work with BSD4.4, BSD4.3, and SysV interfaces (where available).



( run in 0.825 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )