# HG changeset patch # User David Demelier # Date 1468933542 -7200 # Node ID d1afc6cc597444bb34e56435979bc5f98071b42a # Parent db2934ac95c7218fb218a1968b333570ed7836a6 Net: allow ownership and non-ownership in TlsSocket diff -r db2934ac95c7 -r d1afc6cc5974 modules/net/net.hpp --- a/modules/net/net.hpp Tue Jul 19 13:36:29 2016 +0200 +++ b/modules/net/net.hpp Tue Jul 19 15:05:42 2016 +0200 @@ -2021,6 +2021,9 @@ using Context = std::shared_ptr; using Ssl = std::unique_ptr; + // Determine if we created a TlsSocket from a temporary or a lvalue. + bool m_mustclose{false}; + Context m_context; Ssl m_ssl{nullptr, nullptr}; @@ -2058,16 +2061,7 @@ } } -public: - /** - * Wrap a socket around an existing one, takes ownership. - * - * \param sock the TCP socket - * \param mode the mode - * \param method the method - */ - inline TlsSocket(TcpSocket sock, Mode mode = Server, const SSL_METHOD *method = TLSv1_method()) - : Socket(std::move(sock)) + void create(Mode mode, const SSL_METHOD *method) { #if !defined(NET_NO_SSL_AUTO_INIT) ssl::init(); @@ -2083,6 +2077,55 @@ SSL_set_connect_state(m_ssl.get()); } +public: + /** + * Create a socket around an existing one. + * + * The original socket is moved to this instance and must not be used anymore. + * + * \param sock the TCP socket + * \param mode the mode + * \param method the method + */ + TlsSocket(TcpSocket &&sock, Mode mode = Server, const SSL_METHOD *method = TLSv1_method()) + : Socket(std::move(sock)) + , m_mustclose(true) + { + create(mode, method); + } + + /** + * Wrap a socket around an existing one without taking ownership. + * + * The original socket must still exist until this TlsSocket is closed. + * + * \param sock the TCP socket + * \param mode the mode + * \param method the method + */ + TlsSocket(TcpSocket &sock, Mode mode = Server, const SSL_METHOD *method = TLSv1_method()) + : Socket(sock.handle()) + { + create(mode, method); + } + + /** + * Destroy the socket if owned. + */ + ~TlsSocket() + { + /** + * If the socket has been created from a rvalue this class owns the + * socket and will close it in the parent destructor. + * + * Otherwise, when created from a lvalue, mark this socket as invalid + * to avoid double close'ing it as two sockets points to the same + * descriptor. + */ + if (!m_mustclose) + m_handle = Invalid; + } + /** * Get the type of socket. *