#!/usr/bin/env perl -w

#
# Simple benchmark script to check the usage of Event watcher pools.
#
# J. Stenzel (perl@jochen-stenzel.de)
#

# check perl version
require 5.005;


# pragma
use strict;

# modules
use Event;
use Getopt::Long;

# constants
use constant WATCHER_NUMBER => 9999;
use constant WATCHER_DELAY => 0.01;

# global variables
my ($c, @pool, %options)=(0);

# get options
GetOptions(\%options, "pool");

# start now
check('Starting');

# prepare a pool of watchers, if necessary
if (exists $options{'pool'})
 {
  # make IO watchers
  for (my $l=0; $l<=WATCHER_NUMBER; $l++)
    {
     # make a watcher
     push(@pool, Event->io(
			   timeout => WATCHER_DELAY,
			   repeat => 1,
			   cb => \&iosub,
			   prio => 1,
			  )
	 );
    }
 }


# install a timer which terminates the script after a certain runtime
Event->idle(
	    prio => 5,
	    min  => 0.1,
	    max  => 0.1,
	    cb   => sub {
	                 # trace
	                 check('Entering idle watcher', '=' x 45, $c, '=' x 5);

			 # time to terminate?
			 if (++$c==10)
			   {
			    my $cl;
			    check('Cleaning up');
			    $_->cancel, check('After cleanup nr.', $cl++) foreach Event::all_watchers;
			   }
			 else
			   {
			    # install more watchers
			    for (my $l=0; $l<=WATCHER_NUMBER; $l++)
			      {
			       unless (exists $options{'pool'})
				 {
				  # make a real new Event
				  Event->io(
					    fh => \*STDIN,
					    timeout => WATCHER_DELAY,
					    repeat => 1,
					    cb => \&iosub,
					    prio => 1,
					   );
				 }
			       else
				 {
				  no strict;
				  $pool[$l]->fd(\*STDIN);
				  $pool[$l]->again;
				 }
			       
			       check("Started watcher $c/$l");
			      }
			   }
			}
	   );

# start the event loop
check('Loop begins');
Event::loop();

# perform a final check
check('All watchers were cancelled');


# SUBROUTINES #########################################################################################

# functions: a memory checker ...
# sub check {warn "[DBG] @_:\n", ' ' x length('[DBG] '), join('-', Event::_memory_counters()), "\n";}
sub check {}

# ... and an IO event handler
sub iosub
 {
  # initial check
  check('Entering IO watcher');

  # simply deinstall (or stop) yourself
  unless ($options{'pool'})
    {
     $_[0]->w->cancel;
     check('Cancelled IO watcher');
    }
  else
    {
     $_[0]->w->stop;
     check('Stopped IO watcher');
    }
 }
