diff options
author | George Hazan <ghazan@miranda.im> | 2017-10-31 13:13:13 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2017-10-31 13:13:13 +0300 |
commit | 9437834f8f4d3abf32a8629747385d666c652084 (patch) | |
tree | 3756bbc3e4648bf539ab78a891697f9a4e89690f | |
parent | ce8b02d7c3df822605392d3e8e6f817953af0864 (diff) |
fixes #1011 (thread-unsafe code in SkypeWeb)
-rw-r--r-- | protocols/SkypeWeb/src/request_queue.cpp | 10 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_polling.cpp | 33 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_proto.cpp | 16 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_proto.h | 6 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_request.cpp | 2 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_trouter.cpp | 10 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/version.h | 2 |
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>
|