From 4df08d8efe655b1fb4b367a729d1c855b5e433f2 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 6 May 2015 16:34:55 -0400 Subject: [PATCH] fix crash in websocket --- include/fc/rpc/api_connection.hpp | 20 +++++++++++++------- include/fc/rpc/websocket_api.hpp | 4 ++++ src/network/http/websocket.cpp | 9 ++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/include/fc/rpc/api_connection.hpp b/include/fc/rpc/api_connection.hpp index 8b0251b..fd67072 100644 --- a/include/fc/rpc/api_connection.hpp +++ b/include/fc/rpc/api_connection.hpp @@ -91,7 +91,7 @@ namespace fc { return _methods[method_id](args); } - fc::api_connection& get_connection(){ return *_api_connection; } + fc::api_connection& get_connection(){ auto tmp = _api_connection.lock(); FC_ASSERT( tmp, "connection closed"); return *tmp; } private: @@ -133,7 +133,7 @@ namespace fc { struct api_visitor { - api_visitor( generic_api& a, const std::shared_ptr& s ):api(a),_api_con(s){ } + api_visitor( generic_api& a, const std::weak_ptr& s ):api(a),_api_con(s){ } template std::function to_generic( const std::function(Args...)>& f )const; @@ -154,11 +154,11 @@ namespace fc { } generic_api& api; - const std::shared_ptr& _api_con; + const std::weak_ptr& _api_con; }; - std::shared_ptr _api_connection; + std::weak_ptr _api_connection; fc::any _api; std::map< std::string, uint32_t > _by_name; std::vector< std::function > _methods; @@ -325,7 +325,7 @@ namespace fc { generic_api::generic_api( const Api& a, const std::shared_ptr& c ) :_api_connection(c),_api(a) { - boost::any_cast(a)->visit( api_visitor( *this, _api_connection ) ); + boost::any_cast(a)->visit( api_visitor( *this, c ) ); } template @@ -335,8 +335,11 @@ namespace fc { auto api_con = _api_con; auto gapi = &api; return [=]( const variants& args ) { + auto con = api_con.lock(); + FC_ASSERT( con, "not connected" ); + auto api_result = gapi->call_generic( f, args.begin(), args.end() ); - return api_con->register_api( api_result ); + return con->register_api( api_result ); }; } template @@ -346,9 +349,12 @@ namespace fc { auto api_con = _api_con; auto gapi = &api; return [=]( const variants& args )-> fc::variant { + auto con = api_con.lock(); + FC_ASSERT( con, "not connected" ); + auto api_result = gapi->call_generic( f, args.begin(), args.end() ); if( api_result ) - return api_con->register_api( *api_result ); + return con->register_api( *api_result ); return variant(); }; } diff --git a/include/fc/rpc/websocket_api.hpp b/include/fc/rpc/websocket_api.hpp index 202a2cb..b4ab6c5 100644 --- a/include/fc/rpc/websocket_api.hpp +++ b/include/fc/rpc/websocket_api.hpp @@ -10,6 +10,10 @@ namespace fc { namespace rpc { class websocket_api_connection : public api_connection { public: + ~websocket_api_connection() + { + } + websocket_api_connection( fc::http::websocket_connection& c ) :_connection(c) { diff --git a/src/network/http/websocket.cpp b/src/network/http/websocket.cpp index 283730b..0250c8a 100644 --- a/src/network/http/websocket.cpp +++ b/src/network/http/websocket.cpp @@ -69,7 +69,12 @@ namespace fc { namespace http { { public: websocket_connection_impl( T con ) - :_ws_connection(con){} + :_ws_connection(con){ + } + + ~websocket_connection_impl() + { + } virtual void send_message( const std::string& message )override { @@ -110,6 +115,7 @@ namespace fc { namespace http { }); _server.set_close_handler( [&]( connection_hdl hdl ){ _server_thread.async( [&](){ + _connections[hdl]->closed(); _connections.erase( hdl ); }).wait(); }); @@ -118,6 +124,7 @@ namespace fc { namespace http { if( _server.is_listening() ) { _server_thread.async( [&](){ + _connections[hdl]->closed(); _connections.erase( hdl ); }).wait(); }