in reply to Re^5: Pipes and IO::Select's method can_write()
in thread Pipes and IO::Select's method can_write()

"can_write" is actually short for "can write without blocking". If trying to write will immediately fail, then it won't block, which is what select cares about (and so makes "can write" true). Just like if reading will immediately fail because of end-of-stream or because of an error, then "can read" becomes true because trying to read won't block ("hang").

- tye        

  • Comment on Re^6: Pipes and IO::Select's method can_write() (blocking)

Replies are listed 'Best First'.
Re^7: Pipes and IO::Select's method can_write() (blocking)
by sgt (Deacon) on Feb 03, 2007 at 22:13 UTC

    Actually the only guarantee for writing is 1 byte (supposing you don't get an error) so if you try to write more you might block, that's why if you don't want to be blocked you need to go all the way to non-blocking handles (which is never easy as you have to deal with partial writes).

    If I need to go non-blocking I usually use a variation on Lincoln's Stein IO::SessionData and IO::SessionSet. Sadly they are packaged with SOAP::Lite, and having "godzilla" as a prerequesite is no fun ;) IO::Multiplex is also interesting.

    hth --stephan

      Interesting. I thought syswrite would only write as much as it could without blocking, but my test (on FreeBSD 6.1) shows otherwise.

      Test:

      use strict; use warnings; use IO::Handle qw( ); use IO::Select qw( ); { pipe(my $fh_r, my $fh_w) or die("Unable to create pipe: $!\n"); $fh_w->autoflush(1); my $sel_w = IO::Select->new($fh_w); { print("Filling up the pipe...\n"); my $buf = 'x'; for (;;) { my @ready_w = $sel_w->can_write(0.5); # Pipe is full! last if not @ready_w; die if @ready_w != 1; die if $ready_w[0] != $fh_w; my $rv = syswrite($fh_w, $buf, length($buf)); if (not defined $rv) { die("Unable to write to the pipe: $!\n"); } if (not $rv) { die("Unable to write to the pipe: 0 bytes written??\n"); } } } { print("Opening up one byte in the pipe...\n"); my $buf = ''; my $rv = sysread($fh_r, $buf, 1); if (not defined $rv) { die("Unable to read from the pipe: $!\n"); } if (not $rv) { die("Unable to read from the pipe: 0 bytes read??\n"); } } { print("Make sure it's safe to write to the pipe...\n"); my @ready_w = $sel_w->can_write(); die if @ready_w != 1; die if $ready_w[0] != $fh_w; } { print("Writing more chars to the pipe than the pipe can handle.. +.\n"); my $buf = 'x' x (1024*1024); my $rv = syswrite($fh_w, $buf, length($buf)); if (not defined $rv) { die("Unable to write to the pipe [2]: $!\n"); } if (not $rv) { die("Unable to write to the pipe [2]: 0 bytes written??\n"); } printf("Wrote %d bytes to the pipe\n", $rv); } close($fh_w); close($fh_r); }

      Output:

      Filling up the pipe... Opening up one byte in the pipe... Make sure it's safe to write to the pipe... Writing more chars to the pipe than the pipe can handle... [blocks]

      That's unfortunate.