diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-01-15 15:58:05 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-01-15 15:58:05 (GMT) |
commit | abf3fbe3dc2b56e1f148b999a3003a0ec7e6ef43 (patch) | |
tree | aeacd7528906e174a370b773e7bcbac52c9489f0 | |
parent | a85b96ec1f65e7cf5bd28dd9ab43d656f20e0696 (diff) | |
download | swift-contrib-abf3fbe3dc2b56e1f148b999a3003a0ec7e6ef43.zip swift-contrib-abf3fbe3dc2b56e1f148b999a3003a0ec7e6ef43.tar.bz2 |
Comply with asio's documentation that we cannot call async_write multiple times simultaniously.
-rw-r--r-- | .cproject | 292 | ||||
-rw-r--r-- | .project | 11 | ||||
-rw-r--r-- | Swiften/Network/BoostConnection.cpp | 23 | ||||
-rw-r--r-- | Swiften/Network/BoostConnection.h | 6 | ||||
-rw-r--r-- | Swiften/QA/NetworkTest/BoostConnectionTest.cpp | 43 |
5 files changed, 369 insertions, 6 deletions
@@ -2058,7 +2058,7 @@ <folderInfo id="0.980756260.1834106966.1405025274.337712890." name="/" resourcePath=""> <toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.756303402" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain"> <targetPlatform binaryParser="org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE;org.eclipse.cdt.core.GNU_ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.756303402.2066002052" name=""/> - <builder arguments="${ProjDirPath}/3rdParty/SCons/scons.py" autoBuildTarget="test=all Swiften/QA/TLSTest" buildPath="" cleanBuildTarget="-c" command="python" enableAutoBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.909263144" incrementalBuildTarget="test=all Swiften/QA/TLSTest" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/> + <builder arguments="${ProjDirPath}/3rdParty/SCons/scons.py" autoBuildTarget="test=all Swiften/QA/TLSTest" buildPath="" cleanBuildTarget="-c" command="python" enableAutoBuild="false" id="org.eclipse.cdt.build.core.settings.default.builder.909263144" incrementalBuildTarget="test=all Swiften/QA/TLSTest" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/> <tool id="org.eclipse.cdt.build.core.settings.holder.libs.1062191353" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/> <tool id="org.eclipse.cdt.build.core.settings.holder.610753786" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder"> <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1253944666" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> @@ -2618,6 +2618,296 @@ </scannerConfigBuildInfo> </storageModule> </cconfiguration> + <cconfiguration id="0.980756260.1834106966.1405025274.1645386896"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.980756260.1834106966.1405025274.1645386896" moduleId="org.eclipse.cdt.core.settings" name="Network Test"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildProperties="" description="" id="0.980756260.1834106966.1405025274.1645386896" name="Network Test" parent="org.eclipse.cdt.build.core.prefbase.cfg"> + <folderInfo id="0.980756260.1834106966.1405025274.1645386896." name="/" resourcePath=""> + <toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1955701303" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain"> + <targetPlatform binaryParser="org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE;org.eclipse.cdt.core.GNU_ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.1955701303.138620748" name=""/> + <builder arguments="${ProjDirPath}/3rdParty/SCons/scons.py" autoBuildTarget="test=all Swiften/QA/StorageTest" buildPath="" cleanBuildTarget="-c" command="python" enableAutoBuild="false" id="org.eclipse.cdt.build.core.settings.default.builder.1225415193" incrementalBuildTarget="test=all Swiften/QA/NetworkTest" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/> + <tool id="org.eclipse.cdt.build.core.settings.holder.libs.156905530" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/> + <tool id="org.eclipse.cdt.build.core.settings.holder.1352696648" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder"> + <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.403933982" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> + </tool> + <tool id="org.eclipse.cdt.build.core.settings.holder.458546237" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder"> + <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1407994904" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> + </tool> + <tool id="org.eclipse.cdt.build.core.settings.holder.1693022292" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder"> + <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1676789809" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/> + </tool> + </toolChain> + </folderInfo> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> + <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> + <storageModule moduleId="org.eclipse.cdt.core.language.mapping"/> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="makefileGenerator"> + <runAction arguments="-E -P -v -dD" command="" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <scannerConfigBuildInfo instanceId="0.980756260.1834106966.1269306596"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="makefileGenerator"> + <runAction arguments="-E -P -v -dD" command="" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="0.980756260"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="makefileGenerator"> + <runAction arguments="-E -P -v -dD" command="" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + </scannerConfigBuildInfo> + </storageModule> + </cconfiguration> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> <project id="swift.null.189117846" name="swift"/> @@ -7,6 +7,7 @@ <buildSpec> <buildCommand> <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> <arguments> <dictionary> <key>?name?</key> @@ -18,7 +19,7 @@ </dictionary> <dictionary> <key>org.eclipse.cdt.make.core.autoBuildTarget</key> - <value></value> + <value>test=all Swiften/QA/StorageTest</value> </dictionary> <dictionary> <key>org.eclipse.cdt.make.core.buildArguments</key> @@ -29,6 +30,10 @@ <value>python</value> </dictionary> <dictionary> + <key>org.eclipse.cdt.make.core.buildLocation</key> + <value></value> + </dictionary> + <dictionary> <key>org.eclipse.cdt.make.core.cleanBuildTarget</key> <value>-c</value> </dictionary> @@ -38,7 +43,7 @@ </dictionary> <dictionary> <key>org.eclipse.cdt.make.core.enableAutoBuild</key> - <value>true</value> + <value>false</value> </dictionary> <dictionary> <key>org.eclipse.cdt.make.core.enableCleanBuild</key> @@ -50,7 +55,7 @@ </dictionary> <dictionary> <key>org.eclipse.cdt.make.core.fullBuildTarget</key> - <value></value> + <value>test=all Swiften/QA/NetworkTest</value> </dictionary> <dictionary> <key>org.eclipse.cdt.make.core.stopOnError</key> 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_; }; } diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp index 530a126..7259807 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp @@ -25,6 +25,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { CPPUNIT_TEST(testDestructor); CPPUNIT_TEST(testDestructor_PendingEvents); CPPUNIT_TEST(testWrite); + CPPUNIT_TEST(testWriteMultipleSimultaniouslyQueuesWrites); #ifdef TEST_IPV6 CPPUNIT_TEST(testWrite_IPv6); #endif @@ -37,6 +38,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { boostIOServiceThread_ = new BoostIOServiceThread(); eventLoop_ = new DummyEventLoop(); disconnected = false; + connectFinished = false; } void tearDown() { @@ -88,6 +90,41 @@ class BoostConnectionTest : public CppUnit::TestFixture { testling->disconnect(); } + + void testWriteMultipleSimultaniouslyQueuesWrites() { + BoostConnection::ref testling(BoostConnection::create(&boostIOService, eventLoop_)); + testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::handleConnectFinished, this)); + testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); + testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); + testling->connect(HostAddressPort(HostAddress("65.99.222.137"), 5222)); + while (!connectFinished) { + boostIOService.run_one(); + eventLoop_->processEvents(); + } + + testling->write(ByteArray("<stream:strea")); + testling->write(ByteArray("m")); + testling->write(ByteArray(">")); + + // Check that we only did one write event, the others are queued + /*int runHandlers = */boostIOService.poll(); + // Disabling this test, because poll runns all handlers that are added during poll() as well, so + // this test doesn't really work any more. We'll have to trust that things are queued. + //CPPUNIT_ASSERT_EQUAL(1, runHandlers); + // Process the other events + while (receivedData.isEmpty()) { + boostIOService.run_one(); + eventLoop_->processEvents(); + } + + // Disconnect & clean up + testling->disconnect(); + while (!disconnected) { + boostIOService.run_one(); + eventLoop_->processEvents(); + } + } + void doWrite(BoostConnection* connection) { connection->write(ByteArray("<stream:stream>")); connection->write(ByteArray("\r\n\r\n")); // Temporarily, while we don't have an xmpp server running on ipv6 @@ -101,11 +138,17 @@ class BoostConnectionTest : public CppUnit::TestFixture { disconnected = true; } + void handleConnectFinished() { + connectFinished = true; + } + private: BoostIOServiceThread* boostIOServiceThread_; + boost::asio::io_service boostIOService; DummyEventLoop* eventLoop_; ByteArray receivedData; bool disconnected; + bool connectFinished; }; CPPUNIT_TEST_SUITE_REGISTRATION(BoostConnectionTest); |