accept.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2. kHTTPd -- the next generation
  3. Accept connections
  4. */
  5. /****************************************************************
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  ****************************************************************/
  21. #include "structure.h"
  22. #include "prototypes.h"
  23. #include "sysctl.h"
  24. #include <linux/smp_lock.h>
  25. /*
  26. Purpose:
  27. AcceptConnections puts all "accepted" connections in the 
  28. "WaitForHeader" queue.
  29. Return value:
  30. The number of accepted connections
  31. */
  32. int AcceptConnections(const int CPUNR, struct socket *Socket)
  33. {
  34. struct http_request *NewRequest;
  35. struct socket *NewSock;
  36. int count = 0;
  37. int error;
  38. EnterFunction("AcceptConnections");
  39. if (atomic_read(&ConnectCount)>sysctl_khttpd_maxconnect)
  40. {
  41. LeaveFunction("AcceptConnections - to many active connections");
  42. return 0;
  43. }
  44. if (Socket==NULL) return 0;
  45. /* 
  46.    Quick test to see if there are connections on the queue.
  47.    This is cheaper than accept() itself because this saves us
  48.    the allocation of a new socket. (Which doesn't seem to be 
  49.    used anyway)
  50. */
  51.     if (Socket->sk->tp_pinfo.af_tcp.accept_queue==NULL)
  52. {
  53. return 0;
  54. }
  55. error = 0;
  56. while (error>=0)
  57. {
  58. NewSock = sock_alloc();
  59. if (NewSock==NULL)
  60. break;
  61. NewSock->type = Socket->type;
  62. NewSock->ops = Socket->ops;
  63. error = Socket->ops->accept(Socket,NewSock,O_NONBLOCK);
  64. if (error<0)
  65. {
  66. sock_release(NewSock);
  67. break;
  68. }
  69. if (NewSock->sk->state==TCP_CLOSE)
  70. {
  71. sock_release(NewSock);
  72. continue;
  73. }
  74. /* Allocate a request-entry for the connection */
  75. NewRequest = kmalloc(sizeof(struct http_request),(int)GFP_KERNEL); 
  76. if (NewRequest == NULL)
  77. {
  78. Send50x(NewSock);  /* Service not available. Try again later */
  79. sock_release(NewSock);
  80. break;
  81. }
  82. memset(NewRequest,0,sizeof(struct http_request));  
  83. NewRequest->sock = NewSock;
  84. NewRequest->Next = threadinfo[CPUNR].WaitForHeaderQueue;
  85. init_waitqueue_entry(&NewRequest->sleep,current);
  86. add_wait_queue(NewSock->sk->sleep,&(NewRequest->sleep));
  87. threadinfo[CPUNR].WaitForHeaderQueue = NewRequest;
  88. atomic_inc(&ConnectCount);
  89. count++;
  90. }
  91. LeaveFunction("AcceptConnections");
  92. return count;
  93. }