File: io.pm

package info (click to toggle)
libgtk-perl 0.7009-12
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 3,956 kB
  • ctags: 2,260
  • sloc: perl: 13,998; xml: 9,919; ansic: 2,894; makefile: 64; cpp: 45
file content (92 lines) | stat: -rw-r--r-- 2,096 bytes parent folder | download | duplicates (3)
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
package Gtk::io;

my %pending = ();
my $sweepid;
my $timeout = 2;

sub get_pending {
	my $fd = shift;
	if (defined $fd) {
		return grep {m/(read|write)$fd$/} keys %pending;
	} else {
		return \%pending;
	}
}

sub _sweeper {
	$sweepid = Gtk->timeout_add(1000, sub {
		my $now = time;
		my ($k, $v);
		while ( ($k, $v) = each %pending) {
			next unless ref $v;
			if ($now - $v->[1] > $timeout) {
				warn "Timeout on $k\n";
				Gtk::Gdk->input_remove($v->[0]);
				$pending{$k} = undef;
			}
		}
		1;
	});
}

sub _wait_for_condition ($$) {
	my ($fd, $cond) = @_;
	my $id;
	warn "Already scheduled a $cond on fd $fd\n" if exists $pending{$cond.$fd};
	_sweeper() unless $sweepid;
	$id = Gtk::Gdk->input_add($fd, [$cond], sub {
		#warn "callback $id for $cond on $fd\n" if $pending{$cond.$fd};
		return 1 unless ($_[1]->{$cond} || $_[1]->{'readwrite'});
		$pending{$cond.$fd} = 0;
		Gtk::Gdk->input_remove($id);
	});
	$pending{$cond.$fd} = [$id, time];
	Gtk->main_iteration while ($pending{$cond.$fd} || Gtk->events_pending);
	return $cond.$fd;
}

# sysread FILEHANDLE,SCALAR,LENGTH,OFFSET
# sysread FILEHANDLE,SCALAR,LENGTH

sub sysread ($$$;$) {
	my $doit = 0;
	my $fd = $_[0]->fileno();
	my $bits = '';
	vec($bits, $fd, 1) = 1;
	# short circuit it
	unless (select($bits, undef, undef, 0)) {
		$doit = defined(delete $pending{_wait_for_condition($fd, 'read')})?1:0;
	} else {
		$doit++;
	}
	return sysread($_[0], $_[1], $_[2], $_[3] || 0) if $doit;
	return undef;
}

# syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET
# syswrite FILEHANDLE,SCALAR,LENGTH
# syswrite FILEHANDLE,SCALAR

sub syswrite ($$$;$) {
	my $doit = 0;
	my $fd = $_[0]->fileno();
	my $bits = '';
	vec($bits, $fd, 1) = 1;
	# short circuit it
	unless (select(undef, $bits, undef, 0)) {
		$doit = defined(delete $pending{_wait_for_condition($fd, 'write')})?1:0;
	} else {
		$doit++;
	}
	return syswrite($_[0], $_[1], $_[2], $_[3] || 0) if $doit;
	return undef;
}

package Gtk::io::INET;
@ISA = qw(Gtk::io IO::Socket::INET);
package Gtk::io::UNIX;
@ISA = qw(Gtk::io IO::Socket::UNIX);
package Gtk::io::Pipe;
@ISA = qw(Gtk::io IO::Pipe);
1;