diff --git a/2.0.2/Projects/Simulator/BTM/server_ws.hpp b/2.0.2/Projects/Simulator/BTM/server_ws.hpp index c508c2f..9ed7a15 100644 --- a/2.0.2/Projects/Simulator/BTM/server_ws.hpp +++ b/2.0.2/Projects/Simulator/BTM/server_ws.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -114,7 +115,8 @@ namespace SimpleWeb { private: std::vector > opt_endpoint; - + boost::mutex m_write_mutex; + public: void port(uint16_t aPort) { @@ -157,7 +159,10 @@ namespace SimpleWeb { //See http://tools.ietf.org/html/rfc6455#section-5.2 for more information void send(std::shared_ptr connection, std::shared_ptr send_stream, const std::function& callback=nullptr, - unsigned char fin_rsv_opcode=129) const { + unsigned char fin_rsv_opcode=129) { + + m_write_mutex.lock(); + if(fin_rsv_opcode!=136) timer_idle_reset(connection); @@ -190,24 +195,25 @@ namespace SimpleWeb { //Need to copy the callback-function in case its destroyed boost::system::error_code ec; boost::asio::async_write(*connection->socket, *buffer, yield[ec]); - if(ec) { - if(callback) - callback(ec); - return; - } + if (!ec) + { + if (send_stream->sending == true) + throw std::runtime_error("SendStream already in use! Only reuse a SendStream if you are sure a prior send operation using the stream is finished."); + + send_stream->sending = true; + boost::asio::async_write(*connection->socket, send_stream->streambuf, yield[ec]); + send_stream->sending = false; + } + + m_write_mutex.unlock(); - if(send_stream->sending==true) - throw std::runtime_error("SendStream already in use! Only reuse a SendStream if you are sure a prior send operation using the stream is finished."); - send_stream->sending=true; - boost::asio::async_write(*connection->socket, send_stream->streambuf, yield[ec]); - send_stream->sending=false; if(callback) callback(ec); }); } - void send_close(std::shared_ptr connection, int status, const std::string& reason="") const { + void send_close(std::shared_ptr connection, int status, const std::string& reason="") { //Send close only once (in case close is initiated by server) if(connection->closed.load()) { return; @@ -377,7 +383,7 @@ namespace SimpleWeb { } void read_message(std::shared_ptr connection, - std::shared_ptr read_buffer, Endpoint& endpoint) const { + std::shared_ptr read_buffer, Endpoint& endpoint) { boost::asio::async_read(*connection->socket, *read_buffer, boost::asio::transfer_exactly(2), [this, connection, read_buffer, &endpoint] (const boost::system::error_code& ec, size_t bytes_transferred) { @@ -456,7 +462,7 @@ namespace SimpleWeb { void read_message_content(std::shared_ptr connection, std::shared_ptr read_buffer, - size_t length, Endpoint& endpoint, unsigned char fin_rsv_opcode) const { + size_t length, Endpoint& endpoint, unsigned char fin_rsv_opcode) { boost::asio::async_read(*connection->socket, *read_buffer, boost::asio::transfer_exactly(4+length), [this, connection, read_buffer, length, &endpoint, fin_rsv_opcode] (const boost::system::error_code& ec, size_t bytes_transferred) { @@ -554,7 +560,7 @@ namespace SimpleWeb { timer_idle_expired_function(connection); } } - void timer_idle_reset(std::shared_ptr connection) const { + void timer_idle_reset(std::shared_ptr connection) { if(timeout_idle>0 && connection->timer_idle->expires_from_now(boost::posix_time::seconds(timeout_idle))>0) { timer_idle_expired_function(connection); } @@ -564,7 +570,7 @@ namespace SimpleWeb { connection->timer_idle->cancel(); } - void timer_idle_expired_function(std::shared_ptr connection) const { + void timer_idle_expired_function(std::shared_ptr connection) { connection->timer_idle->async_wait([this, connection](const boost::system::error_code& ec){ if(!ec) { //1000=normal closure