Browse Source

Made websocket use weak bind

Paul-Louis Ageneau 5 years ago
parent
commit
661137aa6e
3 changed files with 63 additions and 57 deletions
  1. 12 1
      include/rtc/include.hpp
  2. 1 18
      src/peerconnection.cpp
  3. 50 38
      src/websocket.cpp

+ 12 - 1
include/rtc/include.hpp

@@ -60,10 +60,21 @@ const uint16_t DEFAULT_SCTP_PORT = 5000; // SCTP port to use by default
 const size_t DEFAULT_MAX_MESSAGE_SIZE = 65536;    // Remote max message size if not specified in SDP
 const size_t LOCAL_MAX_MESSAGE_SIZE = 256 * 1024; // Local max message size
 
-
+// overloaded helper
 template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
 template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
 
+// weak_ptr bind helper
+template <typename F, typename T, typename... Args> auto weak_bind(F &&f, T *t, Args &&... _args) {
+	return [bound = std::bind(f, t, _args...), weak_this = t->weak_from_this()](auto &&... args) {
+		using result_type = typename decltype(bound)::result_type;
+		if (auto shared_this = weak_this.lock())
+			return bound(args...);
+		else
+			return (result_type) false;
+	};
+}
+
 template <typename... P> class synchronized_callback {
 public:
 	synchronized_callback() = default;

+ 1 - 18
src/peerconnection.cpp

@@ -32,23 +32,6 @@ using namespace std::placeholders;
 using std::shared_ptr;
 using std::weak_ptr;
 
-template <typename F, typename T, typename... Args> auto weak_bind(F &&f, T *t, Args &&... _args) {
-	return [bound = std::bind(f, t, _args...), weak_this = t->weak_from_this()](auto &&... args) {
-		if (auto shared_this = weak_this.lock())
-			bound(args...);
-	};
-}
-
-template <typename F, typename T, typename... Args>
-auto weak_bind_verifier(F &&f, T *t, Args &&... _args) {
-	return [bound = std::bind(f, t, _args...), weak_this = t->weak_from_this()](auto &&... args) {
-		if (auto shared_this = weak_this.lock())
-			return bound(args...);
-		else
-			return false;
-	};
-}
-
 PeerConnection::PeerConnection() : PeerConnection(Configuration()) {}
 
 PeerConnection::PeerConnection(const Configuration &config)
@@ -270,7 +253,7 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
 
 		auto lower = std::atomic_load(&mIceTransport);
 		auto transport = std::make_shared<DtlsTransport>(
-		    lower, mCertificate, weak_bind_verifier(&PeerConnection::checkFingerprint, this, _1),
+		    lower, mCertificate, weak_bind(&PeerConnection::checkFingerprint, this, _1),
 		    [this, weak_this = weak_from_this()](DtlsTransport::State state) {
 			    auto shared_this = weak_this.lock();
 			    if (!shared_this)

+ 50 - 38
src/websocket.cpp

@@ -151,26 +151,30 @@ std::shared_ptr<TcpTransport> WebSocket::initTcpTransport() {
 		if (auto transport = std::atomic_load(&mTcpTransport))
 			return transport;
 
-		auto transport = std::make_shared<TcpTransport>(mHostname, mService, [this](State state) {
-			switch (state) {
-			case State::Connected:
-				if (mScheme == "ws")
-					initWsTransport();
-				else
-					initTlsTransport();
-				break;
-			case State::Failed:
-				triggerError("TCP connection failed");
-				remoteClose();
-				break;
-			case State::Disconnected:
-				remoteClose();
-				break;
-			default:
-				// Ignore
-				break;
-			}
-		});
+		auto transport = std::make_shared<TcpTransport>(
+		    mHostname, mService, [this, weak_this = weak_from_this()](State state) {
+			    auto shared_this = weak_this.lock();
+			    if (!shared_this)
+				    return;
+			    switch (state) {
+			    case State::Connected:
+				    if (mScheme == "ws")
+					    initWsTransport();
+				    else
+					    initTlsTransport();
+				    break;
+			    case State::Failed:
+				    triggerError("TCP connection failed");
+				    remoteClose();
+				    break;
+			    case State::Disconnected:
+				    remoteClose();
+				    break;
+			    default:
+				    // Ignore
+				    break;
+			    }
+		    });
 		std::atomic_store(&mTcpTransport, transport);
 		if (mState == WebSocket::State::Closed) {
 			mTcpTransport.reset();
@@ -193,23 +197,27 @@ std::shared_ptr<TlsTransport> WebSocket::initTlsTransport() {
 			return transport;
 
 		auto lower = std::atomic_load(&mTcpTransport);
-		auto transport = std::make_shared<TlsTransport>(lower, mHost, [this](State state) {
-			switch (state) {
-			case State::Connected:
-				initWsTransport();
-				break;
-			case State::Failed:
-				triggerError("TCP connection failed");
-				remoteClose();
-				break;
-			case State::Disconnected:
-				remoteClose();
-				break;
-			default:
-				// Ignore
-				break;
-			}
-		});
+		auto transport = std::make_shared<TlsTransport>(
+		    lower, mHost, [this, weak_this = weak_from_this()](State state) {
+			    auto shared_this = weak_this.lock();
+			    if (!shared_this)
+				    return;
+			    switch (state) {
+			    case State::Connected:
+				    initWsTransport();
+				    break;
+			    case State::Failed:
+				    triggerError("TCP connection failed");
+				    remoteClose();
+				    break;
+			    case State::Disconnected:
+				    remoteClose();
+				    break;
+			    default:
+				    // Ignore
+				    break;
+			    }
+		    });
 		std::atomic_store(&mTlsTransport, transport);
 		if (mState == WebSocket::State::Closed) {
 			mTlsTransport.reset();
@@ -235,7 +243,11 @@ std::shared_ptr<WsTransport> WebSocket::initWsTransport() {
 		if (!lower)
 			lower = std::atomic_load(&mTcpTransport);
 		auto transport = std::make_shared<WsTransport>(
-		    lower, mHost, mPath, std::bind(&WebSocket::incoming, this, _1), [this](State state) {
+		    lower, mHost, mPath, weak_bind(&WebSocket::incoming, this, _1),
+		    [this, weak_this = weak_from_this()](State state) {
+			    auto shared_this = weak_this.lock();
+			    if (!shared_this)
+				    return;
 			    switch (state) {
 			    case State::Connected:
 				    if (mState == WebSocket::State::Connecting) {