unique_ptr for sockets
This commit is contained in:
		| @@ -1,6 +1,10 @@ | ||||
| # Changelog | ||||
| All changes to this project will be documented in this file. | ||||
|  | ||||
| ## [9.0.2] - 2020-03-24 | ||||
|  | ||||
| (socket) works with unique_ptr<Socket> instead of shared_ptr<Socket> in many places | ||||
|  | ||||
| ## [9.0.1] - 2020-03-24 | ||||
|  | ||||
| (socket) selectInterrupt member is an unique_ptr instead of being a shared_ptr | ||||
|   | ||||
| @@ -9,7 +9,6 @@ | ||||
| #include <cstring> | ||||
| #include <iomanip> | ||||
| #include <iostream> | ||||
| #include <ixwebsocket/IXSocket.h> | ||||
| #include <ixwebsocket/IXSocketFactory.h> | ||||
| #include <ixwebsocket/IXSocketTLSOptions.h> | ||||
| #include <sstream> | ||||
|   | ||||
| @@ -11,10 +11,10 @@ | ||||
| #include <memory> | ||||
| #include <string> | ||||
|  | ||||
| #include <ixwebsocket/IXSocket.h> | ||||
|  | ||||
| namespace ix | ||||
| { | ||||
|     class Socket; | ||||
|  | ||||
|     class RedisClient | ||||
|     { | ||||
|     public: | ||||
| @@ -57,7 +57,7 @@ namespace ix | ||||
|     private: | ||||
|         std::string writeString(const std::string& str); | ||||
|  | ||||
|         std::shared_ptr<Socket> _socket; | ||||
|         std::unique_ptr<Socket> _socket; | ||||
|         std::atomic<bool> _stop; | ||||
|     }; | ||||
| } // namespace ix | ||||
|   | ||||
| @@ -43,7 +43,7 @@ namespace ix | ||||
|         SocketServer::stop(); | ||||
|     } | ||||
|  | ||||
|     void RedisServer::handleConnection(std::shared_ptr<Socket> socket, | ||||
|     void RedisServer::handleConnection(std::unique_ptr<Socket> socket, | ||||
|                                        std::shared_ptr<ConnectionState> connectionState) | ||||
|     { | ||||
|         _connectedClientsCount++; | ||||
| @@ -102,13 +102,13 @@ namespace ix | ||||
|         _connectedClientsCount--; | ||||
|     } | ||||
|  | ||||
|     void RedisServer::cleanupSubscribers(std::shared_ptr<Socket> socket) | ||||
|     void RedisServer::cleanupSubscribers(std::unique_ptr<Socket>& socket) | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(_mutex); | ||||
|  | ||||
|         for (auto&& it : _subscribers) | ||||
|         { | ||||
|             it.second.erase(socket); | ||||
|             it.second.erase(socket.get()); | ||||
|         } | ||||
|  | ||||
|         for (auto it : _subscribers) | ||||
| @@ -145,7 +145,7 @@ namespace ix | ||||
|     } | ||||
|  | ||||
|     bool RedisServer::parseRequest( | ||||
|         std::shared_ptr<Socket> socket, | ||||
|         std::unique_ptr<Socket>& socket, | ||||
|         std::vector<std::string>& tokens) | ||||
|     { | ||||
|         // Parse first line | ||||
| @@ -191,7 +191,7 @@ namespace ix | ||||
|     } | ||||
|  | ||||
|     bool RedisServer::handleCommand( | ||||
|         std::shared_ptr<Socket> socket, | ||||
|         std::unique_ptr<Socket>& socket, | ||||
|         const std::vector<std::string>& tokens) | ||||
|     { | ||||
|         if (tokens.size() != 1) return false; | ||||
| @@ -230,7 +230,7 @@ namespace ix | ||||
|     } | ||||
|  | ||||
|     bool RedisServer::handleSubscribe( | ||||
|         std::shared_ptr<Socket> socket, | ||||
|         std::unique_ptr<Socket>& socket, | ||||
|         const std::vector<std::string>& tokens) | ||||
|     { | ||||
|         if (tokens.size() != 2) return false; | ||||
| @@ -245,13 +245,13 @@ namespace ix | ||||
|         socket->writeBytes(":1\r\n", cb); | ||||
|  | ||||
|         std::lock_guard<std::mutex> lock(_mutex); | ||||
|         _subscribers[channel].insert(socket); | ||||
|         _subscribers[channel].insert(socket.get()); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     bool RedisServer::handlePublish( | ||||
|         std::shared_ptr<Socket> socket, | ||||
|         std::unique_ptr<Socket>& socket, | ||||
|         const std::vector<std::string>& tokens) | ||||
|     { | ||||
|         if (tokens.size() != 3) return false; | ||||
|   | ||||
| @@ -37,13 +37,13 @@ namespace ix | ||||
|         // Subscribers | ||||
|         // We could store connection states in there, to add better debugging | ||||
|         // since a connection state has a readable ID | ||||
|         std::map<std::string, std::set<std::shared_ptr<Socket>>> _subscribers; | ||||
|         std::map<std::string, std::set<Socket*>> _subscribers; | ||||
|         std::mutex _mutex; | ||||
|  | ||||
|         std::atomic<bool> _stopHandlingConnections; | ||||
|  | ||||
|         // Methods | ||||
|         virtual void handleConnection(std::shared_ptr<Socket>, | ||||
|         virtual void handleConnection(std::unique_ptr<Socket>, | ||||
|                                       std::shared_ptr<ConnectionState> connectionState) final; | ||||
|         virtual size_t getConnectedClientsCount() final; | ||||
|  | ||||
| @@ -51,18 +51,18 @@ namespace ix | ||||
|         std::string writeString(const std::string& str); | ||||
|  | ||||
|         bool parseRequest( | ||||
|             std::shared_ptr<Socket> socket, | ||||
|             std::unique_ptr<Socket>& socket, | ||||
|             std::vector<std::string>& tokens); | ||||
|  | ||||
|         bool handlePublish(std::shared_ptr<Socket> socket, | ||||
|         bool handlePublish(std::unique_ptr<Socket>& socket, | ||||
|                            const std::vector<std::string>& tokens); | ||||
|  | ||||
|         bool handleSubscribe(std::shared_ptr<Socket> socket, | ||||
|         bool handleSubscribe(std::unique_ptr<Socket>& socket, | ||||
|                              const std::vector<std::string>& tokens); | ||||
|  | ||||
|         bool handleCommand(std::shared_ptr<Socket> socket, | ||||
|         bool handleCommand(std::unique_ptr<Socket>& socket, | ||||
|                            const std::vector<std::string>& tokens); | ||||
|  | ||||
|         void cleanupSubscribers(std::shared_ptr<Socket> socket); | ||||
|         void cleanupSubscribers(std::unique_ptr<Socket>& socket); | ||||
|     }; | ||||
| } // namespace ix | ||||
|   | ||||
| @@ -92,7 +92,7 @@ namespace ix | ||||
|         return std::make_tuple(method, requestUri, httpVersion); | ||||
|     } | ||||
|  | ||||
|     std::tuple<bool, std::string, HttpRequestPtr> Http::parseRequest(std::shared_ptr<Socket> socket) | ||||
|     std::tuple<bool, std::string, HttpRequestPtr> Http::parseRequest(std::unique_ptr<Socket>& socket) | ||||
|     { | ||||
|         HttpRequestPtr httpRequest; | ||||
|  | ||||
| @@ -133,7 +133,7 @@ namespace ix | ||||
|         return std::make_tuple(true, "", httpRequest); | ||||
|     } | ||||
|  | ||||
|     bool Http::sendResponse(HttpResponsePtr response, std::shared_ptr<Socket> socket) | ||||
|     bool Http::sendResponse(HttpResponsePtr response, std::unique_ptr<Socket>& socket) | ||||
|     { | ||||
|         // Write the response to the socket | ||||
|         std::stringstream ss; | ||||
|   | ||||
| @@ -115,8 +115,8 @@ namespace ix | ||||
|     { | ||||
|     public: | ||||
|         static std::tuple<bool, std::string, HttpRequestPtr> parseRequest( | ||||
|             std::shared_ptr<Socket> socket); | ||||
|         static bool sendResponse(HttpResponsePtr response, std::shared_ptr<Socket> socket); | ||||
|             std::unique_ptr<Socket>& socket); | ||||
|         static bool sendResponse(HttpResponsePtr response, std::unique_ptr<Socket>& socket); | ||||
|  | ||||
|         static std::pair<std::string, int> parseStatusLine(const std::string& line); | ||||
|         static std::tuple<std::string, std::string, std::string> parseRequestLine( | ||||
|   | ||||
| @@ -95,7 +95,7 @@ namespace ix | ||||
|         std::atomic<bool> _stop; | ||||
|         std::thread _thread; | ||||
|  | ||||
|         std::shared_ptr<Socket> _socket; | ||||
|         std::unique_ptr<Socket> _socket; | ||||
|         std::mutex _mutex; // to protect accessing the _socket (only one socket per client) | ||||
|  | ||||
|         SocketTLSOptions _tlsOptions; | ||||
|   | ||||
| @@ -69,7 +69,7 @@ namespace ix | ||||
|         _onConnectionCallback = callback; | ||||
|     } | ||||
|  | ||||
|     void HttpServer::handleConnection(std::shared_ptr<Socket> socket, | ||||
|     void HttpServer::handleConnection(std::unique_ptr<Socket> socket, | ||||
|                                       std::shared_ptr<ConnectionState> connectionState) | ||||
|     { | ||||
|         _connectedClientsCount++; | ||||
|   | ||||
| @@ -43,7 +43,7 @@ namespace ix | ||||
|         std::atomic<int> _connectedClientsCount; | ||||
|  | ||||
|         // Methods | ||||
|         virtual void handleConnection(std::shared_ptr<Socket>, | ||||
|         virtual void handleConnection(std::unique_ptr<Socket>, | ||||
|                                       std::shared_ptr<ConnectionState> connectionState) final; | ||||
|         virtual size_t getConnectedClientsCount() final; | ||||
|  | ||||
|   | ||||
| @@ -24,28 +24,28 @@ | ||||
|  | ||||
| namespace ix | ||||
| { | ||||
|     std::shared_ptr<Socket> createSocket(bool tls, | ||||
|     std::unique_ptr<Socket> createSocket(bool tls, | ||||
|                                          int fd, | ||||
|                                          std::string& errorMsg, | ||||
|                                          const SocketTLSOptions& tlsOptions) | ||||
|     { | ||||
|         (void) tlsOptions; | ||||
|         errorMsg.clear(); | ||||
|         std::shared_ptr<Socket> socket; | ||||
|         std::unique_ptr<Socket> socket; | ||||
|  | ||||
|         if (!tls) | ||||
|         { | ||||
|             socket = std::make_shared<Socket>(fd); | ||||
|             socket = std::make_unique<Socket>(fd); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
| #ifdef IXWEBSOCKET_USE_TLS | ||||
| #if defined(IXWEBSOCKET_USE_MBED_TLS) | ||||
|             socket = std::make_shared<SocketMbedTLS>(tlsOptions, fd); | ||||
|             socket = std::make_unique<SocketMbedTLS>(tlsOptions, fd); | ||||
| #elif defined(IXWEBSOCKET_USE_OPEN_SSL) | ||||
|             socket = std::make_shared<SocketOpenSSL>(tlsOptions, fd); | ||||
|             socket = std::make_unique<SocketOpenSSL>(tlsOptions, fd); | ||||
| #elif defined(__APPLE__) | ||||
|             socket = std::make_shared<SocketAppleSSL>(tlsOptions, fd); | ||||
|             socket = std::make_unique<SocketAppleSSL>(tlsOptions, fd); | ||||
| #endif | ||||
| #else | ||||
|             errorMsg = "TLS support is not enabled on this platform."; | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
| namespace ix | ||||
| { | ||||
|     class Socket; | ||||
|     std::shared_ptr<Socket> createSocket(bool tls, | ||||
|     std::unique_ptr<Socket> createSocket(bool tls, | ||||
|                                          int fd, | ||||
|                                          std::string& errorMsg, | ||||
|                                          const SocketTLSOptions& tlsOptions); | ||||
|   | ||||
| @@ -340,7 +340,7 @@ namespace ix | ||||
|             std::lock_guard<std::mutex> lock(_connectionsThreadsMutex); | ||||
|             _connectionsThreads.push_back(std::make_pair( | ||||
|                 connectionState, | ||||
|                 std::thread(&SocketServer::handleConnection, this, socket, connectionState))); | ||||
|                 std::thread(&SocketServer::handleConnection, this, std::move(socket), connectionState))); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -101,7 +101,7 @@ namespace ix | ||||
|         // the factory to create ConnectionState objects | ||||
|         ConnectionStateFactory _connectionStateFactory; | ||||
|  | ||||
|         virtual void handleConnection(std::shared_ptr<Socket>, | ||||
|         virtual void handleConnection(std::unique_ptr<Socket>, | ||||
|                                       std::shared_ptr<ConnectionState> connectionState) = 0; | ||||
|         virtual size_t getConnectedClientsCount() = 0; | ||||
|  | ||||
|   | ||||
| @@ -210,7 +210,7 @@ namespace ix | ||||
|         return status; | ||||
|     } | ||||
|  | ||||
|     WebSocketInitResult WebSocket::connectToSocket(std::shared_ptr<Socket> socket, int timeoutSecs) | ||||
|     WebSocketInitResult WebSocket::connectToSocket(std::unique_ptr<Socket> socket, int timeoutSecs) | ||||
|     { | ||||
|         { | ||||
|             std::lock_guard<std::mutex> lock(_configMutex); | ||||
| @@ -218,7 +218,7 @@ namespace ix | ||||
|                 _perMessageDeflateOptions, _socketTLSOptions, _enablePong, _pingIntervalSecs); | ||||
|         } | ||||
|  | ||||
|         WebSocketInitResult status = _ws.connectToSocket(socket, timeoutSecs); | ||||
|         WebSocketInitResult status = _ws.connectToSocket(std::move(socket), timeoutSecs); | ||||
|         if (!status.success) | ||||
|         { | ||||
|             return status; | ||||
|   | ||||
| @@ -113,7 +113,7 @@ namespace ix | ||||
|         static void invokeTrafficTrackerCallback(size_t size, bool incoming); | ||||
|  | ||||
|         // Server | ||||
|         WebSocketInitResult connectToSocket(std::shared_ptr<Socket>, int timeoutSecs); | ||||
|         WebSocketInitResult connectToSocket(std::unique_ptr<Socket>, int timeoutSecs); | ||||
|  | ||||
|         WebSocketTransport _ws; | ||||
|  | ||||
|   | ||||
| @@ -21,7 +21,7 @@ namespace ix | ||||
| { | ||||
|     WebSocketHandshake::WebSocketHandshake( | ||||
|         std::atomic<bool>& requestInitCancellation, | ||||
|         std::shared_ptr<Socket> socket, | ||||
|         std::unique_ptr<Socket>& socket, | ||||
|         WebSocketPerMessageDeflatePtr& perMessageDeflate, | ||||
|         WebSocketPerMessageDeflateOptions& perMessageDeflateOptions, | ||||
|         std::atomic<bool>& enablePerMessageDeflate) | ||||
|   | ||||
| @@ -23,7 +23,7 @@ namespace ix | ||||
|     { | ||||
|     public: | ||||
|         WebSocketHandshake(std::atomic<bool>& requestInitCancellation, | ||||
|                            std::shared_ptr<Socket> _socket, | ||||
|                            std::unique_ptr<Socket>& _socket, | ||||
|                            WebSocketPerMessageDeflatePtr& perMessageDeflate, | ||||
|                            WebSocketPerMessageDeflateOptions& perMessageDeflateOptions, | ||||
|                            std::atomic<bool>& enablePerMessageDeflate); | ||||
| @@ -46,7 +46,7 @@ namespace ix | ||||
|         bool insensitiveStringCompare(const std::string& a, const std::string& b); | ||||
|  | ||||
|         std::atomic<bool>& _requestInitCancellation; | ||||
|         std::shared_ptr<Socket> _socket; | ||||
|         std::unique_ptr<Socket>& _socket; | ||||
|         WebSocketPerMessageDeflatePtr& _perMessageDeflate; | ||||
|         WebSocketPerMessageDeflateOptions& _perMessageDeflateOptions; | ||||
|         std::atomic<bool>& _enablePerMessageDeflate; | ||||
|   | ||||
| @@ -32,7 +32,7 @@ namespace ix | ||||
|     } | ||||
|  | ||||
|     std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders( | ||||
|         std::shared_ptr<Socket> socket, const CancellationRequest& isCancellationRequested) | ||||
|         std::unique_ptr<Socket>& socket, const CancellationRequest& isCancellationRequested) | ||||
|     { | ||||
|         WebSocketHttpHeaders headers; | ||||
|  | ||||
|   | ||||
| @@ -29,5 +29,5 @@ namespace ix | ||||
|     using WebSocketHttpHeaders = std::map<std::string, std::string, CaseInsensitiveLess>; | ||||
|  | ||||
|     std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders( | ||||
|         std::shared_ptr<Socket> socket, const CancellationRequest& isCancellationRequested); | ||||
|         std::unique_ptr<Socket>& socket, const CancellationRequest& isCancellationRequested); | ||||
| } // namespace ix | ||||
|   | ||||
| @@ -71,7 +71,7 @@ namespace ix | ||||
|         _onConnectionCallback = callback; | ||||
|     } | ||||
|  | ||||
|     void WebSocketServer::handleConnection(std::shared_ptr<Socket> socket, | ||||
|     void WebSocketServer::handleConnection(std::unique_ptr<Socket> socket, | ||||
|                                            std::shared_ptr<ConnectionState> connectionState) | ||||
|     { | ||||
|         setThreadName("WebSocketServer::" + connectionState->getId()); | ||||
| @@ -96,7 +96,7 @@ namespace ix | ||||
|             _clients.insert(webSocket); | ||||
|         } | ||||
|  | ||||
|         auto status = webSocket->connectToSocket(socket, _handshakeTimeoutSecs); | ||||
|         auto status = webSocket->connectToSocket(std::move(socket), _handshakeTimeoutSecs); | ||||
|         if (status.success) | ||||
|         { | ||||
|             // Process incoming messages and execute callbacks | ||||
|   | ||||
| @@ -59,7 +59,7 @@ namespace ix | ||||
|         const static bool kDefaultEnablePong; | ||||
|  | ||||
|         // Methods | ||||
|         virtual void handleConnection(std::shared_ptr<Socket> socket, | ||||
|         virtual void handleConnection(std::unique_ptr<Socket> socket, | ||||
|                                       std::shared_ptr<ConnectionState> connectionState) final; | ||||
|         virtual size_t getConnectedClientsCount() final; | ||||
|     }; | ||||
|   | ||||
| @@ -140,7 +140,7 @@ namespace ix | ||||
|     } | ||||
|  | ||||
|     // Server | ||||
|     WebSocketInitResult WebSocketTransport::connectToSocket(std::shared_ptr<Socket> socket, | ||||
|     WebSocketInitResult WebSocketTransport::connectToSocket(std::unique_ptr<Socket> socket, | ||||
|                                                             int timeoutSecs) | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(_socketMutex); | ||||
| @@ -149,7 +149,7 @@ namespace ix | ||||
|         _useMask = false; | ||||
|         _blockingSend = true; | ||||
|  | ||||
|         _socket = socket; | ||||
|         _socket = std::move(socket); | ||||
|         _perMessageDeflate = std::make_unique<WebSocketPerMessageDeflate>(); | ||||
|  | ||||
|         WebSocketHandshake webSocketHandshake(_requestInitCancellation, | ||||
|   | ||||
| @@ -83,7 +83,7 @@ namespace ix | ||||
|                                          int timeoutSecs); | ||||
|  | ||||
|         // Server | ||||
|         WebSocketInitResult connectToSocket(std::shared_ptr<Socket> socket, int timeoutSecs); | ||||
|         WebSocketInitResult connectToSocket(std::unique_ptr<Socket> socket, int timeoutSecs); | ||||
|  | ||||
|         PollResult poll(); | ||||
|         WebSocketSendInfo sendBinary(const std::string& message, | ||||
| @@ -171,7 +171,7 @@ namespace ix | ||||
|         static constexpr size_t kChunkSize = 1 << 15; | ||||
|  | ||||
|         // Underlying TCP socket | ||||
|         std::shared_ptr<Socket> _socket; | ||||
|         std::unique_ptr<Socket> _socket; | ||||
|         std::mutex _socketMutex; | ||||
|  | ||||
|         // Hold the state of the connection (OPEN, CLOSED, etc...) | ||||
|   | ||||
| @@ -6,4 +6,4 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #define IX_WEBSOCKET_VERSION "9.0.1" | ||||
| #define IX_WEBSOCKET_VERSION "9.0.2" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user