Tcl HomeTcl Home hosted by
ActiveState

Google SiteSearch

Is TclHttpd Multi-Threaded?

Here is a common question about TclHttpd:
How does TclHttpd to handle simultaneous hits from multiple clients
- does this involve locking or threading?

Tcl supports non-blocking, event-driven I/O

By default, TclHttpd uses non-blocking, event-driven I/O to multiplex itself among multiple client hits. It takes 1000's of hits daily on big web sites. It does this by using the event loop features built into the Tcl runtime system. Tcl has a "fileevent" command that registers Tcl commands to be called when I/O is available on a socket. It also has a "vwait" command that enters the event loop so that the Tcl runtime can wait for events and make callbacks to the script level. See the simple network server example for more details about how this works.

What happens when the server blocks while servicing a request?

There are 3 answers:
  1. If the request is for a CGI application, then TclHttpd runs the CGI process and communicates with it via a pipe. The Tcl event loop means that TclHttpd only runs when there is data available on the pipe. So, the CGI process can block arbitrarily long and TclHttpd is free to service other I/O requests, such as connections from new clients.
  2. If the server would block because the client has a slow network connection, then because it uses non-blocking I/O, well, it doesn't block. Instead, it relies on the Tcl event loop to trigger a fileevent when there is new data comming from the client, or when the write socket to the client drains its output buffer.
  3. If the server blocks for some other reason it can indeed starve clients. The most typical example is if you make SQL calls to a database server directly from TclHttpd. Those calls will block until the SQL server returns the answer. Right now the OraTcl and SybTcl interfaces do not really support a non-blocking interface that will free up TclHttpd to get back into its event loop. If you don't use threading as described below, you may want to move your long-running SQL queries into a CGI application.
If you are just serving files and short-running dynamic pages, then it doesn't matter. So what if you use some CPU time to compute a page. Passing that request off to another process (a la Apache) or another thread (a la AOLserver) only helps on a multiprocessor. On a uniprocessor, those approaches just add overhead.

Or, you can enable threading the TclHttpd. This requires a recompile of Tcl with the --enable-thread configure option, and the use of the Thread extension. You can get this with TclHttpd "Bundled distribution". With threading, TclHttpd can pass requests to worker threads. The thread extension is described in more detail here.