ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/AIO.pm
Revision: 1.25
Committed: Wed Nov 5 15:38:10 2008 UTC (15 years, 7 months ago) by root
Branch: MAIN
CVS Tags: rel-4_804
Changes since 1.24: +1 -1 lines
Log Message:
4.804

File Contents

# Content
1 =head1 NAME
2
3 Coro::AIO - truly asynchronous file and directory I/O
4
5 =head1 SYNOPSIS
6
7 use Coro::AIO;
8
9 # can now use any of the aio requests your IO::AIO module supports.
10
11 # read 1MB of /etc/passwd, without blocking other coroutines
12 my $fh = aio_open "/etc/passwd", O_RDONLY, 0
13 or die "/etc/passwd: $!";
14 aio_read $fh, 0, 1_000_000, my $buf, 0
15 or die "aio_read: $!";
16 aio_close $fh;
17
18 =head1 DESCRIPTION
19
20 This module is an L<AnyEvent> user, you need to make sure that you use and
21 run a supported event loop.
22
23 This module implements a thin wrapper around L<IO::AIO>. All of
24 the functions that expect a callback are being wrapped by this module.
25
26 The API is exactly the same as that of the corresponding IO::AIO routines,
27 except that you have to specify I<all> arguments I<except> the callback
28 argument. Instead the routines return the values normally passed to the
29 callback. Everything else, including C<$!> and perls stat cache, are set
30 as expected after these functions return.
31
32 You can mix calls to C<IO::AIO> functions with calls to this module. You
33 I<must not>, however, call these routines from within IO::AIO callbacks,
34 as this causes a deadlock. Start a coro inside the callback instead.
35
36 This module also loads L<AnyEvent::AIO> to integrate into the event loop
37 in use, so please refer to its (and L<AnyEvent>'s) documentation on how it
38 selects an appropriate event module.
39
40 All other functions exported by default by IO::AIO (e.g. C<aioreq_pri>)
41 will be exported by default by Coro::AIO, too.
42
43 Functions that can be optionally imported from IO::AIO can be imported
44 from Coro::AIO or can be called directly, e.g. C<Coro::AIO::nreqs>.
45
46 You cannot specify priorities with C<aioreq_pri>, as this module
47 overwrites the request priority with the current coroutine priority at all
48 times.
49
50 For your convienience, here are the changed function signatures for most
51 of the requests, for documentation of these functions please have a look
52 at L<IO::AIO|the IO::AIO manual>. Note that requests added by newer
53 versions of L<IO::AIO> will be automatically wrapped as well.
54
55 =over 4
56
57 =cut
58
59 package Coro::AIO;
60
61 use strict qw(subs vars);
62
63 use IO::AIO 3.1 ();
64 use AnyEvent::AIO ();
65
66 use Coro ();
67 use Coro::AnyEvent ();
68
69 use base Exporter::;
70
71 our $VERSION = 4.804;
72
73 our @EXPORT = (@IO::AIO::EXPORT, qw(aio_wait));
74 our @EXPORT_OK = @IO::AIO::EXPORT_OK;
75 our $AUTOLOAD;
76
77 {
78 my @reqs = @IO::AIO::AIO_REQ ? @IO::AIO::AIO_REQ : @IO::AIO::EXPORT;
79 my %reqs = map +($_ => 1), @reqs;
80
81 eval
82 join "",
83 map "sub $_(" . (prototype "IO::AIO::$_") . ");",
84 grep !$reqs{$_},
85 @IO::AIO::EXPORT, @EXPORT_OK;
86
87 for my $sub (@reqs) {
88 push @EXPORT, $sub;
89
90 my $iosub = "IO::AIO::$sub";
91 my $proto = prototype $iosub;
92
93 $proto =~ s/;?\$$// or die "$iosub: unable to remove callback slot from prototype";
94
95 eval qq{
96 #line 1 "Coro::AIO::$sub($proto)"
97 sub $sub($proto) {
98 my (\$current, \$state) = \$Coro::current;
99
100 push \@_, sub {
101 \$state = _get_state \$current;
102 };
103
104 aioreq_pri \$Coro::current->prio;
105 &$iosub;
106
107 do { &Coro::schedule } while !\$state;
108
109 _set_state \$state
110 }
111 };
112 die if $@;
113 }
114 }
115
116 sub AUTOLOAD {
117 (my $func = $AUTOLOAD) =~ s/^.*:://;
118 *$AUTOLOAD = \&{"IO::AIO::$func"};
119 goto &$AUTOLOAD;
120 }
121
122 =item @results = aio_wait $req
123
124 This is not originally an IO::AIO request: what it does is to wait for
125 C<$req> to finish and return the results. This is most useful with
126 C<aio_group> requests.
127
128 Is currently implemented by replacing the C<$req> callback.
129
130 =cut
131
132 sub aio_wait($) {
133 my ($current, $state, $cb) = $Coro::current;
134
135 $cb = $_[0]->cb (sub {
136 $state = _get_state $current;
137 &$cb if $cb;
138 });
139
140 do { &Coro::schedule } while !$state;
141
142 _set_state $state
143 }
144
145 =item $fh = aio_open $pathname, $flags, $mode
146
147 =item $status = aio_close $fh
148
149 =item $retval = aio_read $fh,$offset,$length, $data,$dataoffset
150
151 =item $retval = aio_write $fh,$offset,$length, $data,$dataoffset
152
153 =item $retval = aio_sendfile $out_fh, $in_fh, $in_offset, $length
154
155 =item $retval = aio_readahead $fh,$offset,$length
156
157 =item $status = aio_stat $fh_or_path
158
159 =item $status = aio_lstat $fh
160
161 =item $status = aio_unlink $pathname
162
163 =item $status = aio_rmdir $pathname
164
165 =item $entries = aio_readdir $pathname
166
167 =item ($dirs, $nondirs) = aio_scandir $path, $maxreq
168
169 =item $status = aio_fsync $fh
170
171 =item $status = aio_fdatasync $fh
172
173 =item ... = aio_xxx ...
174
175 Any additional aio requests follow the same scheme: same parameters except
176 you must not specify a callback but instead get the callback arguments as
177 return values.
178
179 =back
180
181 =head1 SEE ALSO
182
183 L<Coro::Socket> and L<Coro::Handle> for non-blocking socket operation.
184
185 =head1 AUTHOR
186
187 Marc Lehmann <schmorp@schmorp.de>
188 http://home.schmorp.de/
189
190 =cut
191
192 1