When the server process is started, it establishes standard sockets for clients to connect to it and waits for incoming connections. When a client connects to the server, the server will fork a new process (unless -nofork was specified on the command line) to deal with incoming requests from the client. The result of this is that each logical application has its own dedicated request server. This prevents event handling in one application from blocking event dispatching in another.
Each request server is essentially an event loop. It waits for an event to occur, and dispatches that event to the appropriate handlers. If the event represents input available on the client connection, it reads the message off the stream and executes the corresponding request. If the event is an X event or a Motif callback, relevant information about that event is packed into a message and sent to the Lisp client. After sending the event notification, the server will enter a callback event loop to allow processing of requests from the client’s callback procedure. However, during the callback event loop, only input events from the client will be processed; all other events will be deferred until the callback is terminated.
The server supports a standard means for reading and writing data objects into messages for communication with the Lisp client. For every available type of data which may be transported there are reader and writer functions. For instance, WIDGET is a valid type for argument data. Two functions are defined in the server: message_read_widget() and message_write_widget(). To allow for a more generalized interface to argument passing, the server defines the functions toolkit_write_value() and toolkit_read_value(). These functions are passed data and a type identifier; it is their job to look up the correct reader/writer function. Clearly, if the type of an argument is known at compile time then it is best to use the specific reader/writer functions. However, if such type information is not known at compile time, as is the case with arbitrary resource lists, the higher level toolkit_xxx_value() functions are the only available options.