1 |
=head1 NAME |
2 |
|
3 |
AnyEvent::AIO - truly asynchronous file and directory I/O |
4 |
|
5 |
=head1 SYNOPSIS |
6 |
|
7 |
use AnyEvent::DBus; |
8 |
|
9 |
# now use the Net::DBus API, preferably the non-blocking variants |
10 |
|
11 |
=head1 DESCRIPTION |
12 |
|
13 |
This module is an L<AnyEvent> user, you need to make sure that you use and |
14 |
run a supported event loop. |
15 |
|
16 |
Loading this module will install the necessary magic to seamlessly |
17 |
integrate L<Net::DBus> into L<AnyEvent>. It does this by quite brutally |
18 |
hacking L<Net::DBus::Reactor> so that all dbus connections created after |
19 |
loading this module will automatically be managed by this module. |
20 |
|
21 |
Note that a) a lot inside Net::DBus is still blocking b) if you call a |
22 |
method that blocks, you again block your process (basically anything |
23 |
but calls to the Net::DBus::Binding::Connection objects block, but |
24 |
see Net::DBus::Annoation, specifically dbus_call_async) and c) this |
25 |
module only implements the minimum API required to make Net::DBus work - |
26 |
Net::DBus unfortunately has no nice hooking API. |
27 |
|
28 |
However, unlike L<Net::DBus::Reactor>, this module should be fully |
29 |
non-blocking as long as you only use non-blocking APIs (Net::DBus::Reactor |
30 |
blocks on writes). |
31 |
|
32 |
=cut |
33 |
|
34 |
package AnyEvent::DBus; |
35 |
|
36 |
use common::sense; |
37 |
|
38 |
use AnyEvent (); |
39 |
use Net::DBus (); |
40 |
use Net::DBus::Binding::Watch (); |
41 |
|
42 |
our $VERSION = '0.1'; |
43 |
|
44 |
# yup, Net::DBus checks by using exists on %INC... |
45 |
$INC{'Net/DBus/Reactor.pm'} = undef; |
46 |
|
47 |
# claim we are the main reactor mainloop |
48 |
*Net::DBus::Reactor::main = sub { __PACKAGE__ }; |
49 |
|
50 |
our $I = 0; |
51 |
our %O; # watchers and timers, unfortunately, dbus only supports attaching integers... |
52 |
|
53 |
sub watch_off { |
54 |
delete $O{$_[1]->get_data}; |
55 |
} |
56 |
|
57 |
sub io_toggle { |
58 |
my ($con, $w) = @_; |
59 |
|
60 |
my $id = $w->get_data; |
61 |
my $f = $w->get_flags; |
62 |
my $fd = $w->get_fileno; |
63 |
my $on = $w->is_enabled; |
64 |
|
65 |
warn "io $id $on?$f\n"; |
66 |
|
67 |
$f & Net::DBus::Binding::Watch::READABLE () |
68 |
and |
69 |
$O{$id}[0] = $on && AE::io $fd, 0, sub { |
70 |
$w->handle (Net::DBus::Binding::Watch::READABLE ()); |
71 |
$con->dispatch; # wtf., we tell it data is ready, but have to call dispatch ourselves??? |
72 |
}; |
73 |
|
74 |
$f & Net::DBus::Binding::Watch::WRITABLE () |
75 |
and |
76 |
$O{$id}[1] = $on && AE::io $fd, 1, sub { |
77 |
$w->handle (Net::DBus::Binding::Watch::WRITABLE ()); |
78 |
# calling flush, as NEt::DBus::Reactor does, is blocking :/ |
79 |
}; |
80 |
} |
81 |
|
82 |
sub io_on { |
83 |
my ($con, $w) = @_; |
84 |
|
85 |
my $id = ++$I; |
86 |
$w->set_data ($id); |
87 |
|
88 |
&io_toggle; |
89 |
} |
90 |
|
91 |
sub timeout_toggle { |
92 |
my ($con, $w) = @_; |
93 |
|
94 |
my $id = $w->get_data; |
95 |
my $i = $w->get_interval * 0.001; |
96 |
|
97 |
$O{$id} = $w->is_enabled && AE::timer $i, $i, sub { $w->handle }; |
98 |
} |
99 |
|
100 |
sub timeout_on { |
101 |
my ($con, $w) = @_; |
102 |
my $id = ++$I; |
103 |
$w->set_data ($id); |
104 |
|
105 |
&timeout_toggle; |
106 |
} |
107 |
|
108 |
sub manage { |
109 |
my (undef, $con) = @_; |
110 |
|
111 |
$con->set_watch_callbacks (\&io_on, \&watch_off, \&io_toggle); |
112 |
$con->set_timeout_callbacks (\&timeout_on, \&watch_off, \&timeout_toggle); |
113 |
} |
114 |
|
115 |
use Net::DBus::Annotation qw(:call); |
116 |
my $bus = Net::DBus->find; |
117 |
my $ob = $bus->get_bus_object; |
118 |
#my $res = $ob->ListNames (dbus_call_async, "x" x 8192000); |
119 |
my $res = $ob->ListNames (dbus_call_async); |
120 |
#Net::DBus::Binding::PendingCall |
121 |
$res->set_notify (sub { |
122 |
warn "<@_>\n";#d# |
123 |
for my $name (sort @{$_[0]->get_result}) { |
124 |
print " ", $name, "\n"; |
125 |
} |
126 |
}); |
127 |
AE::cv->recv; |
128 |
warn $ob; |
129 |
|
130 |
=head1 SEE ALSO |
131 |
|
132 |
L<AnyEvent>, L<Net::DBus>. |
133 |
|
134 |
=head1 AUTHOR |
135 |
|
136 |
Marc Lehmann <schmorp@schmorp.de> |
137 |
http://home.schmorp.de/ |
138 |
|
139 |
=cut |
140 |
|
141 |
1 |