Exemple #1
0
Connection::~Connection()
{
    // ensure we emit this before our vtable goes down, since we are the
    // Bridge on the underlying Atlas codec, and otherwise we might get
    // a pure virtual method call
    hardDisconnect(true);
}
Exemple #2
0
int BaseConnection::connect(const std::string & host, short port)
{
    if (_socket) {
        _socket->detach();
        _socket.reset();
    }
    try {
        StreamSocket::Callbacks callbacks;
        callbacks.dispatch = [&] {this->dispatch();};
        callbacks.stateChanged =
                [&](StreamSocket::Status state) {
            if (state == StreamSocket::NEGOTIATE) {
                //Turn off Nagle's algorithm to increase responsiveness.
                ((ResolvableAsioStreamSocket<ip::tcp>*)_socket.get())->getAsioSocket().set_option(ip::tcp::no_delay(true));
            }
            this->stateChanged(state);};
        auto socket = new ResolvableAsioStreamSocket<ip::tcp>(_io_service, _clientName,
                _bridge, callbacks);
        _socket.reset(socket);
        std::stringstream ss;
        ss << port;
        ip::tcp::resolver::query query(host, ss.str());
        setStatus(CONNECTING);
        socket->connectWithQuery(query);
    } catch (const std::exception& e) {
        error() << "Error when trying to connect to " << host << " on port "
                << port << ": " << e.what();
        hardDisconnect(true);
        return -1;
    }
    return 0;
}
Exemple #3
0
void Connection::send(const Atlas::Objects::Root &obj)
{
    if ((_status != CONNECTED) && (_status != DISCONNECTING)) {
        error() << "called send on closed connection";
        return;
    }

    if (!_socket) {
        handleFailure("Connection::send: stream failed");
        hardDisconnect(true);
        return;
    }

#ifdef ATLAS_LOG
    std::stringstream debugStream;

    Atlas::Codecs::Bach debugCodec(debugStream, *this /*dummy*/);
    Atlas::Objects::ObjectsEncoder debugEncoder(debugCodec);
    debugEncoder.streamObjectsMessage(obj);
    debugStream << std::flush;

    std::cout << "sending:" << debugStream.str() << std::endl;
#endif

    _socket->getEncoder().streamObjectsMessage(obj);
    _socket->write();
}
Exemple #4
0
void BaseConnection::onConnectTimeout()
{
    std::ostringstream os;
    os << "Connect to " << _host << ':' << _port << " timed out";
    handleTimeout(os.str());
    hardDisconnect(true);
}
Exemple #5
0
BaseConnection::~BaseConnection()
{
    if (_status != DISCONNECTED) {
        hardDisconnect(true);
    }
    if (_socket) {
        _socket->detach();
        _socket.reset();
    }
}
Exemple #6
0
void BaseConnection::stateChanged(StreamSocket::Status status)
{
    switch (status) {
    case StreamSocket::CONNECTING:
        setStatus(CONNECTING);
        break;
    case StreamSocket::CONNECTING_TIMEOUT:
        onConnectTimeout();
        break;
    case StreamSocket::CONNECTING_FAILED:
        handleFailure("Failed to connect to " + _host);
        hardDisconnect(true);
        break;
    case StreamSocket::NEGOTIATE:
        setStatus(NEGOTIATE);
        break;
    case StreamSocket::NEGOTIATE_FAILED:
        hardDisconnect(true);
        break;
    case StreamSocket::NEGOTIATE_TIMEOUT:
        onNegotiateTimeout();
        break;
    case StreamSocket::CONNECTED:
        setStatus(CONNECTED);
        onConnect();
        break;
    case StreamSocket::CONNECTION_FAILED:
        hardDisconnect(true);
        break;
    case StreamSocket::DISCONNECTING:
        setStatus(DISCONNECTING);
        break;
    default:
        break;
    }
}
Exemple #7
0
void Connection::unlock()
{
    if (m_lock < 1)
        throw InvalidOperation("Imbalanced lock/unlock calls on Connection");

    if (--m_lock == 0) {
        switch (_status)
        {
        case DISCONNECTING:
            debug() << "Connection unlocked in DISCONNECTING, closing socket";
            debug() << "have " << m_opDeque.size() << " ops waiting";
            m_opDeque.clear();
            hardDisconnect(true);
            break;

        default:
            warning() << "Connection unlocked in spurious state : this may cause a failure later";
            break;
        }
    }
}
Exemple #8
0
int BaseConnection::connectLocal(const std::string & filename)
{
    if (_socket) {
        _socket->detach();
        _socket.reset();
    }
    try {
        StreamSocket::Callbacks callbacks;
        callbacks.dispatch = [&] {this->dispatch();};
        callbacks.stateChanged =
                [&](StreamSocket::Status state) {this->stateChanged(state);};
        auto socket = new AsioStreamSocket<local::stream_protocol>(
                _io_service, _clientName, _bridge, callbacks);
        _socket.reset(socket);
        setStatus(CONNECTING);
        socket->connect(local::stream_protocol::endpoint(filename));
    } catch (const std::exception& e) {
        hardDisconnect(true);
        return -1;
    }
    return 0;
}
Exemple #9
0
int Connection::disconnect()
{
    if (_status == DISCONNECTING) {
        warning() << "duplicate disconnect on Connection that's already disconnecting";
        return -1;
    }

    if (_status == DISCONNECTED) {
        warning() << "called disconnect on already disconnected Connection";
        return -1;
    }

    // This assert means that this function will always return early below
    // where m_lock is checked. m_lock seems to be used by Account to prevent
    // disconnecting when something is pending.
    // FIXME Look into this.
    assert(m_lock == 0);

    // this is a soft disconnect; it will give people a chance to do tear down and so on
    // in response, people who need to hold the disconnect will lock() the
    // connection, and unlock when their work is done. A timeout stops
    // locks from preventing disconnection
    setStatus(DISCONNECTING);
    Disconnecting.emit();

    if (m_lock == 0) {
        hardDisconnect(true);
        return 0;
    }

    // fell through, so someone has locked =>
    // start a disconnect timeout
//    _timeout = new Timeout(5000);
//    _timeout->Expired.connect(sigc::mem_fun(this, &Connection::onDisconnectTimeout));
    return 0;
}
Exemple #10
0
 void test_hardDisconnect(bool flag) {
     hardDisconnect(flag);
 }
Exemple #11
0
void Connection::onDisconnectTimeout()
{
    handleTimeout("timed out waiting for disconnection");
    hardDisconnect(true);
}
Exemple #12
0
void BaseConnection::onNegotiateTimeout()
{
    handleTimeout("Atlas negotiation timed out");
    hardDisconnect(true);
}