HTTP::Daemon::Threaded::IOSelector


HTTP-Daemon-Threaded documentation Contained in the HTTP-Daemon-Threaded distribution.

Index


Code Index:


HTTP-Daemon-Threaded documentation Contained in the HTTP-Daemon-Threaded distribution.
package HTTP::Daemon::Threaded::IOSelector;

use IO::Select;
use Time::HiRes qw(time);

use strict;
use warnings;

our $VERSION = '0.91';

use constant HTTPD_SELECT_RD => 1;
use constant HTTPD_SELECT_WR => 2;
use constant HTTPD_SELECT_EX => 4;

sub new {
	my ($class, $interval) = @_;
#
#	create 3 selectors: read, write, and exception,
#	and accepts a static timeout to use for all
#	select() ops
#
	my $readsel = IO::Select->new();
	my $writesel = IO::Select->new();
	my $exceptsel = IO::Select->new();
	return bless [ $readsel, $writesel, $exceptsel, $interval ], $class;
}

sub addRead {
	$_[0]->[0]->add($_[1]);
	return $_[0];
}

sub addWrite {
	$_[0]->[1]->add($_[1]);
	return $_[0];
}

sub addExcept {
	$_[0]->[2]->add($_[1]);
	return $_[0];
}

sub addNoWrite {
	$_[0]->[0]->add($_[1]);
	$_[0]->[2]->add($_[1]);
	return $_[0];
}

sub addAll {
	$_[0]->[0]->add($_[1]);
	$_[0]->[1]->add($_[1]);
	$_[0]->[2]->add($_[1]);
	return $_[0];
}

sub removeRead {
	$_[0]->[0]->remove($_[1]);
	return $_[0];
}

sub removeWrite {
	$_[0]->[1]->remove($_[1]);
	return $_[0];
}

sub removeExcept {
	$_[0]->[2]->remove($_[1]);
	return $_[0];
}

sub removeNoWrite {
	$_[0]->[0]->remove($_[1]);
	$_[0]->[2]->remove($_[1]);
	return $_[0];
}

sub removeAll {

#	my @frame = caller(1);

#	print STDERR 'IOSelector removing for ',
#		join('', $frame[3], ':', $frame[2]), "\n";

	$_[0]->[0]->remove($_[1]);
	$_[0]->[1]->remove($_[1]);
	$_[0]->[2]->remove($_[1]);
	return $_[0];
}

sub getRead { return $_[0]->[0]; }

sub getWrite { return $_[0]->[1]; }

sub getExcept { return $_[0]->[2]; }

sub getAll { return ( @{$_[0]} ); }

sub setTimeout { $_[0]->[3] = $_[1]; return $_[0]; }

sub getTimeout { return $_[0]->[3] = $_[1]; }

sub select {
	my $obj = shift;

	my $start = time();
	$! = undef;
	my ($read, $write, $except) = IO::Select->select(
		$obj->[0],
		$obj->[1],
		$obj->[2],
		$obj->[3] );

	if ($! ne '') {
		print STDERR "select() failure: $!\n";
		print STDERR join("\n",
			$obj->[0]->as_string(),
			$obj->[1]->as_string(),
			$obj->[2]->as_string()), "\n";
	}
#
#	returns undef if no events
#
	return time() - $start
		unless $read;

#	print STDERR "IO::Select failed after ", time() - $start, " secs:\n",
#		join("\n", $obj->[0]->as_string(), $obj->[1]->as_string(), $obj->[2]->as_string()),
#		"\n";
#
#	consolidate selected objects, with a flag indicating which
#	events they have
#
	my %ready = ();
	my %ready_flags = ();

	$ready_flags{$_} = HTTPD_SELECT_RD,
	$ready{$_} = $_
		foreach (@$read);

	$ready_flags{$_} |= HTTPD_SELECT_WR,
	$ready{$_} = $_
		foreach (@$write);

	$ready_flags{$_} |= HTTPD_SELECT_EX,
	$ready{$_} = $_
		foreach (@$except);

	$ready{$_}->handleSocketEvent($ready_flags{$_}) foreach (keys %ready);
#
#	returns the time spent here..
#
	return time() - $start;
}