void TMultiplexingServer::emitIncomingRequest(int fd, THttpBuffer &buffer) { QHostAddress host = buffer.clientAddress(); emit incomingHttpRequest(fd, buffer.read(INT_MAX), host.toString()); threadCounter.fetchAndAddOrdered(1); buffer.clear(); buffer.setClientAddress(host); // inherits the host adress }
void TMultiplexingServer::run() { QString mpm = Tf::app()->multiProcessingModuleString(); maxWorkers = Tf::app()->appSettings().value(QLatin1String("MPM.") + mpm + ".MaxWorkersPerAppServer").toInt(); if (maxWorkers <= 0) { maxWorkers = Tf::app()->appSettings().value(QLatin1String("MPM.") + mpm + ".MaxWorkersPerServer", "128").toInt(); } tSystemDebug("MaxWorkers: %d", maxWorkers); int appsvrnum = qMax(Tf::app()->maxNumberOfAppServers(), 1); setNoDeleyOption(listenSocket); TEpollSocket *sock = TEpollSocket::create(listenSocket, QHostAddress()); TEpoll::instance()->addPoll(sock, EPOLLIN); int numEvents = 0; for (;;) { if (!numEvents && TActionWorker::workerCount() > 0) { TEpollSocket::waitSendData(5); // mitigation of busy loop } TEpollSocket::dispatchSendData(); // Poll Sending/Receiving/Incoming int timeout = (TActionWorker::workerCount() > 0) ? 0 : 100; numEvents = TEpoll::instance()->wait(timeout); if (numEvents < 0) break; TEpollSocket *epSock; while ( (epSock = TEpoll::instance()->next()) ) { int cltfd = epSock->socketDescriptor(); if (cltfd == listenSocket) { for (;;) { TEpollSocket *sock = TEpollSocket::accept(listenSocket); if (!sock) break; TEpoll::instance()->addPoll(sock, (EPOLLIN | EPOLLOUT | EPOLLET)); if (appsvrnum > 1) { break; // Load smoothing } } continue; } else { if ( TEpoll::instance()->canSend() ) { // Send data int len = epSock->send(); if (len < 0) { TEpoll::instance()->deletePoll(epSock); epSock->close(); epSock->deleteLater(); continue; } } if ( TEpoll::instance()->canReceive() ) { if (TActionWorker::workerCount() >= maxWorkers) { // not receive TEpoll::instance()->modifyPoll(epSock, (EPOLLIN | EPOLLOUT | EPOLLET)); // reset continue; } // Receive data int len = epSock->recv(); if (len < 0) { TEpoll::instance()->deletePoll(epSock); epSock->close(); epSock->deleteLater(); continue; } if (epSock->canReadHttpRequest()) { #if 1 //TODO: delete here for HTTP 2.0 support // Stop receiving, otherwise the responses is sometimes // placed in the wrong order in case of HTTP-pipeline. TEpoll::instance()->modifyPoll(epSock, (EPOLLOUT | EPOLLET)); // reset #endif emit incomingHttpRequest(epSock); } } } } // Check stop flag if (stopped) { break; } } TEpollSocket::releaseAllSockets(); TActionContext::releaseAll(); }