From bbbc1e32dd664c5b0d95074339b997d9b4eb65cf Mon Sep 17 00:00:00 2001 From: "melo.yao" Date: Tue, 25 Aug 2015 11:04:14 +0800 Subject: [PATCH] add boolean message type, fix crash of a synchronization bug --- src/internal/sio_packet.cpp | 14 ++++++++++++++ src/sio_message.h | 31 +++++++++++++++++++++++++++++- src/sio_socket.cpp | 38 ++++++++++++++++++++++++++++++------- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/internal/sio_packet.cpp b/src/internal/sio_packet.cpp index 5b1757d2..14a54f7d 100755 --- a/src/internal/sio_packet.cpp +++ b/src/internal/sio_packet.cpp @@ -19,6 +19,11 @@ namespace sio using namespace std; void accept_message(message const& msg,Value& val, Document& doc,vector >& buffers); + void accept_bool_message(bool_message const& msg, Value& val) + { + val.SetBool(msg.get_bool()); + } + void accept_int_message(int_message const& msg, Value& val) { val.SetInt64(msg.get_int()); @@ -95,6 +100,11 @@ namespace sio accept_string_message(*(static_cast(msg_ptr)), val); break; } + case message::flag_boolean: + { + accept_bool_message(*(static_cast(msg_ptr)), val); + break; + } case message::flag_binary: { accept_binary_message(*(static_cast(msg_ptr)), val,doc,buffers); @@ -163,6 +173,10 @@ namespace sio } return ptr; } + else if(value.IsBool()) + { + return bool_message::create(value.GetBool()); + } return message::ptr(); } diff --git a/src/sio_message.h b/src/sio_message.h index b635380e..60535235 100755 --- a/src/sio_message.h +++ b/src/sio_message.h @@ -26,7 +26,8 @@ namespace sio flag_string, flag_binary, flag_array, - flag_object + flag_object, + flag_boolean }; virtual ~message(){}; @@ -39,6 +40,12 @@ namespace sio } typedef shared_ptr ptr; + + virtual bool get_bool() const + { + assert(false); + return false; + } virtual int64_t get_int() const { @@ -105,6 +112,28 @@ namespace sio protected: message(flag f):_flag(f){} }; + + class bool_message : public message + { + bool _v; + + protected: + bool_message(bool v) + :message(flag_boolean),_v(v) + { + } + + public: + static message::ptr create(bool v) + { + return ptr(new bool_message(v)); + } + + bool get_bool() const + { + return _v; + } + }; class int_message : public message { diff --git a/src/sio_socket.cpp b/src/sio_socket.cpp index 122dc5bd..6be373da 100644 --- a/src/sio_socket.cpp +++ b/src/sio_socket.cpp @@ -183,6 +183,8 @@ namespace sio std::queue m_packet_queue; std::mutex m_event_mutex; + + std::mutex m_packet_mutex; friend class socket; }; @@ -306,9 +308,18 @@ namespace sio { m_connected = true; m_client->on_socket_opened(m_nsp); - while (!m_packet_queue.empty()) { - m_client->send(m_packet_queue.front()); + + while (true) { + m_packet_mutex.lock(); + if(m_packet_queue.empty()) + { + m_packet_mutex.unlock(); + return; + } + sio::packet front_pack = std::move(m_packet_queue.front()); m_packet_queue.pop(); + m_packet_mutex.unlock(); + m_client->send(front_pack); } } } @@ -325,9 +336,12 @@ namespace sio m_connection_timer.reset(); } m_connected = false; - while (!m_packet_queue.empty()) { - m_packet_queue.pop(); - } + { + std::lock_guard guard(m_packet_mutex); + while (!m_packet_queue.empty()) { + m_packet_queue.pop(); + } + } client->on_socket_closed(m_nsp); client->remove_socket(m_nsp); } @@ -343,6 +357,7 @@ namespace sio if(m_connected) { m_connected = false; + std::lock_guard guard(m_packet_mutex); while (!m_packet_queue.empty()) { m_packet_queue.pop(); } @@ -479,14 +494,23 @@ namespace sio NULL_GUARD(m_client); if(m_connected) { - while (!m_packet_queue.empty()) { - m_client->send(m_packet_queue.front()); + while (true) { + m_packet_mutex.lock(); + if(m_packet_queue.empty()) + { + m_packet_mutex.unlock(); + break; + } + sio::packet front_pack = std::move(m_packet_queue.front()); m_packet_queue.pop(); + m_packet_mutex.unlock(); + m_client->send(front_pack); } m_client->send(p); } else { + std::lock_guard guard(m_packet_mutex); m_packet_queue.push(p); } }