The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

IO::Events - Events for non-blocking IPC via pipes

SYNOPSIS

   # run 'bc' as a co-process
   use IO::Events;

   my $loop = IO::Events::Loop-> new();

   my $stdin_alive = 1;
   my $calculator = IO::Events::Process::ReadWrite-> new(
      owner    => $loop,
      process  => 'bc -l', 
      on_read  => sub {
         while ( my $line = $_[0]-> readline) {
            print "bc says: $line";
         }
      },
      on_close => sub {
         exit 1 if $stdin_alive; # fork/exec error
      }
   );

   my $stdin = IO::Events::stdin-> new(
      owner => $loop,
      on_read => sub { 
        $calculator-> write( $_[0]-> read );
      },
      on_close => sub {
         $stdin_alive = 0;
         exit;
      },
   );

   $loop-> yield while 1;

DESCRIPTION

The module implements object-oriented approach to select-driven events and contains set of convenience objects for inter-process communication.

The main part of the module is the 'loop' instance of IO::Events::Loop class, which knows about all IO handles subject to select(). The handles are inherited from IO::Events::Handle class, which property handle holds reference to a IO handle object, - a file scalar or IO::Handle instance. IO::Events::Handle object propagates select-based events - on_read, on_write, on_exception, as well as generic on_create, on_close and on_error. It is a requirement that handles are non-blocking.

All instances are created by calling new with arbitrary number of named parameters. The unrecognized parameters are stored in the object and cause no conflict:

   my $a = IO::Events::Handle-> new( my_var => 1 );
   die $a->{my_var};

The module is not meant to serve as replacement of IO::Select and IPC::Open, and can perfectly live together with the first and counteract with the handles managed by the second. The example in "SYNOPSIS" section displays how to harness the non-blocking IO between stdin and a co-process.

IO::Events::Loop

new() parameters

timeout INTEGER

Number of seconds passed to select() as the fourth parameter.

Default value: 50

waitpid BOOLEAN

In addition to select(), IO::Events::Loop also waits for finished processes, automatically getting rid of handles associated with them, if set to 1.

Default value: 1

Methods

handles

Returns number of handles owner by loop object. When a program automatically disposes of handles, not needed anymore, it may choose to stop when there are no more handles to serve.

yield %HASH

Enters select() loop and dispatches pending IO if data are available to read or write. Hash values of 'block_read', 'block_write', and 'block_exc' can be set to 1 if read, write, or exception events are not to be used. Practically,

   $loop-> yield( block_read => 1, block_exc => 1, timeout => 0 )

call effectively ( but still in the non-blocking fashion ) flushes write buffers.

Returns result of select() call, the number of streams handled.

flush

Flushes write sockets, if possible.

Fields

%id

All handles are assigned an unique id, and are stored in internal {id} hash. This hash is read-only, and can be used to look-up a handle object by its id string.

%filenos

Hash of file numbers, read-only.

%processes

Hash of PIDs associated with handles, read-only. Used for IPC and waitpid results processing.

IO::Events::Handle

Root of IO handle object hierarchy, dispatches IO events and auto-destructs when handle is closed or an IO error occurs. The explicit destruction is invoked by calling destroy, which is reentrant-safe.

Parameters to new()

auto_close BOOLEAN

If set to 1, IO handle is explicitly closed as the object instance is destroyed. Doesn't affect anything otherwise.

Default value: 1

flush [ DISCARD = 0]

Flushes not yet written data. If DISCARD is 1, does not return until all data are written or error is signalled. If 0, discards all data.

handle IOHANDLE

IO::Handle object or a file scalar. If not specified, a new IO::Handle instance is created automatically.

The handle is set to non-blocking mode. If this is already done, nonblock optional boolean parameter can be set to 1 to prevent extra fcntl calls.

read BOOLEAN

Set to 1 if handle is to be read from.

Default value: 0

shutdown @WHO

Defined in IO::Events::Fork::ReadWrite and IO::Event::IPC::Process::ReadWrite namespaces. @WHO can contain string 'read' and 'write', to tell what part of bidirectional IPC is to be closed.

