예제 #1
0
//telo provadeciho vlakna procesu
DWORD CProcess::Start()
{
    Run();                // popis aktivnich fazi procesu
                        // po jejich vykonani:
    CProcess* next;
    if (event != NULL)        // pokud ma proces zaznam o udalosti
    {
        next=NextEv();
        event->Out();
        delete(event);        // odstrani jej
        event = NULL;

        if (next!=NULL)         // v SQS je zaznam o dalsim procesu
                                         // tady nekde prerusit pri krokovani
            next->Resume();        // aktivuj tento proces
    }
    terminated = true;            // oznac proces za ukonceny
    return 0;                        // a ukonci proceduru vlakna
}
예제 #2
0
void CJobObject::Suspend() {
   CMutex::CEnter MutexEnter(m_Mutex);

   map<DWORD, int> ErrorProcesses;             
   map<DWORD, int>::iterator ErrorProcess;
   map<DWORD, BOOL> Processes;             
   map<DWORD, BOOL>::iterator CurrentProcess;
   map<DWORD, CProcess*>::iterator OldProcess;
   BOOL bNewProcesses;

   // Clear all Threads contained in the m_Threads member
   for (OldProcess = m_Processes.begin();
        OldProcess != m_Processes.end();
        OldProcess++) {
      delete OldProcess->second;
   }
   m_Processes.clear();

   
   // A)

   // Seach all threads which belong to this process and suspend them. To do this we create
   // a snapshot and suspend all threads contained in the snapshot.
   // Between A1 and A2 it is possible that new threads will be created. This makes it necessary to 
   // create a new snapshot and to suspend all new threads which we not suspended in a previous 
   // iteration.

   bNewProcesses = TRUE;
   while (bNewProcesses) {
      PJOBOBJECT_BASIC_PROCESS_ID_LIST pPidList;

      bNewProcesses = FALSE;
      pPidList = CreatePidList();
      // A1

      if (pPidList == NULL) {
         throw CCodineException(L"Pid List is NULL", __FILE__, __LINE__);
      } else {
         for (int i = 0; i < pPidList->NumberOfProcessIdsInList; i++) {
            if (m_Processes.find(pPidList->ProcessIdList[i]) == m_Processes.end()) {
               CProcess *NewProcess = NULL;

               try {
                  NewProcess = new CProcess(pPidList->ProcessIdList[i]);
                  NewProcess->Suspend();
                  m_Processes[pPidList->ProcessIdList[i]] = NewProcess;
                  Processes[pPidList->ProcessIdList[i]] = true;
                  bNewProcesses = TRUE;
               } catch (CCodineException& ex) {
                  ErrorProcess = ErrorProcesses.find(pPidList->ProcessIdList[i]);
                  if (ErrorProcess == ErrorProcesses.end() 
                      || (ErrorProcess != ErrorProcesses.end() && ErrorProcess->second < 3)) {

                     // Possible reasons for the exception
                     //    * We didn't get a handle
                     //       - Thread exited
                     //    * Thread belongs to a different process 
                     //      (no access)
                     //       - Thread exited and another process created 
                     //         a thread with the same id between A1 and A2
                     //
                     // => we try it once more -> the next snapshot won't 
                     //    contain the current thread

                     CTrace::Print(CTrace::Layer::TEST, L"Catched Exception during suspended"
                        L" for thread %ld", pPidList->ProcessIdList[i]);

                     ErrorProcesses[pPidList->ProcessIdList[i]]++;
                     bNewProcesses = TRUE;
                  } else {

                     // If we get an error three times for the same thread
                     // then we will assume that this thread belongs really 
                     // to this process
                     //
                     // => we could not solve the problem => ERROR
                     throw ex;
                  }
               }
            }
         }
         // A2
      }
      DestroyPidList();
   }      

   // B

   // Between A and B we created  a map of suspended threads (Threads) 
   // but we can not be sure that all these threads belong to this process 
   // (=> recycling of thread id's). It is possible, that we suspended 
   // threads of foreign processes!. Now we will set pair.second to false 
   // for all threads which belong to the current process
   {
      PJOBOBJECT_BASIC_PROCESS_ID_LIST pPidList;
      int i;


      pPidList = CreatePidList();
      if (pPidList == NULL) {
         throw CCodineException(L"Pid List is NULL", __FILE__, __LINE__);
      } else {
         try {
            for (i = 0; i < pPidList->NumberOfProcessIdsInList; i++) {
               CurrentProcess = Processes.find(pPidList->ProcessIdList[i]);
               if (CurrentProcess == Processes.end()) {
                  // If we get a new thread id here, then someone else
                  // created a new thread for this process (CreateRemoteThread())
                  CTrace::Print(CTrace::Layer::TEST, L"Unexpected new thread %ld", pPidList->ProcessIdList[i]);
                  throw CCodineException(L"", __FILE__, __LINE__);
               } else {
                  CurrentProcess->second = FALSE;
               }
            }
         } catch (CCodineException& ex) {
            map<DWORD, CProcess*>::iterator TheProcess;

            // If we come here then we will rollback previous activities
            // Therefore we have to resume all threads contained in Threads            
            for (TheProcess = m_Processes.begin();
                 TheProcess != m_Processes.end();
                 TheProcess++) {
               try {
                  (*TheProcess).second->Resume();
               } catch (CCodineException&) {
                  ;
               }
            }
            throw ex;
         }
      }
      DestroyPidList();
   }

   // C

   // Between B and C we set pair.second to false for all threads 
   // which belong to the current process
   // Now we have to resume the remaining threads
   // We will also add the suspended threads of this process to
   // the member m_Threads. 
   try {
      // Resume and copy
      for (CurrentProcess = Processes.begin();
           CurrentProcess != Processes.end();
           CurrentProcess++) {
         if (CurrentProcess->second == TRUE) {
            CProcess *ForeignProcess = m_Processes[CurrentProcess->first];

            ForeignProcess->Resume();
            m_Processes.erase(CurrentProcess->first);
            CTrace::Print(CTrace::Layer::TEST, L"Resumed foreign thread %ld", CurrentProcess->first);
            break;
         } 
      }
   } catch (CCodineException& ex) {
   
      // What can we do here?

      throw ex;
   }
}