ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Util.pm
Revision: 1.28
Committed: Sun May 25 03:03:51 2008 UTC (16 years, 1 month ago) by root
Branch: MAIN
CVS Tags: rel-4_03
Changes since 1.27: +5 -3 lines
Log Message:
*** empty log message ***

File Contents

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