Skip to content

Commit 2e2fb30

Browse files
committed
add more thread safty
1 parent 4d65010 commit 2e2fb30

4 files changed

Lines changed: 78 additions & 40 deletions

File tree

examples/Console/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,12 @@ MAIN_FUNC
166166
current_socket->close();
167167
}
168168
current_socket = h.socket(new_nsp);
169-
//if change to default nsp, we do not need to bind events again.
169+
bind_events(current_socket);
170+
//if change to default nsp, we do not need to login again (since it is not closed).
170171
if(current_socket->get_namespace() == "/")
171172
{
172173
continue;
173174
}
174-
bind_events(current_socket);
175175
goto Login;
176176
}
177177
current_socket->emit("new message", line);

src/internal/sio_client_impl.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ namespace sio {
186186
{
187187
case packet::frame_message:
188188
{
189-
get_socket_locked(p.get_nsp())->on_message_packet(p);
189+
socket::ptr so_ptr = get_socket_locked(p.get_nsp());
190+
if(so_ptr)so_ptr->on_message_packet(p);
190191
break;
191192
}
192193
case packet::frame_open:
@@ -471,9 +472,7 @@ namespace sio {
471472
"run loop end");
472473
}
473474

474-
socket::ptr empty_socket_ptr;
475-
476-
socket::ptr const& client_impl::get_socket_locked(std::string const& nsp)
475+
socket::ptr client_impl::get_socket_locked(std::string const& nsp)
477476
{
478477
std::lock_guard<std::mutex> guard(m_socket_mutex);
479478
auto it = m_sockets.find(nsp);
@@ -483,7 +482,7 @@ namespace sio {
483482
}
484483
else
485484
{
486-
return empty_socket_ptr;
485+
return socket::ptr();
487486
}
488487
}
489488

src/internal/sio_client_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void set_##__FIELD__(__TYPE__ const& l) \
120120

121121
void __timeout_connection(const boost::system::error_code& ec);
122122

123-
socket::ptr const& get_socket_locked(std::string const& nsp);
123+
socket::ptr get_socket_locked(std::string const& nsp);
124124

125125
void sockets_invoke_void(void (sio::socket::*fn)(void));
126126

src/sio_socket.cpp

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -92,29 +92,13 @@ namespace sio {
9292
impl(client_impl *,std::string const&);
9393
~impl();
9494

95-
void on(std::string const& event_name,event_listener_aux const& func)
96-
{
97-
m_event_binding[event_name] = event_adapter::do_adapt(func);
98-
}
95+
void on(std::string const& event_name,event_listener_aux const& func);
9996

100-
void on(std::string const& event_name,event_listener const& func)
101-
{
102-
m_event_binding[event_name] = func;
103-
}
97+
void on(std::string const& event_name,event_listener const& func);
10498

105-
void off(std::string const& event_name)
106-
{
107-
auto it = m_event_binding.find(event_name);
108-
if(it!=m_event_binding.end())
109-
{
110-
m_event_binding.erase(it);
111-
}
112-
}
99+
void off(std::string const& event_name);
113100

114-
void off_all()
115-
{
116-
m_event_binding.clear();
117-
}
101+
void off_all();
118102

119103
#define SYNTHESIS_SETTER(__TYPE__,__FIELD__) \
120104
void set_##__FIELD__(__TYPE__ const& l) \
@@ -162,6 +146,8 @@ void set_##__FIELD__(__TYPE__ const& l) \
162146
void on_socketio_ack(int msgId, message::ptr const& message);
163147
void on_socketio_error(message::ptr const& err_message);
164148

149+
event_listener get_bind_listener_locked(string const& event);
150+
165151
void __ack(int msgId,string const& name,message::ptr const& ack_message);
166152

167153
void __timeout_connection(const boost::system::error_code &ec);
@@ -170,6 +156,8 @@ void set_##__FIELD__(__TYPE__ const& l) \
170156

171157
void __send_packet(packet& p);
172158

159+
static event_listener s_null_event_listener;
160+
173161
static unsigned int s_global_event_id;
174162

175163
sio::client_impl *m_client;
@@ -187,9 +175,38 @@ void set_##__FIELD__(__TYPE__ const& l) \
187175

188176
std::queue<packet> m_packet_queue;
189177

178+
std::mutex m_event_mutex;
179+
190180
friend class socket;
191181
};
192182

183+
void socket::impl::on(std::string const& event_name,event_listener_aux const& func)
184+
{
185+
this->on(event_name,event_adapter::do_adapt(func));
186+
}
187+
188+
void socket::impl::on(std::string const& event_name,event_listener const& func)
189+
{
190+
std::lock_guard<std::mutex> guard(m_event_mutex);
191+
m_event_binding[event_name] = func;
192+
}
193+
194+
void socket::impl::off(std::string const& event_name)
195+
{
196+
std::lock_guard<std::mutex> guard(m_event_mutex);
197+
auto it = m_event_binding.find(event_name);
198+
if(it!=m_event_binding.end())
199+
{
200+
m_event_binding.erase(it);
201+
}
202+
}
203+
204+
void socket::impl::off_all()
205+
{
206+
std::lock_guard<std::mutex> guard(m_event_mutex);
207+
m_event_binding.clear();
208+
}
209+
193210
void socket::impl::on_error(error_listener const& l)
194211
{
195212
m_error_listener = l;
@@ -229,7 +246,10 @@ void set_##__FIELD__(__TYPE__ const& l) \
229246
NULL_GUARD(m_client);
230247
message::ptr msg_ptr = make_message(name, message);
231248
packet p(m_nsp, msg_ptr,s_global_event_id);
232-
m_acks[s_global_event_id++] = ack;
249+
{
250+
std::lock_guard<std::mutex> guard(m_event_mutex);
251+
m_acks[s_global_event_id++] = ack;
252+
}
233253
__send_packet(p);
234254
}
235255

@@ -246,7 +266,10 @@ void set_##__FIELD__(__TYPE__ const& l) \
246266
NULL_GUARD(m_client);
247267
message::ptr msg_ptr = make_message(name, args);
248268
packet p(m_nsp, msg_ptr,s_global_event_id);
249-
m_acks[s_global_event_id++] = ack;
269+
{
270+
std::lock_guard<std::mutex> guard(m_event_mutex);
271+
m_acks[s_global_event_id++] = ack;
272+
}
250273
__send_packet(p);
251274
}
252275

