On Sun, Sep 09, 2001 at 09:08:12AM -0700, [EMAIL PROTECTED] wrote:
> well-understood. The 'standard' solution (employed by netscape and
> squid among others) is to fork one or more 'helper' processes. The
This is actually what the Coro module does (Coro::Util::gethostbyname),
albeit very suboptimal (one fork for every resolve, but that could be
transparently improved).
> - has anyone done this already? Someone else must have
> encountered this problem before. Are there pre-existing solutions?
The drawback is that Coro does not work with callbacks and just blocks the
calling coroutine ;->
Anyway, if you don't call gethostbyname in a tight loop, it's fairly
trivial to implement a seperate process solution. My (suboptimal) one
looks like this (obviously one would have to modify it to use a callback
instead of using the "unblock" call.
sub _do_asy(&;@) {
require POSIX; # just for _exit
my $sub = shift;
$jobs->down; # semaphore to limit max. number of parallel jobs
my $fh;
if (0 == open $fh, "-|") {
syswrite STDOUT, join "\0", map { unpack "H*", $_ } &$sub;
POSIX::_exit(0);
}
my $buf;
$fh = unblock $fh;
$fh->read($buf, 16384);
close $fh;
$jobs->up; # semaphore to limit max. number of parallel jobs
my @r = map { pack "H*", $_ } split /\0/, $buf;
wantarray ? @r : $r[0];
}
=item gethostbyname, gethostbyaddr
Work exactly like their perl counterparts, but do not block. Currently
this is being implemented by forking, so it's not exactly low-cost.
=cut
sub gethostbyname($) {
_do_asy { gethostbyname $_[0] } @_;
}
sub gethostbyaddr($$) {
_do_asy { gethostbyaddr $_[0], $_[1] } @_;
}
--
-----==- |
----==-- _ |
---==---(_)__ __ ____ __ Marc Lehmann +--
--==---/ / _ \/ // /\ \/ / [EMAIL PROTECTED] |e|
-=====/_/_//_/\_,_/ /_/\_\ XX11-RIPE --+
The choice of a GNU generation |
|