summaryrefslogtreecommitdiff
path: root/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Event.pm
blob: a3ad32cd7fb8c628abad29da0ca1e2c5527bde00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package NDB::Util::Event;

use strict;
use Carp;
use Errno;

require NDB::Util::Base;

use vars qw(@ISA);
@ISA = qw(NDB::Util::Base);

# constructors

my $log;

sub initmodule {
    $log = NDB::Util::Log->instance;
}

NDB::Util::Event->attributes();

sub new {
    my $class = shift;
    @_ % 2 == 0 or confess 0+@_;
    my(%attr) = @_;
    my $event = $class->SUPER::new(%attr);
    return $event;
}

# set and test bits

sub check {
    my $event = shift;
    my($file, $type) = @_;
    my $fileno;
    if (ref($file) eq 'GLOB') {
	$fileno = fileno($file);
    }
    elsif (ref($file)) {
	$file->can("getfh") or confess 'oops';
	$fileno = fileno($file->getfh);
    }
    else {
	$fileno = $file;
    }
    defined($fileno) or confess 'oops';
    $fileno =~ s/^\s+|\s+$//g;
    $fileno =~ /^\d+$/ or confess 'oops';
    $type =~ /^[rwe]$/ or confess 'oops';
    return ($fileno, $type);
}

sub set {
    my $event = shift;
    @_ == 2 or confess 0+@_;
    my($fileno, $type) = $event->check(@_);
    vec($event->{"i_$type"}, $fileno, 1) = 1;
}

sub clear {
    my $event = shift;
    @_ == 2 or confess 0+@_;
    my($fileno, $type) = $event->check(@_);
    vec($event->{"i_$type"}, $fileno, 1) = 0;
}

sub test {
    my $event = shift;
    @_ == 2 or confess 0+@_;
    my($fileno, $type) = $event->check(@_);
    return vec($event->{"o_$type"}, $fileno, 1);
}

# poll

sub poll {
    my $event = shift;
    @_ <= 1 or confess 'oops';
    my $timeout = shift;
    if (defined($timeout)) {
	$timeout =~ /^\d+$/ or confess 'oops';
    }
    $event->{o_r} = $event->{i_r};
    $event->{o_w} = $event->{i_w};
    $event->{o_e} = $event->{i_e};
    my $n;
    $n = select($event->{o_r}, $event->{o_w}, $event->{o_e}, $timeout);
    if ($n < 0 || ! defined($n)) {
	if ($! == Errno::EINTR) {
	    $log->put("select interrupted");
	    return 0;
	}
	$log->put("select failed: $!");
	return undef;
    }
    if (! $n) {
	$log->put("select timed out");
    }
    return $n;
}

1;
# vim:set sw=4: