AnyEvent::FDpasser

Pass file descriptors between processes using non-blocking buffers
Download

AnyEvent::FDpasser Ranking & Summary

Advertisement

  • Rating:
  • License:
  • Perl Artistic License
  • Price:
  • FREE
  • Publisher Name:
  • Doug Hoyte
  • Publisher web site:
  • http://www.hcsw.org

AnyEvent::FDpasser Tags


AnyEvent::FDpasser Description

AnyEvent::FDpasser is a Perl module that provides an object oriented interface for passing filehandles between processes. Its primary goals are API simplicity, portability, and reliability. It is suitable for use in non-blocking programs where blocking in even exceptional circumstances is undesirable. Finally, this module should be efficient enough for nearly all use-cases.This module currently works on BSD4.4-like systems (*BSD, Linux, Mac OS X) where it uses the SCM_RIGHTS ancillary data feature over AF_UNIX sockets, on BSD4.3-like systems (Solaris, IRIX?) where it uses msg_accrights field of msghdr over AF_UNIX sockets, and on SysV-like systems (Solaris, HP-UX, AIX?) where it uses the ioctl(I_SENDFD/I_RECVFD) feature of STREAMS pipes.Note that a passer object is "bidrectional" and you can use the same object to both send and receive filehandles (each side has a separate input and output buffer).After sending a filehandle, the sending process will automatically destroy it and you shouldn't close it yourself. Forgetting all references to it is what you should do so that the underlying descriptor is actually closed after it is sent. The exception to this is when you also wish to keep the handle in the sender. Usually you will only do this for sockets that you accept() from.my $passer = AnyEvent::FDpasser->new() ## Both of these are the same my $passer = AnyEvent::FDpasser->new; my $passer = AnyEvent::FDpasser->new( fh => ); ## Make sure filehandles are AF_UNIX sockets (BSD) or STREAMS pipes (SysV) my $passer = AnyEvent::FDpasser->new( fh => ); ## No i_am_parent or i_am_child required in this case: my $passer = AnyEvent::FDpasser->new( fh => $fh, ); When creating a passer objects with two filehandles, it is assumed you want to fork. After you fork you are then supposed call $passer->i_am_parent and $passer->i_am_child. Creating a passer object with zero filehandles automatically creates a socketpair (or 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) 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) 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.SYNOPSIS use AnyEvent; use AnyEvent::FDpasser; my $passer = AnyEvent::FDpasser->new; if (fork) { $passer->i_am_parent; open(my $fh, '>>', '/tmp/fdpasser_output') || die; syswrite $fh, "This line is from PID $$\n"; $passer->push_send_fh($fh); undef $fh; # don't close() it though } else { $passer->i_am_child; $passer->push_recv_fh(sub { my $fh = shift; syswrite $fh, "This line is from PID $$\n"; }); } AE->cv->recv; # AnyEvent main loopProduct's homepage


AnyEvent::FDpasser Related Software