From 96767ff85614974ff8c31686bce19001ec5cccd2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 20 May 2009 17:00:33 +0200 Subject: waitWhile-Methoden f?r Connection hinzugef?gt --- src/Net/ClientConnection.cpp | 2 +- src/Net/Connection.cpp | 12 ++++++------ src/Net/Connection.h | 36 +++++++++++++++++++++++++++++------- src/Net/Listener.cpp | 2 +- src/Net/ThreadManager.cpp | 1 + 5 files changed, 38 insertions(+), 15 deletions(-) (limited to 'src/Net') diff --git a/src/Net/ClientConnection.cpp b/src/Net/ClientConnection.cpp index 9cdf796..07a9121 100644 --- a/src/Net/ClientConnection.cpp +++ b/src/Net/ClientConnection.cpp @@ -45,7 +45,7 @@ void ClientConnection::connect(const boost::asio::ip::tcp::endpoint &address) th } peer = address; - state = CONNECT; + _setState(CONNECT); socket.lowest_layer().async_connect(address, boost::bind(&ClientConnection::handleConnect, this, boost::asio::placeholders::error)); } diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp index b9691cb..2f65bb0 100644 --- a/src/Net/Connection.cpp +++ b/src/Net/Connection.cpp @@ -47,7 +47,7 @@ void Connection::handleHandshake(const boost::system::error_code& error) { { boost::lock_guard lock(connectionLock); - state = CONNECTED; + _setState(CONNECTED); receiving = false; sending = 0; @@ -64,10 +64,11 @@ void Connection::handleShutdown(const boost::system::error_code& error) { boost::lock_guard lock(connectionLock); if(error) { - // TODO Error + Common::Logger::logf(Common::Logger::VERBOSE, "Shutdown error: %s", error.message().c_str()); } - state = DISCONNECTED; + _setState(DISCONNECTED); + ThreadManager::get()->pushWork(boost::bind((void (boost::signal0::*)())&boost::signal0::operator(), &disconnectedSignal)); } @@ -223,7 +224,7 @@ void Connection::disconnect() { if(!_isConnected() || _isDisconnecting()) return; - state = DISCONNECT; + _setState(DISCONNECT); if(sending) return; @@ -235,8 +236,7 @@ void Connection::disconnect() { void Connection::doDisconnect() { boost::lock_guard lock(connectionLock); - if(_isConnected()) - socket.async_shutdown(boost::bind(&Connection::handleShutdown, this, boost::asio::placeholders::error)); + socket.async_shutdown(boost::bind(&Connection::handleShutdown, this, boost::asio::placeholders::error)); } } diff --git a/src/Net/Connection.h b/src/Net/Connection.h index 303485d..625fc94 100644 --- a/src/Net/Connection.h +++ b/src/Net/Connection.h @@ -37,9 +37,14 @@ namespace Net { class ThreadManager; class Connection : boost::noncopyable { - private: + protected: friend class ThreadManager; + enum State { + DISCONNECTED, CONNECT, CONNECTED, DISCONNECT + }; + + private: class Buffer { public: Buffer(const uint8_t *data0, std::size_t length) : data(new std::vector(data0, data0+length)), buffer(boost::asio::buffer(*data)) {} @@ -55,6 +60,9 @@ class Connection : boost::noncopyable { boost::asio::const_buffer buffer; }; + boost::condition_variable_any stateChanged; + + State state; std::vector receiveBuffer; std::size_t received; @@ -86,11 +94,6 @@ class Connection : boost::noncopyable { boost::shared_mutex connectionLock; - enum State { - DISCONNECTED, CONNECT, CONNECTED, DISCONNECT - } state; - - boost::asio::ssl::stream socket; boost::asio::ip::tcp::endpoint peer; @@ -105,10 +108,15 @@ class Connection : boost::noncopyable { return (state == DISCONNECT); } + void _setState(State newState) { + state = newState; + stateChanged.notify_all(); + } + void doDisconnect(); Connection(boost::asio::ssl::context &sslContext) : - receiveBuffer(1024*1024), state(DISCONNECTED), socket(ioService, sslContext) {} + state(DISCONNECTED), receiveBuffer(1024*1024), socket(ioService, sslContext) {} public: virtual ~Connection(); @@ -128,6 +136,20 @@ class Connection : boost::noncopyable { return _isDisconnecting(); } + void waitWhileConnecting() { + boost::shared_lock lock(connectionLock); + + while(_isConnecting()) + stateChanged.wait(lock); + } + + void waitWhileConnected() { + boost::shared_lock lock(connectionLock); + + while(_isConnected()) + stateChanged.wait(lock); + } + /*const gnutls_datum_t* getCertificate() const { // TODO Thread-safeness return gnutls_certificate_get_ours(session); diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp index 6f49a74..16689db 100644 --- a/src/Net/Listener.cpp +++ b/src/Net/Listener.cpp @@ -35,7 +35,7 @@ void Listener::handleAccept(const boost::system::error_code &error, boost::share { boost::lock_guard lock(con->connectionLock); - con->state = ServerConnection::CONNECT; + con->_setState(ServerConnection::CONNECT); boost::signals::connection con1 = con->signalConnected().connect(boost::bind(&Listener::handleConnect, this, con)); boost::signals::connection con2 = con->signalDisconnected().connect(boost::bind(&Listener::handleDisconnect, this, con)); diff --git a/src/Net/ThreadManager.cpp b/src/Net/ThreadManager.cpp index 0fb0716..d24ba01 100644 --- a/src/Net/ThreadManager.cpp +++ b/src/Net/ThreadManager.cpp @@ -133,6 +133,7 @@ void ThreadManager::doDeinit() { // IO thread is next ioWorker.reset(); + Connection::ioService.stop(); ioThread->join(); delete ioThread; -- cgit v1.2.3