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/Common/ClientConnection.cpp | 8 ++++++++ src/Common/ClientConnection.h | 3 +++ src/Common/Connection.h | 2 -- src/Common/LogManager.cpp | 3 +++ 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 + src/Server/ConnectionManager.cpp | 9 +++------ src/mad.cpp | 6 ++---- src/madc.cpp | 37 ++++++++++++++++++++++++++----------- 12 files changed, 83 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/Common/ClientConnection.cpp b/src/Common/ClientConnection.cpp index d061c8d..ee9f5cf 100644 --- a/src/Common/ClientConnection.cpp +++ b/src/Common/ClientConnection.cpp @@ -45,6 +45,14 @@ bool ClientConnection::isConnected() const { return connection->isConnected(); } +void ClientConnection::waitWhileConnecting() const { + connection->waitWhileConnecting(); +} + +void ClientConnection::waitWhileConnected() const { + connection->waitWhileConnected(); +} + bool ClientConnection::disconnect() { connection->disconnect(); return true; diff --git a/src/Common/ClientConnection.h b/src/Common/ClientConnection.h index 4710bd4..a455c29 100644 --- a/src/Common/ClientConnection.h +++ b/src/Common/ClientConnection.h @@ -49,6 +49,9 @@ class ClientConnection : public Connection { bool isConnecting() const; bool isConnected() const; + void waitWhileConnecting() const; + void waitWhileConnected() const; + virtual bool disconnect(); //virtual void* getCertificate(size_t *size) const; //virtual void* getPeerCertificate(size_t *size) const; diff --git a/src/Common/Connection.h b/src/Common/Connection.h index 0cfc742..5ac46a2 100644 --- a/src/Common/Connection.h +++ b/src/Common/Connection.h @@ -65,8 +65,6 @@ class Connection { //virtual void* getCertificate(size_t *size) const = 0; //virtual void* getPeerCertificate(size_t *size) const = 0; - virtual - void setAuthenticated() { authenticated = true; } diff --git a/src/Common/LogManager.cpp b/src/Common/LogManager.cpp index b17d916..bd83a5e 100644 --- a/src/Common/LogManager.cpp +++ b/src/Common/LogManager.cpp @@ -73,6 +73,9 @@ void LogManager::configFinished() { if(loggers.empty()) registerLogger(static_cast(&consoleLogger)); + // TODO Debug + consoleLogger.Logger::setLevel(LoggerBase::DEBUG); + queueLock.lock(); configured = true; queueLock.unlock(); 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; diff --git a/src/Server/ConnectionManager.cpp b/src/Server/ConnectionManager.cpp index bbaf673..abb66b0 100644 --- a/src/Server/ConnectionManager.cpp +++ b/src/Server/ConnectionManager.cpp @@ -231,17 +231,14 @@ boost::shared_ptr ConnectionManager::getDaemonConnection(con } } - throw(Net::Exception::NOT_AVAILABLE); + throw Net::Exception(Net::Exception::NOT_AVAILABLE); } std::string ConnectionManager::getDaemonName(const Common::Connection *con) const throw (Net::Exception&) { const ServerConnection *connection = dynamic_cast(con); - if(connection) { - if(connection->isIdentified()) { - return connection->getHostInfo()->getName(); - } - } + if(connection && connection->getConnectionType() == ServerConnection::DAEMON) + return connection->getHostInfo()->getName(); throw Net::Exception(Net::Exception::UNKNOWN_DAEMON); } diff --git a/src/mad.cpp b/src/mad.cpp index 22a3b44..a5162c3 100644 --- a/src/mad.cpp +++ b/src/mad.cpp @@ -58,8 +58,7 @@ int main() { connection->connect(boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4::from_string("127.0.0.1"), 6666)); - while(connection->isConnecting()) - usleep(100000); + connection->waitWhileConnecting(); Common::RequestManager::get()->registerConnection(connection); @@ -72,8 +71,7 @@ int main() { //Common::RequestManager::get()->sendRequest(connection, sigc::ptr_fun(requestFinished), hostname); Common::RequestManager::get()->sendRequest(connection, &requestFinished, "test"); - while(connection->isConnected()) - usleep(100000); + connection->waitWhileConnected(); Common::LogManager::get()->unregisterLogger(networkLogger); diff --git a/src/madc.cpp b/src/madc.cpp index a902144..8499232 100644 --- a/src/madc.cpp +++ b/src/madc.cpp @@ -31,17 +31,25 @@ #include #include +#include + + using namespace Mad; static bool commandRunning = false; +static boost::mutex commandMutex; +static boost::condition_variable commandNotify; static void usage(const std::string &cmd) { std::cerr << "Usage: " << cmd << " address" << std::endl; } static void commandFinished() { + boost::lock_guard lock(commandMutex); commandRunning = false; + + commandNotify.notify_one(); } int main(int argc, char *argv[]) { @@ -62,15 +70,17 @@ int main(int argc, char *argv[]) { std::cerr << "Connecting to " << argv[1] << "..." << std::flush; - while(connection->isConnecting()) - usleep(100000); + connection->waitWhileConnecting(); Common::RequestManager::get()->registerConnection(connection); - commandRunning = true; - Common::RequestManager::get()->sendRequest(connection, boost::bind(&commandFinished)); - while(commandRunning) { - usleep(100000); + { + boost::unique_lock lock(commandMutex); + commandRunning = true; + Common::RequestManager::get()->sendRequest(connection, boost::bind(&commandFinished)); + while(commandRunning) { + commandNotify.wait(lock); + } } std::cerr << " connected." << std::endl; @@ -86,23 +96,28 @@ int main(int argc, char *argv[]) { Client::CommandParser::get()->setConnection(connection); Client::CommandManager::get()->signalFinished().connect(&commandFinished); - while(connection->isConnected()) { + while(connection->isConnected() && !Client::CommandManager::get()->willDisconnect()) { char *cmd = readline("mad> "); + boost::unique_lock lock(commandMutex); + if(!cmd) { - commandRunning = true; Client::CommandParser::get()->requestDisconnect(); } else if(*cmd) { - commandRunning = true; Client::CommandParser::get()->parse(cmd); add_history(cmd); } + else continue; - while(Client::CommandManager::get()->requestsActive()) - usleep(100000); + commandRunning = Client::CommandManager::get()->requestsActive(); + + while(commandRunning) + commandNotify.wait(lock); } + connection->waitWhileConnected(); + Common::RequestManager::get()->unregisterConnection(connection); } catch(Net::Exception &e) { -- cgit v1.2.3