ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Impl/Glib.pm
Revision: 1.32
Committed: Thu Apr 5 04:12:22 2012 UTC (12 years, 1 month ago) by root
Branch: MAIN
Changes since 1.31: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.12 =head1 NAME
2    
3     AnyEvent::Impl::Glib - AnyEvent adaptor for Glib
4    
5     =head1 SYNOPSIS
6    
7 root 1.16 use AnyEvent;
8     use Glib;
9    
10     # this module gets loaded automatically as required
11 root 1.12
12     =head1 DESCRIPTION
13    
14     This module provides transparent support for AnyEvent. You don't have to
15     do anything to make Glib work with AnyEvent except by loading Glib before
16     creating the first AnyEvent watcher.
17    
18     Glib is probably the most inefficient event loop that has ever seen the
19 root 1.20 light of the world: Glib not only scans all its watchers (really, ALL of
20     them, whether I/O-related, timer-related or what not) during each loop
21 root 1.12 iteration, it also does so multiple times and rebuilds the poll list for
22     the kernel each time again, dynamically even.
23    
24 root 1.21 On the positive side, and most importantly, Glib generally works
25     correctly, no quarrels there.
26 root 1.20
27 root 1.12 If you create many watchers (as in: more than two), you might consider one
28     of the L<Glib::EV>, L<EV::Glib> or L<Glib::Event> modules that map Glib to
29     other, more efficient, event loops.
30    
31 root 1.21 This module uses the default Glib main context for all its watchers.
32 root 1.12
33     =cut
34    
35 root 1.1 package AnyEvent::Impl::Glib;
36    
37 root 1.25 use AnyEvent (); BEGIN { AnyEvent::common_sense }
38 root 1.28 use Glib 1.210 (); # (stable 1.220 2009, also Glib 2.4+ required, 2004)
39 root 1.1
40 root 1.22 our $mainloop = Glib::MainContext->default;
41 root 1.1
42 root 1.24 my %io_cond = (
43     r => ["in" , "hup"],
44     w => ["out", "hup"],
45     );
46    
47 root 1.2 sub io {
48     my ($class, %arg) = @_;
49    
50 root 1.17 my $cb = $arg{cb};
51 root 1.24 my $fd = fileno $arg{fh};
52     defined $fd or $fd = $arg{fh};
53 root 1.2
54 root 1.24 my $source = add_watch Glib::IO
55     $fd,
56     $io_cond{$arg{poll}},
57     sub { &$cb; 1 };
58 root 1.2
59 root 1.17 bless \\$source, $class
60 root 1.1 }
61    
62 root 1.2 sub timer {
63     my ($class, %arg) = @_;
64 root 1.1
65 root 1.18 my $cb = $arg{cb};
66     my $ival = $arg{interval} * 1000;
67 root 1.1
68 root 1.26 my $source; $source = add Glib::Timeout $arg{after} < 0 ? 0 : $arg{after} * 1000,
69 root 1.18 $ival ? sub {
70     remove Glib::Source $source;
71     $source = add Glib::Timeout $ival, sub { &$cb; 1 };
72     &$cb;
73     0
74     }
75     : sub { &$cb; 0 };
76 root 1.1
77 root 1.17 bless \\$source, $class
78 root 1.1 }
79    
80 root 1.21 sub idle {
81     my ($class, %arg) = @_;
82    
83     my $cb = $arg{cb};
84     my $source = add Glib::Idle sub { &$cb; 1 };
85 root 1.28
86 root 1.21 bless \\$source, $class
87     }
88    
89 root 1.6 sub DESTROY {
90 root 1.17 remove Glib::Source $${$_[0]};
91 root 1.2 }
92    
93 root 1.28 our %pid_w;
94     our %pid_cb;
95    
96     sub 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"
115     }
116    
117     sub AnyEvent::Impl::Glib::child::DESTROY {
118     my ($pid, $icb) = @{ $_[0] };
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 root 1.27 #sub loop {
128     # # hackish, but we do not have a mainloop, just a maincontext
129     # $mainloop->iteration (1) while 1;
130     #}
131 root 1.7
132 root 1.29 sub _poll {
133     $mainloop->iteration (1);
134     }
135    
136     sub AnyEvent::CondVar::Base::_wait {
137 root 1.30 $mainloop->iteration (1) until exists $_[0]{_ae_sent};
138 root 1.29 }
139    
140 root 1.12 =head1 SEE ALSO
141    
142 root 1.14 L<AnyEvent>, L<Glib>.
143 root 1.12
144     =head1 AUTHOR
145    
146     Marc Lehmann <schmorp@schmorp.de>
147 root 1.32 http://software.schmorp.de/pkg/AnyEvent.html
148 root 1.12
149     =cut
150 root 1.1
151 root 1.31 1
152