bool CTabStack::GetTabDrawRect(int anIndex, RECT* rcTab) { bool lbExist = false; MSectionLockSimple SC; SC.Lock(mpc_Section); int iReal = GetVisualToRealIndex(anIndex); if (iReal >= 0 && iReal < mn_Used) { CTabID* pTab = mpp_Stack[iReal]; if (pTab) { if (rcTab) *rcTab = pTab->DrawInfo.rcTab; lbExist = true; } else { _ASSERTE(pTab!=NULL); } } else { _ASSERTE(iReal >= 0 && iReal < mn_Used); } SC.Unlock(); return lbExist; }
bool CTabStack::SetTabDrawRect(int anIndex, const RECT& rcTab) { bool lbExist = false; MSectionLockSimple SC; SC.Lock(mpc_Section); int iReal = GetVisualToRealIndex(anIndex); if (iReal >= 0 && iReal < mn_Used) { CTabID* pTab = mpp_Stack[iReal]; if (pTab) { if (memcmp(&pTab->DrawInfo.rcTab, &rcTab, sizeof(rcTab)) != 0) { pTab->ReleaseDrawRegion(); pTab->DrawInfo.rcTab = rcTab; } lbExist = true; } else { _ASSERTE(pTab!=NULL); } } else { _ASSERTE(iReal >= 0 && iReal < mn_Used); } SC.Unlock(); return lbExist; }
void CRunQueue::RequestRConStartup(CRealConsole* pRCon) { bool bFound = false; CVirtualConsole* pVCon = pRCon->VCon(); // Должен вызываться в главной нити, чтобы соблюсти порядок создания при запуске группы _ASSERTE(isMainThread() == true); MSectionLockSimple cs; cs.Lock(mpcs_QueueLock); // May be exist already in queue? for (INT_PTR i = m_RunQueue.size(); (--i) >= 0;) { if (m_RunQueue[i].pVCon == pVCon) { bFound = true; break; } } // push if (!bFound) { RunQueueItem item = {pVCon}; m_RunQueue.push_back(item); } cs.Unlock(); // Trigger our thread AdvanceQueue(); }
bool CTabStack::GetNextTab(const CTabID* pTab, BOOL abForward, /*OUT*/ CTab& rTab) { MSectionLockSimple SC; SC.Lock(mpc_Section); CTabID* pNextTab = NULL; for (int i = 0; i < mn_Used; i++) { if (mpp_Stack[i] == pTab) { if (abForward) { if ((i + 1) < mn_Used) pNextTab = mpp_Stack[i+1]; } else { if (i > 0) pNextTab = mpp_Stack[i-1]; } break; } } rTab.Init(pNextTab); SC.Unlock(); return (pNextTab!=NULL); }
bool CTabStack::GetTabByIndex(int anIndex, /*OUT*/ CTab& rTab) { MSectionLockSimple SC; SC.Lock(mpc_Section); int iReal = GetVisualToRealIndex(anIndex); if (iReal >= 0 && iReal < mn_Used) { rTab.Init(mpp_Stack[iReal]); } else { rTab.Init(NULL); } SC.Unlock(); return (rTab.Tab() != NULL); }
bool CTabStack::GetTabInfoByIndex(int anIndex, /*OUT*/ TabInfo& rInfo) { bool lbFound = false; MSectionLockSimple SC; SC.Lock(mpc_Section); int iReal = GetVisualToRealIndex(anIndex); if (iReal >= 0 && iReal < mn_Used) { if (mpp_Stack[iReal]) { rInfo = mpp_Stack[iReal]->Info; lbFound = true; } } SC.Unlock(); return lbFound; }
int CTabStack::GetIndexByTab(const CTabID* pTab) { MSectionLockSimple SC; SC.Lock(mpc_Section); int nIndex = -1; for (int i = 0; i < mn_Used; i++) { if (!mpp_Stack[i]) continue; if (mpp_Stack[i]->Info.Status == tisValid) nIndex++; else continue; if (mpp_Stack[i] == pTab) break; } SC.Unlock(); return nIndex; }
// Возвращает "true" если были изменения в КОЛИЧЕСТВЕ табов (ЗДЕСЬ больше ничего не проверяется) bool CTabStack::UpdateEnd(HANDLE hUpdate, DWORD anActiveFarPID) { MSectionLockSimple* pUpdateLock = (MSectionLockSimple*)hUpdate; // Функция должна вызваться ТОЛЬКО между UpdateBegin & UpdateEnd if (mn_UpdatePos < 0) { _ASSERTE(mn_UpdatePos>=0); return false; } bool bVConClosed = false; if (!mb_FarUpdateMode && (mn_UpdatePos == 0)) { if (!CVConGroup::isVConExists(0)) { bVConClosed = true; } else { // Фукнция UpdateFarWindow должна была быть вызвана хотя бы раз! //UpdateFarWindow(CVirtualConsole* apVCon, LPCWSTR asName, int anType, int anPID, int anFarWindowID, int anViewEditID, CEFarWindowType anFlags) _ASSERTE(mn_UpdatePos>0 || CVConGroup::GetConCount()==0); pUpdateLock->Unlock(); delete pUpdateLock; mn_UpdatePos = -1; return false; } } bool bChanged = (mn_Used != mn_UpdatePos); #if 1 _ASSERTE(pUpdateLock->isLocked()); #else pUpdateLock->RelockExclusive(); #endif if (mb_FarUpdateMode) { _ASSERTE(mn_UpdatePos > 0); // Все табы ПОСЛЕ последнего добавленного/обновленного - помечаем неактивными for (int i = mn_UpdatePos; i < mn_Used; i++) { CTabID *pTab = mpp_Stack[i]; if (pTab && (pTab->Info.Status != tisInvalid)) { pTab->Info.Status = tisPassive; } } // Активен Far? ВСЕ tisPassive табы этого Far-а - разрушаем if (anActiveFarPID) { for (int i = 0; i < mn_Used; i++) { CTabID *pTab = mpp_Stack[i]; // Проверяем только табы активного фара (пассивные [Far -> Far -> Far] не трогаем) if (!pTab || (pTab->Info.nPID != anActiveFarPID)) continue; // Панели и табы с не пассивным статусом - не трогаем if ((pTab->Type() == fwt_Panels) || (pTab->Info.Status != tisPassive)) continue; // Таб (редактор/вьювер) был закрыт, разрушаем _ASSERTE(pTab->Type()==fwt_Editor || pTab->Type()==fwt_Viewer); // Kill this tab pTab->Info.Status = tisInvalid; } } } else { // Для самого таббара - весь хвост просто выкинуть из списка, но сами CTabID не разрушать (tisInvalid не ставить) for (int i = mn_UpdatePos; i < mn_Used; i++) { CTabID *pTab = mpp_Stack[i]; if (pTab) { if (!CVConGroup::isValid((CVirtualConsole*)pTab->Info.pVCon)) pTab->Info.Status = tisInvalid; #ifdef TAB_REF_PLACE pTab->DelPlace(m_rp); #endif pTab->Release(); // Remove from list mpp_Stack[i] = NULL; bChanged = true; } } } for (int i = 0; i < mn_Used; i++) { CTabID *pTab = mpp_Stack[i]; // Kill all invalid tabs if (!pTab || (pTab->Info.Status != tisInvalid)) continue; #ifdef TAB_REF_PLACE pTab->DelPlace(m_rp); #endif pTab->Release(); // Remove from list mpp_Stack[i] = NULL; bChanged = true; } CleanNulls(); pUpdateLock->Unlock(); delete pUpdateLock; return bChanged; }
CDragDrop::~CDragDrop() { //DestroyDragImageBits(); //DestroyDragImageWindow(); if (mb_DragDropRegistered && ghWnd) { mb_DragDropRegistered = FALSE; RevokeDragDrop(ghWnd); } MSectionLockSimple CS; CS.Lock(mp_CrThreads); BOOL lbEmpty = m_OpThread.empty() && !InDragDrop(); CS.Unlock(); if (!lbEmpty) { if (MessageBox(ghWnd, L"Not all shell operations was finished!\r\nDo You want to terminate them (it's may be harmful)?", gpConEmu->GetDefaultTitle(), MB_YESNO|MB_ICONEXCLAMATION) == IDYES) { // Terminate all shell (copying) threads CS.Lock(mp_CrThreads); //std::vector<ThInfo>::iterator iter = m_OpThread.begin(); //while (iter != m_OpThread.end()) while (m_OpThread.size() > 0) { INT_PTR j = m_OpThread.size()-1; const ThInfo* iter = &(m_OpThread[j]); HANDLE hThread = iter->hThread; TerminateThread(hThread, 100); CloseHandle(hThread); //iter = m_OpThread.erase(iter); m_OpThread.erase(j); } CS.Unlock(); } else { // Wait until finished BOOL lbActive = TRUE; while (lbActive) { Sleep(100); CS.Lock(mp_CrThreads); lbActive = (!m_OpThread.empty()) || InDragDrop(); CS.Unlock(); } } } else { // незаконченных нитей нет // -- Leave Critical Section(&m_CrThreads); -- 101229 секция уже закрыта } // Завершение всех нитей драга TerminateDrag(); //if (m_pfpi) free(m_pfpi); m_pfpi=NULL; //if (mp_DesktopID) { CoTaskMemFree(mp_DesktopID); mp_DesktopID = NULL; } SafeDelete(mp_CrThreads); }
void CRunQueue::ProcessRunQueue() { #ifdef _DEBUG // We run in self thread if (mb_InExecution) { _ASSERTE(!mb_InExecution); } #endif // Block adding new requests from other threads MArray<RunQueueItem> Stack; MSectionLockSimple cs; cs.Lock(mpcs_QueueLock); RunQueueItem item = {}; while (m_RunQueue.pop_back(item)) { //item = m_RunQueue[0]; //m_RunQueue.erase(0); Stack.push_back(item); } cs.Unlock(); DWORD nCurDelay, nWaitExtra; bool bOpt; // And process stack while (!mb_Terminate && Stack.pop_back(item)) { if (!gpConEmu->isValid(item.pVCon)) continue; CVConGuard VCon(item.pVCon); if (!VCon.VCon()) continue; // Avoid too fast process creation? if (mn_LastExecutionTick) { nCurDelay = (GetTickCount() - mn_LastExecutionTick); if (nCurDelay < RUNQUEUE_CREATE_LAG) { nWaitExtra = (RUNQUEUE_CREATE_LAG - nCurDelay); Sleep(nWaitExtra); } } mb_InExecution = true; bOpt = gpConEmu->ExecuteProcessPrepare(); VCon->RCon()->OnStartProcessAllowed(); gpConEmu->ExecuteProcessFinished(bOpt); mb_InExecution = false; // Remember last execution moment mn_LastExecutionTick = GetTickCount(); } }