2014-05-16 18:51:01 +08:00
|
|
|
//===-- MICmnThreadMgrStd.h -------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
//++
|
|
|
|
// File: MICmnThreadMgrStd.h
|
|
|
|
//
|
|
|
|
// Overview: CMICmnThreadMgr interface.
|
|
|
|
//
|
|
|
|
// Environment: Compilers: Visual C++ 12.
|
|
|
|
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
|
|
|
|
// Libraries: See MIReadmetxt.
|
|
|
|
//
|
|
|
|
// Copyright: None.
|
|
|
|
//--
|
|
|
|
|
|
|
|
#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 );
|
|
|
|
bool Shutdown( void );
|
|
|
|
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 */ virtual ~CMICmnThreadMgrStd( void );
|
|
|
|
|
|
|
|
// 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.
|
2014-06-25 00:35:50 +08:00
|
|
|
// Args: vrwThreadObj - (RW) A CMIUtilThreadActiveObjBase derived object.
|
2014-05-16 18:51:01 +08:00
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
|
|
|
//--
|
|
|
|
template< typename T >
|
2014-06-25 00:35:50 +08:00
|
|
|
bool CMICmnThreadMgrStd::ThreadStart( T & vrwThreadObj )
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
bool bOk = MIstatus::success;
|
|
|
|
|
|
|
|
// Grab a reference to the base object type
|
2014-06-25 00:35:50 +08:00
|
|
|
CMIUtilThreadActiveObjBase & rObj = static_cast< CMIUtilThreadActiveObjBase & >( vrwThreadObj );
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
// Add to the thread managers internal database
|
|
|
|
bOk &= AddThread( rObj );
|
|
|
|
if( !bOk )
|
|
|
|
{
|
2014-06-25 00:35:50 +08:00
|
|
|
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrwThreadObj.ThreadGetName().c_str() ) );
|
2014-05-16 18:51:01 +08:00
|
|
|
SetErrorDescription( errMsg );
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Grab a reference on behalf of the caller
|
2014-06-25 00:35:50 +08:00
|
|
|
bOk &= vrwThreadObj.Acquire();
|
2014-05-16 18:51:01 +08:00
|
|
|
if( !bOk )
|
|
|
|
{
|
2014-06-25 00:35:50 +08:00
|
|
|
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrwThreadObj.ThreadGetName().c_str() ) );
|
2014-05-16 18:51:01 +08:00
|
|
|
SetErrorDescription( errMsg );
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Thread is already started
|
2014-06-25 00:35:50 +08:00
|
|
|
// This call must come after the reference count increment
|
|
|
|
if( vrwThreadObj.ThreadIsActive() )
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
// Early exit on thread already running condition
|
|
|
|
return MIstatus::success;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start the thread running
|
2014-06-25 00:35:50 +08:00
|
|
|
bOk &= vrwThreadObj.ThreadExecute();
|
2014-05-16 18:51:01 +08:00
|
|
|
if( !bOk )
|
|
|
|
{
|
2014-06-25 00:35:50 +08:00
|
|
|
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrwThreadObj.ThreadGetName().c_str() ) );
|
2014-05-16 18:51:01 +08:00
|
|
|
SetErrorDescription( errMsg );
|
|
|
|
return MIstatus::failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MIstatus::success;
|
|
|
|
}
|