write BOOLEAN

Set to 1 if handle is to be written from.

Default value: 0

pid INTEGER

If a handle is associated with a process, IO::Events::Loop uses this field to waitpid() and auto-destruct the handle.

Default value: undef

Methods

can_read BOOLEAN

Selects whether the handle is readable.

can_write BOOLEAN

Selects whether the handle is writable.

can_exception BOOLEAN

Selects whether the handle accepts exception events.

readline

Returns newline-ended read data, if available.

read

Return contents of the read buffer.

write DATA

Appends DATA to the write buffer

destroy

Destructs handle instance

notify $EVENT, @PARAMETERS

Dispatches EVENT, passing PARAMETERS to each callback.

Events

A single event can cause several callback routines to be called. This is useful when a class declares its own, for example, cleanup code in on_close sub, whereas the class instance user can add another listener to the same on_close notification:

   package MyHandle;
   ...
   sub on_close { ... }
   ...

   MyHandle-> new( on_close => sub { ... });

The class declares static ( per-class ) instance of hash %events, which contains declaration of events and their execution flow. SINGLE-declared events call only single callback, be it static or dynamic. MULTIPLE-declared events call all callbacks, but execution flow can be stopped by setting {event_flag} to 1. This is useful, for example, to dynamically override default behavior of IO::Events::Handle::on_error which emits a warning message to stderr and destroys the handle.

on_close

Called before object instance is destroyed.

In a special case for ReadWrite objects, on_close can be called twice, when either read or write handles are destroyed. In the latter case the second parameter is set to 1.

Declared as MULTIPLE.

on_create

Called after object instance is created.

Declared as MULTIPLE.

on_error

Called when read or write calls encounter error.

Declared as MULTIPLE.

on_exception

Called when exception is arrived. Consult your system select manpage to see what events and on what socket types can be expected.

on_fork

Special event, called by IO::Events::Fork objects when a new process is instantiated. Although the syntax for specifying on_fork is the same as for the other events, on_fork does not interact with these, and is not called from within yield.

When on_fork returned, process is terminated. If you wish to terminate process yourself, do not call perl's exit but rather POSIX::_exit, since otherwise perl stuctures created before fork will be destroyed twice.

on_read

Called after data is read.

on_write

Called when handle is writable and the write buffer is empty. If the event doesn't fill the write buffer, the handle write flag is cleared and further on_write notifications are suppressed until the write buffer is filled.

IO::Events::Process::Read

Runs a process with its stdout tied to a newly created handle. The process name is passed to process parameter to the new() contructor.

IO::Events::Process::Write

Runs a process with its stdin tied to a newly created handle. The process name is passed to process parameter to the new() contructor.

IO::Events::Process::ReadWrite

Runs a process with its stdin and stdout tied to two newly created handles. The both handles are transparently mapped to a single handle object.

Note: check IPC::Open2 and IPC::Open3 also.

IO::Events::Fork::Read

Forks a child with its stdout tied to a newly created handle.

IO::Events::Fork::Write

Forks a child with its stdin tied to a newly created handle.

IO::Events::Fork::ReadWrite

Forks a child with its stdin and stdout tied to two newly created handles. The both handles are transparently mapped to a single handle object.

IO::Events::stdin

Shortcut class for STDIN handle.

IO::Events::stdout

Shortcut class for STDOUT handle.

IO::Events::stderr

Shortcut class for STDERR handle.

IO::Events::Socket::TCP

Shortcut class for TCP socket. Parameters accepted:

connect HOSTNAME

If set, connect() call is issued on the socket to HOSTNAME and port set in port parameter.

listen

If set, socket listens on port.

port INTEGER

Number of a port to bind to.

accept GENERIC

Accepts connection from GENERIC socket.

SEE ALSO

perlipc, IO::Handle, IO::Select, IPC::Open2.

COPYRIGHT

Copyright (c) 2004 catpipe Systems ApS. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

AUTHOR

Dmitry Karasik <dmitry@karasik.eu.org>