home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / OneWay.pm < prev    next >
Encoding:
Perl POD Document  |  2003-11-21  |  4.8 KB  |  188 lines

  1. # $Id: OneWay.pm,v 1.13 2003/11/21 05:08:26 rcaputo Exp $
  2.  
  3. # Portable one-way pipe creation, trying as many different methods as
  4. # we can.
  5.  
  6. package POE::Pipe::OneWay;
  7.  
  8. use strict;
  9.  
  10. use vars qw($VERSION);
  11. $VERSION = do {my@r=(q$Revision: 1.13 $=~/\d+/g);sprintf"%d."."%04d"x$#r,@r};
  12.  
  13. use Symbol qw(gensym);
  14. use IO::Socket;
  15. use POE::Pipe;
  16.  
  17. @POE::Pipe::OneWay::ISA = qw( POE::Pipe );
  18.  
  19. sub DEBUG () { 0 }
  20.  
  21. sub new {
  22.   my $type         = shift;
  23.   my $conduit_type = shift;
  24.  
  25.   # Dummy object used to inherit the base POE::Pipe class.
  26.   my $self = bless [], $type;
  27.  
  28.   # Generate symbols to be used as filehandles for the pipe's ends.
  29.   my $a_read  = gensym();
  30.   my $b_write = gensym();
  31.  
  32.   if (defined $conduit_type) {
  33.     return ($a_read, $b_write)
  34.       if $self->_try_type($conduit_type, \$a_read, \$b_write);
  35.   }
  36.  
  37.   while (my $try_type = $self->get_next_preference()) {
  38.     return ($a_read, $b_write)
  39.       if $self->_try_type($try_type, \$a_read, \$b_write);
  40.     $self->shift_preference();
  41.   }
  42.  
  43.   # There's nothing left to try.
  44.   DEBUG and warn "nothing worked";
  45.   return;
  46. }
  47.  
  48. # Try a pipe by type.
  49.  
  50. sub _try_type {
  51.   my ($self, $type, $a_read, $b_write) = @_;
  52.  
  53.   # Try a pipe().
  54.   if ($type eq "pipe") {
  55.     eval {
  56.       pipe($$a_read, $$b_write) or die "pipe failed: $!";
  57.     };
  58.  
  59.     # Pipe failed.
  60.     if (length $@) {
  61.       warn "pipe failed: $@" if DEBUG;
  62.       return;
  63.     }
  64.  
  65.     DEBUG and do {
  66.       warn "using a pipe";
  67.       warn "ar($$a_read) bw($$b_write)\n";
  68.     };
  69.  
  70.     # Turn off buffering.  POE::Kernel does this for us, but
  71.     # someone might want to use the pipe class elsewhere.
  72.     select((select($$b_write), $| = 1)[0]);
  73.     return 1;
  74.   }
  75.  
  76.   # Try a UNIX-domain socketpair.
  77.   if ($type eq "socketpair") {
  78.     eval {
  79.       socketpair($$a_read, $$b_write, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
  80.         or die "socketpair failed: $!";
  81.     };
  82.  
  83.     if (length $@) {
  84.       warn "socketpair failed: $@" if DEBUG;
  85.       return;
  86.     }
  87.  
  88.     DEBUG and do {
  89.       warn "using a UNIX domain socketpair";
  90.       warn "ar($$a_read) bw($$b_write)\n";
  91.     };
  92.  
  93.     # It's one-way, so shut down the unused directions.
  94.     shutdown($$a_read,  1);
  95.     shutdown($$b_write, 0);
  96.  
  97.     # Turn off buffering.  POE::Kernel does this for us, but someone
  98.     # might want to use the pipe class elsewhere.
  99.     select((select($$b_write), $| = 1)[0]);
  100.     return 1;
  101.   }
  102.  
  103.   # Try a pair of plain INET sockets.
  104.   if ($type eq "inet") {
  105.     eval {
  106.       ($$a_read, $$b_write) = $self->make_socket();
  107.     };
  108.  
  109.     if (length $@) {
  110.       warn "make_socket failed: $@" if DEBUG;
  111.       return;
  112.     }
  113.  
  114.     DEBUG and do {
  115.       warn "using a plain INET socket";
  116.       warn "ar($$a_read) bw($$b_write)\n";
  117.     };
  118.  
  119.     # It's one-way, so shut down the unused directions.
  120.     shutdown($$a_read,  1);
  121.     shutdown($$b_write, 0);
  122.  
  123.     # Turn off buffering.  POE::Kernel does this for us, but someone
  124.     # might want to use the pipe class elsewhere.
  125.     select((select($$b_write), $| = 1)[0]);
  126.     return 1;
  127.   }
  128.  
  129.   # There's nothing left to try.
  130.   DEBUG and warn "unknown OneWay socket type ``$type''";
  131.   return;
  132. }
  133.  
  134. ###############################################################################
  135. 1;
  136.  
  137. __END__
  138.  
  139. =head1 NAME
  140.  
  141. POE::Pipe::OneWay - portable one-way pipe creation (works without POE)
  142.  
  143. =head1 SYNOPSIS
  144.  
  145.   my ($read, $write) = POE::Pipe::OneWay->new();
  146.   die "couldn't create a pipe: $!" unless defined $read;
  147.  
  148. =head1 DESCRIPTION
  149.  
  150. POE::Pipe::OneWay makes unbuffered one-way pipes or it dies trying.
  151.  
  152. Pipes are troublesome beasts because the different pipe creation
  153. methods have spotty support from one system to another.  Some systems
  154. have C<pipe()>, others have C<socketfactory()>, and still others have
  155. neither.
  156.  
  157. POE::Pipe::OneWay tries different ways to make a pipe in the hope that
  158. one of them will succeed on any given platform.  It tries them in
  159. pipe() -> socketpair() -> IO::Socket::INET order.
  160.  
  161. So anyway, the syntax is pretty easy:
  162.  
  163.   my ($read, $write) = POE::Pipe::OneWay->new();
  164.   die "couldn't create a pipe: $!" unless defined $read;
  165.  
  166. And now you have a pipe with a read side and a write side.
  167.  
  168. =head1 DEBUGGING
  169.  
  170. It's possible to force POE::Pipe::OneWay to use one of its underlying
  171. pipe methods.  This was implemented for exercising each method in
  172. tests, but it's possibly useful for others.
  173.  
  174. However, forcing OneWay's pipe method isn't documented because it's
  175. cheezy and likely to change.  Use it at your own risk.
  176.  
  177. =head1 BUGS
  178.  
  179. The INET domain socket method may block for up to 1s if it fails.
  180.  
  181. =head1 AUTHOR & COPYRIGHT
  182.  
  183. POE::Pipe::OneWay is copyright 2000 by Rocco Caputo.  All rights
  184. reserved.  POE::Pipe::OneWay is free software; you may redistribute it
  185. and/or modify it under the same terms as Perl itself.
  186.  
  187. =cut
  188.