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