Пример #1
0
Status TransportLayerASIO::start() {
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    _running.store(true);

    // If we're in async mode then the ServiceExecutor will handle calling run_one() in a pool
    // of threads. Otherwise we need a thread to just handle the async_accept calls.
    if (!_listenerOptions.async) {
        _listenerThread = stdx::thread([this] {
            setThreadName("listener");
            while (_running.load()) {
                try {
                    _ioContext->run();
                    _ioContext->reset();
                } catch (...) {
                    severe() << "Uncaught exception in the listener: " << exceptionToStatus();
                    fassertFailed(40491);
                }
            }
        });
    }

    for (auto& acceptor : _acceptors) {
        acceptor.listen();
        _acceptConnection(acceptor);
    }

    return Status::OK();
}
Пример #2
0
void TransportLayerASIO::_acceptConnection(GenericAcceptor& acceptor) {
    auto session = createSession();
    if (!session) {
        _acceptConnection(acceptor);
        return;
    }

    auto& socket = session->getSocket();
    auto acceptCb = [ this, session = std::move(session), &acceptor ](std::error_code ec) mutable {
        if (!_running.load())
            return;

        if (ec) {
            log() << "Error accepting new connection on "
                  << endpointToHostAndPort(acceptor.local_endpoint()) << ": " << ec.message();
            _acceptConnection(acceptor);
            return;
        }

        size_t connCount = _currentConnections.addAndFetch(1);
        if (connCount > _listenerOptions.maxConns) {
            log() << "connection refused because too many open connections: " << connCount;
            _currentConnections.subtractAndFetch(1);
            _acceptConnection(acceptor);
            return;
        }

        session->postAcceptSetup(_listenerOptions.async);

        _createdConnections.addAndFetch(1);
        if (!serverGlobalParams.quiet.load()) {
            const auto word = (connCount == 1 ? " connection"_sd : " connections"_sd);
            log() << "connection accepted from " << session->remote() << " #" << session->id()
                  << " (" << connCount << word << " now open)";
        }

        _sep->startSession(std::move(session));
        _acceptConnection(acceptor);
    };

    acceptor.async_accept(socket, std::move(acceptCb));
}
Пример #3
0
void HTTPAcceptor::handleEnqueue(Message *message)
{
    if (!message)
       return;

    PEGASUS_ASSERT(_rep != 0);
    switch (message->getType())
    {
        case SOCKET_MESSAGE:
        {
            SocketMessage* socketMessage = (SocketMessage*)message;

            // If this is a connection request:
            PEGASUS_ASSERT(socketMessage->socket == _rep->socket);

            PEGASUS_ASSERT(socketMessage->events & SocketMessage::READ);

            _acceptConnection();

            break;
        }

       case CLOSE_CONNECTION_MESSAGE:
       {
           CloseConnectionMessage* closeConnectionMessage =
               (CloseConnectionMessage*)message;

           AutoMutex autoMut(_rep->_connection_mut);

           for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
           {
               HTTPConnection* connection = _rep->connections[i];
               SocketHandle socket = connection->getSocket();

               if (socket == closeConnectionMessage->socket)
               {
                   _monitor->unsolicitSocketMessages(socket);
                   _rep->connections.remove(i);
                   delete connection;
                   break;
               }
           }

           break;
       }

       default:
           PEGASUS_ASSERT(false);
           break;
    }

    delete message;
}
Пример #4
0
Status TransportLayerASIO::start() {
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    _running.store(true);

    // If we're in async mode then the ServiceExecutor will handle calling run_one() in a pool
    // of threads. Otherwise we need a thread to just handle the async_accept calls.
    if (!_listenerOptions.async) {
        _listenerThread = stdx::thread([this] {
            setThreadName("listener");
            while (_running.load()) {
                try {
                    _ioContext->run();
                    _ioContext->reset();
                } catch (...) {
                    severe() << "Uncaught exception in the listener: " << exceptionToStatus();
                    fassertFailed(40491);
                }
            }
        });
    }

    for (auto& acceptor : _acceptors) {
        acceptor.listen();
        _acceptConnection(acceptor);
    }

    const char* ssl = "";
#ifdef MONGO_CONFIG_SSL
    if (_sslMode != SSLParams::SSLMode_disabled) {
        ssl = " ssl";
    }
#endif
    log() << "waiting for connections on port " << _listenerOptions.port << ssl;

    return Status::OK();
}