ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Impl/Glib.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/Impl/Glib.pm (file contents):
Revision 1.11 by root, Sun Jul 8 08:52:10 2007 UTC vs.
Revision 1.29 by root, Thu Aug 4 09:14:02 2011 UTC

1=head1 NAME
2
3AnyEvent::Impl::Glib - AnyEvent adaptor for Glib
4
5=head1 SYNOPSIS
6
7 use AnyEvent;
8 use Glib;
9
10 # this module gets loaded automatically as required
11
12=head1 DESCRIPTION
13
14This module provides transparent support for AnyEvent. You don't have to
15do anything to make Glib work with AnyEvent except by loading Glib before
16creating the first AnyEvent watcher.
17
18Glib is probably the most inefficient event loop that has ever seen the
19light of the world: Glib not only scans all its watchers (really, ALL of
20them, whether I/O-related, timer-related or what not) during each loop
21iteration, it also does so multiple times and rebuilds the poll list for
22the kernel each time again, dynamically even.
23
24On the positive side, and most importantly, Glib generally works
25correctly, no quarrels there.
26
27If you create many watchers (as in: more than two), you might consider one
28of the L<Glib::EV>, L<EV::Glib> or L<Glib::Event> modules that map Glib to
29other, more efficient, event loops.
30
31This module uses the default Glib main context for all its watchers.
32
33=cut
34
1package AnyEvent::Impl::Glib; 35package AnyEvent::Impl::Glib;
2 36
3no warnings; 37use AnyEvent (); BEGIN { AnyEvent::common_sense }
4use strict; 38use Glib 1.210 (); # (stable 1.220 2009, also Glib 2.4+ required, 2004)
5 39
6use Glib (); 40our $mainloop = Glib::MainContext->default;
7 41
8my $maincontext = Glib::MainContext->default; 42my %io_cond = (
43 r => ["in" , "hup"],
44 w => ["out", "hup"],
45);
9 46
10sub io { 47sub io {
11 my ($class, %arg) = @_; 48 my ($class, %arg) = @_;
12 49
13 my $self = bless \%arg, $class;
14 my $rcb = \$self->{cb}; 50 my $cb = $arg{cb};
51 my $fd = fileno $arg{fh};
52 defined $fd or $fd = $arg{fh};
15 53
16 my @cond; 54 my $source = add_watch Glib::IO
17 # some glibs need hup, others error with it, YMMV 55 $fd,
18 push @cond, "in", "hup" if $self->{poll} eq "r"; 56 $io_cond{$arg{poll}},
19 push @cond, "out", "hup" if $self->{poll} eq "w"; 57 sub { &$cb; 1 };
20 58
21 $self->{source} = add_watch Glib::IO fileno $self->{fh}, \@cond, sub { 59 bless \\$source, $class
22 $$rcb->();
23 ! ! $$rcb
24 };
25
26 $self
27} 60}
28 61
29sub timer { 62sub timer {
30 my ($class, %arg) = @_; 63 my ($class, %arg) = @_;
31 64
32 my $self = bless \%arg, $class;
33 my $cb = $self->{cb}; 65 my $cb = $arg{cb};
66 my $ival = $arg{interval} * 1000;
34 67
35 $self->{source} = add Glib::Timeout $self->{after} * 1000, sub { 68 my $source; $source = add Glib::Timeout $arg{after} < 0 ? 0 : $arg{after} * 1000,
36 $cb->(); 69 $ival ? sub {
37 0 70 remove Glib::Source $source;
38 }; 71 $source = add Glib::Timeout $ival, sub { &$cb; 1 };
72 &$cb;
73 0
74 }
75 : sub { &$cb; 0 };
39 76
40 $self 77 bless \\$source, $class
78}
79
80sub idle {
81 my ($class, %arg) = @_;
82
83 my $cb = $arg{cb};
84 my $source = add Glib::Idle sub { &$cb; 1 };
85
86 bless \\$source, $class
41} 87}
42 88
43sub DESTROY { 89sub DESTROY {
44 my ($self) = @_; 90 remove Glib::Source $${$_[0]};
45
46 remove Glib::Source delete $self->{source} if $self->{source};
47 # need to undef $cb because we hold references to it
48 $self->{cb} = undef;
49 %$self = ();
50} 91}
51 92
52sub one_event { 93our %pid_w;
53 $maincontext->iteration (1); 94our %pid_cb;
95
96sub child {
97 my ($class, %arg) = @_;
98
99 $arg{pid} > 0
100 or Carp::croak "Glib does not support watching for all pids (pid == 0) as attempted";
101
102 my $pid = $arg{pid};
103 my $cb = $arg{cb};
104
105 $pid_cb{$pid}{$cb+0} = $cb;
106
107 $pid_w{$pid} ||= Glib::Child->watch_add ($pid, sub {
108 $_->($_[0], $_[1])
109 for values %{ $pid_cb{$pid} };
110
111 1
112 });
113
114 bless [$pid, $cb+0], "AnyEvent::Impl::Glib::child"
54} 115}
55 116
561 117sub AnyEvent::Impl::Glib::child::DESTROY {
118 my ($pid, $icb) = @{ $_[0] };
57 119
120 delete $pid_cb{$pid}{$icb};
121 unless (%{ $pid_cb{$pid} }) {
122 delete $pid_cb{$pid};
123 remove Glib::Source delete $pid_w{$pid};
124 }
125}
126
127#sub loop {
128# # hackish, but we do not have a mainloop, just a maincontext
129# $mainloop->iteration (1) while 1;
130#}
131
132sub _poll {
133 $mainloop->iteration (1);
134}
135
136sub AnyEvent::CondVar::Base::_wait {
137 $mainloop->iteration (1) until $_[0]{_ae_sent};
138}
139
1401;
141
142=head1 SEE ALSO
143
144L<AnyEvent>, L<Glib>.
145
146=head1 AUTHOR
147
148 Marc Lehmann <schmorp@schmorp.de>
149 http://home.schmorp.de/
150
151=cut
152

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines