summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-05-20 17:00:33 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-05-20 17:00:33 +0200
commit96767ff85614974ff8c31686bce19001ec5cccd2 (patch)
treee9a66ebde9e6bfd2db81011e63d56834a8b4e943
parent776377bb21ee1cfe0bcdbc000f7c6fa0be227226 (diff)
downloadmad-96767ff85614974ff8c31686bce19001ec5cccd2.tar
mad-96767ff85614974ff8c31686bce19001ec5cccd2.zip
waitWhile-Methoden f?r Connection hinzugef?gt
-rw-r--r--src/Common/ClientConnection.cpp8
-rw-r--r--src/Common/ClientConnection.h3
-rw-r--r--src/Common/Connection.h2
-rw-r--r--src/Common/LogManager.cpp3
-rw-r--r--src/Net/ClientConnection.cpp2
-rw-r--r--src/Net/Connection.cpp12
-rw-r--r--src/Net/Connection.h36
-rw-r--r--src/Net/Listener.cpp2
-rw-r--r--src/Net/ThreadManager.cpp1
-rw-r--r--src/Server/ConnectionManager.cpp9
-rw-r--r--src/mad.cpp6
-rw-r--r--src/madc.cpp37
12 files changed, 83 insertions, 38 deletions
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<Logger*>(&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<boost::shared_mutex> 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<boost::shared_mutex> 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<void>::*)())&boost::signal0<void>::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<boost::shared_mutex> 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<uint8_t>(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<boost::uint8_t> 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<boost::asio::ip::tcp::socket> 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<boost::shared_mutex> lock(connectionLock);
+
+ while(_isConnecting())
+ stateChanged.wait(lock);
+ }
+
+ void waitWhileConnected() {
+ boost::shared_lock<boost::shared_mutex> 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<boost::shared_mutex> 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<Common::Connection> 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<const ServerConnection*>(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<Daemon::Requests::IdentifyRequest>(connection, sigc::ptr_fun(requestFinished), hostname);
Common::RequestManager::get()->sendRequest<Common::Requests::IdentifyRequest>(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 <readline/readline.h>
#include <readline/history.h>
+#include <boost/thread/condition_variable.hpp>
+
+
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<boost::mutex> 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<Common::Requests::IdentifyRequest>(connection, boost::bind(&commandFinished));
- while(commandRunning) {
- usleep(100000);
+ {
+ boost::unique_lock<boost::mutex> lock(commandMutex);
+ commandRunning = true;
+ Common::RequestManager::get()->sendRequest<Common::Requests::IdentifyRequest>(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<boost::mutex> 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) {