Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2015
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.66 KB | None | 0 0
  1. void serve_connection (void* sockfd) {
  2. ssize_t n, result;
  3. char line[MAXLINE];
  4. connection_t conn;
  5. connection_init (&conn);
  6. conn.sockfd = (int)sockfd;
  7. while (! shutting_down) {
  8. if ((n = readline (&conn, line, MAXLINE)) == 0) goto quit;
  9. /* connection closed by other end */
  10. if (shutting_down) goto quit;
  11. if (n < 0) {
  12. perror ("readline failed");
  13. goto quit;
  14. }
  15. result = writen (&conn, line, n);
  16. if (shutting_down) goto quit;
  17. if (result != n) {
  18. perror ("writen failed");
  19. goto quit;
  20. }
  21. }
  22. quit:
  23. pthread_mutex_lock(&lock);
  24. --running;
  25. pthread_mutex_unlock(&lock);
  26. close (conn.sockfd);
  27. pthread_cond_signal(&con);
  28. }
  29.  
  30.  
  31.  
  32. /* shared data between threads */
  33. int running;
  34. pthread_mutex_t lock;
  35. pthread_cond_t con;
  36.  
  37. int
  38. main (int argc, char **argv) {
  39.  
  40. /* numConn is the number of connections
  41. running is the number of currently running threads */
  42.  
  43. running = 0;
  44. int connfd, listenfd, numConn;
  45. socklen_t clilen;
  46. struct sockaddr_in cliaddr;
  47. if(argc < 2) numConn = 4;
  48. else {numConn = atoi(argv[1]);}
  49. pthread_t threads[numConn];
  50.  
  51. /* make all threads detached */
  52. pthread_attr_t attr;
  53. pthread_attr_init(&attr);
  54. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  55.  
  56. /* initialize lock and con to protect 'running' variable */
  57. pthread_mutex_init(&lock, NULL);
  58. pthread_cond_init(&con, NULL);
  59.  
  60. install_siginthandler();
  61. open_listening_socket (&listenfd);
  62. listen (listenfd, numConn);
  63. /* allow a default of 4 queued connection requests (unless otherwise specified) before refusing */
  64. while (! shutting_down) {
  65. errno = 0;
  66. clilen = sizeof (cliaddr); /* length of address can vary, by protocol */
  67.  
  68. /* wait for running threads to close if numConn has been exceeded */
  69. pthread_mutex_lock(&lock);
  70. while(running == numConn)
  71. {
  72. pthread_cond_wait(&con, &lock);
  73. }
  74. pthread_mutex_unlock(&lock);
  75.  
  76. if ((connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0) {
  77. if (errno != EINTR) ERR_QUIT ("accept");
  78. /* otherwise try again, unless we are shutting down */
  79. } else {
  80. pthread_create(&threads[running], &attr, (void*)&serve_connection, (void*)connfd);
  81.  
  82. pthread_mutex_lock(&lock);
  83. ++running;
  84. pthread_mutex_unlock(&lock);
  85.  
  86. /* server_handoff (connfd); process the connection */
  87. }
  88. }
  89.  
  90. /* waiting for any open threads */
  91. pthread_mutex_lock(&lock);
  92. while(running > 0)
  93. {
  94. printf("Waiting on thread #%dn", running);
  95. pthread_cond_wait(&con, &lock);
  96. }
  97. pthread_mutex_unlock(&lock);
  98.  
  99. pthread_cond_destroy(&con);
  100. pthread_mutex_destroy(&lock);
  101.  
  102. close (listenfd);
  103. return 0;
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement