summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-01-15 15:58:05 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-01-15 15:58:05 (GMT)
commitabf3fbe3dc2b56e1f148b999a3003a0ec7e6ef43 (patch)
treeaeacd7528906e174a370b773e7bcbac52c9489f0 /Swiften/Network
parenta85b96ec1f65e7cf5bd28dd9ab43d656f20e0696 (diff)
downloadswift-abf3fbe3dc2b56e1f148b999a3003a0ec7e6ef43.zip
swift-abf3fbe3dc2b56e1f148b999a3003a0ec7e6ef43.tar.bz2
Comply with asio's documentation that we cannot call async_write multiple times simultaniously.
Diffstat (limited to 'Swiften/Network')
-rw-r--r--Swiften/Network/BoostConnection.cpp23
-rw-r--r--Swiften/Network/BoostConnection.h6
2 files changed, 27 insertions, 2 deletions
diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp
index f3cf9a6..7751535 100644
--- a/Swiften/Network/BoostConnection.cpp
+++ b/Swiften/Network/BoostConnection.cpp
@@ -43,7 +43,7 @@ class SharedBuffer {
// -----------------------------------------------------------------------------
BoostConnection::BoostConnection(boost::asio::io_service* ioService, EventLoop* eventLoop) :
- eventLoop(eventLoop), socket_(*ioService), readBuffer_(BUFFER_SIZE) {
+ eventLoop(eventLoop), socket_(*ioService), readBuffer_(BUFFER_SIZE), writing_(false) {
}
BoostConnection::~BoostConnection() {
@@ -67,6 +67,17 @@ void BoostConnection::disconnect() {
}
void BoostConnection::write(const ByteArray& data) {
+ boost::lock_guard<boost::mutex> lock(writeMutex_);
+ if (!writing_) {
+ writing_ = true;
+ doWrite(data);
+ }
+ else {
+ writeQueue_ += data;
+ }
+}
+
+void BoostConnection::doWrite(const ByteArray& data) {
boost::asio::async_write(socket_, SharedBuffer(data),
boost::bind(&BoostConnection::handleDataWritten, shared_from_this(), boost::asio::placeholders::error));
}
@@ -110,6 +121,16 @@ void BoostConnection::handleDataWritten(const boost::system::error_code& error)
else {
eventLoop->postEvent(boost::bind(boost::ref(onDisconnected), WriteError), shared_from_this());
}
+ {
+ boost::lock_guard<boost::mutex> lock(writeMutex_);
+ if (writeQueue_.isEmpty()) {
+ writing_ = false;
+ }
+ else {
+ doWrite(writeQueue_);
+ writeQueue_.clear();
+ }
+ }
}
HostAddressPort BoostConnection::getLocalAddress() const {
diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h
index da4f7b8..7b15966 100644
--- a/Swiften/Network/BoostConnection.h
+++ b/Swiften/Network/BoostConnection.h
@@ -8,6 +8,7 @@
#include <boost/asio.hpp>
#include <boost/enable_shared_from_this.hpp>
+#include <boost/thread/mutex.hpp>
#include "Swiften/Network/Connection.h"
#include "Swiften/EventLoop/EventOwner.h"
@@ -50,11 +51,14 @@ namespace Swift {
void handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred);
void handleDataWritten(const boost::system::error_code& error);
void doRead();
+ void doWrite(const ByteArray& data);
private:
EventLoop* eventLoop;
boost::asio::ip::tcp::socket socket_;
std::vector<char> readBuffer_;
- bool disconnecting_;
+ boost::mutex writeMutex_;
+ bool writing_;
+ ByteArray writeQueue_;
};
}