From 8e91cc3b73d6c77c79781115fc1acbbb7fddfe32 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 7 Mar 2015 19:39:33 +0000 Subject: - old ugly borkred mutexes removed from ICQ, cause all threads work as expected for a long time; - even older ugly linked list of avatars replaced with LIST<>; - version bump git-svn-id: http://svn.miranda-ng.org/main/trunk@12369 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/IcqOscarJ/src/cookies.cpp | 20 +-- protocols/IcqOscarJ/src/directpackets.cpp | 2 +- protocols/IcqOscarJ/src/fam_01service.cpp | 10 +- protocols/IcqOscarJ/src/fam_04message.cpp | 8 +- protocols/IcqOscarJ/src/icq_avatar.cpp | 226 +++++++++---------------- protocols/IcqOscarJ/src/icq_avatar.h | 11 +- protocols/IcqOscarJ/src/icq_direct.cpp | 16 +- protocols/IcqOscarJ/src/icq_infoupdate.cpp | 89 ++++------ protocols/IcqOscarJ/src/icq_proto.cpp | 49 +----- protocols/IcqOscarJ/src/icq_proto.h | 34 ++-- protocols/IcqOscarJ/src/icq_rates.cpp | 96 +++++------ protocols/IcqOscarJ/src/icq_rates.h | 101 +++++------ protocols/IcqOscarJ/src/icq_server.cpp | 40 +++-- protocols/IcqOscarJ/src/icq_servlist.cpp | 93 +++++----- protocols/IcqOscarJ/src/icq_xstatus.cpp | 19 ++- protocols/IcqOscarJ/src/icq_xtraz.cpp | 8 +- protocols/IcqOscarJ/src/oscar_filetransfer.cpp | 18 +- protocols/IcqOscarJ/src/stdpackets.cpp | 4 +- protocols/IcqOscarJ/src/utilities.cpp | 94 ++++------ protocols/IcqOscarJ/src/utilities.h | 41 ----- protocols/IcqOscarJ/src/version.h | 4 +- 21 files changed, 399 insertions(+), 584 deletions(-) (limited to 'protocols/IcqOscarJ') diff --git a/protocols/IcqOscarJ/src/cookies.cpp b/protocols/IcqOscarJ/src/cookies.cpp index be71d6b4ef..22bcf92a95 100644 --- a/protocols/IcqOscarJ/src/cookies.cpp +++ b/protocols/IcqOscarJ/src/cookies.cpp @@ -47,7 +47,7 @@ void CIcqProto::RemoveExpiredCookies() // Generate and allocate cookie DWORD CIcqProto::AllocateCookie(BYTE bType, WORD wIdent, MCONTACT hContact, void *pvExtra) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); DWORD dwThisSeq = wCookieSeq++; dwThisSeq &= 0x7FFF; @@ -67,7 +67,7 @@ DWORD CIcqProto::AllocateCookie(BYTE bType, WORD wIdent, MCONTACT hContact, void DWORD CIcqProto::GenerateCookie(WORD wIdent) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); DWORD dwThisSeq = wCookieSeq++; dwThisSeq &= 0x7FFF; @@ -77,7 +77,7 @@ DWORD CIcqProto::GenerateCookie(WORD wIdent) int CIcqProto::GetCookieType(DWORD dwCookie) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); int i = cookies.getIndex((icq_cookie_info*)&dwCookie); if (i != INVALID_COOKIE_INDEX) @@ -88,7 +88,7 @@ int CIcqProto::GetCookieType(DWORD dwCookie) int CIcqProto::FindCookie(DWORD dwCookie, MCONTACT *phContact, void **ppvExtra) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); int i = cookies.getIndex((icq_cookie_info*)&dwCookie); if (i != INVALID_COOKIE_INDEX) { @@ -106,7 +106,7 @@ int CIcqProto::FindCookie(DWORD dwCookie, MCONTACT *phContact, void **ppvExtra) int CIcqProto::FindCookieByData(void *pvExtra, DWORD *pdwCookie, MCONTACT *phContact) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); for (int i = 0; i < cookies.getCount(); i++) { if (pvExtra == cookies[i]->pvExtra) { @@ -125,7 +125,7 @@ int CIcqProto::FindCookieByData(void *pvExtra, DWORD *pdwCookie, MCONTACT *phCon int CIcqProto::FindCookieByType(BYTE bType, DWORD *pdwCookie, MCONTACT *phContact, void** ppvExtra) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); for (int i = 0; i < cookies.getCount(); i++) { if (bType == cookies[i]->bType) { @@ -146,7 +146,7 @@ int CIcqProto::FindCookieByType(BYTE bType, DWORD *pdwCookie, MCONTACT *phContac int CIcqProto::FindMessageCookie(DWORD dwMsgID1, DWORD dwMsgID2, DWORD *pdwCookie, MCONTACT *phContact, cookie_message_data **ppvExtra) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); for (int i = 0; i < cookies.getCount(); i++) { if (cookies[i]->bType == CKT_MESSAGE || cookies[i]->bType == CKT_FILE || cookies[i]->bType == CKT_REVERSEDIRECT) { @@ -172,7 +172,7 @@ int CIcqProto::FindMessageCookie(DWORD dwMsgID1, DWORD dwMsgID2, DWORD *pdwCooki void CIcqProto::FreeCookie(DWORD dwCookie) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); int i = cookies.getIndex((icq_cookie_info*)&dwCookie); if (i != INVALID_COOKIE_INDEX) { @@ -188,7 +188,7 @@ void CIcqProto::FreeCookie(DWORD dwCookie) void CIcqProto::FreeCookieByData(BYTE bType, void *pvExtra) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); for (int i = 0; i < cookies.getCount(); i++) { icq_cookie_info *cookie = cookies[i]; @@ -205,7 +205,7 @@ void CIcqProto::FreeCookieByData(BYTE bType, void *pvExtra) void CIcqProto::ReleaseCookie(DWORD dwCookie) { - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); int i = cookies.getIndex(( icq_cookie_info* )&dwCookie ); if (i != INVALID_COOKIE_INDEX) { diff --git a/protocols/IcqOscarJ/src/directpackets.cpp b/protocols/IcqOscarJ/src/directpackets.cpp index 2f63211283..34253c5763 100644 --- a/protocols/IcqOscarJ/src/directpackets.cpp +++ b/protocols/IcqOscarJ/src/directpackets.cpp @@ -89,7 +89,7 @@ void CIcqProto::icq_sendAwayMsgReplyDirect(directconnect* dc, WORD wCookie, BYTE if (validateStatusMessageRequest(dc->hContact, msgType)) { NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dc->dwRemoteUin); - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); if (szMsg && *szMsg) { // prepare Ansi message - only Ansi supported diff --git a/protocols/IcqOscarJ/src/fam_01service.cpp b/protocols/IcqOscarJ/src/fam_01service.cpp index 014845ece3..3042967e53 100644 --- a/protocols/IcqOscarJ/src/fam_01service.cpp +++ b/protocols/IcqOscarJ/src/fam_01service.cpp @@ -295,10 +295,10 @@ void CIcqProto::handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_heade unpackWord(&pBuffer, &wClass); pBuffer += 20; unpackDWord(&pBuffer, &dwLevel); - - m_ratesMutex->Enter(); - m_rates->updateLevel(wClass, dwLevel); - m_ratesMutex->Leave(); + { + mir_cslock l(m_ratesMutex); + m_rates->updateLevel(wClass, dwLevel); + } if (wStatus == 2 || wStatus == 3) { // this is only the simplest solution, needs rate management to every section @@ -882,7 +882,7 @@ void CIcqProto::handleServUINSettings(int nPort, serverthread_info *info) if (m_bAimEnabled) { char **szAwayMsg = NULL; - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); szAwayMsg = MirandaStatusToAwayMsg(m_iStatus); if (szAwayMsg) diff --git a/protocols/IcqOscarJ/src/fam_04message.cpp b/protocols/IcqOscarJ/src/fam_04message.cpp index c2b7563bf2..afaa6e59bb 100644 --- a/protocols/IcqOscarJ/src/fam_04message.cpp +++ b/protocols/IcqOscarJ/src/fam_04message.cpp @@ -1868,9 +1868,11 @@ void CIcqProto::handleMessageTypes(DWORD dwUin, char *szUID, DWORD dwTimestamp, int nMsgType; }; - m_ratesMutex->Enter(); - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); - m_ratesMutex->Leave(); + WORD wGroup; + { + mir_cslock l(m_ratesMutex); + wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); + } rates_status_message_response rr(this, wGroup); rr.bExtended = (nMsgFlags & MTF_STATUS_EXTENDED) == MTF_STATUS_EXTENDED; diff --git a/protocols/IcqOscarJ/src/icq_avatar.cpp b/protocols/IcqOscarJ/src/icq_avatar.cpp index 147d16a898..63a8496c55 100644 --- a/protocols/IcqOscarJ/src/icq_avatar.cpp +++ b/protocols/IcqOscarJ/src/icq_avatar.cpp @@ -54,25 +54,6 @@ avatars_request::~avatars_request() } } -avatars_request* CIcqProto::ReleaseAvatarRequestInQueue(avatars_request *request) -{ - avatars_request *pNext = request->pNext; - avatars_request **par = &m_avatarsQueue; - - avatars_request *ar = m_avatarsQueue; - while (ar) { - if (ar == request) { // found it, remove - *par = ar->pNext; - break; - } - par = &ar->pNext; - ar = ar->pNext; - } - - delete request; - return pNext; -} - TCHAR* CIcqProto::GetOwnAvatarFileName() { DBVARIANT dbvFile = {DBVT_DELETED}; @@ -192,7 +173,7 @@ int CIcqProto::IsAvatarChanged(MCONTACT hContact, const BYTE *pHash, size_t nHas void CIcqProto::StartAvatarThread(HANDLE hConn, char *cookie, size_t cookieLen) // called from event { if (!hConn) { - icq_lock l(m_avatarsMutex); // place avatars lock + mir_cslock l(m_avatarsMutex); // place avatars lock if (m_avatarsConnection && m_avatarsConnection->isPending()) { debugLogA("Avatar, Multiple start thread attempt, ignored."); @@ -206,25 +187,26 @@ void CIcqProto::StartAvatarThread(HANDLE hConn, char *cookie, size_t cookieLen) // check if any upload request are waiting in the queue int bYet = 0; - avatars_request *ar = m_avatarsQueue; - while (ar) { + for (int i = 0; i < m_arAvatars.getCount();) { + avatars_request *ar = m_arAvatars[i]; if (ar->type == ART_UPLOAD) { // we found it, return error if (!bYet) { icq_LogMessage(LOG_WARNING, LPGEN("Error uploading avatar to server, server temporarily unavailable.")); bYet = 1; } + // remove upload request from queue - ar = ReleaseAvatarRequestInQueue(ar); - continue; + m_arAvatars.remove(i); + delete ar; } - ar = ar->pNext; + else i++; } SAFE_FREE((void**)&cookie); return; } - icq_lock l(m_avatarsMutex); + mir_cslock l(m_avatarsMutex); if (m_avatarsConnection && m_avatarsConnection->isPending()) { debugLogA("Avatar, Multiple start thread attempt, ignored."); @@ -245,7 +227,7 @@ void CIcqProto::StartAvatarThread(HANDLE hConn, char *cookie, size_t cookieLen) void CIcqProto::StopAvatarThread() { - icq_lock l(m_avatarsMutex); // the connection is about to close + mir_cslock l(m_avatarsMutex); // the connection is about to close if (m_avatarsConnection) m_avatarsConnection->shutdownConnection(); // make the thread stop } @@ -505,11 +487,13 @@ void CIcqProto::handleAvatarContactHash(DWORD dwUIN, char *szUID, MCONTACT hCont if (bJob) { if (bJob == TRUE) { // Remove possible block - hash changed, try again. - icq_lock l(m_avatarsMutex); + mir_cslock l(m_avatarsMutex); - for (avatars_request *ar = m_avatarsQueue; ar; ar = ar->pNext) { + for (int i = 0; i < m_arAvatars.getCount();) { + avatars_request *ar = m_arAvatars[i]; if (ar->hContact == hContact && ar->type == ART_BLOCK) { // found one, remove - ReleaseAvatarRequestInQueue(ar); + m_arAvatars.remove(i); + delete ar; break; } } @@ -548,78 +532,70 @@ int CIcqProto::GetAvatarData(MCONTACT hContact, DWORD dwUin, const char *szUid, pszUid = szUidData; } - m_avatarsMutex->Enter(); + mir_cslockfull alck(m_avatarsMutex); if (m_avatarsConnection && m_avatarsConnection->isReady()) { // check if we are ready // check if requests for this user are not blocked - for (avatars_request *ar = m_avatarsQueue; ar; ) { + for (int i = 0; i < m_arAvatars.getCount();) { + avatars_request *ar = m_arAvatars[i]; if (ar->hContact == hContact && ar->type == ART_BLOCK) { // found a block item if (GetTickCount() > ar->timeOut) { // remove timeouted block - ar = ReleaseAvatarRequestInQueue(ar); + m_arAvatars.remove(i); + delete ar; continue; } - m_avatarsMutex->Leave(); debugLogA("Avatars: Requests for %s avatar are blocked.", strUID(dwUin, pszUid)); return 0; } - ar = ar->pNext; + i++; } - avatars_server_connection *pConnection = m_avatarsConnection; - pConnection->_Lock(); - m_avatarsMutex->Leave(); - - DWORD dwCookie = pConnection->sendGetAvatarRequest(hContact, dwUin, pszUid, hash, hashlen, file); - - m_avatarsMutex->Enter(); - pConnection->_Release(); + mir_cslock l(m_avatarsConnection->getLock()); + alck.unlock(); - if (dwCookie) { // return now if the request was sent successfully - m_avatarsMutex->Leave(); + DWORD dwCookie = m_avatarsConnection->sendGetAvatarRequest(hContact, dwUin, pszUid, hash, hashlen, file); + if (dwCookie) // return now if the request was sent successfully return dwCookie; - } + + alck.lock(); } // we failed to send request, or avatar thread not ready // check if any request for this user is not already in the queue - for (avatars_request *ar = m_avatarsQueue; ar; ) { + for (int i = 0; i < m_arAvatars.getCount();) { + avatars_request *ar = m_arAvatars[i]; if (ar->hContact == hContact) { // we found it, return error if (ar->type == ART_BLOCK && GetTickCount() > ar->timeOut) { // remove timeouted block - ar = ReleaseAvatarRequestInQueue(ar); + m_arAvatars.remove(i); + delete ar; continue; } - m_avatarsMutex->Leave(); + alck.unlock(); debugLogA("Avatars: Ignoring duplicate get %s avatar request.", strUID(dwUin, pszUid)); // make sure avatar connection is in progress requestAvatarConnection(); return 0; } - ar = ar->pNext; + i++; } // add request to queue, processed after successful login avatars_request *ar = new avatars_request(ART_GET); // get avatar - if (!ar) { // out of memory, go away - m_avatarsMutex->Leave(); - return 0; - } ar->hContact = hContact; ar->dwUin = dwUin; if (!dwUin) strcpy(ar->szUid, szUid); ar->hash = (BYTE*)SAFE_MALLOC(hashlen); if (!ar->hash) { // alloc failed - m_avatarsMutex->Leave(); delete ar; return 0; } memcpy(ar->hash, hash, hashlen); // copy the data ar->hashlen = hashlen; ar->szFile = null_strdup(file); // duplicate the string - ar->pNext = m_avatarsQueue; - m_avatarsQueue = ar; - m_avatarsMutex->Leave(); + m_arAvatars.insert(ar); + alck.unlock(); debugLogA("Avatars: Request to get %s image added to queue.", strUID(dwUin, pszUid)); @@ -631,49 +607,38 @@ int CIcqProto::GetAvatarData(MCONTACT hContact, DWORD dwUin, const char *szUid, // upload avatar data to server int CIcqProto::SetAvatarData(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen) { - m_avatarsMutex->Enter(); + mir_cslockfull alck(m_avatarsMutex); if (m_avatarsConnection && m_avatarsConnection->isReady()) { // check if we are ready - avatars_server_connection *pConnection = m_avatarsConnection; - pConnection->_Lock(); - m_avatarsMutex->Leave(); - - DWORD dwCookie = pConnection->sendUploadAvatarRequest(hContact, wRef, data, datalen); - - m_avatarsMutex->Enter(); - pConnection->_Release(); + mir_cslock l(m_avatarsConnection->getLock()); + alck.unlock(); - if (dwCookie) { // return now if the request was sent successfully - m_avatarsMutex->Leave(); + DWORD dwCookie = m_avatarsConnection->sendUploadAvatarRequest(hContact, wRef, data, datalen); + if (dwCookie) // return now if the request was sent successfully return dwCookie; - } + + alck.lock(); } // we failed to send request, or avatar thread not ready // check if any request for this user is not already in the queue - avatars_request *ar = m_avatarsQueue; - while (ar) { + for (int i = 0; i < m_arAvatars.getCount(); i++) { + avatars_request *ar = m_arAvatars[i]; if (ar->hContact == hContact && ar->type == ART_UPLOAD) { // we found it, return error - m_avatarsMutex->Leave(); + alck.unlock(); debugLogA("Avatars: Ignoring duplicate upload avatar request."); // make sure avatar connection is in progress requestAvatarConnection(); return 0; } - ar = ar->pNext; } // add request to queue, processed after successful login - ar = new avatars_request(ART_UPLOAD); // upload avatar - if (!ar) { // out of memory, go away - m_avatarsMutex->Leave(); - return 0; - } + avatars_request *ar = new avatars_request(ART_UPLOAD); // upload avatar ar->hContact = hContact; ar->pData = (BYTE*)SAFE_MALLOC(datalen); if (!ar->pData) { // alloc failed - m_avatarsMutex->Leave(); delete ar; return 0; } @@ -681,9 +646,8 @@ int CIcqProto::SetAvatarData(MCONTACT hContact, WORD wRef, const BYTE *data, siz memcpy(ar->pData, data, datalen); // copy the data ar->cbData = datalen; ar->wRef = wRef; - ar->pNext = m_avatarsQueue; - m_avatarsQueue = ar; - m_avatarsMutex->Leave(); + m_arAvatars.insert(ar); + alck.unlock(); debugLogA("Avatars: Request to upload image added to queue."); @@ -694,15 +658,14 @@ int CIcqProto::SetAvatarData(MCONTACT hContact, WORD wRef, const BYTE *data, siz void CIcqProto::requestAvatarConnection() { - m_avatarsMutex->Enter(); + mir_cslockfull alck(m_avatarsMutex); if (!m_avatarsConnectionPending && (!m_avatarsConnection || (!m_avatarsConnection->isPending() && !m_avatarsConnection->isReady()))) { // avatar connection is not pending, request new one m_avatarsConnectionPending = TRUE; - m_avatarsMutex->Leave(); + alck.unlock(); icq_requestnewfamily(ICQ_AVATAR_FAMILY, &CIcqProto::StartAvatarThread); } - else m_avatarsMutex->Leave(); } void __cdecl CIcqProto::AvatarThread(avatars_server_connection *pInfo) @@ -713,13 +676,11 @@ void __cdecl CIcqProto::AvatarThread(avatars_server_connection *pInfo) pInfo->connectionThread(); { // Remove connection reference - icq_lock l(m_avatarsMutex); + mir_cslock l(m_avatarsMutex); if (m_avatarsConnection == pInfo) m_avatarsConnection = NULL; - } - { + // Release connection handler - icq_lock l(m_avatarsMutex); delete pInfo; } @@ -734,12 +695,8 @@ avatars_server_connection::avatars_server_connection(CIcqProto *_ppro, HANDLE _h hConnection(_hConnection) { // Initialize packet sequence - localSeqMutex = new icq_critical_section(); wLocalSequence = generate_flap_sequence(); - // Initialize rates - m_ratesMutex = new icq_critical_section(); - // Create connection thread ppro->ForkThread((CIcqProto::MyThreadFunc)&CIcqProto::AvatarThread, this); } @@ -747,15 +704,13 @@ avatars_server_connection::avatars_server_connection(CIcqProto *_ppro, HANDLE _h avatars_server_connection::~avatars_server_connection() { delete m_rates; - delete m_ratesMutex; - delete localSeqMutex; } void avatars_server_connection::closeConnection() { stopThread = TRUE; - icq_lock l(localSeqMutex); + mir_cslock l(localSeqMutex); if (hConnection) NetLib_SafeCloseHandle(&hConnection); } @@ -764,7 +719,7 @@ void avatars_server_connection::shutdownConnection() { stopThread = TRUE; - icq_lock l(localSeqMutex); + mir_cslock l(localSeqMutex); if (hConnection) Netlib_Shutdown(hConnection); } @@ -774,7 +729,7 @@ DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD d int i; DWORD dwNow = GetTickCount(); - ppro->m_avatarsMutex->Enter(); + mir_cslockfull alck(ppro->m_avatarsMutex); for (i = 0; i < runCount;) { // look for timeouted requests if (runTime[i] < dwNow) { // found outdated, remove @@ -787,7 +742,6 @@ DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD d for (i = 0; i < runCount; i++) { if (runContact[i] == hContact) { - ppro->m_avatarsMutex->Leave(); ppro->debugLogA("Ignoring duplicate get %s image request.", strUID(dwUin, szUid)); return -1; // Success: request ignored } @@ -797,7 +751,7 @@ DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD d int bSendNow = TRUE; { // rate management - icq_lock l(m_ratesMutex); + mir_cslock l(m_ratesMutex); WORD wGroup = m_rates->getGroupFromSNAC(ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST); if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_ALERT)) { // we will be over quota if we send the request now, add to queue instead @@ -811,7 +765,7 @@ DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD d runTime[runCount] = GetTickCount() + 30000; // 30sec to complete request runCount++; - ppro->m_avatarsMutex->Leave(); + alck.unlock(); int nUinLen = getUIDLen(dwUin, szUid); @@ -844,9 +798,7 @@ DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD d SAFE_FREE((void**)&ack->hash); SAFE_FREE((void**)&ack); } - else ppro->m_avatarsMutex->Leave(); } - else ppro->m_avatarsMutex->Leave(); return 0; // Failure } @@ -879,14 +831,14 @@ DWORD avatars_server_connection::sendUploadAvatarRequest(MCONTACT hContact, WORD void avatars_server_connection::checkRequestQueue() { - ppro->m_avatarsMutex->Enter(); + mir_cslockfull alck(ppro->m_avatarsMutex); - while (ppro->m_avatarsQueue && runCount < 3) { // pick up an request and send it - happens immediatelly after login + while (ppro->m_arAvatars.getCount() && runCount < 3) { // pick up an request and send it - happens immediatelly after login // do not fill queue to top, leave one place free - avatars_request *pRequest = ppro->m_avatarsQueue; + avatars_request *pRequest = ppro->m_arAvatars[0]; { // rate management - icq_lock l(m_ratesMutex); + mir_cslock l(m_ratesMutex); WORD wGroup = m_rates->getGroupFromSNAC(ICQ_AVATAR_FAMILY, (WORD)(pRequest->type == ART_UPLOAD ? ICQ_AVATAR_GET_REQUEST : ICQ_AVATAR_UPLOAD_REQUEST)); // we are over rate, leave queue and wait @@ -895,23 +847,18 @@ void avatars_server_connection::checkRequestQueue() } if (pRequest->type == ART_BLOCK) { // block contact processing - avatars_request **ppRequest = &ppro->m_avatarsQueue; - while (pRequest) { - if (GetTickCount() > pRequest->timeOut) { // expired contact block, remove - *ppRequest = pRequest->pNext; + for (int i = 0; i < ppro->m_arAvatars.getCount(); i++) { + avatars_request *ar = ppro->m_arAvatars[i]; + if (GetTickCount() > ar->timeOut) { // expired contact block, remove + ppro->m_arAvatars.remove(i); delete pRequest; } - else // it is not time, move to next request - ppRequest = &pRequest->pNext; - - pRequest = *ppRequest; } - // end queue processing (only block requests follows) - break; + return; // end processing } - else ppro->m_avatarsQueue = pRequest->pNext; - - ppro->m_avatarsMutex->Leave(); + + ppro->m_arAvatars.remove(int(0)); + alck.unlock(); switch (pRequest->type) { case ART_GET: // get avatar @@ -924,10 +871,8 @@ void avatars_server_connection::checkRequestQueue() } delete pRequest; - ppro->m_avatarsMutex->Enter(); + alck.lock(); } - - ppro->m_avatarsMutex->Leave(); } void avatars_server_connection::connectionThread() @@ -980,13 +925,13 @@ void avatars_server_connection::connectionThread() } { // release connection - icq_lock l(localSeqMutex); + mir_cslock l(localSeqMutex); NetLib_SafeCloseHandle(&hPacketRecver); // Close the packet receiver NetLib_CloseConnection(&hConnection, FALSE); // Close the connection } { // release rates - icq_lock l(m_ratesMutex); + mir_cslock l(m_ratesMutex); SAFE_DELETE((MZeroedObject**)&m_rates); } @@ -998,7 +943,7 @@ int avatars_server_connection::sendServerPacket(icq_packet *pPacket) int lResult = 0; // This critsec makes sure that the sequence order doesn't get screwed up - localSeqMutex->Enter(); + mir_cslock l(localSeqMutex); if (hConnection) { // :IMPORTANT: @@ -1025,15 +970,13 @@ int avatars_server_connection::sendServerPacket(icq_packet *pPacket) else { lResult = 1; // packet sent successfully - icq_lock l(m_ratesMutex); + mir_cslock rlck(m_ratesMutex); if (m_rates) m_rates->packetSent(pPacket); } } else ppro->debugLogA("Error: Failed to send packet (no connection)"); - localSeqMutex->Leave(); - SAFE_FREE((void**)&pPacket->pData); return lResult; @@ -1201,7 +1144,7 @@ void avatars_server_connection::handleAvatarFam(BYTE *pBuffer, size_t wBufferLen BYTE bResult; { // remove from active request list - icq_lock l(ppro->m_avatarsMutex); + mir_cslock l(ppro->m_avatarsMutex); for (int i = 0; i < runCount; i++) { // look for our record if (runContact[i] == pCookieData->hContact) { // found, remove runContact[i] = runContact[runCount - 1]; @@ -1311,24 +1254,11 @@ void avatars_server_connection::handleAvatarFam(BYTE *pBuffer, size_t wBufferLen if (pCookieData->hContact) { avatars_request *ar = new avatars_request(ART_BLOCK); + ar->hContact = pCookieData->hContact; + ar->timeOut = GetTickCount() + 14400000; // do not allow re-request four hours - icq_lock l(ppro->m_avatarsMutex); - - if (ar) { - avatars_request *last = ppro->m_avatarsQueue; - - ar->hContact = pCookieData->hContact; - ar->timeOut = GetTickCount() + 14400000; // do not allow re-request four hours - - // add it to the end of queue, i.e. do not block other requests - while (last && last->pNext) - last = last->pNext; - - if (last) - last->pNext = ar; - else - ppro->m_avatarsQueue = ar; - } + mir_cslock l(ppro->m_avatarsMutex); + ppro->m_arAvatars.insert(ar); } ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&ai, 0); } diff --git a/protocols/IcqOscarJ/src/icq_avatar.h b/protocols/IcqOscarJ/src/icq_avatar.h index 63e2658bae..240a7f076a 100644 --- a/protocols/IcqOscarJ/src/icq_avatar.h +++ b/protocols/IcqOscarJ/src/icq_avatar.h @@ -39,14 +39,13 @@ extern BYTE hashEmptyAvatar[9]; struct CIcqProto; -struct avatars_server_connection : public lockable_struct +class avatars_server_connection : public MZeroedObject { -protected: CIcqProto *ppro; HANDLE hConnection; // handle to the connection HANDLE hPacketRecver; WORD wLocalSequence; - icq_critical_section *localSeqMutex; + mir_cs localSeqMutex, connMutex; BOOL isLoggedIn; BOOL isActive; @@ -66,7 +65,7 @@ protected: void handleAvatarFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader); rates *m_rates; - icq_critical_section *m_ratesMutex; + mir_cs m_ratesMutex; MCONTACT runContact[4]; DWORD runTime[4]; @@ -81,6 +80,7 @@ public: void closeConnection(); void shutdownConnection(); + __inline mir_cs& getLock() { return connMutex; } __inline BOOL isPending() { return !isLoggedIn; }; __inline BOOL isReady() { return isLoggedIn && isActive && !stopThread; }; @@ -88,8 +88,6 @@ public: DWORD sendUploadAvatarRequest(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen); }; -__inline static void SAFE_DELETE(avatars_server_connection **p) { SAFE_DELETE((lockable_struct**)p); }; - struct avatars_request : public MZeroedObject { int type; @@ -103,7 +101,6 @@ struct avatars_request : public MZeroedObject size_t cbData; WORD wRef; DWORD timeOut; - avatars_request *pNext; public: avatars_request(int type); diff --git a/protocols/IcqOscarJ/src/icq_direct.cpp b/protocols/IcqOscarJ/src/icq_direct.cpp index e034de40f0..40d1a2961d 100644 --- a/protocols/IcqOscarJ/src/icq_direct.cpp +++ b/protocols/IcqOscarJ/src/icq_direct.cpp @@ -46,7 +46,7 @@ static char client_check_data[] = { void CIcqProto::CloseContactDirectConns(MCONTACT hContact) { - icq_lock l(directConnListMutex); + mir_cslock l(directConnListMutex); for (int i = 0; i < directConns.getCount(); i++) { if (!hContact || directConns[i]->hContact == hContact) { @@ -62,7 +62,7 @@ void CIcqProto::CloseContactDirectConns(MCONTACT hContact) directconnect* CIcqProto::FindFileTransferDC(filetransfer* ft) { directconnect* dc = NULL; - icq_lock l(directConnListMutex); + mir_cslock l(directConnListMutex); for (int i = 0; i < directConns.getCount(); i++) { if (directConns[i]->ft == ft) { @@ -78,7 +78,7 @@ directconnect* CIcqProto::FindFileTransferDC(filetransfer* ft) filetransfer* CIcqProto::FindExpectedFileRecv(DWORD dwUin, DWORD dwTotalSize) { filetransfer* pFt = NULL; - icq_lock l(expectedFileRecvMutex); + mir_cslock l(expectedFileRecvMutex); for (int i = 0; i < expectedFileRecvs.getCount(); i++) { if (expectedFileRecvs[i]->dwUin == dwUin && expectedFileRecvs[i]->dwTotalSize == dwTotalSize) { @@ -125,7 +125,7 @@ BOOL CIcqProto::IsDirectConnectionOpen(MCONTACT hContact, int type, int bPassive BOOL bIsOpen = FALSE, bIsCreated = FALSE; { - icq_lock l(directConnListMutex); + mir_cslock l(directConnListMutex); for (int i = 0; i < directConns.getCount(); i++) { if (directConns[i] && (directConns[i]->type == type)) { @@ -178,7 +178,7 @@ void CIcqProto::OpenDirectConnection(MCONTACT hContact, int type, void* pvExtra) // Safely close NetLib connection - do not corrupt direct connection list void CIcqProto::CloseDirectConnection(directconnect *dc) { - icq_lock l(directConnListMutex); + mir_cslock l(directConnListMutex); NetLib_CloseConnection(&dc->hConnection, FALSE); @@ -202,7 +202,7 @@ void __cdecl CIcqProto::icq_directThread(directthreadstartinfo *dtsi) srand(time(NULL)); { // add to DC connection list - icq_lock l(directConnListMutex); + mir_cslock l(directConnListMutex); directConns.insert(&dc); } @@ -435,7 +435,7 @@ void __cdecl CIcqProto::icq_directThread(directthreadstartinfo *dtsi) LBL_Exit: // remove from DC connection list - icq_lock l(directConnListMutex); + mir_cslock l(directConnListMutex); directConns.remove(&dc); } @@ -825,7 +825,7 @@ int DecryptDirectPacket(directconnect* dc, PBYTE buf, size_t wLen) // This should be called only if connection already exists int CIcqProto::SendDirectMessage(MCONTACT hContact, icq_packet *pkt) { - icq_lock l(directConnListMutex); + mir_cslock l(directConnListMutex); for (int i = 0; i < directConns.getCount(); i++) { if (directConns[i] == NULL) diff --git a/protocols/IcqOscarJ/src/icq_infoupdate.cpp b/protocols/IcqOscarJ/src/icq_infoupdate.cpp index be305be872..565dff43ee 100644 --- a/protocols/IcqOscarJ/src/icq_infoupdate.cpp +++ b/protocols/IcqOscarJ/src/icq_infoupdate.cpp @@ -35,9 +35,6 @@ void CIcqProto::icq_InitInfoUpdate(void) // Create wait objects hInfoQueueEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hInfoQueueEvent) { - // Init mutexes - infoUpdateMutex = new icq_critical_section(); - // Init list for (int i = 0; i < LISTSIZE; i++) { m_infoUpdateList[i].dwUin = 0; @@ -56,25 +53,22 @@ void CIcqProto::icq_InitInfoUpdate(void) // Returns FALSE if the list was full BOOL CIcqProto::icq_QueueUser(MCONTACT hContact) { - if (!infoUpdateMutex) + if (!hInfoQueueEvent) return FALSE; if (nInfoUserCount >= LISTSIZE) return FALSE; int i, nChecked = 0, nFirstFree = -1; - BOOL bFound = FALSE; - infoUpdateMutex->Enter(); + mir_cslock l(infoUpdateMutex); // Check if in list for (i = 0; (i < LISTSIZE && nChecked < nInfoUserCount); i++) { if (m_infoUpdateList[i].hContact) { nChecked++; - if (m_infoUpdateList[i].hContact == hContact) { - bFound = TRUE; - break; - } + if (m_infoUpdateList[i].hContact == hContact) + return TRUE; } else if (nFirstFree == -1) nFirstFree = i; @@ -83,23 +77,20 @@ BOOL CIcqProto::icq_QueueUser(MCONTACT hContact) nFirstFree = i; // Add to list - if (!bFound) { - DWORD dwUin = getContactUin(hContact); - if (dwUin) { - m_infoUpdateList[nFirstFree].dwUin = dwUin; - m_infoUpdateList[nFirstFree].hContact = hContact; - m_infoUpdateList[nFirstFree].queued = time(NULL); - nInfoUserCount++; - - debugLogA("Queued user %u, place %u, count %u", dwUin, nFirstFree, nInfoUserCount); - - // Notify worker thread - if (hInfoQueueEvent && bInfoUpdateEnabled) - SetEvent(hInfoQueueEvent); - } + DWORD dwUin = getContactUin(hContact); + if (dwUin) { + m_infoUpdateList[nFirstFree].dwUin = dwUin; + m_infoUpdateList[nFirstFree].hContact = hContact; + m_infoUpdateList[nFirstFree].queued = time(NULL); + nInfoUserCount++; + + debugLogA("Queued user %u, place %u, count %u", dwUin, nFirstFree, nInfoUserCount); + + // Notify worker thread + if (hInfoQueueEvent && bInfoUpdateEnabled) + SetEvent(hInfoQueueEvent); } - infoUpdateMutex->Leave(); return TRUE; } @@ -108,7 +99,7 @@ void CIcqProto::icq_DequeueUser(DWORD dwUin) if (nInfoUserCount > 0) { int nChecked = 0; // Check if in list - infoUpdateMutex->Enter(); + mir_cslock l(infoUpdateMutex); for (int i = 0; (i < LISTSIZE && nChecked < nInfoUserCount); i++) { if (m_infoUpdateList[i].dwUin) { nChecked++; @@ -124,7 +115,6 @@ void CIcqProto::icq_DequeueUser(DWORD dwUin) } } } - infoUpdateMutex->Leave(); } } @@ -193,18 +183,19 @@ void __cdecl CIcqProto::InfoUpdateThread( void* ) // Check the list, take only users that were there for at least 5sec // wait if any user is there shorter than 5sec and not a single user is there longer than 20sec - infoUpdateMutex->Enter(); - for (i = 0; i < LISTSIZE; i++) { - if (m_infoUpdateList[i].hContact) { - if (m_infoUpdateList[i].queued + 20 < now) { - bTimeOuted = TRUE; - break; + { + mir_cslock l(infoUpdateMutex); + for (i = 0; i < LISTSIZE; i++) { + if (m_infoUpdateList[i].hContact) { + if (m_infoUpdateList[i].queued + 20 < now) { + bTimeOuted = TRUE; + break; + } + if (m_infoUpdateList[i].queued + 5 >= now) + bNotReady = TRUE; } - if (m_infoUpdateList[i].queued + 5 >= now) - bNotReady = TRUE; } } - infoUpdateMutex->Leave(); if (!bTimeOuted && bNotReady) { SleepEx(1000, TRUE); @@ -230,17 +221,15 @@ void __cdecl CIcqProto::InfoUpdateThread( void* ) debugLogA("Info-Update: Users %u in queue.", nInfoUserCount); // Either some user is waiting long enough, or all users are ready (waited at least the minimum time) - m_ratesMutex->Enter(); - if (!m_rates) { // we cannot send info request - icq is offline - m_ratesMutex->Leave(); + mir_cslockfull rlck(m_ratesMutex); + if (!m_rates) // we cannot send info request - icq is offline break; - } WORD wGroup = m_rates->getGroupFromSNAC(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST); while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_IDLE_30)) { // we are over rate, need to wait before sending int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_50); - m_ratesMutex->Leave(); + rlck.unlock(); debugLogA("Rates: InfoUpdate delayed %dms", nDelay); @@ -249,22 +238,21 @@ void __cdecl CIcqProto::InfoUpdateThread( void* ) debugLogA("%s thread ended.", "Info-Update"); goto LBL_Exit; } - m_ratesMutex->Enter(); + rlck.lock(); if (!m_rates) // we lost connection when we slept, go away break; } - if (!m_rates) { // we cannot send info request - icq is offline - m_ratesMutex->Leave(); + if (!m_rates) // we cannot send info request - icq is offline break; - } - m_ratesMutex->Leave(); + + rlck.unlock(); userinfo *hContactList[LISTSIZE]; int nListIndex = 0; BYTE *pRequestData = NULL; size_t nRequestSize = 0; - infoUpdateMutex->Enter(); + mir_cslock l(infoUpdateMutex); for (i = 0; i < LISTSIZE; i++) { if (m_infoUpdateList[i].hContact) { // check TS again, maybe it has been updated while we slept @@ -303,14 +291,11 @@ void __cdecl CIcqProto::InfoUpdateThread( void* ) debugLogA("Request info for %u user(s).", nListIndex); - if (!nListIndex) { // no users to request info for - infoUpdateMutex->Leave(); + if (!nListIndex) // no users to request info for break; - } if (!(dwInfoActiveRequest = sendUserInfoMultiRequest(pRequestData, nRequestSize, nListIndex))) { // sending data packet failed SAFE_FREE((void**)&pRequestData); - infoUpdateMutex->Leave(); break; } SAFE_FREE((void**)&pRequestData); @@ -321,7 +306,6 @@ void __cdecl CIcqProto::InfoUpdateThread( void* ) hContactList[i]->queued = 0; nInfoUserCount--; } - infoUpdateMutex->Leave(); } break; @@ -335,7 +319,6 @@ void __cdecl CIcqProto::InfoUpdateThread( void* ) debugLogA("%s thread ended.", "Info-Update"); LBL_Exit: - SAFE_DELETE(&infoUpdateMutex); CloseHandle(hInfoQueueEvent); } diff --git a/protocols/IcqOscarJ/src/icq_proto.cpp b/protocols/IcqOscarJ/src/icq_proto.cpp index fcab8c9715..43bd09ff40 100644 --- a/protocols/IcqOscarJ/src/icq_proto.cpp +++ b/protocols/IcqOscarJ/src/icq_proto.cpp @@ -77,39 +77,22 @@ CIcqProto::CIcqProto(const char* aProtoName, const TCHAR* aUserName) : expectedFileRecvs(10, CompareFT), contactsCache(10, CompareContactsCache), CustomCapList(1), - cheekySearchId(-1) + cheekySearchId(-1), + m_arAvatars(5) { debugLogA("Setting protocol/module name to '%s'", m_szModuleName); - oftMutex = new icq_critical_section(); - - // Initialize direct connections - directConnListMutex = new icq_critical_section(); - expectedFileRecvMutex = new icq_critical_section(); - // Initialize server lists - servlistMutex = new icq_critical_section(); - servlistQueueMutex = new icq_critical_section(); HookProtoEvent(ME_CLIST_GROUPCHANGE, &CIcqProto::ServListCListGroupChange); // Initialize status message struct memset(&m_modeMsgs, 0, sizeof(icq_mode_messages)); - m_modeMsgsMutex = new icq_critical_section(); - connectionHandleMutex = new icq_critical_section(); - localSeqMutex = new icq_critical_section(); m_modeMsgsEvent = CreateProtoEvent(ME_ICQ_STATUSMSGREQ); // Initialize cookies - cookieMutex = new icq_critical_section(); wCookieSeq = 2; - // Initialize rates - m_ratesMutex = new icq_critical_section(); - - // Initialize avatars - m_avatarsMutex = new icq_critical_section(); - // Initialize temporary DB settings db_set_resident(m_szModuleName, "Status"); // NOTE: XStatus cannot be temporary db_set_resident(m_szModuleName, "TemporaryVisible"); @@ -225,8 +208,8 @@ CIcqProto::~CIcqProto() SAFE_FREE((void**)&servlistQueueList); // Finalize avatars - /// TODO: cleanup remaining avatar requests - SAFE_DELETE(&m_avatarsMutex); + for (int i = 0; i < m_arAvatars.getCount(); i++) + delete m_arAvatars[i]; // NetLib clean-up NetLib_SafeCloseHandle(&m_hDirectNetlibUser); @@ -239,19 +222,6 @@ CIcqProto::~CIcqProto() // Clean-up remaining protocol instance members UninitContactsCache(); - SAFE_DELETE(&m_ratesMutex); - - SAFE_DELETE(&servlistMutex); - SAFE_DELETE(&servlistQueueMutex); - - SAFE_DELETE(&m_modeMsgsMutex); - SAFE_DELETE(&localSeqMutex); - SAFE_DELETE(&connectionHandleMutex); - SAFE_DELETE(&oftMutex); - SAFE_DELETE(&directConnListMutex); - SAFE_DELETE(&expectedFileRecvMutex); - SAFE_DELETE(&cookieMutex); - SAFE_FREE(&m_modeMsgs.szOnline); SAFE_FREE(&m_modeMsgs.szAway); SAFE_FREE(&m_modeMsgs.szNa); @@ -511,9 +481,8 @@ HANDLE __cdecl CIcqProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const T if (dwUin && ft->ft_magic == FT_MAGIC_ICQ) { filetransfer *ft = (filetransfer *)hTransfer; ft->szSavePath = tchar_to_utf8(szPath); - { - icq_lock l(expectedFileRecvMutex); + mir_cslock l(expectedFileRecvMutex); expectedFileRecvs.insert(ft); } @@ -1593,7 +1562,7 @@ char* CIcqProto::PrepareStatusNote(int nStatus) szStatusNote = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, ""); if (!szStatusNote || !szStatusNote[0]) { // get standard status message (no custom status defined) - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); char **pszStatusNote = MirandaStatusToAwayMsg(nStatus); if (pszStatusNote) @@ -1707,7 +1676,7 @@ int __cdecl CIcqProto::SetStatus(int iNewStatus) SAFE_FREE(&szStatusNote); if (m_bAimEnabled) { - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); char ** pszStatusNote = MirandaStatusToAwayMsg(m_iStatus); @@ -1858,7 +1827,7 @@ int __cdecl CIcqProto::RecvAwayMsg(MCONTACT hContact, int, PROTORECVEVENT* evt) int __cdecl CIcqProto::SetAwayMsg(int status, const TCHAR* msg) { - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); char **ppszMsg = MirandaStatusToAwayMsg(MirandaStatusToSupported(status)); if (!ppszMsg) @@ -1897,7 +1866,7 @@ int __cdecl CIcqProto::SetAwayMsg(int status, const TCHAR* msg) INT_PTR CIcqProto::GetMyAwayMsg(WPARAM wParam, LPARAM lParam) { - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); char **ppszMsg = MirandaStatusToAwayMsg(wParam ? wParam : m_iStatus); diff --git a/protocols/IcqOscarJ/src/icq_proto.h b/protocols/IcqOscarJ/src/icq_proto.h index 56db448000..4634f68aae 100644 --- a/protocols/IcqOscarJ/src/icq_proto.h +++ b/protocols/IcqOscarJ/src/icq_proto.h @@ -159,8 +159,8 @@ struct CIcqProto : public PROTO BYTE m_bXStatusEnabled; BYTE m_bMoodsEnabled; - icq_critical_section *localSeqMutex; - icq_critical_section *connectionHandleMutex; + mir_cs localSeqMutex; + mir_cs connectionHandleMutex; int m_bIdleAllow; DWORD m_dwLocalUIN; @@ -223,7 +223,7 @@ struct CIcqProto : public PROTO void CheckKeepAlive(serverthread_info *info); //----| cookies.cpp |----------------------------------------------------------------- - icq_critical_section *cookieMutex; // we want this in avatar thread, used as queue lock + mir_cs cookieMutex; // we want this in avatar thread, used as queue lock LIST cookies; WORD wCookieSeq; @@ -279,7 +279,7 @@ struct CIcqProto : public PROTO //----| fam_04message.cpp |----------------------------------------------------------- icq_mode_messages m_modeMsgs; - icq_critical_section *m_modeMsgsMutex; + mir_cs m_modeMsgsMutex; HANDLE m_modeMsgsEvent; void handleMsgFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader); @@ -383,8 +383,8 @@ struct CIcqProto : public PROTO void sendClientAuth(const char *szKey, size_t wKeyLen, BOOL bSecure); //----| icq_avatars.cpp |------------------------------------------------------------- - icq_critical_section *m_avatarsMutex; - avatars_request *m_avatarsQueue; + mir_cs m_avatarsMutex; + LIST m_arAvatars; BOOL m_avatarsConnectionPending; avatars_server_connection *m_avatarsConnection; @@ -395,8 +395,6 @@ struct CIcqProto : public PROTO void handleAvatarOwnerHash(BYTE bFlags, BYTE *pData, size_t nDataLen); void handleAvatarContactHash(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *pHash, size_t nHashLen); - avatars_request *ReleaseAvatarRequestInQueue(avatars_request *request); - TCHAR* GetOwnAvatarFileName(); void GetFullAvatarFileName(int dwUin, const char *szUid, int dwFormat, TCHAR *pszDest, size_t cbLen); void GetAvatarFileName(int dwUin, const char *szUid, TCHAR *pszDest, size_t cbLen); @@ -431,10 +429,10 @@ struct CIcqProto : public PROTO void setStatusMsgVar(MCONTACT hContact, char* szStatusMsg, bool isAnsi); //----| icq_direct.cpp |-------------------------------------------------------------- - icq_critical_section *directConnListMutex; + mir_cs directConnListMutex; LIST directConns; - icq_critical_section *expectedFileRecvMutex; + mir_cs expectedFileRecvMutex; LIST expectedFileRecvs; void __cdecl icq_directThread(struct directthreadstartinfo* dtsi); @@ -476,7 +474,7 @@ struct CIcqProto : public PROTO void handleFileTransferIdle(directconnect *dc); //----| icq_infoupdate.cpp |---------------------------------------------------------- - icq_critical_section *infoUpdateMutex; + mir_cs infoUpdateMutex; HANDLE hInfoQueueEvent; int nInfoUserCount; int bInfoPendingUsers; @@ -529,8 +527,8 @@ struct CIcqProto : public PROTO char* PrepareStatusNote(int nStatus); //----| icq_rates.cpp |--------------------------------------------------------------- - icq_critical_section *m_ratesMutex; - rates *m_rates; + mir_cs m_ratesMutex; + rates *m_rates; rates_queue *m_ratesQueue_Request; // rate queue for xtraz requests rates_queue *m_ratesQueue_Response; // rate queue for msg responses @@ -566,14 +564,14 @@ struct CIcqProto : public PROTO HANDLE hHookSettingChanged; HANDLE hHookContactDeleted; HANDLE hHookCListGroupChange; - icq_critical_section *servlistMutex; + mir_cs servlistMutex; DWORD* pdwServerIDList; int nServerIDListCount; int nServerIDListSize; // server-list update board - icq_critical_section *servlistQueueMutex; + mir_cs servlistQueueMutex; int servlistQueueCount; int servlistQueueSize; ssiqueueditems **servlistQueueList; @@ -806,8 +804,8 @@ struct CIcqProto : public PROTO void RequestPassword(); //----| oscar_filetransfer.cpp |------------------------------------------------------ - icq_critical_section *oftMutex; - int fileTransferCount; + mir_cs oftMutex; + int fileTransferCount; basic_filetransfer** fileTransferList; oscar_filetransfer* CreateOscarTransfer(); @@ -872,7 +870,7 @@ struct CIcqProto : public PROTO int NetLog_Direct(const char *fmt,...); int NetLog_Uni(BOOL bDC, const char *fmt,...); - icq_critical_section *contactsCacheMutex; + mir_cs contactsCacheMutex; LIST contactsCache; void AddToContactsCache(MCONTACT hContact, DWORD dwUin, const char *szUid); diff --git a/protocols/IcqOscarJ/src/icq_rates.cpp b/protocols/IcqOscarJ/src/icq_rates.cpp index 5d4c5740cd..f205ce94a1 100644 --- a/protocols/IcqOscarJ/src/icq_rates.cpp +++ b/protocols/IcqOscarJ/src/icq_rates.cpp @@ -276,7 +276,7 @@ void rates_queue_item::execute() BOOL rates_queue_item::isOverRate(int nLevel) { - icq_lock l(ppro->m_ratesMutex); + mir_cslock l(ppro->m_ratesMutex); if (ppro->m_rates) return ppro->m_rates->getNextRateLevel(wGroup) < ppro->m_rates->getLimitLevel(wGroup, nLevel); @@ -286,7 +286,6 @@ BOOL rates_queue_item::isOverRate(int nLevel) rates_queue::rates_queue(CIcqProto *ppro, const char *szDescr, int nLimitLevel, int nWaitLevel, int nDuplicates) { - this->listsMutex = new icq_critical_section(); this->ppro = ppro; this->szDescr = szDescr; limitLevel = nLimitLevel; @@ -297,7 +296,6 @@ rates_queue::rates_queue(CIcqProto *ppro, const char *szDescr, int nLimitLevel, rates_queue::~rates_queue() { cleanup(); - delete listsMutex; } @@ -332,7 +330,7 @@ void rates_queue::initDelay(int nDelay, IcqRateFunc delaycode) void rates_queue::cleanup() { - icq_lock l(listsMutex); + mir_cslock l(listsMutex); if (pendingListSize) ppro->debugLogA("Rates: Purging %d %s(s).", pendingListSize, szDescr); @@ -353,21 +351,22 @@ void rates_queue::processQueue() cleanup(); return; } + // take from queue, execute + mir_cslockfull l(listsMutex); rates_queue_item *item = pendingList[0]; - - ppro->m_ratesMutex->Enter(); - listsMutex->Enter(); - if (item->isOverRate(limitLevel)) { // the rate is higher, keep sleeping - int nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, ppro->m_rates->getLimitLevel(item->wGroup, waitLevel)); - - listsMutex->Leave(); - ppro->m_ratesMutex->Leave(); - if (nDelay < 10) nDelay = 10; - initDelay(nDelay, &rates_queue::processQueue); - return; + { + mir_cslockfull rlck(ppro->m_ratesMutex); + if (item->isOverRate(limitLevel)) { // the rate is higher, keep sleeping + int nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, ppro->m_rates->getLimitLevel(item->wGroup, waitLevel)); + + l.unlock(); + rlck.unlock(); + if (nDelay < 10) nDelay = 10; + initDelay(nDelay, &rates_queue::processQueue); + return; + } } - ppro->m_ratesMutex->Leave(); if (pendingListSize > 1) { // we need to keep order memmove(&pendingList[0], &pendingList[1], (pendingListSize - 1) * sizeof(rates_queue_item*)); @@ -377,7 +376,7 @@ void rates_queue::processQueue() int bSetupTimer = --pendingListSize != 0; - listsMutex->Leave(); + l.unlock(); if (ppro->icqOnline()) { ppro->debugLogA("Rates: Resuming %s.", szDescr); @@ -387,9 +386,11 @@ void rates_queue::processQueue() if (bSetupTimer) { // in queue remained some items, setup timer - ppro->m_ratesMutex->Enter(); - int nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, waitLevel); - ppro->m_ratesMutex->Leave(); + int nDelay; + { + mir_cslockfull rlck(ppro->m_ratesMutex); + nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, waitLevel); + } if (nDelay < 10) nDelay = 10; initDelay(nDelay, &rates_queue::processQueue); @@ -407,19 +408,18 @@ void rates_queue::putItem(rates_queue_item *pItem, int nMinDelay) ppro->debugLogA("Rates: Delaying %s.", szDescr); - listsMutex->Enter(); + mir_cslockfull l(listsMutex); if (pendingListSize) { for (int i = 0; i < pendingListSize; i++) { if (pendingList[i]->isEqual(pItem)) { + if (duplicates == 1) // keep existing, ignore new + return; + if (duplicates == -1) { // discard existing, append new item delete pendingList[i]; memcpy(&pendingList[i], &pendingList[i + 1], (pendingListSize - i - 1) * sizeof(rates_queue_item*)); bFound = TRUE; } - else if (duplicates == 1) { // keep existing, ignore new - listsMutex->Leave(); - return; - } // otherwise keep existing and append new } } @@ -431,43 +431,43 @@ void rates_queue::putItem(rates_queue_item *pItem, int nMinDelay) pendingList[pendingListSize - 1] = pItem->copyItem(); if (pendingListSize == 1) { // queue was empty setup timer - listsMutex->Leave(); - ppro->m_ratesMutex->Enter(); - int nDelay = ppro->m_rates->getDelayToLimitLevel(pItem->wGroup, waitLevel); - ppro->m_ratesMutex->Leave(); + l.unlock(); + + int nDelay; + { + mir_cslock rlck(ppro->m_ratesMutex); + nDelay = ppro->m_rates->getDelayToLimitLevel(pItem->wGroup, waitLevel); + } if (nDelay < 10) nDelay = 10; if (nDelay < nMinDelay) nDelay = nMinDelay; initDelay(nDelay, &rates_queue::processQueue); } - else listsMutex->Leave(); } int CIcqProto::handleRateItem(rates_queue_item *item, int nQueueType, int nMinDelay, BOOL bAllowDelay) { rates_queue *pQueue = NULL; + { + mir_cslock rlck(m_ratesMutex); + switch (nQueueType) { + case RQT_REQUEST: + pQueue = m_ratesQueue_Request; + break; + case RQT_RESPONSE: + pQueue = m_ratesQueue_Response; + break; + } - m_ratesMutex->Enter(); - switch (nQueueType) { - case RQT_REQUEST: - pQueue = m_ratesQueue_Request; - break; - case RQT_RESPONSE: - pQueue = m_ratesQueue_Response; - break; - } - - if (pQueue) { - if (bAllowDelay && (item->isOverRate(pQueue->waitLevel) || nMinDelay)) { - // limit reached or min delay configured, add to queue - pQueue->putItem(item, nMinDelay); - - m_ratesMutex->Leave(); - return 1; + if (pQueue) { + if (bAllowDelay && (item->isOverRate(pQueue->waitLevel) || nMinDelay)) { + // limit reached or min delay configured, add to queue + pQueue->putItem(item, nMinDelay); + return 1; + } } } - m_ratesMutex->Leave(); item->execute(); return 0; diff --git a/protocols/IcqOscarJ/src/icq_rates.h b/protocols/IcqOscarJ/src/icq_rates.h index e8445fb44b..c0977b4f72 100644 --- a/protocols/IcqOscarJ/src/icq_rates.h +++ b/protocols/IcqOscarJ/src/icq_rates.h @@ -34,42 +34,44 @@ struct rates_group { - DWORD dwWindowSize; - DWORD dwClearLevel; - DWORD dwAlertLevel; - DWORD dwLimitLevel; - DWORD dwMaxLevel; - // current level - int rCurrentLevel; - int tCurrentLevel; - // links - WORD *pPairs; - int nPairs; + DWORD dwWindowSize; + DWORD dwClearLevel; + DWORD dwAlertLevel; + DWORD dwLimitLevel; + DWORD dwMaxLevel; + + // current level + int rCurrentLevel; + int tCurrentLevel; + + // links + WORD *pPairs; + int nPairs; }; struct rates : public MZeroedObject { private: - CIcqProto *ppro; - int nGroups; - rates_group groups[MAX_RATES_GROUP_COUNT]; + CIcqProto *ppro; + int nGroups; + rates_group groups[MAX_RATES_GROUP_COUNT]; - rates_group *getGroup(WORD wGroup); + rates_group *getGroup(WORD wGroup); public: - rates(CIcqProto *ppro, BYTE *pBuffer, size_t wLen); - ~rates(); + rates(CIcqProto *ppro, BYTE *pBuffer, size_t wLen); + ~rates(); - WORD getGroupFromSNAC(WORD wFamily, WORD wCommand); + WORD getGroupFromSNAC(WORD wFamily, WORD wCommand); WORD getGroupFromPacket(icq_packet *pPacket); - int getLimitLevel(WORD wGroup, int nLevel); - int getDelayToLimitLevel(WORD wGroup, int nLevel); - int getNextRateLevel(WORD wGroup); + int getLimitLevel(WORD wGroup, int nLevel); + int getDelayToLimitLevel(WORD wGroup, int nLevel); + int getNextRateLevel(WORD wGroup); void packetSent(icq_packet *pPacket); void updateLevel(WORD wGroup, int nLevel); - void initAckPacket(icq_packet *pPacket); + void initAckPacket(icq_packet *pPacket); }; #define RML_CLEAR 0x01 @@ -92,54 +94,53 @@ public: // struct rates_queue_item : public MZeroedObject { - friend struct rates_queue; + friend class rates_queue; protected: - CIcqProto *ppro; - BOOL bCreated; - WORD wGroup; + CIcqProto *ppro; + BOOL bCreated; + WORD wGroup; - virtual BOOL isEqual(rates_queue_item *pItem); - virtual rates_queue_item* copyItem(rates_queue_item *pDest = NULL); + virtual BOOL isEqual(rates_queue_item *pItem); + virtual rates_queue_item* copyItem(rates_queue_item *pDest = NULL); public: - rates_queue_item(CIcqProto *ppro, WORD wGroup); - virtual ~rates_queue_item(); + rates_queue_item(CIcqProto *ppro, WORD wGroup); + virtual ~rates_queue_item(); - BOOL isOverRate(int nLevel); + BOOL isOverRate(int nLevel); - virtual void execute(); + virtual void execute(); - MCONTACT hContact; - DWORD dwUin; - char *szUid; + MCONTACT hContact; + DWORD dwUin; + char *szUid; }; -struct rates_queue; +class rates_queue; typedef void (rates_queue::*IcqRateFunc)(void); // // generic item queue (FIFO) // -struct rates_queue : public MZeroedObject +class rates_queue : public MZeroedObject { -private: - CIcqProto *ppro; - const char *szDescr; - icq_critical_section *listsMutex; // we need to be thread safe + CIcqProto *ppro; + const char *szDescr; + mir_cs listsMutex; // we need to be thread safe int pendingListSize; rates_queue_item **pendingList; - int duplicates; + int duplicates; protected: - void cleanup(); - void processQueue(); - void initDelay(int nDelay, IcqRateFunc delaycode); + void cleanup(); + void processQueue(); + void initDelay(int nDelay, IcqRateFunc delaycode); public: - rates_queue(CIcqProto *ppro, const char *szDescr, int nLimitLevel, int nWaitLevel, int nDuplicates = 0); - ~rates_queue(); + rates_queue(CIcqProto *ppro, const char *szDescr, int nLimitLevel, int nWaitLevel, int nDuplicates = 0); + ~rates_queue(); - void putItem(rates_queue_item *pItem, int nMinDelay); + void putItem(rates_queue_item *pItem, int nMinDelay); - int limitLevel; // RML_* - int waitLevel; + int limitLevel; // RML_* + int waitLevel; }; diff --git a/protocols/IcqOscarJ/src/icq_server.cpp b/protocols/IcqOscarJ/src/icq_server.cpp index 5ea930f0b7..3bc7e459a3 100644 --- a/protocols/IcqOscarJ/src/icq_server.cpp +++ b/protocols/IcqOscarJ/src/icq_server.cpp @@ -96,7 +96,7 @@ void __cdecl CIcqProto::ServerThread(serverthread_start_info *infoParam) // Initialize rate limiting queues { - icq_lock l(m_ratesMutex); + mir_cslock l(m_ratesMutex); m_ratesQueue_Request = new rates_queue(this, "request", RML_IDLE_30, RML_IDLE_50, 1); m_ratesQueue_Response = new rates_queue(this, "response", RML_IDLE_10, RML_IDLE_30, -1); } @@ -196,7 +196,7 @@ void __cdecl CIcqProto::ServerThread(serverthread_start_info *infoParam) // release rates queues { - icq_lock l(m_ratesMutex); + mir_cslock l(m_ratesMutex); delete m_ratesQueue_Request; m_ratesQueue_Request = NULL; delete m_ratesQueue_Response; m_ratesQueue_Response = NULL; delete m_rates; m_rates = NULL; @@ -292,25 +292,26 @@ int CIcqProto::handleServerPackets(BYTE *buf, int len, serverthread_info *info) void CIcqProto::sendServPacket(icq_packet *pPacket) { // make sure to have the connection handle - connectionHandleMutex->Enter(); + mir_cslockfull l(connectionHandleMutex); if (hServerConn) { // This critsec makes sure that the sequence order doesn't get screwed up - localSeqMutex->Enter(); + int nSendResult; + { + mir_cslock slck(localSeqMutex); - // :IMPORTANT: - // The FLAP sequence must be a WORD. When it reaches 0xFFFF it should wrap to - // 0x0000, otherwise we'll get kicked by server. - wLocalSequence++; + // :IMPORTANT: + // The FLAP sequence must be a WORD. When it reaches 0xFFFF it should wrap to + // 0x0000, otherwise we'll get kicked by server. + wLocalSequence++; - // Pack sequence number - pPacket->pData[2] = ((wLocalSequence & 0xff00) >> 8); - pPacket->pData[3] = (wLocalSequence & 0x00ff); + // Pack sequence number + pPacket->pData[2] = ((wLocalSequence & 0xff00) >> 8); + pPacket->pData[3] = (wLocalSequence & 0x00ff); - int nSendResult = Netlib_Send(hServerConn, (const char *)pPacket->pData, pPacket->wLen, 0); - - localSeqMutex->Leave(); - connectionHandleMutex->Leave(); + nSendResult = Netlib_Send(hServerConn, (const char *)pPacket->pData, pPacket->wLen, 0); + } + l.unlock(); // Send error if (nSendResult == SOCKET_ERROR) { @@ -320,14 +321,11 @@ void CIcqProto::sendServPacket(icq_packet *pPacket) icq_serverDisconnect(); } else { // Rates management - icq_lock l(m_ratesMutex); + mir_cslock l(m_ratesMutex); m_rates->packetSent(pPacket); } } - else { - connectionHandleMutex->Leave(); - debugLogA("Error: Failed to send packet (no connection)"); - } + else debugLogA("Error: Failed to send packet (no connection)"); SAFE_FREE((void**)&pPacket->pData); } @@ -353,7 +351,7 @@ void CIcqProto::sendServPacketAsync(icq_packet *packet) int CIcqProto::IsServerOverRate(WORD wFamily, WORD wCommand, int nLevel) { - icq_lock l(m_ratesMutex); + mir_cslock l(m_ratesMutex); if (m_rates) { WORD wGroup = m_rates->getGroupFromSNAC(wFamily, wCommand); diff --git a/protocols/IcqOscarJ/src/icq_servlist.cpp b/protocols/IcqOscarJ/src/icq_servlist.cpp index d0f0f1b442..20b52d5396 100644 --- a/protocols/IcqOscarJ/src/icq_servlist.cpp +++ b/protocols/IcqOscarJ/src/icq_servlist.cpp @@ -70,7 +70,8 @@ void __cdecl CIcqProto::servlistQueueThread(void *param) SleepEx(50, FALSE); // handle server-list requests queue - servlistQueueMutex->Enter(); + mir_cslockfull l(servlistQueueMutex); + while (servlistQueueCount) { ssiqueueditems* pItem = NULL; int bItemDouble; @@ -94,14 +95,14 @@ void __cdecl CIcqProto::servlistQueueThread(void *param) if (bFound) break; // reset queue state, keep sleeping *queueState = FALSE; - servlistQueueMutex->Leave(); + l.unlock(); SleepEx(100, TRUE); - servlistQueueMutex->Enter(); + l.lock(); } if (!icqOnline()) { // do not try to send packets if offline - servlistQueueMutex->Leave(); + l.unlock(); SleepEx(100, TRUE); - servlistQueueMutex->Enter(); + l.lock(); continue; } @@ -111,29 +112,32 @@ void __cdecl CIcqProto::servlistQueueThread(void *param) pItem = servlistQueueList[0]; // take first (queue contains at least one item here) wItemAction = (WORD)(pItem->pItems[0]->dwOperation & SSOF_ACTIONMASK); bItemDouble = pItem->pItems[0]->dwOperation & SSOG_DOUBLE; + // check item rate - too high -> sleep - m_ratesMutex->Enter(); { + mir_cslockfull rlck(m_ratesMutex); + WORD wRateGroup = m_rates->getGroupFromSNAC(ICQ_LISTS_FAMILY, wItemAction); int nRateLevel = bItemDouble ? RML_IDLE_30 : RML_IDLE_10; while (m_rates->getNextRateLevel(wRateGroup) < m_rates->getLimitLevel(wRateGroup, nRateLevel)) { // the rate is higher, keep sleeping int nDelay = m_rates->getDelayToLimitLevel(wRateGroup, nRateLevel); - m_ratesMutex->Leave(); + rlck.unlock(); // do not keep the queue frozen - servlistQueueMutex->Leave(); - if (nDelay < 10) nDelay = 10; + l.unlock(); + if (nDelay < 10) + nDelay = 10; debugLogA("Server-List: Delaying %dms [Rates]", nDelay); SleepEx(nDelay, FALSE); // check if the rate is now ok - servlistQueueMutex->Enter(); - m_ratesMutex->Enter(); + l.lock(); + rlck.lock(); } } - m_ratesMutex->Leave(); + { // setup group packet(s) & cookie int totalSize = 0; @@ -230,7 +234,7 @@ void __cdecl CIcqProto::servlistQueueThread(void *param) servlistQueueList = (ssiqueueditems**)SAFE_REALLOC(servlistQueueList, servlistQueueSize * sizeof(ssiqueueditems*)); } } - servlistQueueMutex->Leave(); + l.unlock(); // send group packet sendServPacket(&groupPacket); // send second group packet (if present) @@ -241,19 +245,19 @@ void __cdecl CIcqProto::servlistQueueThread(void *param) servlistEndOperation(nEndOperations); // loose the loop a bit SleepEx(100, TRUE); - servlistQueueMutex->Enter(); + l.lock(); } + // clean-up thread CloseHandle(servlistQueueThreadHandle); servlistQueueThreadHandle = NULL; - servlistQueueMutex->Leave(); debugLogA("Server-List: Update Board ending."); } void CIcqProto::servlistQueueAddGroupItem(servlistgroupitem* pGroupItem, int dwTimeout) { - icq_lock l(servlistQueueMutex); + mir_cslock l(servlistQueueMutex); // add the packet to queue DWORD dwMark = pGroupItem->dwOperation & SSOF_GROUPINGMASK; @@ -450,7 +454,7 @@ servlistpendingitem* CIcqProto::servlistPendingRemoveItem(int nType, MCONTACT hC int iItem; servlistpendingitem *pItem = NULL; - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); if ((iItem = servlistPendingFindItem(nType, hContact, pszGroup)) != -1) { // found, remove from the pending list pItem = servlistPendingList[iItem]; @@ -501,7 +505,7 @@ void CIcqProto::servlistPendingAddContactOperation(MCONTACT hContact, LPARAM par int iItem; servlistpendingitem *pItem = NULL; - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); if ((iItem = servlistPendingFindItem(ITEM_PENDING_CONTACT, hContact, NULL)) != -1) pItem = servlistPendingList[iItem]; @@ -523,7 +527,7 @@ void CIcqProto::servlistPendingAddGroupOperation(const char *pszGroup, LPARAM pa int iItem; servlistpendingitem *pItem = NULL; - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); if ((iItem = servlistPendingFindItem(ITEM_PENDING_GROUP, NULL, pszGroup)) != -1) pItem = servlistPendingList[iItem]; @@ -544,7 +548,7 @@ int CIcqProto::servlistPendingAddContact(MCONTACT hContact, WORD wContactID, WOR int iItem; servlistpendingitem *pItem = NULL; - servlistMutex->Enter(); + mir_cslockfull l(servlistMutex); if ((iItem = servlistPendingFindItem(ITEM_PENDING_CONTACT, hContact, NULL)) != -1) pItem = servlistPendingList[iItem]; @@ -556,8 +560,6 @@ int CIcqProto::servlistPendingAddContact(MCONTACT hContact, WORD wContactID, WOR if (operationCallback) servlistPendingAddContactOperation(hContact, operationParam, operationCallback, 0); - - servlistMutex->Leave(); return 0; // Pending } @@ -574,7 +576,7 @@ int CIcqProto::servlistPendingAddContact(MCONTACT hContact, WORD wContactID, WOR if (operationCallback) servlistPendingAddContactOperation(hContact, operationParam, operationCallback, 0); - servlistMutex->Leave(); + l.unlock(); if (bDoInline) // not postponed, called directly if requested (this->*callback)(hContact, wContactID, wGroupID, param, PENDING_RESULT_INLINE); @@ -587,7 +589,7 @@ int CIcqProto::servlistPendingAddGroup(const char *pszGroup, WORD wGroupID, LPAR int iItem; servlistpendingitem *pItem = NULL; - servlistMutex->Enter(); + mir_cslockfull l(servlistMutex); if ((iItem = servlistPendingFindItem(ITEM_PENDING_GROUP, NULL, pszGroup)) != -1) pItem = servlistPendingList[iItem]; @@ -599,9 +601,6 @@ int CIcqProto::servlistPendingAddGroup(const char *pszGroup, WORD wGroupID, LPAR if (operationCallback) servlistPendingAddGroupOperation(pszGroup, operationParam, operationCallback, 0); - - servlistMutex->Leave(); - return 0; // Pending } @@ -617,7 +616,7 @@ int CIcqProto::servlistPendingAddGroup(const char *pszGroup, WORD wGroupID, LPAR if (operationCallback) servlistPendingAddGroupOperation(pszGroup, operationParam, operationCallback, 0); - servlistMutex->Leave(); + l.unlock(); if (bDoInline) // not postponed, called directly if requested (this->*callback)(pszGroup, wGroupID, param, PENDING_RESULT_INLINE); @@ -684,7 +683,7 @@ void CIcqProto::servlistPendingRemoveGroup(const char *pszGroup, WORD wGroupID, // Remove All pending operations void CIcqProto::servlistPendingFlushOperations() { - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); for (int i = servlistPendingCount; i; i--) { // purge all items servlistpendingitem *pItem = servlistPendingList[i - 1]; @@ -706,7 +705,7 @@ void CIcqProto::servlistPendingFlushOperations() // used for adding new contacts to list - sync with visible items void CIcqProto::AddJustAddedContact(MCONTACT hContact) { - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); if (nJustAddedCount >= nJustAddedSize) { nJustAddedSize += 10; @@ -720,7 +719,7 @@ void CIcqProto::AddJustAddedContact(MCONTACT hContact) // was the contact added during this serv-list load BOOL CIcqProto::IsContactJustAdded(MCONTACT hContact) { - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); if (pdwJustAddedList) for (int i = 0; i < nJustAddedCount; i++) @@ -733,7 +732,7 @@ BOOL CIcqProto::IsContactJustAdded(MCONTACT hContact) void CIcqProto::FlushJustAddedContacts() { - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); SAFE_FREE((void**)&pdwJustAddedList); nJustAddedSize = 0; @@ -746,15 +745,15 @@ void CIcqProto::FlushJustAddedContacts() // You should call CheckServerID before reserving an ID. void CIcqProto::ReserveServerID(WORD wID, int bGroupType, int bFlags) { - servlistMutex->Enter(); - if (nServerIDListCount >= nServerIDListSize) { - nServerIDListSize += 100; - pdwServerIDList = (DWORD*)SAFE_REALLOC(pdwServerIDList, nServerIDListSize * sizeof(DWORD)); - } + { mir_cslock l(servlistMutex); + if (nServerIDListCount >= nServerIDListSize) { + nServerIDListSize += 100; + pdwServerIDList = (DWORD*)SAFE_REALLOC(pdwServerIDList, nServerIDListSize * sizeof(DWORD)); + } - pdwServerIDList[nServerIDListCount] = wID | (bGroupType & 0x00FF0000) | (bFlags & 0xFF000000); - nServerIDListCount++; - servlistMutex->Leave(); + pdwServerIDList[nServerIDListCount] = wID | (bGroupType & 0x00FF0000) | (bFlags & 0xFF000000); + nServerIDListCount++; + } if (!bIsSyncingCL) StoreServerIDs(); @@ -766,7 +765,7 @@ void CIcqProto::FreeServerID(WORD wID, int bGroupType) { DWORD dwId = wID | (bGroupType & 0x00FF0000); - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); if (pdwServerIDList) { for (int i = 0; i < nServerIDListCount; i++) { @@ -783,7 +782,7 @@ void CIcqProto::FreeServerID(WORD wID, int bGroupType) // Returns true if dwID is reserved BOOL CIcqProto::CheckServerID(WORD wID, unsigned int wCount) { - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); if (pdwServerIDList) { for (int i = 0; i < nServerIDListCount; i++) { @@ -797,7 +796,7 @@ BOOL CIcqProto::CheckServerID(WORD wID, unsigned int wCount) void CIcqProto::FlushServerIDs() { - icq_lock l(servlistMutex); + mir_cslock l(servlistMutex); SAFE_FREE((void**)&pdwServerIDList); nServerIDListCount = 0; @@ -836,7 +835,7 @@ void CIcqProto::LoadServerIDs() WORD wSrvID; int nGroups = 0, nContacts = 0, nPermits = 0, nDenys = 0, nIgnores = 0, nUnhandled = 0; - servlistMutex->Enter(); + mir_cslockfull l(servlistMutex); if (wSrvID = getWord(DBSETTING_SERVLIST_AVATAR, 0)) ReserveServerID(wSrvID, SSIT_ITEM, 0); if (wSrvID = getWord(DBSETTING_SERVLIST_PHOTO, 0)) @@ -884,7 +883,7 @@ void CIcqProto::LoadServerIDs() hContact = db_find_next(hContact, m_szModuleName); } - servlistMutex->Leave(); + l.unlock(); DBVARIANT dbv = { 0 }; if (!getSetting(NULL, DBSETTING_SERVLIST_UNHANDLED, &dbv)) { @@ -915,7 +914,7 @@ void CIcqProto::StoreServerIDs() /// TODO: allow delayed BYTE *pUnhandled = NULL; size_t cbUnhandled = 0; - servlistMutex->Enter(); + mir_cslockfull l(servlistMutex); if (pdwServerIDList) for (int i = 0; i < nServerIDListCount; i++) if ((pdwServerIDList[i] & 0xFF000000) == SSIF_UNHANDLED) { @@ -924,7 +923,7 @@ void CIcqProto::StoreServerIDs() /// TODO: allow delayed ppackByte(&pUnhandled, &cbUnhandled, (pdwServerIDList[i] & 0xFF000000) >> 0x18); } - servlistMutex->Leave(); + l.unlock(); if (pUnhandled) setSettingBlob(NULL, DBSETTING_SERVLIST_UNHANDLED, pUnhandled, (int)cbUnhandled); diff --git a/protocols/IcqOscarJ/src/icq_xstatus.cpp b/protocols/IcqOscarJ/src/icq_xstatus.cpp index af99fd5ec2..7c25aca840 100644 --- a/protocols/IcqOscarJ/src/icq_xstatus.cpp +++ b/protocols/IcqOscarJ/src/icq_xstatus.cpp @@ -100,9 +100,11 @@ DWORD CIcqProto::requestXStatusDetails(MCONTACT hContact, BOOL bAllowDelay) DWORD dwCookie; }; - m_ratesMutex->Enter(); - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND); - m_ratesMutex->Leave(); + WORD wGroup; + { + mir_cslock l(m_ratesMutex); + wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND); + } rates_xstatus_request rr(this, wGroup); rr.bForced = !bAllowDelay; @@ -523,11 +525,12 @@ void CIcqProto::updateServerCustomStatus(int fullUpdate) // retrieve standard status message (e.g. custom status set to none) else { char **pszMsg = MirandaStatusToAwayMsg(m_iStatus); - - m_modeMsgsMutex->Enter(); - if (pszMsg) - szStatusNote = null_strdup(*pszMsg); - m_modeMsgsMutex->Leave(); + { + mir_cslock l(m_modeMsgsMutex); + if (pszMsg) + szStatusNote = null_strdup(*pszMsg); + } + // no default status message, set empty if (!szStatusNote) szStatusNote = null_strdup(""); diff --git a/protocols/IcqOscarJ/src/icq_xtraz.cpp b/protocols/IcqOscarJ/src/icq_xtraz.cpp index b5c31adfb3..21d9b9592c 100644 --- a/protocols/IcqOscarJ/src/icq_xtraz.cpp +++ b/protocols/IcqOscarJ/src/icq_xtraz.cpp @@ -133,9 +133,11 @@ void CIcqProto::handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD w char *szResponse; }; - m_ratesMutex->Enter(); - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); - m_ratesMutex->Leave(); + WORD wGroup; + { + mir_cslock rlck(m_ratesMutex); + wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); + } rates_xstatus_response rr(this, wGroup); rr.hContact = hContact; diff --git a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp b/protocols/IcqOscarJ/src/oscar_filetransfer.cpp index 727c279d2c..464b9fc916 100644 --- a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp +++ b/protocols/IcqOscarJ/src/oscar_filetransfer.cpp @@ -85,7 +85,7 @@ oscar_filetransfer* CIcqProto::CreateOscarTransfer() // Init members ft->fileId = -1; - icq_lock l(oftMutex); + mir_cslock l(oftMutex); fileTransferList = (basic_filetransfer**)SAFE_REALLOC(fileTransferList, sizeof(basic_filetransfer*)*(fileTransferCount + 1)); fileTransferList[fileTransferCount++] = ft; @@ -101,7 +101,7 @@ filetransfer *CIcqProto::CreateIcqFileTransfer() ft->ft_magic = FT_MAGIC_ICQ; - icq_lock l(oftMutex); + mir_cslock l(oftMutex); fileTransferList = (basic_filetransfer**)SAFE_REALLOC(fileTransferList, sizeof(basic_filetransfer*)*(fileTransferCount + 1)); fileTransferList[fileTransferCount++] = (basic_filetransfer*)ft; @@ -132,19 +132,19 @@ void CIcqProto::ReleaseFileTransfer(void *ft) int CIcqProto::IsValidFileTransfer(void *ft) { - icq_lock l(oftMutex); + mir_cslock l(oftMutex); return getFileTransferIndex(ft) != -1; } int CIcqProto::IsValidOscarTransfer(void *ft) { - icq_lock l(oftMutex); + mir_cslock l(oftMutex); return getFileTransferIndex(ft) != -1 && ((basic_filetransfer*)ft)->ft_magic == FT_MAGIC_OSCAR; } oscar_filetransfer* CIcqProto::FindOscarTransfer(MCONTACT hContact, DWORD dwID1, DWORD dwID2) { - icq_lock l(oftMutex); + mir_cslock l(oftMutex); for (int i = 0; i < fileTransferCount; i++) { if (fileTransferList[i]->ft_magic == FT_MAGIC_OSCAR) { @@ -162,7 +162,7 @@ void CIcqProto::SafeReleaseFileTransfer(void **ft) { basic_filetransfer **bft = (basic_filetransfer**)ft; - icq_lock l(oftMutex); + mir_cslock l(oftMutex); // Check for filetransfer validity if (getFileTransferIndex(*ft) == -1) @@ -1051,7 +1051,7 @@ static void oft_buildProtoFileTransferStatus(oscar_filetransfer* ft, PROTOFILETR void CIcqProto::CloseOscarConnection(oscar_connection *oc) { - icq_lock l(oftMutex); + mir_cslock l(oftMutex); if (oc) { oc->type = OCT_CLOSING; @@ -1343,7 +1343,7 @@ void __cdecl CIcqProto::oft_connectionThread(oscarthreadstartinfo *otsi) // Clean up { - icq_lock l(oftMutex); + mir_cslock l(oftMutex); if (getFileTransferIndex(oc.ft) != -1) oc.ft->connection = NULL; // release link @@ -2010,7 +2010,7 @@ void CIcqProto::oft_sendFileData(oscar_connection *oc) void CIcqProto::oft_sendPeerInit(oscar_connection *oc) { - icq_lock l(oftMutex); + mir_cslock l(oftMutex); // prepare init frame oscar_filetransfer *ft = oc->ft; diff --git a/protocols/IcqOscarJ/src/stdpackets.cpp b/protocols/IcqOscarJ/src/stdpackets.cpp index b8295252dd..7ce4d6ca90 100644 --- a/protocols/IcqOscarJ/src/stdpackets.cpp +++ b/protocols/IcqOscarJ/src/stdpackets.cpp @@ -927,7 +927,7 @@ void CIcqProto::icq_sendAwayMsgReplyServ(DWORD dwUin, DWORD dwMsgID1, DWORD dwMs if (validateStatusMessageRequest(hContact, msgType)) { NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dwUin); - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); if (szMsg && *szMsg) { char *pszMsg = NULL; @@ -969,7 +969,7 @@ void CIcqProto::icq_sendAwayMsgReplyServExt(DWORD dwUin, char *szUID, DWORD dwMs if (validateStatusMessageRequest(hContact, msgType)) { NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dwUin); - icq_lock l(m_modeMsgsMutex); + mir_cslock l(m_modeMsgsMutex); if (szMsg && *szMsg) { char *pszMsg = NULL; diff --git a/protocols/IcqOscarJ/src/utilities.cpp b/protocols/IcqOscarJ/src/utilities.cpp index 8dc21e8c19..f8d2250b44 100644 --- a/protocols/IcqOscarJ/src/utilities.cpp +++ b/protocols/IcqOscarJ/src/utilities.cpp @@ -31,7 +31,7 @@ struct gateway_index DWORD dwIndex; }; -static icq_critical_section *gatewayMutex = NULL; +static mir_cs gatewayMutex; static gateway_index *gateways = NULL; static int gatewayCount = 0; @@ -265,7 +265,7 @@ int AwayMsgTypeToStatus(int nMsgType) void SetGatewayIndex(HANDLE hConn, DWORD dwIndex) { - icq_lock l(gatewayMutex); + mir_cslock l(gatewayMutex); for (int i = 0; i < gatewayCount; i++) { if (hConn == gateways[i].hConn) { @@ -283,7 +283,7 @@ void SetGatewayIndex(HANDLE hConn, DWORD dwIndex) DWORD GetGatewayIndex(HANDLE hConn) { - icq_lock l(gatewayMutex); + mir_cslock l(gatewayMutex); for (int i = 0; i < gatewayCount; i++) if (hConn == gateways[i].hConn) @@ -295,7 +295,7 @@ DWORD GetGatewayIndex(HANDLE hConn) void FreeGatewayIndex(HANDLE hConn) { - icq_lock l(gatewayMutex); + mir_cslock l(gatewayMutex); for (int i = 0; i < gatewayCount; i++) { if (hConn == gateways[i].hConn) { @@ -312,7 +312,7 @@ void FreeGatewayIndex(HANDLE hConn) void CIcqProto::AddToSpammerList(DWORD dwUIN) { - icq_lock l(gatewayMutex); + mir_cslock l(gatewayMutex); spammerList = (DWORD *)SAFE_REALLOC(spammerList, sizeof(DWORD)* (spammerListCount + 1)); spammerList[spammerListCount] = dwUIN; @@ -322,7 +322,7 @@ void CIcqProto::AddToSpammerList(DWORD dwUIN) BOOL CIcqProto::IsOnSpammerList(DWORD dwUIN) { - icq_lock l(gatewayMutex); + mir_cslock l(gatewayMutex); for (int i = 0; i < spammerListCount; i++) if (dwUIN == spammerList[i]) @@ -345,22 +345,15 @@ void CIcqProto::AddToContactsCache(MCONTACT hContact, DWORD dwUin, const char *s if (!dwUin) cache_item->szUid = null_strdup(szUid); - icq_lock l(contactsCacheMutex); + mir_cslock l(contactsCacheMutex); contactsCache.insert(cache_item); } void CIcqProto::InitContactsCache() { - if (!gatewayMutex) - gatewayMutex = new icq_critical_section(); - else - gatewayMutex->_Lock(); - - contactsCacheMutex = new icq_critical_section(); - // build cache - icq_lock l(contactsCacheMutex); + mir_cslock l(contactsCacheMutex); MCONTACT hContact = db_find_first(m_szModuleName); @@ -378,32 +371,24 @@ void CIcqProto::InitContactsCache() void CIcqProto::UninitContactsCache(void) { - contactsCacheMutex->Enter(); + { mir_cslock l(contactsCacheMutex); - // cleanup the cache - for (int i = 0; i < contactsCache.getCount(); i++) { - icq_contacts_cache *cache_item = contactsCache[i]; + // cleanup the cache + for (int i = 0; i < contactsCache.getCount(); i++) { + icq_contacts_cache *cache_item = contactsCache[i]; - SAFE_FREE((void**)&cache_item->szUid); - SAFE_FREE((void**)&cache_item); - } - - contactsCache.destroy(); - - contactsCacheMutex->Leave(); - - SAFE_DELETE(&contactsCacheMutex); + SAFE_FREE((void**)&cache_item->szUid); + SAFE_FREE((void**)&cache_item); + } - if (gatewayMutex && gatewayMutex->getLockCount() > 1) - gatewayMutex->_Release(); - else - SAFE_DELETE(&gatewayMutex); + contactsCache.destroy(); + } } void CIcqProto::DeleteFromContactsCache(MCONTACT hContact) { - icq_lock l(contactsCacheMutex); + mir_cslock l(contactsCacheMutex); for (int i = 0; i < contactsCache.getCount(); i++) { icq_contacts_cache *cache_item = contactsCache[i]; @@ -423,7 +408,7 @@ MCONTACT CIcqProto::HandleFromCacheByUid(DWORD dwUin, const char *szUid) { icq_contacts_cache cache_item = { NULL, dwUin, szUid }; - icq_lock l(contactsCacheMutex); + mir_cslock l(contactsCacheMutex); // find in list int i = contactsCache.getIndex(&cache_item); if (i != -1) @@ -1032,30 +1017,30 @@ void __cdecl CIcqProto::SetStatusNoteThread(void *pDelay) if (pDelay) SleepEx((DWORD)pDelay, TRUE); - cookieMutex->Enter(); + mir_cslockfull l(cookieMutex); if (icqOnline() && (setStatusNoteText || setStatusMoodData)) { // send status note change packets, write status note to database if (setStatusNoteText) { // change status note in directory - m_ratesMutex->Enter(); + mir_cslockfull rlck(m_ratesMutex); if (m_rates) { // rate management WORD wGroup = m_rates->getGroupFromSNAC(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST); while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_LIMIT)) { // we are over rate, need to wait before sending int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_10); - m_ratesMutex->Leave(); - cookieMutex->Leave(); + rlck.unlock(); + l.unlock(); debugLogA("Rates: SetStatusNote delayed %dms", nDelay); SleepEx(nDelay, TRUE); // do not keep things locked during sleep - cookieMutex->Enter(); - m_ratesMutex->Enter(); + l.lock(); + rlck.lock(); if (!m_rates) // we lost connection when we slept, go away break; } } - m_ratesMutex->Leave(); + rlck.unlock(); BYTE *pBuffer = NULL; size_t cbBuffer = 0; @@ -1067,26 +1052,26 @@ void __cdecl CIcqProto::SetStatusNoteThread(void *pDelay) } if (setStatusNoteText || setStatusMoodData) { // change status note and mood in session data - m_ratesMutex->Enter(); + mir_cslockfull rlck(m_ratesMutex); if (m_rates) { // rate management WORD wGroup = m_rates->getGroupFromSNAC(ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS); while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_LIMIT)) { // we are over rate, need to wait before sending int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_10); - m_ratesMutex->Leave(); - cookieMutex->Leave(); + rlck.unlock(); + l.unlock(); debugLogA("Rates: SetStatusNote delayed %dms", nDelay); SleepEx(nDelay, TRUE); // do not keep things locked during sleep - cookieMutex->Enter(); - m_ratesMutex->Enter(); + l.lock(); + rlck.lock(); if (!m_rates) // we lost connection when we slept, go away break; } } - m_ratesMutex->Leave(); + rlck.unlock(); // check if the session data were not updated already char *szCurrentStatusNote = getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, NULL); @@ -1138,8 +1123,6 @@ void __cdecl CIcqProto::SetStatusNoteThread(void *pDelay) } SAFE_FREE(&setStatusNoteText); SAFE_FREE(&setStatusMoodData); - - cookieMutex->Leave(); } @@ -1152,7 +1135,7 @@ int CIcqProto::SetStatusNote(const char *szStatusNote, DWORD dwDelay, int bForce if (!bForce && !icqOnline()) return bChanged; // reuse generic critical section (used for cookies list and object variables locks) - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); if (!setStatusNoteText && (!m_bMoodsEnabled || !setStatusMoodData)) { // check if the status note was changed and if yes, create thread to change it char *szCurrentStatusNote = getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, NULL); @@ -1188,7 +1171,7 @@ int CIcqProto::SetStatusMood(const char *szMoodData, DWORD dwDelay) if (!icqOnline()) return bChanged; // reuse generic critical section (used for cookies list and object variables locks) - icq_lock l(cookieMutex); + mir_cslock l(cookieMutex); if (!setStatusNoteText && !setStatusMoodData) { // check if the status mood was changed and if yes, create thread to change it char *szCurrentStatusMood = NULL; @@ -1371,15 +1354,6 @@ void __fastcall SAFE_DELETE(MZeroedObject **p) } -void __fastcall SAFE_DELETE(lockable_struct **p) -{ - if (*p) { - (*p)->_Release(); - *p = NULL; - } -} - - void __fastcall SAFE_FREE(void** p) { if (*p) { diff --git a/protocols/IcqOscarJ/src/utilities.h b/protocols/IcqOscarJ/src/utilities.h index ce1763039c..8b12897596 100644 --- a/protocols/IcqOscarJ/src/utilities.h +++ b/protocols/IcqOscarJ/src/utilities.h @@ -95,51 +95,10 @@ void* __fastcall SAFE_REALLOC(void* p, size_t size); __inline static void SAFE_FREE(char** str) { SAFE_FREE((void**)str); } __inline static void SAFE_FREE(WCHAR** str) { SAFE_FREE((void**)str); } -struct lockable_struct: public MZeroedObject -{ -private: - int nLockCount; -public: - lockable_struct() { _Lock(); }; - virtual ~lockable_struct() {}; - - void _Lock() { nLockCount++; }; - void _Release() { nLockCount--; if (!nLockCount) delete this; }; - - int getLockCount() { return nLockCount; }; -}; - void __fastcall SAFE_DELETE(MZeroedObject **p); -void __fastcall SAFE_DELETE(lockable_struct **p); DWORD ICQWaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds, int bWaitAlways = FALSE); - -struct icq_critical_section: public lockable_struct -{ -private: - HANDLE hMutex; - -public: - icq_critical_section() { hMutex = CreateMutex(NULL, FALSE, NULL); } - ~icq_critical_section() { CloseHandle(hMutex); } - - void Enter(void) { ICQWaitForSingleObject(hMutex, INFINITE, TRUE); } - void Leave(void) { ReleaseMutex(hMutex); } -}; - -__inline static void SAFE_DELETE(icq_critical_section **p) { SAFE_DELETE((lockable_struct**)p); } - -struct icq_lock -{ -private: - icq_critical_section *pMutex; -public: - icq_lock(icq_critical_section *mutex) { pMutex = mutex; pMutex->Enter(); }; - ~icq_lock() { pMutex->Leave(); pMutex = NULL; }; -}; - - HANDLE NetLib_OpenConnection(HANDLE hUser, const char* szIdent, NETLIBOPENCONNECTION* nloc); void NetLib_CloseConnection(HANDLE *hConnection, int bServerConn); void NetLib_SafeCloseHandle(HANDLE *hConnection); diff --git a/protocols/IcqOscarJ/src/version.h b/protocols/IcqOscarJ/src/version.h index 0030e8609b..1ac289d41b 100644 --- a/protocols/IcqOscarJ/src/version.h +++ b/protocols/IcqOscarJ/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 11 -#define __RELEASE_NUM 2 -#define __BUILD_NUM 7 +#define __RELEASE_NUM 3 +#define __BUILD_NUM 1 #include -- cgit v1.2.3