@@ -40,6 +40,8 @@ void vuapi AsyncSocket::initialze()
40
40
{
41
41
m_n_events = 0 ;
42
42
43
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
44
+
43
45
memset (m_connections, int (INVALID_SOCKET), sizeof (m_connections));
44
46
memset (m_events, int (0 ), sizeof (m_events));
45
47
@@ -95,6 +97,8 @@ VUResult vuapi AsyncSocket::listen(const int maxcon)
95
97
return 2 ;
96
98
}
97
99
100
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
101
+
98
102
m_connections[m_n_events] = m_socket.handle ();
99
103
m_events[m_n_events] = event;
100
104
m_n_events++;
@@ -106,11 +110,11 @@ VUResult vuapi AsyncSocket::listen(const int maxcon)
106
110
return result;
107
111
}
108
112
109
- IResult vuapi AsyncSocket::close ()
113
+ IResult vuapi AsyncSocket::close (const Socket:: shutdowns_t flags, const bool cleanup )
110
114
{
111
115
this ->stop ();
112
116
113
- this ->disconnect_connections ();
117
+ this ->disconnect_connections (flags, cleanup );
114
118
115
119
if (m_thread != INVALID_HANDLE_VALUE)
116
120
{
@@ -148,6 +152,8 @@ VUResult vuapi AsyncSocket::connect(const Endpoint& endpoint)
148
152
return 2 ;
149
153
}
150
154
155
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
156
+
151
157
auto result = m_socket.connect (endpoint);
152
158
if (result == VU_OK)
153
159
{
@@ -169,34 +175,37 @@ VUResult vuapi AsyncSocket::connect(const std::string& address, const ushort por
169
175
return this ->connect (endpoint);
170
176
}
171
177
172
- std::set<SOCKET> vuapi AsyncSocket::get_connections () const
178
+ void vuapi AsyncSocket::get_connections (std::set<SOCKET>& connections)
173
179
{
174
- std::set<SOCKET> result ;
180
+ connections. clear () ;
175
181
176
182
if (m_socket.available ())
177
183
{
184
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
185
+
178
186
for (auto & socket : m_connections)
179
187
{
180
- if (socket == INVALID_SOCKET)
188
+ if (socket == INVALID_SOCKET) // ignore invalid socket handle
181
189
{
182
190
continue ;
183
191
}
184
192
185
- if (m_side == side_type::SERVER && socket == m_socket.handle ())
193
+ if (m_side == side_type::SERVER && socket == m_socket.handle ()) // ignore server socket handle
186
194
{
187
195
continue ;
188
196
}
189
197
190
- result .insert (socket);
198
+ connections .insert (socket);
191
199
}
192
200
}
193
-
194
- return result;
195
201
}
196
202
197
203
VUResult vuapi AsyncSocket::disconnect_connections (const Socket::shutdowns_t flags, const bool cleanup)
198
204
{
199
- auto connections = this ->get_connections ();
205
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
206
+
207
+ std::set<SOCKET> connections;
208
+ this ->get_connections (connections);
200
209
for (const auto & connection : connections)
201
210
{
202
211
Socket socket (m_socket);
@@ -217,14 +226,21 @@ static DWORD WINAPI AsyncSocket_Threading(LPVOID lpParam)
217
226
return 0 ;
218
227
}
219
228
220
- VUResult vuapi AsyncSocket::run_in_thread ( )
229
+ VUResult vuapi AsyncSocket::run ( const bool in_worker_thread )
221
230
{
222
- m_thread = CreateThread (nullptr , 0 , LPTHREAD_START_ROUTINE (AsyncSocket_Threading), this , 0 , nullptr );
223
- m_last_error_code = GetLastError ();
224
- return m_thread != INVALID_HANDLE_VALUE ? VU_OK : 1 ;
231
+ if (in_worker_thread)
232
+ {
233
+ m_thread = CreateThread (nullptr , 0 , LPTHREAD_START_ROUTINE (AsyncSocket_Threading), this , 0 , nullptr );
234
+ m_last_error_code = GetLastError ();
235
+ return m_thread != INVALID_HANDLE_VALUE ? VU_OK : 1 ;
236
+ }
237
+ else
238
+ {
239
+ return this ->run_loop ();
240
+ }
225
241
}
226
242
227
- VUResult vuapi AsyncSocket::run ()
243
+ VUResult vuapi AsyncSocket::run_loop ()
228
244
{
229
245
if (!m_socket.available ())
230
246
{
@@ -349,6 +365,8 @@ IResult vuapi AsyncSocket::do_open(WSANETWORKEVENTS& events, SOCKET& connection)
349
365
return events.iErrorCode [FD_ACCEPT_BIT];
350
366
}
351
367
368
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
369
+
352
370
Socket::Handle obj = { 0 };
353
371
int n = static_cast <int >(sizeof (obj.sai ));
354
372
@@ -380,6 +398,8 @@ IResult vuapi AsyncSocket::do_recv(WSANETWORKEVENTS& events, SOCKET& connection)
380
398
return events.iErrorCode [FD_READ_BIT];
381
399
}
382
400
401
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
402
+
383
403
Socket socket (m_socket);
384
404
socket.attach (connection);
385
405
this ->on_recv (socket);
@@ -395,6 +415,8 @@ IResult vuapi AsyncSocket::do_send(WSANETWORKEVENTS& events, SOCKET& connection)
395
415
return events.iErrorCode [FD_WRITE_BIT];
396
416
}
397
417
418
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
419
+
398
420
Socket socket (m_socket);
399
421
socket.attach (connection);
400
422
this ->on_send (socket);
@@ -405,10 +427,15 @@ IResult vuapi AsyncSocket::do_send(WSANETWORKEVENTS& events, SOCKET& connection)
405
427
406
428
IResult vuapi AsyncSocket::do_close (WSANETWORKEVENTS& events, SOCKET& connection)
407
429
{
408
- if (events.iErrorCode [FD_CLOSE_BIT] != 0 )
409
- {
410
- return events.iErrorCode [FD_CLOSE_BIT];
411
- }
430
+ // TODO: In certain cases(e.g., user - mode drivers), it crashes.
431
+ // I'm not sure why, so temporarily comment out these codes.
432
+ //
433
+ // if (events.iErrorCode[FD_CLOSE_BIT] != 0)
434
+ // {
435
+ // return events.iErrorCode[FD_CLOSE_BIT];
436
+ // }
437
+
438
+ std::lock_guard<std::recursive_mutex> lg (m_mutex_client_list);
412
439
413
440
std::vector<std::pair<SOCKET, HANDLE>> in_used_connections;
414
441
0 commit comments