AnyEvent-FDpasser
view release on metacpan or search on metacpan
pipe on SysV systems) for you after which you should also fork and
call "$passer->i_am_parent" and "$passer->i_am_child".
If you don't plan on forking and instead wish to establish the
passing connection via the filesystem, you should only pass one
filehandle in. If you only need to support the BSD interface, this
filehandle can be created as a normal "AF_UNIX" socket. If you wish
your code to also be portable to SysV systems, see the
"fdpasser_server", "fdpasser_accept", and "fdpasser_connect"
functions described below.
The AnyEvent::FDpasser constructor will set all filehandles to
non-blocking mode. You can override this by passing
"dont_set_nonblocking => 1," in. Even though this module will only
attempt to send or receive descriptors when the OS has indicated it
is ready, some event loops deliver spurious readiness deliveries on
sockets so this parameter is not recommended. However, if you are
creating passers often and your sockets are known to already be in
non-blocking mode, "dont_set_nonblocking" will provide a slight
performance improvement in that it avoids a couple syscalls.
An error callback can be passed in with the "on_error" parameter. If
an error happens, the passer object will be shutdown and the
callback invoked. $@ will be set to the error reason or will be
undef in the event of an orderly shutdown.
$passer->i_am_parent
If forking the passer object, this method must be called by the
parent process after forking.
$passer->i_am_child
If forking the passer object, this method must be called by the
child process after forking.
$passer->push_send_fh($fh[, $cb->()])
After calling "push_send_fh", the filehandle passed in will be added
to an order-preserving queue. Once the main event loop is entered
the filehandle will usually be sent immediately since the peer is a
local process. However, if the receiving process's socket buffer is
full it may not be sent until that buffer is drained.
In any case, the "push_send_fh" method will not block. If you wish
to perform some action once the socket actually has been sent, you
can pass a callback as the second argument to "push_send_fh". It
will be invoked after the descriptor has been sent to the OS and the
descriptor has been closed in the sending process, but not
necessarily before the receiving process has received the
descriptor.
This method is called "push_send_fh" instead of, say, "send_fh" to
indicate that it is pushing the filehandle onto the end of a queue.
Hopefully it should remind you of the similarly named "push_write"
method in AnyEvent::Handle.
$passer->push_recv_fh($cb->($fh))
In order to receive the filehandle, the receiving process calls
"push_recv_fh" and passes it a callback that will be called once one
is available. The filehandle will be the first argument to this
callback.
Note that you can add multiple callbacks with "push_recv_fh" to the
input queue between returning to the main loop. The callbacks will
be invoked in the same order that the filehandles are received
(which is the same order that they were sent).
This method is called "push_recv_fh" instead of, say, "recv_fh" to
indicate that it is pushing a callback onto the end of a queue.
Hopefully it should remind you of the similarly named "push_read"
method in AnyEvent::Handle.
AnyEvent::FDpasser::fdpasser_socketpair()
This function returns two handles representing both ends of a
connected socketpair. On BSD systems it uses socketpair(2) and on
SysV systems it uses pipe(2). Note that this function doesn't work
on windows so it's not really useful as a fully-generic socketpair.
See "AnyEvent::Util::portable_socketpair" for a windows-portable
socketpair (but these handles can only be used with
AnyEvent::FDpasser if using the BSD interface).
$listener_fh = AnyEvent::FDpasser::fdpasser_server($path[, $backlog ])
This function creates a listening node on the filesystem that other
processes can connect to and establish FDpasser-capable connections.
It is portable between BSD systems where it uses "AF_UNIX" sockets
and SysV systems where it uses the "connld" STREAMS module.
$passer_fh = AnyEvent::FDpasser::fdpasser_accept($listener_fh)
Given a listener filehandle created with
AnyEvent::FDpasser::fdpasser_server, this function accepts and
creates a new filehandle suitable for creating an FDpasser object.
It is portable between BSD systems where it uses the socket
accept(2) system call and SysV systems where it uses
"ioctl(I_RECVFD)".
$passer_fh = AnyEvent::FDpasser::fdpasser_connect($path)
This function connects to a listening node on the filesystem created
with AnyEvent::FDpasser::fdpasser_server and returns a new
filehandle suitable for creating an FDpasser object. It is portable
between BSD systems where it uses the socket connect(2) system call
and SysV systems where it "open()"s a mounted stream.
NOTES
Userspace buffers
Because the underlying operations only transfer file descriptors, it is
undefined whether any data in userspace buffers like IO::Handle or
AnyEvent::Handle will have been written to the file descriptor at the
time it is transfered. You should always flush userspace data before you
initiate a transfer, and not write more data afterwards. This is why the
synopsis uses "syswrite" to bypass userspace buffers.
You should remove all IO watchers associated with the descriptor before
initiating the transfer because after the descriptor is transfered it
will be closed and watchers should always be destroyed before closing
their respective filehandles. Also, if data comes in and is read by a
read watcher before the descriptor is transfered, that data will be
lost.
Forking
This module itself never calls "fork()", but many use-cases of this
module involve the application program forking. All the usual things you
must worry about when forking an AnyEvent application also apply to this
module. In particular, you should ensure that you fork before sending or
receiving any descriptors because these operations create AnyEvent
( run in 0.496 second using v1.01-cache-2.11-cpan-39bf76dae61 )