diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-07-14 17:27:32 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-07-14 17:27:32 (GMT) |
commit | ee3a46975986865fe5064f9d87a27277fc6c235a (patch) | |
tree | 51bae2ed1669ca881f761ca7547fbaf22432ae12 /Swiften/Network/BoostConnection.cpp | |
parent | c34f50d3371f47c88d2ee927a5d59af8e135304c (diff) | |
download | swift-contrib-ee3a46975986865fe5064f9d87a27277fc6c235a.zip swift-contrib-ee3a46975986865fe5064f9d87a27277fc6c235a.tar.bz2 |
Consolidating IncomingConnection & Connection.
BoostConnections no longer have their own thread, but are managed from
a central Boost IO thread instead.
Diffstat (limited to 'Swiften/Network/BoostConnection.cpp')
-rw-r--r-- | Swiften/Network/BoostConnection.cpp | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp index f055f6a..ec15c96 100644 --- a/Swiften/Network/BoostConnection.cpp +++ b/Swiften/Network/BoostConnection.cpp @@ -14,53 +14,67 @@ namespace Swift { static const size_t BUFFER_SIZE = 4096; -BoostConnection::BoostConnection(const String& domain) : - Connection(domain), ioService_(0), thread_(0), socket_(0), readBuffer_(BUFFER_SIZE) { - ioService_ = new boost::asio::io_service(); +// ----------------------------------------------------------------------------- + +// A reference-counted non-modifiable buffer class. +class SharedBuffer { + public: + SharedBuffer(const ByteArray& data) : + data_(new std::vector<char>(data.begin(), data.end())), + buffer_(boost::asio::buffer(*data_)) { + } + + // ConstBufferSequence requirements. + typedef boost::asio::const_buffer value_type; + typedef const boost::asio::const_buffer* const_iterator; + const boost::asio::const_buffer* begin() const { return &buffer_; } + const boost::asio::const_buffer* end() const { return &buffer_ + 1; } + + private: + boost::shared_ptr< std::vector<char> > data_; + boost::asio::const_buffer buffer_; +}; + +// ----------------------------------------------------------------------------- + +BoostConnection::BoostConnection(boost::asio::io_service* ioService) : + socket_(*ioService), readBuffer_(BUFFER_SIZE) { } BoostConnection::~BoostConnection() { MainEventLoop::removeEventsFromOwner(this); - ioService_->stop(); - thread_->join(); - delete socket_; - delete thread_; - delete ioService_; } -void BoostConnection::connect() { - thread_ = new boost::thread(boost::bind(&BoostConnection::doConnect, this)); +void BoostConnection::listen() { + doRead(); } -void BoostConnection::disconnect() { - if (ioService_) { - ioService_->post(boost::bind(&BoostConnection::doDisconnect, this)); - } -} - -void BoostConnection::write(const ByteArray& data) { - if (ioService_) { - ioService_->post(boost::bind(&BoostConnection::doWrite, this, data)); - } -} - -void BoostConnection::doConnect() { +void BoostConnection::connect(const String& domain) { DomainNameResolver resolver; try { - HostAddressPort addressPort = resolver.resolve(getDomain().getUTF8String()); - socket_ = new boost::asio::ip::tcp::socket(*ioService_); + HostAddressPort addressPort = resolver.resolve(domain.getUTF8String()); boost::asio::ip::tcp::endpoint endpoint( boost::asio::ip::address::from_string(addressPort.getAddress().toString()), addressPort.getPort()); - socket_->async_connect( + // Use shared_from_this + socket_.async_connect( endpoint, boost::bind(&BoostConnection::handleConnectFinished, this, boost::asio::placeholders::error)); - ioService_->run(); } catch (const DomainNameResolveException& e) { - MainEventLoop::postEvent(boost::bind(boost::ref(onError), DomainNameResolveError), this); + onError(DomainNameResolveError); } } +void BoostConnection::disconnect() { + socket_.close(); +} + +void BoostConnection::write(const ByteArray& data) { + // Use shared_from_this + boost::asio::async_write(socket_, SharedBuffer(data), + boost::bind(&BoostConnection::handleDataWritten, this, boost::asio::placeholders::error)); +} + void BoostConnection::handleConnectFinished(const boost::system::error_code& error) { if (!error) { MainEventLoop::postEvent(boost::bind(boost::ref(onConnected)), this); @@ -72,15 +86,12 @@ void BoostConnection::handleConnectFinished(const boost::system::error_code& err } void BoostConnection::doRead() { - socket_->async_read_some( - boost::asio::buffer(readBuffer_), + // Use shared_from_this + socket_.async_read_some( + boost::asio::buffer(readBuffer_), boost::bind(&BoostConnection::handleSocketRead, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } -void BoostConnection::doWrite(const ByteArray& data) { - boost::asio::write(*socket_, boost::asio::buffer(static_cast<const char*>(data.getData()), data.getSize())); -} - void BoostConnection::handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred) { if (!error) { MainEventLoop::postEvent(boost::bind(boost::ref(onDataRead), ByteArray(&readBuffer_[0], bytesTransferred)), this); @@ -91,9 +102,9 @@ void BoostConnection::handleSocketRead(const boost::system::error_code& error, s } } -void BoostConnection::doDisconnect() { - if (socket_) { - socket_->close(); +void BoostConnection::handleDataWritten(const boost::system::error_code& error) { + if (error && error != boost::asio::error::operation_aborted) { + MainEventLoop::postEvent(boost::bind(boost::ref(onError), WriteError), this); } } |