37 * over it.
38 */
39 pthread_attr_destroy (&detached_attr);
40 }
41
42 /*
43 * Create and initialize a request structure.
44 */
45 request = (request_t*)malloc (sizeof (request_t));
46 if (request == NULL)
47 errno_abort ('Allocate request');
48 request->next = NULL;
49 request->operation = operation;
50 request->synchronous = sync;
51 if (sync) {
52 request->done_flag = 0;
53 status = pthread_cond_init (&request->done, NULL);
54 if (status != 0)
55 err_abort (status, 'Init request condition');
56 }
57 if (prompt != NULL)
58 strncpy (request->prompt, prompt, 32);
59 else
60 request->prompt[0] = ' ';
61 if (operation == REQ_WRITE && string != NULL)
62 strncpy (request->text, string, 128);
63 else
64 request->text[0] = ' ';
65
66 /*
67 * Add the request to the queue, maintaining the first and
68 * last pointers.
69 */
70 if (tty_server.first == NULL) {
71 tty_server.first = request;
72 tty_server.last = request;
73 } else {
74 (tty_server.last)->next = request;
75 tty_server.last = request;
76 } 77
78 /*
79 * Tell the server that a request is available.
80 */
81 status = pthread_cond_signal (&tty_server.request);
82 if (status != 0)
83 err_abort (status, 'Wake server');
84
85 /*
86 * If the request was 'synchronous', then wait for a reply.
87 */
88 if (sync) {
89 while (!request->done_flag) {
90 status = pthread_cond_wait (
91 &request->done, &tty_server.mutex);
92 if (status != 0)
93 err_abort (status, 'Wait for sync request');
94 }
95 if (operation == REQ_READ) {
96 if (strlen (request->text) > 0)
97 strcpy (string, request->text);
98 else
99 string[0] = ' *;
100 }
101 status = pthread_cond_destroy (&request->done);
102 if (status != 0)
103 err_abort (status, 'Destroy request condition');
104 free (request);
105 }
106 status = pthread_mutex_unlock (&tty_server.mutex);
107 if (status != 0)
108 err_abort (status, 'Unlock mutex');
109 }
Part 4 shows the thread start function for the client threads, which repeatedly queue tty operation requests to the server.
12-22 Read a line through the tty server. If the resulting string is empty, break out of the loop and terminate. Otherwise, loop four times printing the result string, at one-second intervals. Why four? It just 'mixes things up' a little.
26-31 Decrease the count of client threads, and wake the main thread if this is the last client thread to terminate.
¦ server.c part 4 client_routine
1 /*
2 * Client routine — multiple copies will request server.
3 */
4 void *client_routine (void *arg)
5 {
6 int my_number = (int)arg, loops;
7 char prompt[32];
8 char string[128], formatted[128];
9 int status;
10
11 sprintf (prompt, 'Client %d> ', my_number);
12 while (1) {
13 tty_server_request (REQ_READ, 1, prompt, string);
14 if (strlen (string) == 0)
15 break;
16 for (loops = 0; loops < 4; loops++) {
17 sprintf (
18 formatted, '(%d#%d) %s', my_number, loops, string);
19 tty_server_request (REQ_WRITE, 0, NULL, formatted);