ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Impl/Glib.pm
Revision: 1.30
Committed: Sun Aug 14 01:38:14 2011 UTC (12 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-6_1, rel-6_11, rel-6_12, rel-6_13, rel-6_02, rel-6_01, rel-6_14
Changes since 1.29: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 AnyEvent::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
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 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 iteration, it also does so multiple times and rebuilds the poll list for
22 the kernel each time again, dynamically even.
23
24 On the positive side, and most importantly, Glib generally works
25 correctly, no quarrels there.
26
27 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 This module uses the default Glib main context for all its watchers.
32
33 =cut
34
35 package AnyEvent::Impl::Glib;
36
37 use AnyEvent (); BEGIN { AnyEvent::common_sense }
38 use Glib 1.210 (); # (stable 1.220 2009, also Glib 2.4+ required, 2004)
39
40 our $mainloop = Glib::MainContext->default;
41
42 my %io_cond = (
43 r => ["in" , "hup"],
44 w => ["out", "hup"],
45 );
46
47 sub io {
48 my ($class, %arg) = @_;
49
50 my $cb = $arg{cb};
51 my $fd = fileno $arg{fh};
52 defined $fd or $fd = $arg{fh};
53
54 my $source = add_watch Glib::IO
55 $fd,
56 $io_cond{$arg{poll}},
57 sub { &$cb; 1 };
58
59 bless \\$source, $class
60 }
61
62 sub timer {
63 my ($class, %arg) = @_;
64
65 my $cb = $arg{cb};
66 my $ival = $arg{interval} * 1000;
67
68 my $source; $source = add Glib::Timeout $arg{after} < 0 ? 0 : $arg{after} * 1000,
69 $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
77 bless \\$source, $class
78 }
79
80 sub 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
87 }
88
89 sub DESTROY {
90 remove Glib::Source $${$_[0]};
91 }
92
93 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 #sub loop {
128 # # hackish, but we do not have a mainloop, just a maincontext
129 # $mainloop->iteration (1) while 1;
130 #}
131
132 sub _poll {
133 $mainloop->iteration (1);
134 }
135
136 sub AnyEvent::CondVar::Base::_wait {
137 $mainloop->iteration (1) until exists $_[0]{_ae_sent};
138 }
139
140 1;
141
142 =head1 SEE ALSO
143
144 L<AnyEvent>, L<Glib>.
145
146 =head1 AUTHOR
147
148 Marc Lehmann <schmorp@schmorp.de>
149 http://home.schmorp.de/
150
151 =cut
152