allocated and initialized here. The list of requests is empty, and the server is not running. The mutex and condition variable are statically initialized.

43-45 The main program and client threads coordinate their shutdown using these synchronization objects (client_mutex and clients_done) rather than using pthread_join.

¦ server.c part 1 definitions

1 #include <pthread.h>

2 #include <math.h>

3 #include 'errors.h' 4

5 #define CLIENT THREADS 4 /* Number of clients */

6

7 #define REQ_READ 1 /* Read with prompt */

8 #define REQ WRITE 2 /* Write */

9 #define REQ_QUIT 3 /* Quit server */

10

11 /*

12 * Internal to server 'package' — one for each request.

13 */

14 typedef struct request_tag {

15  struct request_tag *next; /* Link to next */

16  int operation; /* Function code */

17  int synchronous; /* Nonzero if synchronous */

18  int done_flag; /* Predicate for wait */

19  pthread_cond_t done; /* Wait for completion */

20  char prompt[32]; /* Prompt string for reads */

21  char text[128]; /* Read/write text */

22 } request_t;

23

24 /*

25 * Static context for the server

26 */

27 typedef struct tty_server_tag {

28  request_t *first;

29  request_t *last;

30  int running;

31  pthread_mutex_t mutex;

32  pthread_cond_t request;

33 } tty_server_t;

34

35 tty_server_t tty_server = {

36  NULL, NULL, 0,

37  PTHREAD MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};

38

39 /*

40 * Main program data

41 */ 42

43 int client_threads;

44 pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;

45 pthread_cond_t clients_done = PTHREAD_COND_INITIALIZER;

Part 2 shows the server thread function, tty_server_routine. It loops, processing requests continuously until asked to quit.

25-30 The server waits for a request to appear using the request condition variable.

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');

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату