* Server socket had something happen. We accept all waiting client * connections on fd and assign TConnection objects to handle those requests. */
| 957 | * connections on fd and assign TConnection objects to handle those requests. |
| 958 | */ |
| 959 | void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) { |
| 960 | (void)which; |
| 961 | // Make sure that libevent didn't mess up the socket handles |
| 962 | assert(fd == serverSocket_); |
| 963 | |
| 964 | // Going to accept a new client socket |
| 965 | std::shared_ptr<TSocket> clientSocket; |
| 966 | |
| 967 | clientSocket = serverTransport_->accept(); |
| 968 | if (clientSocket) { |
| 969 | // If we're overloaded, take action here |
| 970 | if (overloadAction_ != T_OVERLOAD_NO_ACTION && serverOverloaded()) { |
| 971 | Guard g(connMutex_); |
| 972 | nConnectionsDropped_++; |
| 973 | nTotalConnectionsDropped_++; |
| 974 | if (overloadAction_ == T_OVERLOAD_CLOSE_ON_ACCEPT) { |
| 975 | clientSocket->close(); |
| 976 | return; |
| 977 | } else if (overloadAction_ == T_OVERLOAD_DRAIN_TASK_QUEUE) { |
| 978 | if (!drainPendingTask()) { |
| 979 | // Nothing left to discard, so we drop connection instead. |
| 980 | clientSocket->close(); |
| 981 | return; |
| 982 | } |
| 983 | } |
| 984 | } |
| 985 | |
| 986 | // Create a new TConnection for this client socket. |
| 987 | TConnection* clientConnection = createConnection(clientSocket); |
| 988 | |
| 989 | // Fail fast if we could not create a TConnection object |
| 990 | if (clientConnection == nullptr) { |
| 991 | TOutput::instance().printf("thriftServerEventHandler: failed TConnection factory"); |
| 992 | clientSocket->close(); |
| 993 | return; |
| 994 | } |
| 995 | |
| 996 | /* |
| 997 | * Either notify the ioThread that is assigned this connection to |
| 998 | * start processing, or if it is us, we'll just ask this |
| 999 | * connection to do its initial state change here. |
| 1000 | * |
| 1001 | * (We need to avoid writing to our own notification pipe, to |
| 1002 | * avoid possible deadlocks if the pipe is full.) |
| 1003 | * |
| 1004 | * The IO thread #0 is the only one that handles these listen |
| 1005 | * events, so unless the connection has been assigned to thread #0 |
| 1006 | * we know it's not on our thread. |
| 1007 | */ |
| 1008 | if (clientConnection->getIOThreadNumber() == 0) { |
| 1009 | clientConnection->transition(); |
| 1010 | } else { |
| 1011 | if (!clientConnection->notifyIOThread()) { |
| 1012 | TOutput::instance().perror("[ERROR] notifyIOThread failed on fresh connection, closing", errno); |
| 1013 | clientConnection->close(); |
| 1014 | } |
| 1015 | } |
| 1016 | } |
no test coverage detected