Title: synchronous alarm task

The network service listens for messages from 3 sources: the file system service, the synchronous alarm task, and the ethernet task. The function of the synchronous alarm task is described in Operating Systems, Design and Implementation by Tanenbaum and Woodhull, page 229:

"The synchronous alarm mechanism was added to MINIX to support the network server, which like the memory manager and the file server, runs as a separate process. Frequently there is a need to set a limit on the time a process may be blocked while waiting for input. For instance in a network, failure to receive an acknowledgement of a data packet within a definite period is probably due to a failure of transmission. A network server can set a synchronous alarm before it tries to receive a message and blocks. Since the synchronous alarm is delivered as a message, it will unblock the server eventually if no message is received from the network. Upon receiving any message the server must first reset the alarm. Then by examining the type or origin of the message, it can determine a packet has arrived or if it has been unblocked by a timeout. If it is the latter, then the server can try to recover, usually by resending the last unacknowledged packet."

In other words, the synchronous alarm task prevents client connections (specifically, tcp and arp connections) from hanging.

The synchronous alarm works as follows:

If a client wishes to set a synchronous alarm, clck_timer() is called and a timer is added to the existing timers. For example, the arp client calls clck_timer() in order to set a limit on the time it's willing to wait for another system on the network to respond to an arp request. If the new timer expires before any of the other timers are due to expire, a message is sent to the clock task requesting an alarm set for the appropriate time. (Note that the clock task is only aware of at most one alarm at any given time.)

When the alarm message is eventually received by the network service (this process), set_timer() sets the global variable clck_call_expire and returns. The next time around its endless while loop, main() processes the received alarm message by calling clck_expire_timers(). This function calls the client-specific function (e.g., arp_timeout()) that handles alarms, passing in the necessary information so that the client can identify the connection associated with the alarm.

After handling the alarm, set_timer() again sends a message to the clock task requesting an alarm message be sent for the next timer due to expire (assuming that there are other timers in timer_chain).