From c2f2cb951b94b302a963b486d0b536312c254257 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Tue, 10 Dec 2013 22:02:22 -0600 Subject: [PATCH] Fixes some calls to empty lib::functions, references #310 --- changelog.md | 1 + test/transport/integration.cpp | 8 ++++++- websocketpp/transport/asio/connection.hpp | 28 ++++++++++++++++++++--- websocketpp/transport/base/connection.hpp | 7 +++++- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index a51f4b69ab..622c038d60 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,7 @@ HEAD buffer sizes based on profiling, caching of handler binding for async reads/writes, non-malloc allocators for read/write handlers, disabling of a number of questionably useful range sanity checks in tight inner loops. +- Bug: Fix some cases of calls to empty lib::function objects. - Bug: Fix memory leak of connection objects due to cached handlers holding on to reference counted pointers. #310 Thank you otaras for reporting. - Bug: Fix issue with const endpoint accessors (such as `get_user_agent`) not diff --git a/test/transport/integration.cpp b/test/transport/integration.cpp index d117617966..05ba672c81 100644 --- a/test/transport/integration.cpp +++ b/test/transport/integration.cpp @@ -403,7 +403,7 @@ BOOST_AUTO_TEST_CASE( client_self_initiated_close_handshake_timeout ) { websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6)); tthread.detach(); - run_client(c, "http://localhost:9005",false); + run_client(c, "http://localhost:9005", false); sthread.join(); } @@ -492,3 +492,9 @@ BOOST_AUTO_TEST_CASE( client_is_perpetual ) { cthread.join(); } + +BOOST_AUTO_TEST_CASE( client_failed_connection ) { + client c; + + run_time_limited_client(c,"http://localhost:9005", 5, true); +} \ No newline at end of file diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp index 79bc1a6083..f0aefa579f 100644 --- a/websocketpp/transport/asio/connection.hpp +++ b/websocketpp/transport/asio/connection.hpp @@ -621,7 +621,8 @@ protected: boost::system::error_code const & ec) { if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection handle_proxy_write"); + m_alog.write(log::alevel::devel, + "asio connection handle_proxy_write"); } m_bufs.clear(); @@ -688,7 +689,8 @@ protected: boost::system::error_code const & ec, size_t bytes_transferred) { if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection handle_proxy_read"); + m_alog.write(log::alevel::devel, + "asio connection handle_proxy_read"); } // Timer expired or the operation was aborted for some reason. @@ -774,6 +776,13 @@ protected: m_alog.write(log::alevel::devel,s.str()); } + if (!m_async_read_handler) { + m_alog.write(log::alevel::devel, + "async_read_at_least called after async_shutdown"); + handler(make_error_code(transport::error::action_after_shutdown), 0); + return; + } + // TODO: safety vs speed ? // maybe move into an if devel block /*if (num_bytes > len) { @@ -820,7 +829,14 @@ protected: } void async_write(const char* buf, size_t len, write_handler handler) { - m_bufs.push_back(boost::asio::buffer(buf,len)); + if (!m_async_write_handler) { + m_alog.write(log::alevel::devel, + "async_write (single) called after async_shutdown"); + handler(make_error_code(transport::error::action_after_shutdown)); + return; + } + + m_bufs.push_back(boost::asio::buffer(buf,len)); m_write_handler = handler; @@ -835,6 +851,12 @@ protected: } void async_write(const std::vector& bufs, write_handler handler) { + if (!m_async_write_handler) { + m_alog.write(log::alevel::devel, + "async_write (vector) called after async_shutdown"); + handler(make_error_code(transport::error::action_after_shutdown)); + return; + } std::vector::const_iterator it; for (it = bufs.begin(); it != bufs.end(); ++it) { diff --git a/websocketpp/transport/base/connection.hpp b/websocketpp/transport/base/connection.hpp index 1db6310d23..70e1ec50cb 100644 --- a/websocketpp/transport/base/connection.hpp +++ b/websocketpp/transport/base/connection.hpp @@ -169,7 +169,10 @@ enum value { tls_short_read, /// Timer expired - timeout + timeout, + + /// read or write after shutdown + action_after_shutdown }; class category : public lib::error_category { @@ -198,6 +201,8 @@ class category : public lib::error_category { return "TLS Short Read"; case timeout: return "Timer Expired"; + case action_after_shutdown: + return "A transport action was requested after shutdown"; default: return "Unknown"; }