From 256f9df327d13447ec110bbaebe813b86e57a610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Wed, 26 Jan 2011 19:36:30 +0100 Subject: Make boost io_service a shared object. This should avoid problems when destroying an event loop containing timer or network events, after the network factory (and io_service object) has disappeared (i.e. at shutdown). diff --git a/.project b/.project index 312fabe..fcdfcdc 100644 --- a/.project +++ b/.project @@ -7,7 +7,6 @@ org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, ?name? @@ -19,7 +18,7 @@ org.eclipse.cdt.make.core.autoBuildTarget - test=all Swiften/QA/StorageTest + org.eclipse.cdt.make.core.buildArguments @@ -30,10 +29,6 @@ python - org.eclipse.cdt.make.core.buildLocation - - - org.eclipse.cdt.make.core.cleanBuildTarget -c @@ -43,7 +38,7 @@ org.eclipse.cdt.make.core.enableAutoBuild - false + true org.eclipse.cdt.make.core.enableCleanBuild @@ -55,7 +50,7 @@ org.eclipse.cdt.make.core.fullBuildTarget - test=all Swiften/QA/NetworkTest + org.eclipse.cdt.make.core.stopOnError diff --git a/Limber/main.cpp b/Limber/main.cpp index 0ab4710..6db623e 100644 --- a/Limber/main.cpp +++ b/Limber/main.cpp @@ -30,7 +30,7 @@ using namespace Swift; class Server { public: Server(UserRegistry* userRegistry, EventLoop* eventLoop) : userRegistry_(userRegistry) { - serverFromClientConnectionServer_ = BoostConnectionServer::create(5222, &boostIOServiceThread_.getIOService(), eventLoop); + serverFromClientConnectionServer_ = BoostConnectionServer::create(5222, boostIOServiceThread_.getIOService(), eventLoop); serverFromClientConnectionServer_->onNewConnection.connect(boost::bind(&Server::handleNewConnection, this, _1)); serverFromClientConnectionServer_->start(); } diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp index c6e700e..b8cffb0 100644 --- a/Slimber/Server.cpp +++ b/Slimber/Server.cpp @@ -59,7 +59,7 @@ Server::~Server() { void Server::start() { assert(!serverFromClientConnectionServer); serverFromClientConnectionServer = BoostConnectionServer::create( - clientConnectionPort, &boostIOServiceThread.getIOService(), eventLoop); + clientConnectionPort, boostIOServiceThread.getIOService(), eventLoop); serverFromClientConnectionServerSignalConnections.push_back( serverFromClientConnectionServer->onNewConnection.connect( boost::bind(&Server::handleNewClientConnection, this, _1))); @@ -69,7 +69,7 @@ void Server::start() { assert(!serverFromNetworkConnectionServer); serverFromNetworkConnectionServer = BoostConnectionServer::create( - linkLocalConnectionPort, &boostIOServiceThread.getIOService(), eventLoop); + linkLocalConnectionPort, boostIOServiceThread.getIOService(), eventLoop); serverFromNetworkConnectionServerSignalConnections.push_back( serverFromNetworkConnectionServer->onNewConnection.connect( boost::bind(&Server::handleNewLinkLocalConnection, this, _1))); @@ -256,7 +256,7 @@ void Server::handleElementReceived(boost::shared_ptr element, boost::sh new LinkLocalConnector( *service, linkLocalServiceBrowser->getQuerier(), - BoostConnection::create(&boostIOServiceThread.getIOService(), eventLoop))); + BoostConnection::create(boostIOServiceThread.getIOService(), eventLoop))); connector->onConnectFinished.connect( boost::bind(&Server::handleConnectFinished, this, connector, _1)); connectors.push_back(connector); diff --git a/Swiften/Examples/SendFile/SendFile.cpp b/Swiften/Examples/SendFile/SendFile.cpp index 630daac..c355ce7 100644 --- a/Swiften/Examples/SendFile/SendFile.cpp +++ b/Swiften/Examples/SendFile/SendFile.cpp @@ -29,7 +29,7 @@ int exitCode = 2; class FileSender { public: FileSender(const JID& jid, const String& password, const JID& recipient, const boost::filesystem::path& file, int port) : jid(jid), password(password), recipient(recipient), file(file), transfer(NULL) { - connectionServer = BoostConnectionServer::create(port, &networkFactories.getIOServiceThread()->getIOService(), &eventLoop); + connectionServer = BoostConnectionServer::create(port, networkFactories.getIOServiceThread()->getIOService(), &eventLoop); socksBytestreamServer = new SOCKS5BytestreamServer(connectionServer); client = new Swift::Client(&eventLoop, &networkFactories, jid, password); diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp index bba2c07..908585d 100644 --- a/Swiften/Network/BoostConnection.cpp +++ b/Swiften/Network/BoostConnection.cpp @@ -44,8 +44,8 @@ class SharedBuffer { // ----------------------------------------------------------------------------- -BoostConnection::BoostConnection(boost::asio::io_service* ioService, EventLoop* eventLoop) : - eventLoop(eventLoop), socket_(*ioService), readBuffer_(BUFFER_SIZE), writing_(false) { +BoostConnection::BoostConnection(boost::shared_ptr ioService, EventLoop* eventLoop) : + eventLoop(eventLoop), ioService(ioService), socket_(*ioService), readBuffer_(BUFFER_SIZE), writing_(false) { } BoostConnection::~BoostConnection() { diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h index 7b15966..506eedf 100644 --- a/Swiften/Network/BoostConnection.h +++ b/Swiften/Network/BoostConnection.h @@ -29,7 +29,7 @@ namespace Swift { ~BoostConnection(); - static ref create(boost::asio::io_service* ioService, EventLoop* eventLoop) { + static ref create(boost::shared_ptr ioService, EventLoop* eventLoop) { return ref(new BoostConnection(ioService, eventLoop)); } @@ -45,7 +45,7 @@ namespace Swift { HostAddressPort getLocalAddress() const; private: - BoostConnection(boost::asio::io_service* ioService, EventLoop* eventLoop); + BoostConnection(boost::shared_ptr ioService, EventLoop* eventLoop); void handleConnectFinished(const boost::system::error_code& error); void handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred); @@ -55,6 +55,7 @@ namespace Swift { private: EventLoop* eventLoop; + boost::shared_ptr ioService; boost::asio::ip::tcp::socket socket_; std::vector readBuffer_; boost::mutex writeMutex_; diff --git a/Swiften/Network/BoostConnectionFactory.cpp b/Swiften/Network/BoostConnectionFactory.cpp index 00b36c6..743bb61 100644 --- a/Swiften/Network/BoostConnectionFactory.cpp +++ b/Swiften/Network/BoostConnectionFactory.cpp @@ -9,7 +9,7 @@ namespace Swift { -BoostConnectionFactory::BoostConnectionFactory(boost::asio::io_service* ioService, EventLoop* eventLoop) : ioService(ioService), eventLoop(eventLoop) { +BoostConnectionFactory::BoostConnectionFactory(boost::shared_ptr ioService, EventLoop* eventLoop) : ioService(ioService), eventLoop(eventLoop) { } boost::shared_ptr BoostConnectionFactory::createConnection() { diff --git a/Swiften/Network/BoostConnectionFactory.h b/Swiften/Network/BoostConnectionFactory.h index 551defe..ea9d656 100644 --- a/Swiften/Network/BoostConnectionFactory.h +++ b/Swiften/Network/BoostConnectionFactory.h @@ -16,12 +16,12 @@ namespace Swift { class BoostConnectionFactory : public ConnectionFactory { public: - BoostConnectionFactory(boost::asio::io_service*, EventLoop* eventLoop); + BoostConnectionFactory(boost::shared_ptr, EventLoop* eventLoop); virtual boost::shared_ptr createConnection(); private: - boost::asio::io_service* ioService; + boost::shared_ptr ioService; EventLoop* eventLoop; }; } diff --git a/Swiften/Network/BoostConnectionServer.cpp b/Swiften/Network/BoostConnectionServer.cpp index 839c990..4c6403c 100644 --- a/Swiften/Network/BoostConnectionServer.cpp +++ b/Swiften/Network/BoostConnectionServer.cpp @@ -13,7 +13,7 @@ namespace Swift { -BoostConnectionServer::BoostConnectionServer(int port, boost::asio::io_service* ioService, EventLoop* eventLoop) : port_(port), ioService_(ioService), eventLoop(eventLoop), acceptor_(NULL) { +BoostConnectionServer::BoostConnectionServer(int port, boost::shared_ptr ioService, EventLoop* eventLoop) : port_(port), ioService_(ioService), eventLoop(eventLoop), acceptor_(NULL) { } @@ -50,7 +50,7 @@ void BoostConnectionServer::stop(boost::optional e) { } void BoostConnectionServer::acceptNextConnection() { - BoostConnection::ref newConnection(BoostConnection::create(&acceptor_->io_service(), eventLoop)); + BoostConnection::ref newConnection(BoostConnection::create(ioService_, eventLoop)); acceptor_->async_accept(newConnection->getSocket(), boost::bind(&BoostConnectionServer::handleAccept, shared_from_this(), newConnection, boost::asio::placeholders::error)); } diff --git a/Swiften/Network/BoostConnectionServer.h b/Swiften/Network/BoostConnectionServer.h index 223f264..a45e598 100644 --- a/Swiften/Network/BoostConnectionServer.h +++ b/Swiften/Network/BoostConnectionServer.h @@ -25,7 +25,7 @@ namespace Swift { UnknownError }; - static ref create(int port, boost::asio::io_service* ioService, EventLoop* eventLoop) { + static ref create(int port, boost::shared_ptr ioService, EventLoop* eventLoop) { return ref(new BoostConnectionServer(port, ioService, eventLoop)); } @@ -37,7 +37,7 @@ namespace Swift { boost::signal)> onStopped; private: - BoostConnectionServer(int port, boost::asio::io_service* ioService, EventLoop* eventLoop); + BoostConnectionServer(int port, boost::shared_ptr ioService, EventLoop* eventLoop); void stop(boost::optional e); void acceptNextConnection(); @@ -45,7 +45,7 @@ namespace Swift { private: int port_; - boost::asio::io_service* ioService_; + boost::shared_ptr ioService_; EventLoop* eventLoop; boost::asio::ip::tcp::acceptor* acceptor_; }; diff --git a/Swiften/Network/BoostIOServiceThread.cpp b/Swiften/Network/BoostIOServiceThread.cpp index 50fe9a8..031e7b5 100644 --- a/Swiften/Network/BoostIOServiceThread.cpp +++ b/Swiften/Network/BoostIOServiceThread.cpp @@ -6,19 +6,24 @@ #include "Swiften/Network/BoostIOServiceThread.h" +#include + namespace Swift { -BoostIOServiceThread::BoostIOServiceThread() : thread_(boost::bind(&BoostIOServiceThread::doRun, this)) { +BoostIOServiceThread::BoostIOServiceThread() { + ioService_ = boost::make_shared(); + thread_ = new boost::thread(boost::bind(&BoostIOServiceThread::doRun, this)); } BoostIOServiceThread::~BoostIOServiceThread() { - ioService_.stop(); - thread_.join(); + ioService_->stop(); + thread_->join(); + delete thread_; } void BoostIOServiceThread::doRun() { - boost::asio::io_service::work work(ioService_); - ioService_.run(); + boost::asio::io_service::work work(*ioService_); + ioService_->run(); } } diff --git a/Swiften/Network/BoostIOServiceThread.h b/Swiften/Network/BoostIOServiceThread.h index 3cbea28..1f72049 100644 --- a/Swiften/Network/BoostIOServiceThread.h +++ b/Swiften/Network/BoostIOServiceThread.h @@ -8,6 +8,7 @@ #include #include +#include namespace Swift { class BoostIOServiceThread { @@ -15,7 +16,7 @@ namespace Swift { BoostIOServiceThread(); ~BoostIOServiceThread(); - boost::asio::io_service& getIOService() { + boost::shared_ptr getIOService() { return ioService_; } @@ -23,7 +24,7 @@ namespace Swift { void doRun(); private: - boost::asio::io_service ioService_; - boost::thread thread_; + boost::shared_ptr ioService_; + boost::thread* thread_; }; } diff --git a/Swiften/Network/BoostNetworkFactories.cpp b/Swiften/Network/BoostNetworkFactories.cpp index b9d5b49..a8e3d0a 100644 --- a/Swiften/Network/BoostNetworkFactories.cpp +++ b/Swiften/Network/BoostNetworkFactories.cpp @@ -12,8 +12,8 @@ namespace Swift { BoostNetworkFactories::BoostNetworkFactories(EventLoop* eventLoop) { - timerFactory = new BoostTimerFactory(&ioServiceThread.getIOService(), eventLoop); - connectionFactory = new BoostConnectionFactory(&ioServiceThread.getIOService(), eventLoop); + timerFactory = new BoostTimerFactory(ioServiceThread.getIOService(), eventLoop); + connectionFactory = new BoostConnectionFactory(ioServiceThread.getIOService(), eventLoop); domainNameResolver = new PlatformDomainNameResolver(eventLoop); } diff --git a/Swiften/Network/BoostTimer.cpp b/Swiften/Network/BoostTimer.cpp index 1812688..12d06c1 100644 --- a/Swiften/Network/BoostTimer.cpp +++ b/Swiften/Network/BoostTimer.cpp @@ -13,8 +13,8 @@ namespace Swift { -BoostTimer::BoostTimer(int milliseconds, boost::asio::io_service* service, EventLoop* eventLoop) : - timeout(milliseconds), timer(*service), eventLoop(eventLoop) { +BoostTimer::BoostTimer(int milliseconds, boost::shared_ptr service, EventLoop* eventLoop) : + timeout(milliseconds), ioService(service), timer(*service), eventLoop(eventLoop) { } void BoostTimer::start() { diff --git a/Swiften/Network/BoostTimer.h b/Swiften/Network/BoostTimer.h index 548133f..1139dcf 100644 --- a/Swiften/Network/BoostTimer.h +++ b/Swiften/Network/BoostTimer.h @@ -20,7 +20,7 @@ namespace Swift { public: typedef boost::shared_ptr ref; - static ref create(int milliseconds, boost::asio::io_service* service, EventLoop* eventLoop) { + static ref create(int milliseconds, boost::shared_ptr service, EventLoop* eventLoop) { return ref(new BoostTimer(milliseconds, service, eventLoop)); } @@ -28,12 +28,13 @@ namespace Swift { virtual void stop(); private: - BoostTimer(int milliseconds, boost::asio::io_service* service, EventLoop* eventLoop); + BoostTimer(int milliseconds, boost::shared_ptr service, EventLoop* eventLoop); void handleTimerTick(const boost::system::error_code& error); private: int timeout; + boost::shared_ptr ioService; boost::asio::deadline_timer timer; EventLoop* eventLoop; }; diff --git a/Swiften/Network/BoostTimerFactory.cpp b/Swiften/Network/BoostTimerFactory.cpp index 38842f9..b8e628f 100644 --- a/Swiften/Network/BoostTimerFactory.cpp +++ b/Swiften/Network/BoostTimerFactory.cpp @@ -9,7 +9,7 @@ namespace Swift { -BoostTimerFactory::BoostTimerFactory(boost::asio::io_service* ioService, EventLoop* eventLoop) : ioService(ioService), eventLoop(eventLoop) { +BoostTimerFactory::BoostTimerFactory(boost::shared_ptr ioService, EventLoop* eventLoop) : ioService(ioService), eventLoop(eventLoop) { } boost::shared_ptr BoostTimerFactory::createTimer(int milliseconds) { diff --git a/Swiften/Network/BoostTimerFactory.h b/Swiften/Network/BoostTimerFactory.h index a987763..c0e9ef7 100644 --- a/Swiften/Network/BoostTimerFactory.h +++ b/Swiften/Network/BoostTimerFactory.h @@ -17,12 +17,12 @@ namespace Swift { class BoostTimerFactory : public TimerFactory { public: - BoostTimerFactory(boost::asio::io_service*, EventLoop* eventLoop); + BoostTimerFactory(boost::shared_ptr, EventLoop* eventLoop); virtual boost::shared_ptr createTimer(int milliseconds); private: - boost::asio::io_service* ioService; + boost::shared_ptr ioService; EventLoop* eventLoop; }; } diff --git a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp index 4c38576..57e7a5a 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp @@ -39,15 +39,15 @@ class BoostConnectionServerTest : public CppUnit::TestFixture { } void testConstructor_TwoServersOnSamePort() { - BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService(), eventLoop_)); - BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); } void testStart_Conflict() { - BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling->start(); - BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling2->onStopped.connect( boost::bind(&BoostConnectionServerTest::handleStopped, this, _1)); @@ -55,12 +55,12 @@ class BoostConnectionServerTest : public CppUnit::TestFixture { } void testStop() { - BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling->start(); testling->stop(); - BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, &boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling2->start(); testling2->stop(); diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp index 543689d..61572a0 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "Swiften/Base/String.h" #include "Swiften/Base/sleep.h" @@ -34,6 +35,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { public: void setUp() { boostIOServiceThread_ = new BoostIOServiceThread(); + boostIOService = boost::make_shared(); eventLoop_ = new DummyEventLoop(); disconnected = false; connectFinished = false; @@ -46,14 +48,14 @@ class BoostConnectionTest : public CppUnit::TestFixture { void testDestructor() { { - BoostConnection::ref testling(BoostConnection::create(&boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); testling->connect(HostAddressPort(HostAddress(address, 4), 5222)); } } void testDestructor_PendingEvents() { { - BoostConnection::ref testling(BoostConnection::create(&boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); testling->connect(HostAddressPort(HostAddress(address, 4), 5222)); while (!eventLoop_->hasEvents()) { Swift::sleep(10); @@ -63,7 +65,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { } void testWrite() { - BoostConnection::ref testling(BoostConnection::create(&boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); @@ -76,7 +78,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { } void testWrite_IPv6() { - BoostConnection::ref testling(BoostConnection::create(&boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); @@ -90,13 +92,13 @@ class BoostConnectionTest : public CppUnit::TestFixture { void testWriteMultipleSimultaniouslyQueuesWrites() { - BoostConnection::ref testling(BoostConnection::create(&boostIOService, eventLoop_)); + 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(); + boostIOService->run_one(); eventLoop_->processEvents(); } @@ -105,20 +107,20 @@ class BoostConnectionTest : public CppUnit::TestFixture { testling->write(ByteArray(">")); // Check that we only did one write event, the others are queued - /*int runHandlers = */boostIOService.poll(); + /*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(); + boostIOService->run_one(); eventLoop_->processEvents(); } // Disconnect & clean up testling->disconnect(); while (!disconnected) { - boostIOService.run_one(); + boostIOService->run_one(); eventLoop_->processEvents(); } } @@ -142,7 +144,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { private: BoostIOServiceThread* boostIOServiceThread_; - boost::asio::io_service boostIOService; + boost::shared_ptr boostIOService; DummyEventLoop* eventLoop_; ByteArray receivedData; bool disconnected; -- cgit v0.10.2-6-g49f6