diff options
Diffstat (limited to 'Swiften/Network/BoostConnectionServer.cpp')
-rw-r--r-- | Swiften/Network/BoostConnectionServer.cpp | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/Swiften/Network/BoostConnectionServer.cpp b/Swiften/Network/BoostConnectionServer.cpp index 18a3ca4..4e83ad5 100644 --- a/Swiften/Network/BoostConnectionServer.cpp +++ b/Swiften/Network/BoostConnectionServer.cpp @@ -1,28 +1,64 @@ #include "Swiften/Network/BoostConnectionServer.h" #include <boost/bind.hpp> +#include <boost/system/system_error.hpp> #include "Swiften/EventLoop/MainEventLoop.h" namespace Swift { -BoostConnectionServer::BoostConnectionServer(int port, boost::asio::io_service* ioService) : acceptor_(*ioService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) { +BoostConnectionServer::BoostConnectionServer(int port, boost::asio::io_service* ioService) : port_(port), ioService_(ioService), acceptor_(NULL) { } void BoostConnectionServer::start() { - acceptNextConnection(); + try { + assert(!acceptor_); + acceptor_ = new boost::asio::ip::tcp::acceptor( + *ioService_, + boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port_)); + acceptNextConnection(); + } + catch (const boost::system::system_error& e) { + if (e.code() == boost::asio::error::address_in_use) { + MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), Conflict), shared_from_this()); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), UnknownError), shared_from_this()); + } + } +} + + +void BoostConnectionServer::stop() { + stop(boost::optional<Error>()); +} + +void BoostConnectionServer::stop(boost::optional<Error> e) { + if (acceptor_) { + acceptor_->close(); + acceptor_ = NULL; + } + MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), e), shared_from_this()); } void BoostConnectionServer::acceptNextConnection() { - boost::shared_ptr<BoostConnection> newConnection(new BoostConnection(&acceptor_.io_service())); - acceptor_.async_accept(newConnection->getSocket(), + boost::shared_ptr<BoostConnection> newConnection(new BoostConnection(&acceptor_->io_service())); + acceptor_->async_accept(newConnection->getSocket(), boost::bind(&BoostConnectionServer::handleAccept, shared_from_this(), newConnection, boost::asio::placeholders::error)); } void BoostConnectionServer::handleAccept(boost::shared_ptr<BoostConnection> newConnection, const boost::system::error_code& error) { - if (!error) { - MainEventLoop::postEvent(boost::bind(boost::ref(onNewConnection), newConnection), shared_from_this()); + if (error) { + MainEventLoop::postEvent( + boost::bind( + &BoostConnectionServer::stop, shared_from_this(), UnknownError), + shared_from_this()); + } + else { + MainEventLoop::postEvent( + boost::bind(boost::ref(onNewConnection), newConnection), + shared_from_this()); newConnection->listen(); acceptNextConnection(); } |