Skip to content

Commit 137b315

Browse files
committed
Vutils
1 parent 69cbe9f commit 137b315

File tree

4 files changed

+75
-43
lines changed

4 files changed

+75
-43
lines changed

Test/Sample.AsyncSocket.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ void example_binding(const vu::Endpoint& endpoint)
2121
printf("client %d closed\n", client.get_remote_sai().sin_port);
2222
});
2323

24-
server.on(vu::AsyncSocket::SEND, [](vu::Socket& client) -> void
25-
{
26-
std::string s = "hello from server";
27-
client.send(s.data(), int(s.size()));
28-
printf("client %d send `%s`\n", client.get_remote_sai().sin_port, s.c_str());
29-
});
24+
//server.on(vu::AsyncSocket::SEND, [](vu::Socket& client) -> void
25+
//{
26+
// std::string s = "hello from server";
27+
// client.send(s.data(), int(s.size()));
28+
// printf("client %d send `%s`\n", client.get_remote_sai().sin_port, s.c_str());
29+
//});
3030

3131
server.on(vu::AsyncSocket::RECV, [](vu::Socket& client) -> void
3232
{
@@ -57,12 +57,12 @@ void example_inheritance(const vu::Endpoint& endpoint)
5757
printf("client %d closed\n", client.get_remote_sai().sin_port);
5858
}
5959

60-
virtual void on_send(vu::Socket& client)
61-
{
62-
std::string s = "hello from server";
63-
client.send(s.data(), int(s.size()));
64-
printf("client %d send `%s`\n", client.get_remote_sai().sin_port, s.c_str());
65-
}
60+
//virtual void on_send(vu::Socket& client)
61+
//{
62+
// std::string s = "hello from server";
63+
// client.send(s.data(), int(s.size()));
64+
// printf("client %d send `%s`\n", client.get_remote_sai().sin_port, s.c_str());
65+
//}
6666

6767
virtual void on_recv(vu::Socket& client)
6868
{

include/Vutils.h

+16-11
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ class Socket : public LastError
13241324
VUResult vuapi accept(Handle& socket);
13251325

13261326
VUResult vuapi connect(const Endpoint& endpoint);
1327-
VUResult vuapi disconnect(const shutdowns_t flags = SD_BOTH, const bool cleanup = true);
1327+
VUResult vuapi disconnect(const shutdowns_t flags = SD_BOTH, const bool cleanup = false);
13281328

13291329
IResult vuapi send(const char* ptr_data, int size, const flags_t flags = MSG_NONE);
13301330
IResult vuapi send(const Buffer& data, const flags_t flags = MSG_NONE);
@@ -1376,11 +1376,11 @@ class AsyncSocket : public LastError
13761376

13771377
enum function : uint
13781378
{
1379-
CONNECT,
1380-
OPEN,
1381-
CLOSE,
1382-
RECV,
1383-
SEND,
1379+
CONNECT, // for only client side
1380+
OPEN, // for only server side
1381+
CLOSE, // for both server & client
1382+
RECV, // for both server & client
1383+
SEND, // for both server & client (should not use except required a special case)
13841384
UNDEFINED,
13851385
};
13861386

@@ -1404,12 +1404,16 @@ class AsyncSocket : public LastError
14041404
bool vuapi running() const;
14051405

14061406
/**
1407+
* for client side
14071408
* https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaeventselect?redirectedfrom=MSDN#return-value
14081409
* Note: After connected (FD_CONNECT), client will be auto generated first event FD_WRITE.
14091410
*/
14101411
VUResult vuapi connect(const Endpoint& endpoint);
14111412
VUResult vuapi connect(const std::string& address, const ushort port);
14121413

1414+
/**
1415+
* for server side
1416+
*/
14131417
VUResult vuapi bind(const Endpoint& endpoint);
14141418
VUResult vuapi bind(const std::string& address, const ushort port);
14151419

@@ -1419,14 +1423,13 @@ class AsyncSocket : public LastError
14191423
*/
14201424
VUResult vuapi listen(const int maxcon = SOMAXCONN);
14211425

1422-
VUResult vuapi run();
1423-
VUResult vuapi run_in_thread();
1426+
VUResult vuapi run(const bool in_worker_thread = false);
14241427

14251428
VUResult vuapi stop();
1426-
IResult vuapi close();
1429+
IResult vuapi close(const Socket::shutdowns_t flags = SD_BOTH, const bool cleanup = false);
14271430

1428-
std::set<SOCKET> vuapi get_connections() const;
1429-
VUResult vuapi disconnect_connections(const Socket::shutdowns_t flags = SD_BOTH, const bool cleanup = true);
1431+
void vuapi get_connections(std::set<SOCKET>& connections);
1432+
VUResult vuapi disconnect_connections(const Socket::shutdowns_t flags = SD_BOTH, const bool cleanup = false);
14301433

14311434
IResult vuapi send(const SOCKET& connection, const char* ptr_data, int size, const Socket::flags_t flags = MSG_NONE);
14321435
IResult vuapi send(const SOCKET& connection, const Buffer& data, const Socket::flags_t flags = MSG_NONE);
@@ -1442,6 +1445,7 @@ class AsyncSocket : public LastError
14421445
protected:
14431446
void vuapi initialze();
14441447
VUResult vuapi loop();
1448+
VUResult vuapi run_loop();
14451449

14461450
IResult vuapi do_connect(WSANETWORKEVENTS& events, SOCKET& connection);
14471451
IResult vuapi do_open(WSANETWORKEVENTS& events, SOCKET& connection);
@@ -1455,6 +1459,7 @@ class AsyncSocket : public LastError
14551459
bool m_running;
14561460
DWORD m_n_events;
14571461
SOCKET m_connections[WSA_MAXIMUM_WAIT_EVENTS];
1462+
std::recursive_mutex m_mutex_client_list;
14581463
WSAEVENT m_events[WSA_MAXIMUM_WAIT_EVENTS];
14591464
fn_prototype_t m_functions[function::UNDEFINED];
14601465
std::mutex m_mutex;

src/details/asyncsocket.cpp

+46-19
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ void vuapi AsyncSocket::initialze()
4040
{
4141
m_n_events = 0;
4242

43+
std::lock_guard<std::recursive_mutex> lg(m_mutex_client_list);
44+
4345
memset(m_connections, int(INVALID_SOCKET), sizeof(m_connections));
4446
memset(m_events, int(0), sizeof(m_events));
4547

@@ -95,6 +97,8 @@ VUResult vuapi AsyncSocket::listen(const int maxcon)
9597
return 2;
9698
}
9799

100+
std::lock_guard<std::recursive_mutex> lg(m_mutex_client_list);
101+
98102
m_connections[m_n_events] = m_socket.handle();
99103
m_events[m_n_events] = event;
100104
m_n_events++;
@@ -106,11 +110,11 @@ VUResult vuapi AsyncSocket::listen(const int maxcon)
106110
return result;
107111
}
108112

109-
IResult vuapi AsyncSocket::close()
113+
IResult vuapi AsyncSocket::close(const Socket::shutdowns_t flags, const bool cleanup)
110114
{
111115
this->stop();
112116

113-
this->disconnect_connections();
117+
this->disconnect_connections(flags, cleanup);
114118

115119
if (m_thread != INVALID_HANDLE_VALUE)
116120
{
@@ -148,6 +152,8 @@ VUResult vuapi AsyncSocket::connect(const Endpoint& endpoint)
148152
return 2;
149153
}
150154

155+
std::lock_guard<std::recursive_mutex> lg(m_mutex_client_list);
156+
151157
auto result = m_socket.connect(endpoint);
152158
if (result == VU_OK)
153159
{
@@ -169,34 +175,37 @@ VUResult vuapi AsyncSocket::connect(const std::string& address, const ushort por
169175
return this->connect(endpoint);
170176
}
171177

172-
std::set<SOCKET> vuapi AsyncSocket::get_connections() const
178+
void vuapi AsyncSocket::get_connections(std::set<SOCKET>& connections)
173179
{
174-
std::set<SOCKET> result;
180+
connections.clear();
175181

176182
if (m_socket.available())
177183
{
184+
std::lock_guard<std::recursive_mutex> lg(m_mutex_client_list);
185+
178186
for (auto& socket : m_connections)
179187
{
180-
if (socket == INVALID_SOCKET)
188+
if (socket == INVALID_SOCKET) // ignore invalid socket handle
181189
{
182190
continue;
183191
}
184192

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
186194
{
187195
continue;
188196
}
189197

190-
result.insert(socket);
198+
connections.insert(socket);
191199
}
192200
}
193-
194-
return result;
195201
}
196202

197203
VUResult vuapi AsyncSocket::disconnect_connections(const Socket::shutdowns_t flags, const bool cleanup)
198204
{
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);
200209
for (const auto& connection : connections)
201210
{
202211
Socket socket(m_socket);
@@ -217,14 +226,21 @@ static DWORD WINAPI AsyncSocket_Threading(LPVOID lpParam)
217226
return 0;
218227
}
219228

220-
VUResult vuapi AsyncSocket::run_in_thread()
229+
VUResult vuapi AsyncSocket::run(const bool in_worker_thread)
221230
{
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+
}
225241
}
226242

227-
VUResult vuapi AsyncSocket::run()
243+
VUResult vuapi AsyncSocket::run_loop()
228244
{
229245
if (!m_socket.available())
230246
{
@@ -349,6 +365,8 @@ IResult vuapi AsyncSocket::do_open(WSANETWORKEVENTS& events, SOCKET& connection)
349365
return events.iErrorCode[FD_ACCEPT_BIT];
350366
}
351367

368+
std::lock_guard<std::recursive_mutex> lg(m_mutex_client_list);
369+
352370
Socket::Handle obj = { 0 };
353371
int n = static_cast<int>(sizeof(obj.sai));
354372

@@ -380,6 +398,8 @@ IResult vuapi AsyncSocket::do_recv(WSANETWORKEVENTS& events, SOCKET& connection)
380398
return events.iErrorCode[FD_READ_BIT];
381399
}
382400

401+
std::lock_guard<std::recursive_mutex> lg(m_mutex_client_list);
402+
383403
Socket socket(m_socket);
384404
socket.attach(connection);
385405
this->on_recv(socket);
@@ -395,6 +415,8 @@ IResult vuapi AsyncSocket::do_send(WSANETWORKEVENTS& events, SOCKET& connection)
395415
return events.iErrorCode[FD_WRITE_BIT];
396416
}
397417

418+
std::lock_guard<std::recursive_mutex> lg(m_mutex_client_list);
419+
398420
Socket socket(m_socket);
399421
socket.attach(connection);
400422
this->on_send(socket);
@@ -405,10 +427,15 @@ IResult vuapi AsyncSocket::do_send(WSANETWORKEVENTS& events, SOCKET& connection)
405427

406428
IResult vuapi AsyncSocket::do_close(WSANETWORKEVENTS& events, SOCKET& connection)
407429
{
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);
412439

413440
std::vector<std::pair<SOCKET, HANDLE>> in_used_connections;
414441

src/details/socket.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ VUResult vuapi Socket::disconnect(const shutdowns_t flags, const bool cleanup)
637637
return 1;
638638
}
639639

640-
if (cleanup) // clean-up all remaining data in the socket
640+
if (cleanup) // clean-up all remaining data in the socket (does not need with the SD_BOTH flag)
641641
{
642642
vu::Buffer temp;
643643
this->recv_all(temp);

0 commit comments

Comments
 (0)