From 0dd998f1a2d1ca3a3fca9bc6ea85c40ccfeae850 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 12 May 2019 20:38:09 +0300 Subject: fixes #1948 (memory allocation problem in Scriver) --- plugins/Scriver/src/cmdlist.cpp | 7 +-- plugins/Scriver/src/msgdialog.cpp | 2 +- plugins/Scriver/src/sendqueue.cpp | 122 +++++++++++++------------------------- plugins/Scriver/src/sendqueue.h | 16 +++-- 4 files changed, 56 insertions(+), 91 deletions(-) diff --git a/plugins/Scriver/src/cmdlist.cpp b/plugins/Scriver/src/cmdlist.cpp index 4b8b66da7d..509b1f503f 100644 --- a/plugins/Scriver/src/cmdlist.cpp +++ b/plugins/Scriver/src/cmdlist.cpp @@ -57,7 +57,7 @@ TCmdList* tcmdlist_remove_first(TCmdList *list) return list; } -TCmdList *tcmdlist_remove(TCmdList *list, TCmdList *n) +TCmdList* tcmdlist_remove(TCmdList *list, TCmdList *n) { if (n->next) n->next->prev = n->prev; if (n->prev) n->prev->next = n->next; @@ -87,10 +87,9 @@ TCmdList* tcmdlist_last(TCmdList *list) void tcmdlist_free(TCmdList *&list) { - TCmdList *n = list, *next; - + TCmdList *n = list; while (n != nullptr) { - next = n->next; + auto *next = n->next; mir_free(n->szCmd); mir_free(n); n = next; diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp index 9444c5078b..ab2d569f71 100644 --- a/plugins/Scriver/src/msgdialog.cpp +++ b/plugins/Scriver/src/msgdialog.cpp @@ -460,7 +460,7 @@ void CSrmmWindow::onClick_Ok(CCtrlButton *pButton) cmdListNew = tcmdlist_last(cmdList); } if (msi.sendBuffer != nullptr) - cmdList = tcmdlist_append(cmdList, rtrim(msi.sendBuffer), 20, FALSE); + cmdList = tcmdlist_append(cmdList, mir_strdup(rtrim(msi.sendBuffer)), 20, FALSE); cmdListCurrent = nullptr; diff --git a/plugins/Scriver/src/sendqueue.cpp b/plugins/Scriver/src/sendqueue.cpp index c1278c1353..886dd1fc3c 100644 --- a/plugins/Scriver/src/sendqueue.cpp +++ b/plugins/Scriver/src/sendqueue.cpp @@ -23,29 +23,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" -static MessageSendQueueItem *global_sendQueue = nullptr; +static OBJLIST arQueue(1, PtrKeySortT); static mir_cs queueMutex; MessageSendQueueItem* CreateSendQueueItem(HWND hwndSender) { - MessageSendQueueItem *item = (MessageSendQueueItem*)mir_calloc(sizeof(MessageSendQueueItem)); - - mir_cslock lck(queueMutex); + MessageSendQueueItem *item = new MessageSendQueueItem(); item->hwndSender = hwndSender; - item->next = global_sendQueue; - if (global_sendQueue != nullptr) - global_sendQueue->prev = item; - global_sendQueue = item; + mir_cslock lck(queueMutex); + arQueue.insert(item); return item; } MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, MCONTACT hContact) { mir_cslock lck(queueMutex); - for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) - if (item->hwndSender == hwndSender && item->hContact == hContact && item->hwndErrorDlg == nullptr) - return item; + for (auto &it : arQueue) + if (it->hwndSender == hwndSender && it->hContact == hContact && it->hwndErrorDlg == nullptr) + return it; return nullptr; } @@ -53,61 +49,47 @@ MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, MCONTACT h MessageSendQueueItem* FindSendQueueItem(MCONTACT hContact, HANDLE hSendId) { mir_cslock lock(queueMutex); - for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) - if (item->hContact == hContact && HANDLE(item->hSendId) == hSendId) - return item; + for (auto &it : arQueue) + if (it->hContact == hContact && HANDLE(it->hSendId) == hSendId) + return it; return nullptr; } -BOOL RemoveSendQueueItem(MessageSendQueueItem* item) +bool RemoveSendQueueItem(MessageSendQueueItem *item) { HWND hwndSender = item->hwndSender; + { + mir_cslock lock(queueMutex); + arQueue.remove(item); + } - mir_cslock lock(queueMutex); - if (item->prev != nullptr) - item->prev->next = item->next; - else - global_sendQueue = item->next; - - if (item->next != nullptr) - item->next->prev = item->prev; - - mir_free(item->sendBuffer); - mir_free(item->proto); - mir_free(item); - - for (item = global_sendQueue; item != nullptr; item = item->next) - if (item->hwndSender == hwndSender) - return FALSE; + for (auto &it : arQueue) + if (it->hwndSender == hwndSender) + return false; - return TRUE; + return true; } void ReportSendQueueTimeouts(HWND hwndSender) { - MessageSendQueueItem *item, *item2; int timeout = g_plugin.getDword(SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT); mir_cslock lock(queueMutex); - for (item = global_sendQueue; item != nullptr; item = item2) { - item2 = item->next; - if (item->timeout < timeout) { - item->timeout += 1000; - if (item->timeout >= timeout) { - if (item->hwndSender == hwndSender && item->hwndErrorDlg == nullptr) { - if (hwndSender != nullptr) { - CErrorDlg *pDlg = new CErrorDlg(TranslateT("The message send timed out."), hwndSender, item); - PostMessage(hwndSender, DM_SHOWERRORMESSAGE, 0, (LPARAM)pDlg); - } - else { - /* TODO: Handle errors outside messaging window in a better way */ - RemoveSendQueueItem(item); - } - } - } + for (auto &it : arQueue.rev_iter()) { + if (it->timeout >= timeout) + continue; + + it->timeout += 1000; + if (it->timeout < timeout || it->hwndSender != hwndSender || it->hwndErrorDlg != nullptr) + continue; + + if (hwndSender != nullptr) { + CErrorDlg *pDlg = new CErrorDlg(TranslateT("The message send timed out."), hwndSender, it); + PostMessage(hwndSender, DM_SHOWERRORMESSAGE, 0, (LPARAM)pDlg); } + else arQueue.remove(arQueue.indexOf(&it)); } } @@ -115,13 +97,13 @@ void ReleaseSendQueueItems(HWND hwndSender) { mir_cslock lock(queueMutex); - for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) { - if (item->hwndSender == hwndSender) { - item->hwndSender = nullptr; - if (item->hwndErrorDlg != nullptr) - DestroyWindow(item->hwndErrorDlg); + for (auto &it : arQueue) { + if (it->hwndSender == hwndSender) { + it->hwndSender = nullptr; - item->hwndErrorDlg = nullptr; + if (it->hwndErrorDlg != nullptr) + DestroyWindow(it->hwndErrorDlg); + it->hwndErrorDlg = nullptr; } } } @@ -132,10 +114,10 @@ int ReattachSendQueueItems(HWND hwndSender, MCONTACT hContact) mir_cslock lock(queueMutex); - for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) { - if (item->hContact == hContact && item->hwndSender == nullptr) { - item->hwndSender = hwndSender; - item->timeout = 0; + for (auto &it : arQueue) { + if (it->hContact == hContact && it->hwndSender == nullptr) { + it->hwndSender = hwndSender; + it->timeout = 0; count++; } } @@ -144,32 +126,12 @@ int ReattachSendQueueItems(HWND hwndSender, MCONTACT hContact) void RemoveAllSendQueueItems() { - MessageSendQueueItem *item, *item2; mir_cslock lock(queueMutex); - for (item = global_sendQueue; item != nullptr; item = item2) { - item2 = item->next; - RemoveSendQueueItem(item); - } + arQueue.destroy(); } void SendSendQueueItem(MessageSendQueueItem* item) { - mir_cslockfull lock(queueMutex); item->timeout = 0; - - if (item->prev != nullptr) { - item->prev->next = item->next; - if (item->next != nullptr) - item->next->prev = item->prev; - - item->next = global_sendQueue; - item->prev = nullptr; - if (global_sendQueue != nullptr) - global_sendQueue->prev = item; - - global_sendQueue = item; - } - lock.unlock(); - item->hSendId = ProtoChainSend(item->hContact, PSS_MESSAGE, item->flags, (LPARAM)item->sendBuffer); } diff --git a/plugins/Scriver/src/sendqueue.h b/plugins/Scriver/src/sendqueue.h index 1efb70dbe4..092d43a602 100644 --- a/plugins/Scriver/src/sendqueue.h +++ b/plugins/Scriver/src/sendqueue.h @@ -24,8 +24,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef SRMM_SENDQUEUE_H #define SRMM_SENDQUEUE_H -struct MessageSendQueueItem +struct MessageSendQueueItem : public MZeroedObject { + ~MessageSendQueueItem() + { + mir_free(proto); + mir_free(sendBuffer); + } + HWND hwndSender; MCONTACT hContact; char *proto; @@ -36,18 +42,16 @@ struct MessageSendQueueItem int codepage; int flags; HWND hwndErrorDlg; - - MessageSendQueueItem *prev, *next; }; MessageSendQueueItem* CreateSendQueueItem(HWND hwndSender); -wchar_t * GetSendBufferMsg(MessageSendQueueItem *item); MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, MCONTACT hContact); MessageSendQueueItem* FindSendQueueItem(MCONTACT hContact, HANDLE hSendId); -BOOL RemoveSendQueueItem(MessageSendQueueItem* item); + +bool RemoveSendQueueItem(MessageSendQueueItem* item); void ReportSendQueueTimeouts(HWND hwndSender); void ReleaseSendQueueItems(HWND hwndSender); -int ReattachSendQueueItems(HWND hwndSender, MCONTACT hContact); +int ReattachSendQueueItems(HWND hwndSender, MCONTACT hContact); void RemoveAllSendQueueItems(); void SendSendQueueItem(MessageSendQueueItem* item); -- cgit v1.2.3