CS360 Final Exam: December 12, 2000. Question 3: Answer and Grading

This is pretty straightforward. You will have a global variable which is the number of clients. You will increment this when you get a connection, and decrement it when you lose a connection. Since this will be threaded, you'll have to protect the incrementing and decrementing of this number with a mutex.

You'll have a main thread which spins on a accept_connection() call, and forks a thread when it gets a connection -- use jthread_create() so that you don't have to join these threads. Here's the main thread:

pthread_mutex_t lock;
int count;

main()
{
  int sock, fd, *fdp;

  jthread_system_init();
  pthread_mutex_init(&lock, NULL);
  count = 0;

  sock = serve_socket("hydra3a.cs.utk.edu", 5678);

  while (1) {
    fd = accept_connection(sock);
    fdp = (int *) malloc(sizeof(int));
    *fdp = fd;
    jthread_create(thread, (void *) fdp);
  }
}
Each thread increments the count, sends it to the client, then spins on a loop, reading stuff from the client and ignoring it. We read in large units (larger than 1 at least), so that we aren't making too many system calls. When read() returns zero, the connection is gone, so we decrement the number of connections, close the file descriptor and exit. Here is the code for the threads:
void thread(void *arg)
{
  int *fdp;
  int fd;
  char s[100];

  fdp = (int *) arg;
  fd = *fdp;
  free(fdp);

  pthread_mutex_lock(&lock);
  count++;
  sprintf(s, "%d\n", count);
  pthread_mutex_unlock(&lock);
  write(fd, s, strlen(s));

  while(read(fd, s, 100) > 0) ;

  pthread_mutex_lock(&lock);
  count--;
  pthread_mutex_unlock(&lock);
  close(fd);
}
A bunch of you had the main thread write the count to the client. This is not right -- the main thread should go back to accepting connections while another thread performs the write, in case the write takes a long time to complete.

Grading

11 points total.

Points were assigned as follows:

And points were deducted for the following reasons: