The DNS blocking problem
The problem is that the standard resolver library blocks while looking up names. This can cause a Tcl application - and more obviously an Tk application - to hang while a host name is resolved. Typically system resolvers use DNS to convert a name to an address, but the system may also use files, NIS, LDAP and other systems.
Another solution is to fire up a slave process to perform name resolution and use non-blocking communications with the slave. This is the approach used in Netscape and BrowseX. The advantage of this method is that the resolver process will use normal resolver library calls and block as normal, while the parent can continue processing events while waiting for the answer to arrive.
An extension of this idea on a platform with good thread support (ie Windows) is to use a worker thread instead of a slave process. The method is otherwise the same.
I have a loadable package that uses this approach to perform non-blocking name resolution for Windows (though this can obviously be extended to other platforms). At the moment this package just creates a resolve command and then talks to the slave. Testing this gives me a Tk application that continues to process events and update the display while waiting for slow responses (ie: DNS queries for non-existant hostnames.) The code and binary for this is provided below.
This implementation presents a synchronous interface to the programmer but keeps the Tcl event loop running while the name resolution is performed. This make it simple to use. A more completely asynchronous package would need to use tokens as done by the tcllib dns package or the tcl http library. However, this achieves the main aim of keeping the Tk user interface from freezing while we look up names. See the included demo application for an example of this in practice.
Asynchronous name resolution in the Tcl core
There is only one function in the Tcl core that actually uses gethostbyname on Windows - this is the CreateSocketAddress function in tclWinSock.c. Unix tcl has a similar function but also uses this library function to obtain the nodename. To make non-blocking name resolution a seamless option it will be necessary to provide a way to register an alternative implementation of this function via a loaded package.
An alternative that has been suggested is to include this style of name resolution in the core, but only for use in the creation of asynchronous sockets - when socket -async is used. This may well fit in quite seamlessly into Tcl
Source and binary files
|tclresolver04.zip||1764b50b4e0b82d376ac4b861bf3a937||Windows binary release|