summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2017-10-31 13:13:13 +0300
committerGeorge Hazan <ghazan@miranda.im>2017-10-31 13:13:13 +0300
commit9437834f8f4d3abf32a8629747385d666c652084 (patch)
tree3756bbc3e4648bf539ab78a891697f9a4e89690f
parentce8b02d7c3df822605392d3e8e6f817953af0864 (diff)
fixes #1011 (thread-unsafe code in SkypeWeb)
-rw-r--r--protocols/SkypeWeb/src/request_queue.cpp10
-rw-r--r--protocols/SkypeWeb/src/skype_polling.cpp33
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp16
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h6
-rw-r--r--protocols/SkypeWeb/src/skype_request.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_trouter.cpp10
-rw-r--r--protocols/SkypeWeb/src/version.h2
7 files changed, 36 insertions, 43 deletions
diff --git a/protocols/SkypeWeb/src/request_queue.cpp b/protocols/SkypeWeb/src/request_queue.cpp
index a2c125e0c4..84d725aba4 100644
--- a/protocols/SkypeWeb/src/request_queue.cpp
+++ b/protocols/SkypeWeb/src/request_queue.cpp
@@ -26,6 +26,11 @@ RequestQueue::RequestQueue(HNETLIBUSER _nlu) :
RequestQueue::~RequestQueue()
{
+ if (hRequestQueueThread) {
+ WaitForSingleObject(hRequestQueueThread, INFINITE);
+ hRequestQueueThread = nullptr;
+ }
+
requests.destroy();
}
@@ -92,8 +97,11 @@ unsigned int RequestQueue::WorkerThread(void *arg)
{
RequestQueue *queue = (RequestQueue*)arg;
- while (!queue->isTerminated) {
+ while (true) {
queue->hRequestQueueEvent.Wait();
+ if (queue->isTerminated)
+ break;
+
while (true) {
RequestQueueItem *item = NULL;
{
diff --git a/protocols/SkypeWeb/src/skype_polling.cpp b/protocols/SkypeWeb/src/skype_polling.cpp
index 872c19d53d..00b6c4e57b 100644
--- a/protocols/SkypeWeb/src/skype_polling.cpp
+++ b/protocols/SkypeWeb/src/skype_polling.cpp
@@ -21,10 +21,12 @@ void CSkypeProto::PollingThread(void*)
{
debugLogA(__FUNCTION__ ": entering");
- int nErrors = 0;
- while (!m_bThreadsTerminated) {
+ while (true) {
m_hPollingEvent.Wait();
- nErrors = 0;
+ if (m_bThreadsTerminated)
+ break;
+
+ int nErrors = 0;
PollRequest *request = new PollRequest(li);
@@ -40,17 +42,8 @@ void CSkypeProto::PollingThread(void*)
if (response->resultCode == 200) {
nErrors = 0;
-
- if (response->pData) {
- char *pData = mir_strdup(response->pData);
- if (pData != NULL) {
- ForkThread(&CSkypeProto::ParsePollData, pData);
- }
- else {
- debugLogA(__FUNCTION__ ": memory overflow !!!");
- break;
- }
- }
+ if (response->pData)
+ ParsePollData(response->pData);
}
else {
nErrors++;
@@ -58,12 +51,8 @@ void CSkypeProto::PollingThread(void*)
if (response->pData) {
JSONNode root = JSONNode::parse(response->pData);
const JSONNode &error = root["errorCode"];
- if (error != NULL) {
- int errorCode = error.as_int();
- if (errorCode == 729) {
- break;
- }
- }
+ if (error && error.as_int() == 729)
+ break;
}
}
m_pollingConnection = response->nlc;
@@ -80,12 +69,10 @@ void CSkypeProto::PollingThread(void*)
debugLogA(__FUNCTION__ ": leaving");
}
-void CSkypeProto::ParsePollData(void *pData)
+void CSkypeProto::ParsePollData(const char *szData)
{
debugLogA(__FUNCTION__);
- ptrA szData((char*)pData); // memory must be freed in any case
-
JSONNode data = JSONNode::parse(szData);
if (!data) return;
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index e6d76d9e10..e1c3368f74 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -23,9 +23,9 @@ CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) :
m_InviteDialogs(1),
m_GCCreateDialogs(1),
m_OutMessages(3, PtrKeySortT),
- m_bThreadsTerminated(0),
- m_TrouterConnection(0),
- m_pollingConnection(0),
+ m_bThreadsTerminated(false),
+ m_TrouterConnection(nullptr),
+ m_pollingConnection(nullptr),
m_opts(this),
Contacts(this)
{
@@ -60,25 +60,25 @@ CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) :
CSkypeProto::~CSkypeProto()
{
requestQueue->Stop();
- delete requestQueue;
+ delete requestQueue; requestQueue = nullptr;
UnInitNetwork();
UninitPopups();
if (m_hPollingThread) {
- TerminateThread(m_hPollingThread, NULL);
+ WaitForSingleObject(m_hPollingThread, INFINITE);
m_hPollingThread = NULL;
}
if (m_hTrouterThread) {
- TerminateThread(m_hTrouterThread, NULL);
+ WaitForSingleObject(m_hTrouterThread, INFINITE);
m_hTrouterThread = NULL;
}
SkypeUnsetTimer();
}
-int CSkypeProto::OnPreShutdown(WPARAM, LPARAM)
+int CSkypeProto::OnExit()
{
debugLogA(__FUNCTION__);
@@ -299,7 +299,7 @@ int CSkypeProto::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam
return OnInitStatusMenu();
case EV_PROTO_ONEXIT:
- return OnPreShutdown(wParam, lParam);
+ return OnExit();
}
return 1;
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
index a767f571f1..cc70467445 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -25,8 +25,6 @@ struct CSkypeProto : public PROTO < CSkypeProto >
{
friend CSkypeOptionsMain;
friend CSkypeGCCreateDlg;
- //friend CSkypeChatroom;
- //friend ChatUser;
public:
@@ -77,7 +75,7 @@ public:
// events
static int OnModulesLoaded(WPARAM, LPARAM);
int __cdecl OnDbEventRead(WPARAM, LPARAM);
- int __cdecl OnPreShutdown(WPARAM, LPARAM);
+ int __cdecl OnExit();
//search
void __cdecl SearchBasicThread(void* id);
@@ -362,7 +360,7 @@ private:
//polling
void __cdecl PollingThread (void*);
- void __cdecl ParsePollData (void *pData);
+ void __cdecl ParsePollData (const char*);
void ProcessEndpointPresence (const JSONNode &node);
void ProcessUserPresence (const JSONNode &node);
void ProcessNewMessage (const JSONNode &node);
diff --git a/protocols/SkypeWeb/src/skype_request.cpp b/protocols/SkypeWeb/src/skype_request.cpp
index 7b8107c10c..6be0271352 100644
--- a/protocols/SkypeWeb/src/skype_request.cpp
+++ b/protocols/SkypeWeb/src/skype_request.cpp
@@ -56,4 +56,4 @@ void CSkypeProto::SendRequest(HttpRequest *request, SkypeResponseWithArgCallback
{
SkypeResponseDelegateBase *delegate = new SkypeResponseDelegateWithArg(this, response, arg);
requestQueue->Send(request, SkypeHttpResponse, delegate);
-} \ No newline at end of file
+}
diff --git a/protocols/SkypeWeb/src/skype_trouter.cpp b/protocols/SkypeWeb/src/skype_trouter.cpp
index a34e35c8e9..c5c055e213 100644
--- a/protocols/SkypeWeb/src/skype_trouter.cpp
+++ b/protocols/SkypeWeb/src/skype_trouter.cpp
@@ -118,12 +118,12 @@ void CSkypeProto::TRouterThread(void*)
{
debugLogA(__FUNCTION__": entering");
- int errors = 0;
-
- while (!m_bThreadsTerminated) {
-
+ while (true) {
m_hTrouterEvent.Wait();
- errors = 0;
+ if (m_bThreadsTerminated)
+ break;
+
+ int errors = 0;
TrouterPollRequest *request = new TrouterPollRequest(TRouter.socketIo, TRouter.connId, TRouter.st, TRouter.se, TRouter.sig, TRouter.instance, TRouter.ccid, TRouter.sessId);
diff --git a/protocols/SkypeWeb/src/version.h b/protocols/SkypeWeb/src/version.h
index 4df19f1089..9a4796f6cc 100644
--- a/protocols/SkypeWeb/src/version.h
+++ b/protocols/SkypeWeb/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 12
#define __RELEASE_NUM 2
-#define __BUILD_NUM 4
+#define __BUILD_NUM 5
#include <stdver.h>