1//===-- MICmnThreadMgrStd.cpp -----------------------------------*- 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// In-house headers:
11#include "MICmnThreadMgrStd.h"
12#include "MICmnLog.h"
13#include "MICmnResources.h"
14#include "MIUtilSingletonHelper.h"
15
16//++ ------------------------------------------------------------------------------------
17// Details: CMICmnThreadMgr constructor.
18// Type:    Method.
19// Args:    None.
20// Return:  None.
21// Throws:  None.
22//--
23CMICmnThreadMgrStd::CMICmnThreadMgrStd()
24{
25}
26
27//++ ------------------------------------------------------------------------------------
28// Details: CMICmnThreadMgr destructor.
29// Type:    Method.
30// Args:    None.
31// Return:  None.
32// Throws:  None.
33//--
34CMICmnThreadMgrStd::~CMICmnThreadMgrStd()
35{
36    Shutdown();
37}
38
39//++ ------------------------------------------------------------------------------------
40// Details: Initialise resources for *this thread manager.
41// Type:    Method.
42// Args:    None.
43// Return:  MIstatus::success - Functional succeeded.
44//          MIstatus::failure - Functional failed.
45// Throws:  None.
46//--
47bool
48CMICmnThreadMgrStd::Initialize()
49{
50    m_clientUsageRefCnt++;
51
52    if (m_bInitialized)
53        return MIstatus::success;
54
55    bool bOk = MIstatus::success;
56
57    ClrErrorDescription();
58    CMIUtilString errMsg;
59
60    // Note initialisation order is important here as some resources depend on previous
61    MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
62    MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
63
64    m_bInitialized = bOk;
65
66    if (!bOk)
67    {
68        CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_THREADMGR), errMsg.c_str()));
69        SetErrorDescription(strInitError);
70        return MIstatus::failure;
71    }
72
73    return bOk;
74}
75
76//++ ------------------------------------------------------------------------------------
77// Details: Release resources for *this thread manager.
78// Type:    Method.
79// Args:    None.
80// Return:  MIstatus::success - Functional succeeded.
81//          MIstatus::failure - Functional failed.
82// Throws:  None.
83//--
84bool
85CMICmnThreadMgrStd::Shutdown()
86{
87    if (--m_clientUsageRefCnt > 0)
88        return MIstatus::success;
89
90    if (!m_bInitialized)
91        return MIstatus::success;
92
93    m_bInitialized = false;
94
95    ClrErrorDescription();
96
97    bool bOk = MIstatus::success;
98    CMIUtilString errMsg;
99
100    // Tidy up
101    ThreadAllTerminate();
102
103    // Note shutdown order is important here
104    MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
105    MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
106
107    if (!bOk)
108    {
109        SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
110    }
111
112    return bOk;
113}
114
115//++ ------------------------------------------------------------------------------------
116// Details: Ask the thread manager to kill all threads and wait until they have died
117// Type:    Method.
118// Args:    None.
119// Return:  MIstatus::success - Functional succeeded.
120//          MIstatus::failure - Functional failed.
121// Throws:  None.
122//--
123bool
124CMICmnThreadMgrStd::ThreadAllTerminate()
125{
126    ThreadList_t::const_iterator it = m_threadList.begin();
127    for (; it != m_threadList.end(); ++it)
128    {
129        // If the thread is still running
130        CMIUtilThreadActiveObjBase *pThread = *it;
131        if (pThread->ThreadIsActive())
132        {
133            // Ask this thread to kill itself
134            pThread->ThreadKill();
135
136            // Wait for this thread to die
137            pThread->ThreadJoin();
138        }
139    }
140
141    return MIstatus::success;
142}
143
144//++ ------------------------------------------------------------------------------------
145// Details: Add a thread object to *this manager's list of thread objects. The list to
146//          used to manage thread objects centrally.
147// Type:    Method.
148// Args:    vrObj   - (R) A thread object.
149// Return:  MIstatus::success - Functional succeeded.
150//          MIstatus::failure - Functional failed.
151// Throws:  None.
152//--
153bool
154CMICmnThreadMgrStd::AddThread(const CMIUtilThreadActiveObjBase &vrObj)
155{
156    m_threadList.push_back(const_cast<CMIUtilThreadActiveObjBase *>(&vrObj));
157
158    return MIstatus::success;
159}
160