@@ -263,7 +286,10 @@ void set_##__FIELD__(__TYPE__ const& l) \
263286
NULL_GUARD(m_client);
264287
message::ptr msg_ptr = make_message(name, binary_ptr);
265288
packet p(m_nsp, msg_ptr,s_global_event_id);
266-
m_acks[s_global_event_id++] = ack;
289+
{
290+
std::lock_guard<std::mutex> guard(m_event_mutex);
291+
m_acks[s_global_event_id++] = ack;
292+
}
267293
__send_packet(p);
268294
}
269295

@@ -431,11 +457,8 @@ void set_##__FIELD__(__TYPE__ const& l) \
431457
{
432458
bool needAck = msgId >= 0;
433459
event ev = event_adapter::create_event(nsp,name, message,needAck);
434-
auto it = m_event_binding.find(name);
435-
if(it!=m_event_binding.end())
436-
{
437-
(it->second)(ev);
438-
}
460+
event_listener func = this->get_bind_listener_locked(name);
461+
if(func)func(ev);
439462
if(needAck)
440463
{
441464
this->__ack(msgId, name, ev.get_ack_message());
@@ -450,12 +473,17 @@ void set_##__FIELD__(__TYPE__ const& l) \
450473

451474
void socket::impl::on_socketio_ack(int msgId, message::ptr const& message)
452475
{
453-
auto it = m_acks.find(msgId);
454-
if(it!=m_acks.end())
476+
std::function<void (message::ptr const&)> l;
455477
{
456-
(it->second)(message);
457-
m_acks.erase(it);
478+
std::lock_guard<std::mutex> guard(m_event_mutex);
479+
auto it = m_acks.find(msgId);
480+
if(it!=m_acks.end())
481+
{
482+
l = it->second;
483+
m_acks.erase(it);
484+
}
458485
}
486+
if(l)l(message);
459487
}
460488

461489
void socket::impl::on_socketio_error(message::ptr const& err_message)
@@ -492,6 +520,17 @@ void set_##__FIELD__(__TYPE__ const& l) \
492520
}
493521
}
494522

523+
socket::event_listener socket::impl::get_bind_listener_locked(const string &event)
524+
{
525+
std::lock_guard<std::mutex> guard(m_event_mutex);
526+
auto it = m_event_binding.find(event);
527+
if(it!=m_event_binding.end())
528+
{
529+
return it->second;
530+
}
531+
return socket::event_listener();
532+
}
533+
495534
socket::socket(client_impl* client,std::string const& nsp):
496535
m_impl(new impl(client,nsp))
497536
{

0 commit comments

Comments
 (0)