コード例 #1
0
TMultiplexingServer::~TMultiplexingServer()
{
    if (listenSocket > 0)
        TF_CLOSE(listenSocket);

    if (epollFd > 0)
        TF_CLOSE(epollFd);
}
コード例 #2
0
TActionForkProcess::~TActionForkProcess()
{
    if (httpSocket)
        delete httpSocket;

    if (TActionContext::socketDesc > 0)
        TF_CLOSE(TActionContext::socketDesc);

    currentActionContext = 0;
}
コード例 #3
0
TActionThread::~TActionThread()
{
    if (httpSocket)
        delete httpSocket;

    if (TActionContext::socketDesc > 0)
        TF_CLOSE(TActionContext::socketDesc);

    threadCounter.fetchAndAddOrdered(-1);
}
コード例 #4
0
void TMultiplexingServer::epollClose(int fd)
{
    tf_epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, NULL);
    TF_CLOSE(fd);
    recvBuffers.remove(fd);
    QQueue<THttpSendBuffer*> que = sendBuffers.take(fd);
    for (QListIterator<THttpSendBuffer*> it(que); it.hasNext(); ) {
        delete it.next();
    }
    pendingRequests.removeAll(fd);
}
コード例 #5
0
TActionContext::~TActionContext()
{
    if (httpSocket)
        delete httpSocket;

    if (socketDesc > 0)
        TF_CLOSE(socketDesc);
    
    // Releases all database sessions
    TActionContext::releaseDatabases();
    
    for (QListIterator<TTemporaryFile *> i(tempFiles); i.hasNext(); ) {
        delete i.next();
    }

    for (QStringListIterator i(autoRemoveFiles); i.hasNext(); ) {
        QFile(i.next()).remove();
    }
}
コード例 #6
0
void TMultiplexingServer::run()
{
    // Listen socket
    quint16 port = Tf::app()->appSettings().value("ListenPort").toUInt();
    int sock = TApplicationServerBase::nativeListen(QHostAddress::Any, port);
    if (sock > 0) {
        tSystemDebug("listen successfully.  port:%d", port);
    } else {
        tSystemError("Failed to set socket descriptor: %d", sock);
        TApplicationServerBase::nativeClose(sock);
        return;
    }

    listenSocket = sock;
    setSocketOption(listenSocket);

    maxWorkers = Tf::app()->maxNumberOfServers(10);
    tSystemDebug("MaxWorkers: %d", maxWorkers);

    // Get send buffer size and recv buffer size
    int res, sendBufSize, recvBufSize;
    socklen_t optlen = sizeof(int);
    res = getsockopt(listenSocket, SOL_SOCKET, SO_SNDBUF, &sendBufSize, &optlen);
    if (res < 0)
        tSystemDebug("SO_SNDBUF: %d", sendBufSize);

    res = getsockopt(listenSocket, SOL_SOCKET, SO_RCVBUF, &recvBufSize, &optlen);
    if (res < 0)
        tSystemDebug("SO_RCVBUF: %d", recvBufSize);

    const int MaxEvents = 128;
    struct epoll_event events[MaxEvents];
    sendBufSize *= 0.8;
    char *sndbuffer = new char[sendBufSize];
    char *rcvbuffer = new char[recvBufSize];

    // Create epoll
    epollFd = epoll_create(1);
    if (epollFd < 0) {
        tSystemError("Failed epoll_create()");
        goto socket_error;
    }

    if (epollAdd(listenSocket, EPOLLIN) < 0) {
        tSystemError("Failed epoll_ctl()");
        goto epoll_error;
    }

    for (;;) {
        // Get send-request
        getSendRequest();

        // Check pending requests
        while (!pendingRequests.isEmpty() && (int)threadCounter < maxWorkers) {
            int fd = pendingRequests.takeFirst();
            THttpBuffer &recvbuf = recvBuffers[fd];
            emitIncomingRequest(fd, recvbuf);
        }

        // Poll Sending/Receiving/Incoming
        int timeout = ((int)threadCounter > 0) ? 1 : 100;
        int nfd = tf_epoll_wait(epollFd, events, MaxEvents, timeout);
        int err = errno;
        if (nfd < 0) {
            tSystemError("Failed epoll_wait() : errno:%d", err);
            break;
        }

        for (int i = 0; i < nfd; ++i) {
            if (events[i].data.fd == listenSocket) {
                if (!pendingRequests.isEmpty())
                    continue;

                // Incoming connection
                struct sockaddr_storage addr;
                socklen_t addrlen = sizeof(addr);

                int clt = ::accept(events[i].data.fd, (sockaddr *)&addr, &addrlen);
                if (clt < 0) {
                    tSystemWarn("Failed accept");
                    continue;
                }

                setNonBlocking(clt);
                if (epollAdd(clt, EPOLLIN) == 0) {
                    THttpBuffer &recvbuf = recvBuffers[clt];
                    recvbuf.clear();
                    recvbuf.setClientAddress(QHostAddress((sockaddr *)&addr));
                }

            } else {
                int cltfd = events[i].data.fd;

                if ( (events[i].events & EPOLLIN) ) {
                    // Receive data
                    int len = ::recv(cltfd, rcvbuffer, recvBufSize, 0);
                    err = errno;
                    if (len > 0) {
                        // Read successfully
                        THttpBuffer &recvbuf = recvBuffers[cltfd];
                        recvbuf.write(rcvbuffer, len);

                        if (recvbuf.canReadHttpRequest()) {
                            // Incoming a request
                            if ((int)threadCounter >= maxWorkers) {
                                pendingRequests << cltfd;
                            } else {
                                emitIncomingRequest(cltfd, recvbuf);
                            }
                        }

                    } else {
                        if (len < 0 && err != ECONNRESET) {
                            tSystemError("Failed recv : errno:%d", err);
                        }

                        // Disconnect
                        epollClose(cltfd);
                        continue;
                    }
                }

                if ( (events[i].events & EPOLLOUT) ) {
                    // Send data
                    THttpSendBuffer *sendbuf = sendBuffers[cltfd].first();
                    if (!sendbuf) {
                        tSystemError("Not found send-buffer");
                        epollClose(cltfd);
                        continue;
                    }

                    int len = sendbuf->read(sndbuffer, sendBufSize);
                    int sentlen = ::send(cltfd, sndbuffer, len, 0);
                    err = errno;
                    TAccessLogger &logger = sendbuf->accessLogger();

                    if (sentlen <= 0) {
                        if (err != ECONNRESET) {
                            tSystemError("Failed send : errno:%d", err);
                        }
                        // Access log
                        logger.setResponseBytes(-1);
                        logger.write();

                        epollClose(cltfd);
                        continue;
                    } else {
                        logger.setResponseBytes(logger.responseBytes() + sentlen);

                        if (len > sentlen) {
                            tSystemDebug("sendbuf prepend: len:%d", len - sentlen);
                            sendbuf->prepend(sndbuffer + sentlen, len - sentlen);
                        }

                        if (sendbuf->atEnd()) {
                            logger.write();  // Writes access log
                            sendbuf->release();

                            QQueue<THttpSendBuffer*> &que = sendBuffers[cltfd];
                            delete que.dequeue(); // delete send-buffer obj

                            // Prepare recv
                            if (que.isEmpty())
                                epollModify(cltfd, EPOLLIN);
                        }
                    }
                }
            }
        }

        // Check stop flag
        if (stopped) {
            if (listenSocket > 0) {
                // Close the listen-socket
                epollClose(listenSocket);
                listenSocket = 0;
            }

            if (!recvBuffers.isEmpty()) {
                for (QMapIterator<int, THttpBuffer> it(recvBuffers); it.hasNext(); ) {
                    it.next();
                    epollClose(it.key());
                }
            }

            if (recvBuffers.isEmpty() && sendBuffers.isEmpty()) {
                break;
            }
        }
    }

epoll_error:
    TF_CLOSE(epollFd);
    epollFd = 0;

socket_error:
    if (listenSocket > 0)
        TF_CLOSE(listenSocket);
    listenSocket = 0;
    delete sndbuffer;
    delete rcvbuffer;
}
コード例 #7
0
void TApplicationServer::nativeClose(int socket)
{
    if (socket > 0)
        TF_CLOSE(socket);
}