ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-DBus/DBus.pm
Revision: 1.1
Committed: Sun Jun 20 23:52:13 2010 UTC (13 years, 10 months ago) by root
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# Content
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