1 //===-- MICmnThreadMgrStd.h -------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #pragma once 11 12 // Third party headers: 13 #include <vector> 14 15 // In-house headers: 16 #include "MICmnBase.h" 17 #include "MICmnResources.h" 18 #include "MIUtilSingletonBase.h" 19 #include "MIUtilThreadBaseStd.h" 20 21 //++ 22 //============================================================================ 23 // Details: MI's worker thread (active thread) manager. 24 // The manager creates threads and behalf of clients. Client are 25 // responsible for their threads and can delete them when necessary. 26 // This manager will stop and delete all threads on *this manager's 27 // shutdown. 28 // Singleton class. 29 //-- 30 class CMICmnThreadMgrStd : public CMICmnBase, 31 public MI::ISingleton<CMICmnThreadMgrStd> { 32 friend MI::ISingleton<CMICmnThreadMgrStd>; 33 34 // Methods: 35 public: 36 bool Initialize() override; 37 bool Shutdown() override; 38 bool ThreadAllTerminate(); // Ask all threads to stop (caution) 39 template <typename T> // Ask the thread manager to start and stop threads on 40 // our behalf 41 bool ThreadStart(T &vrwObject); 42 43 // Typedef: 44 private: 45 typedef std::vector<CMIUtilThreadActiveObjBase *> ThreadList_t; 46 47 // Methods: 48 private: 49 /* ctor */ CMICmnThreadMgrStd(); 50 /* ctor */ CMICmnThreadMgrStd(const CMICmnThreadMgrStd &); 51 void operator=(const CMICmnThreadMgrStd &); 52 // 53 bool AddThread(const CMIUtilThreadActiveObjBase & 54 vrObj); // Add a thread for monitoring by the threadmanager 55 56 // Overridden: 57 private: 58 // From CMICmnBase 59 /* dtor */ ~CMICmnThreadMgrStd() override; 60 61 // Attributes: 62 private: 63 CMIUtilThreadMutex m_mutex; 64 ThreadList_t m_threadList; 65 }; 66 67 //++ 68 //------------------------------------------------------------------------------------ 69 // Details: Given a thread object start its (worker) thread to do work. The 70 // object is 71 // added to the *this manager for housekeeping and deletion of all 72 // thread objects. 73 // Type: Template method. 74 // Args: vrwThreadObj - (RW) A CMIUtilThreadActiveObjBase derived 75 // object. 76 // Return: MIstatus::success - Functional succeeded. 77 // MIstatus::failure - Functional failed. 78 // Throws: None. 79 //-- ThreadStart(T & vrwThreadObj)80template <typename T> bool CMICmnThreadMgrStd::ThreadStart(T &vrwThreadObj) { 81 bool bOk = MIstatus::success; 82 83 // Grab a reference to the base object type 84 CMIUtilThreadActiveObjBase &rObj = 85 static_cast<CMIUtilThreadActiveObjBase &>(vrwThreadObj); 86 87 // Add to the thread managers internal database 88 bOk &= AddThread(rObj); 89 if (!bOk) { 90 const CMIUtilString errMsg( 91 CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE), 92 vrwThreadObj.ThreadGetName().c_str())); 93 SetErrorDescription(errMsg); 94 return MIstatus::failure; 95 } 96 97 // Grab a reference on behalf of the caller 98 bOk &= vrwThreadObj.Acquire(); 99 if (!bOk) { 100 const CMIUtilString errMsg( 101 CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE), 102 vrwThreadObj.ThreadGetName().c_str())); 103 SetErrorDescription(errMsg); 104 return MIstatus::failure; 105 } 106 107 // Thread is already started 108 // This call must come after the reference count increment 109 if (vrwThreadObj.ThreadIsActive()) { 110 // Early exit on thread already running condition 111 return MIstatus::success; 112 } 113 114 // Start the thread running 115 bOk &= vrwThreadObj.ThreadExecute(); 116 if (!bOk) { 117 const CMIUtilString errMsg( 118 CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE), 119 vrwThreadObj.ThreadGetName().c_str())); 120 SetErrorDescription(errMsg); 121 return MIstatus::failure; 122 } 123 124 return MIstatus::success; 125 } 126