summaryrefslogtreecommitdiffstats
path: root/src/Net
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-05-30 13:37:06 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-05-30 13:37:06 +0200
commita77d2d1e08e4e2e8dfb5e4fc326f6c8fe315a898 (patch)
tree36a4c899af336c7e9dc326da7231d4d9e17e8a1b /src/Net
parentcb8e66c1b1f1c8076053d71347d0b1f96ca0bca1 (diff)
downloadmad-a77d2d1e08e4e2e8dfb5e4fc326f6c8fe315a898.tar
mad-a77d2d1e08e4e2e8dfb5e4fc326f6c8fe315a898.zip
Thread-sichere Signale implementiert
Diffstat (limited to 'src/Net')
-rw-r--r--src/Net/Connection.cpp8
-rw-r--r--src/Net/Connection.h32
-rw-r--r--src/Net/Listener.cpp15
-rw-r--r--src/Net/Listener.h11
-rw-r--r--src/Net/Signals/Connection.h45
-rw-r--r--src/Net/Signals/Signal0.h43
-rw-r--r--src/Net/Signals/Signal1.h41
-rw-r--r--src/Net/Signals/Signal2.h41
-rw-r--r--src/Net/Signals/SignalBase.h80
-rw-r--r--src/Net/Signals/Signals.h27
10 files changed, 321 insertions, 22 deletions
diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp
index 2f65bb0..1ff9926 100644
--- a/src/Net/Connection.cpp
+++ b/src/Net/Connection.cpp
@@ -55,7 +55,7 @@ void Connection::handleHandshake(const boost::system::error_code& error) {
received = 0;
}
- ThreadManager::get()->pushWork(boost::bind((void (boost::signal0<void>::*)())&boost::signal0<void>::operator(), &connectedSignal));
+ ThreadManager::get()->pushWork(boost::bind(&Signals::Signal0<void>::emit, &connectedSignal));
enterReceiveLoop();
}
@@ -69,7 +69,7 @@ void Connection::handleShutdown(const boost::system::error_code& error) {
_setState(DISCONNECTED);
- ThreadManager::get()->pushWork(boost::bind((void (boost::signal0<void>::*)())&boost::signal0<void>::operator(), &disconnectedSignal));
+ ThreadManager::get()->pushWork(boost::bind(&Signals::Signal0<void>::emit, &disconnectedSignal));
}
void Connection::enterReceiveLoop() {
@@ -91,7 +91,7 @@ void Connection::handleHeaderReceive(const std::vector<boost::uint8_t> &data) {
}
if(header.length == 0) {
- ThreadManager::get()->pushWork(boost::bind((void (boost::signal1<void, const Packet&>::*)(const Packet&))&boost::signal1<void, const Packet&>::operator(), &receiveSignal, Packet(ntohs(header.requestId))));
+ ThreadManager::get()->pushWork(boost::bind(&Signals::Signal1<void, const Packet&>::emit, &receiveSignal, Packet(ntohs(header.requestId))));
enterReceiveLoop();
}
@@ -105,7 +105,7 @@ void Connection::handleDataReceive(const std::vector<boost::uint8_t> &data) {
boost::upgrade_lock<boost::shared_mutex> lock(connectionLock);
Packet packet(ntohs(header.requestId), data.data(), ntohs(header.length));
- ThreadManager::get()->pushWork(boost::bind((void (boost::signal1<void, const Packet&>::*)(const Packet&))&boost::signal1<void, const Packet&>::operator(), &receiveSignal, packet));
+ ThreadManager::get()->pushWork(boost::bind(&Signals::Signal1<void, const Packet&>::emit, &receiveSignal, packet));
}
enterReceiveLoop();
diff --git a/src/Net/Connection.h b/src/Net/Connection.h
index 6678bd9..cda8bfe 100644
--- a/src/Net/Connection.h
+++ b/src/Net/Connection.h
@@ -23,12 +23,11 @@
#include <config.h>
#include "Packet.h"
+#include "Signals/Signals.h"
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
-#include <boost/signal.hpp>
-
#include <boost/thread/shared_mutex.hpp>
namespace Mad {
@@ -71,9 +70,9 @@ class Connection : boost::noncopyable {
Packet::Data header;
- boost::signal1<void, const Packet&> receiveSignal;
- boost::signal0<void> connectedSignal;
- boost::signal0<void> disconnectedSignal;
+ Signals::Signal1<void, const Packet&> receiveSignal;
+ Signals::Signal0<void> connectedSignal;
+ Signals::Signal0<void> disconnectedSignal;
bool receiving;
unsigned long sending;
@@ -172,9 +171,26 @@ class Connection : boost::noncopyable {
bool send(const Packet &packet);
- boost::signal1<void, const Packet&>& signalReceive() {return receiveSignal;}
- boost::signal0<void>& signalConnected() {return connectedSignal;}
- boost::signal0<void>& signalDisconnected() {return disconnectedSignal;}
+ Signals::Connection connectSignalReceive(const Signals::Signal1<void, const Packet&>::slot_type &slot) {
+ return receiveSignal.connect(slot);
+ }
+ void disconnectSignalReceive(const Signals::Connection &connection) {
+ receiveSignal.disconnect(connection);
+ }
+
+ Signals::Connection connectSignalConnected(const Signals::Signal0<void>::slot_type &slot) {
+ return connectedSignal.connect(slot);
+ }
+ void disconnectSignalConnected(const Signals::Connection &connection) {
+ connectedSignal.disconnect(connection);
+ }
+
+ Signals::Connection connectSignalDisconnected(const Signals::Signal0<void>::slot_type &slot) {
+ return disconnectedSignal.connect(slot);
+ }
+ void disconnectSignalDisconnected(const Signals::Connection &connection) {
+ disconnectedSignal.disconnect(connection);
+ }
};
}
diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp
index be227fd..6da2762 100644
--- a/src/Net/Listener.cpp
+++ b/src/Net/Listener.cpp
@@ -39,8 +39,8 @@ void Listener::handleAccept(const boost::system::error_code &error, boost::share
con->_setState(Connection::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));
+ Signals::Connection con1 = con->connectSignalConnected(boost::bind(&Listener::handleConnect, this, con));
+ Signals::Connection con2 = con->connectSignalDisconnected(boost::bind(&Listener::handleDisconnect, this, con));
connections.insert(std::make_pair(con, std::make_pair(con1, con2)));
@@ -54,18 +54,19 @@ void Listener::handleAccept(const boost::system::error_code &error, boost::share
void Listener::handleConnect(boost::shared_ptr<Connection> con) {
{
boost::lock_guard<boost::mutex> lock(mutex);
- std::map<boost::shared_ptr<Connection>, std::pair<boost::signals::connection, boost::signals::connection> >::iterator it = connections.find(con);
+ std::map<boost::shared_ptr<Connection>, std::pair<Signals::Connection, Signals::Connection> >::iterator it = connections.find(con);
if(it == connections.end())
return;
// Disconnect signal handlers
- it->second.first.disconnect();
- it->second.second.disconnect();
+
+ con->disconnectSignalConnected(it->second.first);
+ con->disconnectSignalDisconnected(it->second.second);
connections.erase(it);
}
- signal(con);
+ signal.emit(con);
}
void Listener::handleDisconnect(boost::shared_ptr<Connection> con) {
@@ -92,7 +93,7 @@ sslContext(Connection::ioService, boost::asio::ssl::context::sslv23)
}
Listener::~Listener() {
- for(std::map<boost::shared_ptr<Connection>,std::pair<boost::signals::connection, boost::signals::connection> >::iterator con = connections.begin(); con != connections.end(); ++con) {
+ for(std::map<boost::shared_ptr<Connection>,std::pair<Signals::Connection, Signals::Connection> >::iterator con = connections.begin(); con != connections.end(); ++con) {
con->first->disconnect();
// TODO wait...
}
diff --git a/src/Net/Listener.h b/src/Net/Listener.h
index 903c907..ec0cd22 100644
--- a/src/Net/Listener.h
+++ b/src/Net/Listener.h
@@ -38,9 +38,9 @@ class Listener : boost::noncopyable {
boost::asio::ip::tcp::acceptor acceptor;
boost::asio::ssl::context sslContext;
- std::map<boost::shared_ptr<Connection>, std::pair<boost::signals::connection, boost::signals::connection> > connections;
+ std::map<boost::shared_ptr<Connection>, std::pair<Signals::Connection, Signals::Connection> > connections;
- boost::signal1<void, boost::shared_ptr<Connection> > signal;
+ Signals::Signal1<void, boost::shared_ptr<Connection> > signal;
void handleAccept(const boost::system::error_code &error, boost::shared_ptr<Connection> con);
@@ -52,7 +52,12 @@ class Listener : boost::noncopyable {
const boost::asio::ip::tcp::endpoint &address0 = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 6666)) throw(Exception);
virtual ~Listener();
- boost::signal1<void, boost::shared_ptr<Connection> >& signalNewConnection() {return signal;}
+ Signals::Connection connectSignalNewConnection(const Signals::Signal1<void, boost::shared_ptr<Connection> >::slot_type &slot) {
+ return signal.connect(slot);
+ }
+ void disconnectSignalNewConnection(const Signals::Connection &connection) {
+ signal.disconnect(connection);
+ }
};
}
diff --git a/src/Net/Signals/Connection.h b/src/Net/Signals/Connection.h
new file mode 100644
index 0000000..0e66611
--- /dev/null
+++ b/src/Net/Signals/Connection.h
@@ -0,0 +1,45 @@
+/*
+ * Connection.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_NET_SIGNALS_CONNECTION_H_
+#define MAD_NET_SIGNALS_CONNECTION_H_
+
+#include <boost/signals/connection.hpp>
+
+namespace Mad {
+namespace Net {
+namespace Signals {
+
+template <typename SignalType, typename FunctionType> class SignalBase;
+
+class Connection {
+ private:
+ template <typename SignalType, typename FunctionType> friend class SignalBase;
+
+ boost::signals::connection connection;
+
+ Connection(const boost::signals::connection &connection0)
+ : connection(connection0) {}
+};
+
+}
+}
+}
+
+#endif /* MAD_NET_SIGNALS_CONNECTION_H_ */
diff --git a/src/Net/Signals/Signal0.h b/src/Net/Signals/Signal0.h
new file mode 100644
index 0000000..32859ab
--- /dev/null
+++ b/src/Net/Signals/Signal0.h
@@ -0,0 +1,43 @@
+/*
+ * Signal0.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_NET_SIGNALS_SIGNAL0_H_
+#define MAD_NET_SIGNALS_SIGNAL0_H_
+
+#include "SignalBase.h"
+
+namespace Mad {
+namespace Net {
+namespace Signals {
+
+template <typename R>
+class Signal0 : public SignalBase<boost::signal0<R>, boost::function0<R> > {
+ public:
+ R emit() {
+ boost::lock_guard<boost::recursive_mutex> lock(SignalBase<boost::signal0<R>, boost::function0<R> >::mutex);
+
+ return SignalBase<boost::signal0<R>, boost::function0<R> >::signal();
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_NET_SIGNALS_SIGNAL0_H_ */
diff --git a/src/Net/Signals/Signal1.h b/src/Net/Signals/Signal1.h
new file mode 100644
index 0000000..78eaa47
--- /dev/null
+++ b/src/Net/Signals/Signal1.h
@@ -0,0 +1,41 @@
+/*
+ * Signal1.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_NET_SIGNALS_SIGNAL1_H_
+#define MAD_NET_SIGNALS_SIGNAL1_H_
+
+namespace Mad {
+namespace Net {
+namespace Signals {
+
+template <typename R, typename T1>
+class Signal1 : public SignalBase<boost::signal1<R, T1>, boost::function1<R, T1> > {
+ public:
+ R emit(T1 arg1) {
+ boost::lock_guard<boost::recursive_mutex> lock(SignalBase<boost::signal1<R, T1>, boost::function1<R, T1> >::mutex);
+
+ return SignalBase<boost::signal1<R, T1>, boost::function1<R, T1> >::signal(arg1);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_NET_SIGNALS_SIGNAL1_H_ */
diff --git a/src/Net/Signals/Signal2.h b/src/Net/Signals/Signal2.h
new file mode 100644
index 0000000..afa528e
--- /dev/null
+++ b/src/Net/Signals/Signal2.h
@@ -0,0 +1,41 @@
+/*
+ * Signal2.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_NET_SIGNALS_SIGNAL2_H_
+#define MAD_NET_SIGNALS_SIGNAL2_H_
+
+namespace Mad {
+namespace Net {
+namespace Signals {
+
+template <typename R, typename T1, typename T2>
+class Signal2 : public SignalBase<boost::signal2<R, T1, T2>, boost::function2<R, T1, T2> > {
+ public:
+ R emit(T1 arg1, T2 arg2) {
+ boost::lock_guard<boost::recursive_mutex> lock(SignalBase<boost::signal2<R, T1, T2>, boost::function2<R, T1, T2> >::mutex);
+
+ return SignalBase<boost::signal2<R, T1, T2>, boost::function2<R, T1, T2> >::signal(arg1, arg2);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_NET_SIGNALS_SIGNAL2_H_ */
diff --git a/src/Net/Signals/SignalBase.h b/src/Net/Signals/SignalBase.h
new file mode 100644
index 0000000..fc5f2c6
--- /dev/null
+++ b/src/Net/Signals/SignalBase.h
@@ -0,0 +1,80 @@
+/*
+ * SignalBase.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_SIGNALS_SIGNALBASE_H_
+#define MAD_SIGNALS_SIGNALBASE_H_
+
+#include "Connection.h"
+
+#include <set>
+#include <boost/signals.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+
+namespace Mad {
+namespace Net {
+namespace Signals {
+
+template <typename SignalType, typename FunctionType>
+class SignalBase : private boost::noncopyable {
+ public:
+ typedef boost::slot<FunctionType> slot_type;
+
+ protected:
+ typedef SignalType signal_type;
+
+ std::set<boost::signals::connection> connections;
+ boost::recursive_mutex mutex;
+
+ signal_type signal;
+
+ SignalBase() {}
+ ~SignalBase() {
+ // Wait for other threads
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
+ }
+
+ public:
+ Connection connect(const slot_type &slot) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
+
+ boost::signals::connection con(signal.connect(slot));
+
+ connections.insert(con);
+ return con;
+ }
+
+ void disconnect(const Connection &connection) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
+
+ std::set<boost::signals::connection>::iterator it = connections.find(connection.connection);
+
+ if(it == connections.end())
+ return;
+
+ it->disconnect();
+ connections.erase(it);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_SIGNALS_SIGNALBASE_H_ */
diff --git a/src/Net/Signals/Signals.h b/src/Net/Signals/Signals.h
new file mode 100644
index 0000000..4ee4f95
--- /dev/null
+++ b/src/Net/Signals/Signals.h
@@ -0,0 +1,27 @@
+/*
+ * Signals.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_SIGNALS_SIGNALS_H_
+#define MAD_SIGNALS_SIGNALS_H_
+
+#include "Signal0.h"
+#include "Signal1.h"
+#include "Signal2.h"
+
+#endif /* MAD_SIGNALS_SIGNALS_H_ */