Skip to content
This repository was archived by the owner on Jul 15, 2021. It is now read-only.

Commit 06dde69

Browse files
author
年迈的老秋风Windy
committed
Thread Bug Fix
See Issue #3 I also added multi-threading support for Socket Wrapper.
1 parent 04b84f7 commit 06dde69

12 files changed

Lines changed: 236 additions & 140 deletions

File tree

examples/Network/Socket/TCPClient/main.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
#include <EasyCrossPlatform.h>
22
#include <iostream>
33

4-
class MySocket{
5-
public:
6-
static void ConnectCB(bool Succeeded, void* ClassPtr){
7-
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
8-
std::cout << "Socket Connected" << std::endl;
9-
}
10-
static void MsgCB(const std::string& Msg, void* ClassPtr){
11-
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
12-
std::cout << "SocketMsg:" << Msg << std::endl;
13-
}
14-
void DisconnectCB(void* ClassPtr){
15-
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
16-
std::cout << "SocketDis" << std::endl;
17-
}
18-
void ErrorCB(int errCode, const std::string& errDescription, void* ClassPtr){
19-
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
20-
std::cout << "Error:" << errDescription << std::endl;
21-
}
4+
class MySocket {
5+
public:
6+
static void ConnectCB(bool Succeeded, void* ClassPtr) {
7+
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
8+
std::cout << "Socket Connected" << std::endl;
9+
}
10+
static void MsgCB(const std::string& Msg, void* ClassPtr) {
11+
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
12+
std::cout << "SocketMsg:" << Msg << std::endl;
13+
}
14+
static void DisconnectCB(void* ClassPtr) {
15+
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
16+
std::cout << "SocketDis" << std::endl;
17+
}
18+
static void ErrorCB(int errCode, const std::string& errDescription, void* ClassPtr) {
19+
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket* MyClass = (EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket*) ClassPtr;
20+
std::cout << "Error:" << errDescription << std::endl;
21+
}
2222
};
2323
int main(int argc, char** args) {
2424
std::cout << "hi" << std::endl;
25-
25+
2626
EasyCrossPlatform::Network::Socket::TCPAsyncClientSocket mSocket;
27+
EasyCrossPlatform::Network::Socket::SocketWorker mSocketWorker;
28+
mSocket.setWorker(mSocketWorker);
2729
mSocket.Init();
2830
//Set CallBack
2931
mSocket.ConnectCallBack = MySocket::ConnectCB;
3032
mSocket.MsgCallBack = MySocket::MsgCB;
3133
mSocket.DisconnectCallBack = MySocket::DisconnectCB;
3234
mSocket.ErrorCallBack = MySocket::ErrorCB;
3335
//Set CallBack finish.
34-
mSocket.setRemoteIPAddr(EasyCrossPlatform::Network::Socket::IpAddr("127.0.0.1",700, true));
36+
mSocket.setRemoteIPAddr(EasyCrossPlatform::Network::Socket::IpAddr("127.0.0.1", 700, true));
3537
mSocket.Connect();
3638
system("pause");
3739
mSocket.SendMsg("2333");

examples/Network/Socket/TCPServer_Echo/main.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <iostream>
33
using namespace EasyCrossPlatform::Network::Socket;
44
std::vector<TCPAsyncClientSocket*> myClients;
5+
std::mutex myMutex;
56
class MyServerFunction{
67
public:
78
static void onServerNewConn(void* newClientSocket, void* ServerClassPtr) {
@@ -21,14 +22,23 @@ class MyServerFunction{
2122
static void onClientDisconnect(void* ClientPtr) {
2223
TCPAsyncClientSocket* MyClient = (TCPAsyncClientSocket*)ClientPtr;
2324
//std::cout << "ClientDisconnect:" << std::endl;
25+
2426
MyClient->Destroy();
25-
for (auto i = myClients.begin(); i != myClients.end(); i++) {
26-
if ((*i) == MyClient) {
27-
delete MyClient;
28-
i=myClients.erase(i);
29-
break;
27+
28+
myMutex.lock();
29+
bool ClientsEmpty = myClients.empty();
30+
31+
32+
if (!ClientsEmpty) {
33+
for (auto i = myClients.begin(); i != myClients.end(); i++) {
34+
if ((*i) == MyClient) {
35+
delete MyClient;
36+
i = myClients.erase(i);
37+
break;
38+
}
3039
}
3140
}
41+
myMutex.unlock();
3242
}
3343
static void onClientMsg(const std::string& data, void* ClientPtr) {
3444
TCPAsyncClientSocket* MyClient = (TCPAsyncClientSocket*)ClientPtr;
@@ -42,8 +52,15 @@ class MyServerFunction{
4252
};
4353
int main(int argc, char** args) {
4454
std::cout << "hi" << std::endl;
45-
55+
EasyCrossPlatform::Network::Socket::SocketWorker myListeningWorker;
56+
EasyCrossPlatform::Network::Socket::SocketWorker myClientWorker1;
57+
EasyCrossPlatform::Network::Socket::SocketWorker myClientWorker2;
58+
std::deque<EasyCrossPlatform::Network::Socket::SocketWorker*> myWorkers;
59+
myWorkers.push_back(&myClientWorker1);
60+
myWorkers.push_back(&myClientWorker2);
61+
4662
EasyCrossPlatform::Network::Socket::TCPAsyncServerSocket mSocket;
63+
mSocket.setWorkers(myListeningWorker, myWorkers);
4764
mSocket.Init();
4865
mSocket.ClientConnectCallBack = MyServerFunction::onClientConnect;
4966
mSocket.ClientDisconnectCallBack = MyServerFunction::onClientDisconnect;

examples/Network/Socket/UDPClient+Server/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ int main(int argc, char** args) {
2020
std::cout << "hi" << std::endl;
2121

2222
MySocket mSocket;
23+
EasyCrossPlatform::Network::Socket::SocketWorker myWorker;
24+
mSocket.setWorker(myWorker);
2325
mSocket.Init();
2426
mSocket.Listen(EasyCrossPlatform::Network::Socket::IpAddr("0.0.0.0", 700, true));
2527
//UDP: If you want every computer in the LAN to recieve, type 255.255.255.255 for IP Address.

include/XSYDMultiTask.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <mutex>
66
namespace EasyCrossPlatform {
77
namespace Thread {
8-
8+
unsigned int getRecommendedThreadNum();
99
typedef void (*SpecificWorkPtr)(std::thread::id ThreadID, void* Parameters, bool * RunningSign, std::mutex *Mutex);
1010
struct WorkInfo {
1111
SpecificWorkPtr MyWork;
@@ -15,13 +15,13 @@
1515
};
1616
class SingleWork {
1717
private:
18-
std::thread *mThread;
19-
bool RunningSign;
18+
std::thread mThread;
2019
SpecificWorkPtr MyWork;
2120
static int DoingJob(WorkInfo MyInfo);
2221
protected:
23-
22+
bool RunningSign;
2423
public:
24+
2525
SingleWork();
2626
SingleWork(SpecificWorkPtr mWork);
2727
SingleWork(const SingleWork &mWork);
@@ -33,7 +33,7 @@
3333
};
3434
class SingleWorkCls {
3535
private:
36-
std::thread *mThread;
36+
std::thread mThread;
3737
std::mutex* TempMutex;
3838
void* TempParameter;
3939
bool RunningSign;

include/XSYDSocketResImpl.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,29 @@
3434
private:
3535

3636
protected:
37-
37+
static EasyCrossPlatform::Thread::SingleWork m_MTManager;
3838
public:
3939
static unsigned int m_num_Client;
4040
static uv_loop_t m_uv_loop;
41-
static EasyCrossPlatform::Thread::SingleWork m_MTManager;
41+
static void Start();
42+
static void Stop();
43+
44+
static void m_MultiThread_Job(std::thread::id ThreadID, void* Parameters, bool * RunningSign, std::mutex *Mutex);
45+
};
46+
class SocketWorker {
47+
private:
48+
49+
protected:
50+
51+
public:
52+
SocketWorker();
53+
unsigned int m_num_Client;
54+
std::shared_ptr<uv_loop_t> m_uv_loop;
55+
EasyCrossPlatform::Thread::SingleWork m_MTManager;
56+
void Start();
57+
void Stop();
4258
static void m_MultiThread_Job(std::thread::id ThreadID, void* Parameters, bool * RunningSign, std::mutex *Mutex);
59+
~SocketWorker();
4360
};
4461
}
4562
}

include/XSYDTCPSocket.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@
2424
bool m_Connected;
2525
bool Inited;
2626
bool Closing;
27-
std::mutex* myMutex;
27+
static std::mutex sharedMutex;
2828
static void m_uv_connect_cb(uv_connect_t* req, int status);
2929
static void m_uv_close_cb(uv_handle_t* handle);
3030
static void m_uv_read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
3131
static void m_uv_shutdown_cb(uv_shutdown_t* req, int state);
3232
static void m_uv_write_cb(uv_write_t* req, int status);
3333
static void m_uv_alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
3434

35+
SocketWorker* mySocketWorker;
3536
void onConnected(bool Succeeded);
3637
void onMsg(const std::string& Msg);
3738
void onDisconnect();
@@ -41,6 +42,7 @@
4142
TCPAsyncClientSocket(const IpAddr& RemoteIP);
4243
TCPAsyncClientSocket(const TCPAsyncClientSocket& oldClient);
4344

45+
void setWorker(SocketWorker& socketWorker);
4446
void Init();
4547
void Connect();
4648
void setRemoteIPAddr(const IpAddr& newIP);
@@ -73,11 +75,14 @@
7375
bool isListening;
7476
bool hasInted;
7577
int m_QueueLength;
78+
SocketWorker* myListenWorker;
79+
std::deque<SocketWorker*> myClientWorker;
7680
public:
7781
TCPAsyncServerSocket();
7882
TCPAsyncServerSocket(const IpAddr& myIP, int QueLength);
7983
TCPAsyncServerSocket(const TCPAsyncServerSocket& oldServer);
8084

85+
void setWorkers(SocketWorker& listeningWorker, std::deque<SocketWorker*>& clientWorkers);
8186
void Init();
8287
void Destroy();
8388

include/XSYDUDPSocket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
IpAddr m_myRemoteAddr;
2626
IpAddr m_myAddr;
27+
SocketWorker* mySocketWorker;
2728
public:
2829
UDPAsyncSocket();
2930
UDPAsyncSocket(const IpAddr& ListeningAddr);
@@ -35,6 +36,7 @@
3536
void Listen(const IpAddr& myNewAddr);
3637
void StopListen();
3738

39+
void setWorker(SocketWorker& myWorker);
3840
void Init();
3941
void Destroy();
4042

src/XSYDDNS.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ void EasyCrossPlatform::Network::Socket::DNSRequest::Init()
135135
this->m_RequestHandle->data = (void*) this;
136136
if (SocketParam::m_num_Client == 0) {
137137
uv_loop_init(&SocketParam::m_uv_loop);
138-
SocketParam::m_MTManager.StartJob();
138+
SocketParam::Start();
139139
}
140140
SocketParam::m_num_Client++;
141141
}
@@ -150,8 +150,7 @@ void EasyCrossPlatform::Network::Socket::DNSRequest::Destroy()
150150
SocketParam::m_num_Client--;
151151
if (SocketParam::m_num_Client == 0) {
152152
uv_stop(&SocketParam::m_uv_loop);
153-
SocketParam::m_MTManager.StopJob();
154-
uv_loop_close(&SocketParam::m_uv_loop);
153+
SocketParam::Stop();
155154
}
156155
}
157156

src/XSYDMultiTask.cpp

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#include <XSYDMultiTask.h>
2+
unsigned int EasyCrossPlatform::Thread::getRecommendedThreadNum() {
3+
return std::thread::hardware_concurrency();
4+
}
25

36
int EasyCrossPlatform::Thread::SingleWork::DoingJob(EasyCrossPlatform::Thread::WorkInfo MyInfo)
47
{
@@ -14,7 +17,6 @@ EasyCrossPlatform::Thread::SingleWork::SingleWork(){
1417
EasyCrossPlatform::Thread::SingleWork::SingleWork(EasyCrossPlatform::Thread::SpecificWorkPtr mWork)
1518
{
1619
this->MyWork = mWork;
17-
this->mThread = NULL;
1820
this->RunningSign = false;
1921
}
2022

@@ -23,7 +25,6 @@ EasyCrossPlatform::Thread::SingleWork::SingleWork(const SingleWork & mWork)
2325
{
2426
this->MyWork = mWork.MyWork;
2527
this->RunningSign = false;
26-
this->mThread = NULL;
2728
}
2829

2930
void EasyCrossPlatform::Thread::SingleWork::setWork(EasyCrossPlatform::Thread::SpecificWorkPtr mWork)
@@ -34,33 +35,20 @@ void EasyCrossPlatform::Thread::SingleWork::setWork(EasyCrossPlatform::Thread::S
3435
bool EasyCrossPlatform::Thread::SingleWork::StartJob(std::mutex *MyMutex, void * Parameter)
3536
{
3637
if (this->RunningSign) { return false; }
37-
if (this->mThread != NULL) {
38-
if (this->mThread->joinable()) {
39-
this->mThread->join();
40-
}
41-
delete this->mThread;
42-
this->mThread = NULL;
43-
}
4438
WorkInfo MyInfo;
4539
MyInfo.mMutex = MyMutex;
4640
MyInfo.MyWork = this->MyWork;
4741
MyInfo.Parameters = Parameter;
4842
MyInfo.RunningSign = &(this->RunningSign);
4943
this->RunningSign = true;
50-
this->mThread = new std::thread(EasyCrossPlatform::Thread::SingleWork::DoingJob, MyInfo);
44+
this->mThread = std::thread(EasyCrossPlatform::Thread::SingleWork::DoingJob, MyInfo);
45+
this->mThread.detach();
5146
return true;
5247
}
5348

5449
void EasyCrossPlatform::Thread::SingleWork::StopJob()
5550
{
5651
this->RunningSign = false;
57-
if (this->mThread != NULL) {
58-
if (this->mThread->joinable()) {
59-
this->mThread->join();
60-
}
61-
delete this->mThread;
62-
this->mThread = NULL;
63-
}
6452
return;
6553
}
6654

@@ -71,14 +59,7 @@ bool EasyCrossPlatform::Thread::SingleWork::getRunningStatus()
7159

7260
EasyCrossPlatform::Thread::SingleWork::~SingleWork()
7361
{
74-
this->RunningSign = false;
75-
if (this->mThread != NULL) {
76-
if (this->mThread->joinable()) {
77-
this->mThread->join();
78-
}
79-
delete this->mThread;
80-
this->mThread = NULL;
81-
}
62+
if (this->RunningSign) { this->StopJob(); }
8263
}
8364

8465
void EasyCrossPlatform::Thread::WorkPool::SuperviseThreads(std::thread::id ThreadID, void * Parameters, bool * RunningSign, std::mutex * Mutex)
@@ -257,7 +238,6 @@ EasyCrossPlatform::Thread::SingleWorkCls::SingleWorkCls()
257238

258239
EasyCrossPlatform::Thread::SingleWorkCls::SingleWorkCls(SingleWorkCls & CopyWorkCls)
259240
{
260-
this->mThread = NULL;
261241
this->RunningSign = false;
262242
}
263243

@@ -269,24 +249,17 @@ bool EasyCrossPlatform::Thread::SingleWorkCls::StartJob(std::mutex* MyMutex, voi
269249
this->TempParameter = Parameters;
270250
this->TempMutex = MyMutex;
271251
this->RunningSign = true;
272-
this->mThread = new std::thread(EasyCrossPlatform::Thread::SingleWorkCls::DoingJob, this);
252+
this->mThread = std::thread(EasyCrossPlatform::Thread::SingleWorkCls::DoingJob, this);
253+
this->mThread.detach();
273254
return true;
274255
}
275256

276257
void EasyCrossPlatform::Thread::SingleWorkCls::StopJob()
277258
{
278259

279-
if (this->mThread != NULL) {
280-
this->RunningSign = false;
281-
if (this->mThread->joinable()) {
282-
this->mThread->join();
283-
}
284-
delete this->mThread;
285-
this->mThread = NULL;
286-
}
260+
this->RunningSign = false;
287261
return;
288262
}
289-
290263
bool EasyCrossPlatform::Thread::SingleWorkCls::getRunningStatus()
291264
{
292265
return this->RunningSign;
@@ -299,12 +272,5 @@ void EasyCrossPlatform::Thread::SingleWorkCls::ThreadJob(std::thread::id ThreadI
299272

300273
EasyCrossPlatform::Thread::SingleWorkCls::~SingleWorkCls()
301274
{
302-
this->RunningSign = false;
303-
if (this->mThread != NULL) {
304-
if (this->mThread->joinable()) {
305-
this->mThread->join();
306-
}
307-
delete this->mThread;
308-
this->mThread = NULL;
309-
}
275+
if (this->RunningSign) { this->StopJob(); }
310276
}

0 commit comments

Comments
 (0)