From ddfc0566f5eb1cf3eefc782cd25cde83c82e7c7b Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Sat, 2 Feb 2013 13:10:06 -0600 Subject: [PATCH] adds timer support --- websocketpp/transport/asio/connection.hpp | 43 +++++-------- websocketpp/transport/asio/endpoint.hpp | 24 ++++++++ websocketpp/transport/base/connection.hpp | 73 ++++++++++++++++++++++- 3 files changed, 110 insertions(+), 30 deletions(-) diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp index 7fe38b6f97..6b2c1e9ef7 100644 --- a/websocketpp/transport/asio/connection.hpp +++ b/websocketpp/transport/asio/connection.hpp @@ -154,7 +154,8 @@ protected: if (num_bytes > len) { m_elog.write(log::elevel::devel, "asio async_read_at_least error::invalid_num_bytes"); - handler(make_error_code(error::invalid_num_bytes),size_t(0)); + handler(make_error_code(transport::error::invalid_num_bytes), + size_t(0)); return; } @@ -181,7 +182,8 @@ protected: s << "asio async_read_at_least error::pass_through" << "Original Error: " << ec << " (" << ec.message() << ")"; m_elog.write(log::elevel::devel,s.str()); - handler(make_error_code(error::pass_through), bytes_transferred); + handler(make_error_code(transport::error::pass_through), + bytes_transferred); } else { m_alog.write(log::alevel::devel,"asio async_read_at_least no error"); handler(lib::error_code(), bytes_transferred); @@ -270,42 +272,29 @@ protected: socket_con_type::shutdown(); } - /*typedef lib::shared_ptr timer_ptr; + typedef lib::shared_ptr timer_ptr; - timer_ptr set_timer(long duration, handler) { - // create a timer - timer_ptr timer(new boost::asio::deadline_timer(*m_io_service)); - - // set timer for milliseconds from now + timer_ptr set_timer(long duration, timer_handler handler) { + timer_ptr timer(new boost::asio::deadline_timer(*m_io_service)); timer->expires_from_now(boost::posix_time::milliseconds(duration)); - - // add timer to list of timers - // async start timer - // return timer_hdl + timer->async_wait(lib::bind(&type::timer_handler, this, handler, + lib::placeholders::_1)); + return timer; } - void cancel_timer(timer_hdl) { - - } - - void timer_handler (handler, const boost::system::error_code& ec) { + void timer_handler(timer_handler h, const boost::system::error_code& ec) { if (ec == boost::asio::error::operation_aborted) { - // was cancelled - handler(make_error_code(error::pass_through)); + h(make_error_code(transport::error::operation_aborted)); } else if (ec) { - // other error std::stringstream s; s << "asio async_wait error::pass_through" << "Original Error: " << ec << " (" << ec.message() << ")"; m_elog.write(log::elevel::devel,s.str()); - handler(make_error_code(error::pass_through)); + h(make_error_code(transport::error::pass_through)); + } else { + h(lib::error_code()); } - - // timer ran out - handler(make_error_code(error::pass_through)); - }*/ - - + } private: // static settings const bool m_is_server; diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp index ae468a0779..8ad13b1f53 100644 --- a/websocketpp/transport/asio/endpoint.hpp +++ b/websocketpp/transport/asio/endpoint.hpp @@ -279,6 +279,30 @@ public: } listen(*endpoint_iterator); } + + typedef lib::shared_ptr timer_ptr; + + timer_ptr set_timer(long duration, timer_handler handler) { + timer_ptr timer(new boost::asio::deadline_timer(*m_io_service)); + timer->expires_from_now(boost::posix_time::milliseconds(duration)); + timer->async_wait(lib::bind(&type::timer_handler, this, handler, + lib::placeholders::_1)); + return timer; + } + + void timer_handler(timer_handler h, const boost::system::error_code& ec) { + if (ec == boost::asio::error::operation_aborted) { + h(make_error_code(transport::error::operation_aborted)); + } else if (ec) { + std::stringstream s; + s << "asio async_wait error::pass_through" + << "Original Error: " << ec << " (" << ec.message() << ")"; + m_elog->write(log::elevel::devel,s.str()); + h(make_error_code(transport::error::pass_through)); + } else { + h(lib::error_code()); + } + } protected: /// Initialize logging /** diff --git a/websocketpp/transport/base/connection.hpp b/websocketpp/transport/base/connection.hpp index ebcd010a18..09ef4a5e7a 100644 --- a/websocketpp/transport/base/connection.hpp +++ b/websocketpp/transport/base/connection.hpp @@ -28,10 +28,12 @@ #ifndef WEBSOCKETPP_TRANSPORT_BASE_CON_HPP #define WEBSOCKETPP_TRANSPORT_BASE_CON_HPP -#include -#include -#include +#include #include +#include +#include +#include + namespace websocketpp { namespace transport { @@ -66,6 +68,7 @@ typedef lib::function endpoint_lock; typedef lib::function init_handler; typedef lib::function read_handler; typedef lib::function write_handler; +typedef lib::function timer_handler; typedef lib::function inturrupt_handler; typedef lib::function dispatch_handler; @@ -78,7 +81,71 @@ struct buffer { size_t len; }; +namespace error { +enum value { + /// Catch-all error for transport policy errors that don't fit in other + /// categories + generic = 1, + + /// underlying transport pass through + pass_through, + + /// async_read_at_least call requested more bytes than buffer can store + invalid_num_bytes, + + /// async_read called while another async_read was in progress + double_read, + + /// Operation aborted + operation_aborted, + + /// Operation not supported + operation_not_supported +}; + +class category : public lib::error_category { + public: + category() {} + + const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { + return "websocketpp.transport"; + } + + std::string message(int value) const { + switch(value) { + case generic: + return "Generic transport policy error"; + case pass_through: + return "Underlying Transport Error"; + case invalid_num_bytes: + return "async_read_at_least call requested more bytes than buffer can store"; + case operation_aborted: + return "The operation was aborted"; + case operation_not_supported: + return "The operation is not supported by this transport"; + default: + return "Unknown"; + } + } +}; + +inline const lib::error_category& get_category() { + static category instance; + return instance; +} + +inline lib::error_code make_error_code(error::value e) { + return lib::error_code(static_cast(e), get_category()); +} + +} // namespace error } // namespace transport } // namespace websocketpp +_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +template<> struct is_error_code_enum +{ + static const bool value = true; +}; +_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ #endif // WEBSOCKETPP_TRANSPORT_BASE_CON_HPP