mit-scheme-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MIT-Scheme-devel] DNS queries, blocking C calls, and non-file-descripto


From: Taylor R Campbell
Subject: [MIT-Scheme-devel] DNS queries, blocking C calls, and non-file-descriptor events
Date: Tue, 8 Aug 2006 22:53:44 +0000
User-agent: IMAIL/1.21; Edwin/3.116; MIT-Scheme/7.7.90.+

Name resolution is a bit annoying on Unix.  Although it *is* possible
for programs to perform DNS requests manually -- and, were I/O
selection ever to be implemented in Scheme48, Andreas Rottmann wants
to port the SUnet DNS client to Scheme48 1.x --, this doesn't respect
any local operating services such as NIS or NetInfo or lookupd; for
some of these, this means only that no advantage would be taken of
system-local caching, while for others this means that the name
resolution might yield incorrect results.  The only reliable way to
resolve internet host names is by calling gethostbyname(3) or
getaddrinfo(3), preferably the latter.  Unfortunately, these block,
making a simple FFI wrapper around them undesirable.

So last week I decided to find some way to call getaddrinfo(3) in a
(POSIX) thread apart from Scheme.  (This is made tricky because
getaddrinfo(3) is not reliably thread-safe, so there is a single
thread dedicated to handling a queue of requests and performing them
serially.  This bit of it, however, is irrelevant to Scheme, although
perhaps someone else will find useful the simple pthread server
abstraction akin to Erlang's gen_server that I built for it.)  The
whole point of this exercise is to keep Scheme from blocking, of
course, but we also need some way of synchronizing the response from
the getaddrinfo(3) server thread.

At present, (on Unix), Scheme48 and MIT Scheme both internally operate
on a select(2) event loop deep inside (or poll(2) in MIT Scheme, if it
is available), and the only external operating system resources that
they can poll and wait for are file descriptors.  The only way, then,
to synchronize Scheme with another pthread while still playing nicely
with the rest of Scheme is to use a pipe to communicate.  My current
getaddrinfo(3) wrapper uses this, and it seems to work for simple
cases in Scheme48.  (I haven't yet made it work in MIT Scheme, but
that would probably be fairly easy.)  This approach does, however,
have some problems with scalability.

This particular instance of my approach avoids the problem of
excessive numbers of pthreads hogging memory by using a single one for
all getaddrinfo(3) requests, but it also has the flaw that all
requests are serialized, and so long-running requests block out all
others.  Even ignoring this, though, there are pretty small limits to
the number of file descriptors that can be open in the whole process
for communicating between the two pthreads.  Even ignoring *this*,
select(2) often has restrictive limits on the number of descriptors it
can handle.

I'm not sure what to do from here.  The library works, and I'll
release it after polishing it a bit if anyone is interested in it, but
it does not scale very well and loses after not even two hundred sort
of simultaneous DNS requests on my system.  Brian Templeton mentioned
a week or two ago that he was looking into making Scheme48 support
epoll by reimplementing the virtual machine's event interface, but
after his initial mumblage to me I haven't heard anything from him
about it, and it wouldn't do me much good on, say, OS X.

Any ideas?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]