AnyEvent-FDpasser
view release on metacpan or search on metacpan
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
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.367 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )