ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Util.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/Util.pm (file contents):
Revision 1.5 by root, Sun Apr 27 20:17:46 2008 UTC vs.
Revision 1.30 by root, Mon May 26 02:30:33 2008 UTC

4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 use AnyEvent::Util; 7 use AnyEvent::Util;
8 8
9 inet_aton $name, $cb->($ipn || undef);
10
11=head1 DESCRIPTION 9=head1 DESCRIPTION
12 10
13This module implements various utility functions, mostly replacing 11This module implements various utility functions, mostly replacing
14well-known functions by event-ised counterparts. 12well-known functions by event-ised counterparts.
13
14All functions documented without C<AnyEvent::Util::> prefix are exported
15by default.
15 16
16=over 4 17=over 4
17 18
18=cut 19=cut
19 20
20package AnyEvent::Util; 21package AnyEvent::Util;
21 22
23no warnings;
22use strict; 24use strict;
23 25
24no warnings "uninitialized"; 26use Carp ();
25 27use Errno ();
26use Socket (); 28use Socket ();
27 29
28use AnyEvent; 30use AnyEvent ();
29 31
30use base 'Exporter'; 32use base 'Exporter';
31 33
32#our @EXPORT = qw(gethostbyname gethostbyaddr); 34BEGIN {
33our @EXPORT_OK = qw(inet_aton); 35 *socket_inet_aton = \&Socket::inet_aton; # take a copy, in case Coro::LWP overrides it
36}
37
38BEGIN {
39 my $af_inet6 = eval { &Socket::AF_INET6 };
40
41 # uhoh
42 $af_inet6 ||= 10 if $^O =~ /linux/;
43 $af_inet6 ||= 23 if $^O =~ /cygwin|mswin32/i;
44 $af_inet6 ||= 24 if $^O =~ /openbsd|netbsd/;
45 $af_inet6 ||= 28 if $^O =~ /freebsd/;
46
47 $af_inet6 && socket my $ipv6_socket, $af_inet6, &Socket::SOCK_STREAM, 0 # check if they can be created
48 or $af_inet6 = 0;
49
50 eval "sub AF_INET6() { $af_inet6 }"; die if $@;
51
52 delete $AnyEvent::PROTOCOL{ipv6} unless $af_inet6;
53}
54
55BEGIN {
56 # broken windows perls use undocumented error codes...
57 if ($^O =~ /mswin32/i) {
58 eval "sub WSAWOULDBLOCK() { 10035 }";
59 eval "sub WSAEINPROGRESS() { 10036 }";
60 } else {
61 eval "sub WSAWOULDBLOCK() { -1e99 }"; # should never match any errno value
62 eval "sub WSAEINPROGRESS() { -1e99 }"; # should never match any errno value
63 }
64}
65
66our @EXPORT = qw(fh_nonblocking guard);
67our @EXPORT_OK = qw(AF_INET6 WSAWOULDBLOCK WSAEINPROGRESS);
34 68
35our $VERSION = '1.0'; 69our $VERSION = '1.0';
36 70
37our $MAXPARALLEL = 16; # max. number of parallel jobs 71our $MAXPARALLEL = 16; # max. number of parallel jobs
38 72
74sub _do_asy { 108sub _do_asy {
75 push @queue, [@_]; 109 push @queue, [@_];
76 _schedule; 110 _schedule;
77} 111}
78 112
113# to be removed
79sub dotted_quad($) { 114sub dotted_quad($) {
80 $_[0] =~ /^(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?) 115 $_[0] =~ /^(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?)
81 \.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?) 116 \.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?)
82 \.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?) 117 \.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?)
83 \.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?)$/x 118 \.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9][0-9]?)$/x
84} 119}
85 120
86my $has_ev_adns; 121# just a forwarder
87 122sub inet_aton {
88sub has_ev_adns { 123 require AnyEvent::Socket;
89 ($has_ev_adns ||= do { 124 *inet_aton = \&AnyEvent::Socket::inet_aton;
90 my $model = AnyEvent::detect; 125 goto &inet_aton
91 (($model eq "AnyEvent::Impl::CoroEV" or $model eq "AnyEvent::Impl::EV")
92 && eval { local $SIG{__DIE__}; require EV::ADNS })
93 ? 2 : 1 # so that || always detects as true
94 }) - 1 # 2 => true, 1 => false
95} 126}
96 127
97=item AnyEvent::Util::inet_aton $name_or_address, $cb->($binary_address_or_undef) 128=item fh_nonblocking $fh, $nonblocking
98 129
99Works almost exactly like its Socket counterpart, except that it uses a 130Sets the blocking state of the given filehandle (true == nonblocking,
100callback. 131false == blocking). Uses fcntl on anything sensible and ioctl FIONBIO on
132broken (i.e. windows) platforms.
101 133
102=cut 134=cut
103 135
104sub inet_aton { 136sub fh_nonblocking($$) {
105 my ($name, $cb) = @_; 137 my ($fh, $nb) = @_;
106 138
107 if (&dotted_quad) { 139 require Fcntl;
108 $cb->(Socket::inet_aton $name); 140
109 } elsif (&has_ev_adns) { 141 if ($^O eq "MSWin32") {
110 EV::ADNS::submit ($name, &EV::ADNS::r_addr, 0, sub { 142 $nb = (! ! $nb) + 0;
111 my (undef, undef, @a) = @_; 143 ioctl $fh, 0x8004667e, \$nb; # FIONBIO
112 $cb->(@a ? Socket::inet_aton $a[0] : undef);
113 });
114 } else { 144 } else {
115 _do_asy $cb, sub { Socket::inet_aton $_[0] }, @_; 145 fcntl $fh, &Fcntl::F_SETFL, $nb ? &Fcntl::O_NONBLOCK : 0;
116 } 146 }
147}
148
149=item $guard = guard { CODE }
150
151This function creates a special object that, when called, will execute the
152code block.
153
154This is often handy in continuation-passing style code to clean up some
155resource regardless of where you break out of a process.
156
157You can call one method on the returned object:
158
159=item $guard->cancel
160
161This simply causes the code block not to be invoked: it "cancels" the
162guard.
163
164=cut
165
166sub AnyEvent::Util::Guard::DESTROY {
167 ${$_[0]}->();
168}
169
170sub AnyEvent::Util::Guard::cancel($) {
171 ${$_[0]} = sub { };
172}
173
174sub guard(&) {
175 bless \(my $cb = shift), AnyEvent::Util::Guard::
117} 176}
118 177
1191; 1781;
120 179
121=back 180=back

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines