31-34 Remove the first request from the queue — if the queue is now empty, also clear the pointer to the last entry (tty_server.last).
43-66 The switch statement performs the requested work, depending on the operation given in the request packet. REQ_QUIT tells the server to shut down. REQ_ READ tells the server to read, with an optional prompt string. REQ_WRITE tells the server to write a string.
67-79 If a request is marked "synchronous" (synchronous flag is nonzero), the server sets done_flag and signals the done condition variable. When the request is synchronous, the client is responsible for freeing the request packet. If the request was asynchronous, the server frees request on completion.
80-81 If the request was REQ_QUIT, terminate the server thread by breaking out of the while loop, to the return statement.
■ server.c part 2 tty_server_routine
1 /*
2 * The server start routine. It waits for a request to appear
3 * in tty_server.requests using the request condition variable.
4 * It processes requests in FIFO order. If a request is marked
5 * "synchronous" (synchronous != 0), the server will set done_flag
6 * and signal the request's condition variable. The client is
7 * responsible for freeing the request. If the request was not
8 * synchronous, the server will free the request on completion.
9 */
10 void *tty_server_routine (void *arg)
11 {
12 static pthread_mutex_t prompt_mutex = PTHREAD_MUTEX_INITIALIZER;
13 request_t *request;
14 int operation, len;
15 int status;
16
17 while (1) {
18 status = pthread_mutex_lock (&tty_server.mutex);
19 if (status != 0)
20 err_abort (status, "Lock server mutex");
21
22 /*
23 * Wait for data
24 */
25 while (tty_server.first == NULL) {
26 status = pthread_cond_wait (
27 &tty_server.request, &tty_server.mutex);
28 if (status != 0)
29 err_abort (status, "Wait for request");
30 }
31 request = tty_server.first;
32 tty_server.first = request->next;
33 if (tty_server.first == NULL)
34 tty_server.last = NULL;
35 status = pthread_mutex_unlock (&tty_server.mutex);
36 if (status != 0)
37 err_abort (status, "Unlock server mutex");
38
39 /*
40 * Process the data
41 */
42 operation = request->operation;
43 switch (operation) {
44 case REQ_QUIT:
45 break;
46 case REQ_READ:
47 if (strlen (request->prompt) > 0)
48 printf (request->prompt);
49 if (fgets (request->text, 128, stdin) == NULL)
50 request->text[0] = '\0';
51 /*
52 * Because fgets returns the newline, and we don't
53 * want it, we look for it, and turn it into a null
54 * (truncating the input) if found. It should be the
55 * last character, if it is there.
56 */
57 len = strlen (request->text);
58 if (len > 0 && request->text[len-l] == '\n')
59 request->text[len-l] = '\0';
60 break;
61 case REQ_WRITE:
62 puts (request->text);
63 break;
64 default:
65 break;
66 }
67 if (request->synchronous) {
68 status = pthread_mutex_lock (&tty_server.mutex);
69 if (status != 0)
70 err_abort (status, "Lock server mutex");
71 request->done_flag = 1;