From bb431ee0d21bc60c412c7cc352202d3bcc3cf45d Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Sun, 26 Jan 2014 20:53:17 -0600 Subject: [PATCH] Fix a crash following use of the stop_listening function. --- changelog.md | 4 +++- test/transport/integration.cpp | 18 ++++++++++++++++++ websocketpp/roles/server_endpoint.hpp | 26 +++++++++++++++++++++----- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index f00a93fd7d..8b71fbe1a0 100644 --- a/changelog.md +++ b/changelog.md @@ -22,10 +22,12 @@ HEAD reference counted pointers. #310 Thank you otaras for reporting. - Bug: Fix issue with const endpoint accessors (such as `get_user_agent`) not compiling due to non-const mutex use. #292 Thank you logofive for reporting. -- Bug: Fix handler allocation crash with multithreaded io_service. +- Bug: Fix handler allocation crash with multithreaded `io_service`. - Bug: Fixes incorrect whitespace handling in header parsing. #301 Thank you Wolfram Schroers for reporting - Bug: Fix a crash when parsing empty HTTP headers. Thank you Thingol for reporting. +- Bug: Fix a crash following use of the `stop_listening` function. Thank you Thingol for + reporting. 0.3.0-alpha4 - 2013-10-11 - HTTP requests ending normally are no longer logged as errors. Thank you Banaan diff --git a/test/transport/integration.cpp b/test/transport/integration.cpp index 0185a4d7d0..c6445e5837 100644 --- a/test/transport/integration.cpp +++ b/test/transport/integration.cpp @@ -504,6 +504,24 @@ BOOST_AUTO_TEST_CASE( client_failed_connection ) { run_time_limited_client(c,"http://localhost:9005", 5, false); } +BOOST_AUTO_TEST_CASE( stop_listening ) { + server s; + client c; + + // the first connection stops the server from listening + s.set_open_handler(bind(&cancel_on_open,&s,::_1)); + + // client immediately closes after opening a connection + c.set_open_handler(bind(&close,&c,::_1)); + + websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,true)); + websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,2)); + tthread.detach(); + + run_client(c, "http://localhost:9005",false); + + sthread.join(); +} BOOST_AUTO_TEST_CASE( pause_reading ) { iostream_server s; diff --git a/websocketpp/roles/server_endpoint.hpp b/websocketpp/roles/server_endpoint.hpp index 77f1c29189..3bdf91ae30 100644 --- a/websocketpp/roles/server_endpoint.hpp +++ b/websocketpp/roles/server_endpoint.hpp @@ -84,7 +84,9 @@ public: // Starts the server's async connection acceptance loop. void start_accept() { connection_ptr con = get_connection(); - + + lib::error_code ec; + transport_type::async_accept( lib::static_pointer_cast(con), lib::bind( @@ -92,16 +94,30 @@ public: this, con, lib::placeholders::_1 - ) + ), + ec ); + + if (ec == error::async_accept_not_listening) { + endpoint_type::m_elog.write(log::elevel::info, + "Stopping acceptance of new connections because the underlying transport is no longer listening."); + } else if (ec) { + endpoint_type::m_elog.write(log::elevel::rerror, + "handle_accept error: "+ec.message()); + } } - void handle_accept(connection_ptr con, const lib::error_code& ec) { + void handle_accept(connection_ptr con, lib::error_code const & ec) { if (ec) { con->terminate(ec); - endpoint_type::m_elog.write(log::elevel::rerror, - "handle_accept error: "+ec.message()); + if (ec == error::operation_canceled) { + endpoint_type::m_elog.write(log::elevel::info, + "handle_accept error: "+ec.message()); + } else { + endpoint_type::m_elog.write(log::elevel::rerror, + "handle_accept error: "+ec.message()); + } } else { con->start(); }