Пример #1
0
//++ ------------------------------------------------------------------------------------
// Details:	Write data to existing opened file.
// Type:	Method.
// Args:	vData - (R) Text data.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIUtilFileStd::Write( const CMIUtilString & vData )
{
	if( vData.size() == 0 )
		return MIstatus::success;

	if( m_bFileError )
		return MIstatus::failure;

	if( m_pFileHandle == nullptr )
	{
		m_bFileError = true;
		SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_NOTOPEN ), m_fileNamePath.c_str() );
		return MIstatus::failure;
	}

	// Get the string size
	MIuint size = vData.size();
	if( ::fwrite( vData.c_str(), 1, size, m_pFileHandle ) == size )
	{
		// Flush the data to the file
		::fflush( m_pFileHandle );
		return MIstatus::success;
	}
	
	// Not all of the data has been transferred
	m_bFileError = true;
	SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_FILE ), m_fileNamePath.c_str() );
	return MIstatus::failure;
}
Пример #2
0
//++ ------------------------------------------------------------------------------------
// Details:	Start worker threads for the driver.
// Type:	Method.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriver::StartWorkerThreads( void )
{
	bool bOk = MIstatus::success;
	
	// Grab the thread manager
	CMICmnThreadMgrStd & rThreadMgr = CMICmnThreadMgrStd::Instance();

	// Start the stdin thread
	bOk &= m_rStdin.SetVisitor( *this );
	if( bOk && !rThreadMgr.ThreadStart< CMICmnStreamStdin >( m_rStdin ))
	{
		const CMIUtilString errMsg = CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str() );
		SetErrorDescriptionn( errMsg );
		return MIstatus::failure;
	}

	// Start the event polling thread
	if( bOk && !rThreadMgr.ThreadStart< CMICmnLLDBDebugger >( m_rLldbDebugger ) )
	{
		const CMIUtilString errMsg = CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str() );
		SetErrorDescriptionn( errMsg );
		return MIstatus::failure;
	}

	return bOk;
}
Пример #3
0
//++ ------------------------------------------------------------------------------------
// Details:	Write data to existing opened file.
// Type:	Method.
// Args:	vData		- (R) Text data.
//			vCharCnt	- (R) Text data length.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIUtilFileStd::Write( const MIchar * vpData, const MIuint vCharCnt )
{
	if( vCharCnt == 0 )
		return MIstatus::success;

	if( m_bFileError )
		return MIstatus::failure;

	if( m_pFileHandle == nullptr )
	{
		m_bFileError = true;
		SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_NOTOPEN ), m_fileNamePath.c_str() );
		return MIstatus::failure;
	}

	if( ::fwrite( vpData, 1, vCharCnt, m_pFileHandle ) == vCharCnt )
	{
		// Flush the data to the file
		::fflush( m_pFileHandle );
		return MIstatus::success;
	}

	// Not all of the data has been transferred
	m_bFileError = true;
	SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_FILE ), m_fileNamePath.c_str() );
	return MIstatus::failure;
}
@@ -509,7 +509,7 @@ bool CMIDriver::StartWorkerThreads() {
    const CMIUtilString errMsg = CMIUtilString::Format(
                                     MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
                                     CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str());
    -    SetErrorDescriptionn(errMsg);
    +    SetErrorDescriptionn(errMsg.c_str());
    return MIstatus::failure;
}
Пример #5
0
//++
//------------------------------------------------------------------------------------
// Details: Release resources for *this thread manager.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnThreadMgrStd::Shutdown() {
  if (--m_clientUsageRefCnt > 0)
    return MIstatus::success;

  if (!m_bInitialized)
    return MIstatus::success;

  m_bInitialized = false;

  ClrErrorDescription();

  bool bOk = MIstatus::success;
  CMIUtilString errMsg;

  // Tidy up
  ThreadAllTerminate();

  // Note shutdown order is important here
  MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
  MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);

  if (!bOk) {
    SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
  }

  return bOk;
}
Пример #6
0
//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_bInitialized = false;

    ClrErrorDescription();

    if (m_pCmdBuffer != nullptr)
    {
        delete[] m_pCmdBuffer;
        m_pCmdBuffer = nullptr;
    }

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
    }

    return MIstatus::success;
}
Пример #7
0
//++ ------------------------------------------------------------------------------------
// Details:	Release resources for *this Stdin stream.
// Type:	Method.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnStreamStdinLinux::Shutdown( void )
{
	if( !m_bInitialized )
		return MIstatus::success;

	m_bInitialized = false;

	ClrErrorDescription();

	bool bOk = MIstatus::success;
	CMIUtilString errMsg;

	// Tidy up
	if( m_pCmdBuffer != nullptr )
	{
		delete [] m_pCmdBuffer;
		m_pCmdBuffer = nullptr;
	}
	m_pStdin = nullptr;

	// Note shutdown order is important here 	
	MI::ModuleShutdown< CMICmnResources >( IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg );
	MI::ModuleShutdown< CMICmnLog >      ( IDS_MI_INIT_ERR_LOG      , bOk, errMsg );

	if( !bOk )
	{
		SetErrorDescriptionn( MIRSRC( IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER ), errMsg.c_str() );
	}

	return MIstatus::success;
}	
Пример #8
0
//++ ------------------------------------------------------------------------------------
// Details: Unbind detach or release resources used by *this driver.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_eCurrentDriverState = eDriverState_ShuttingDown;

    ClrErrorDescription();

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    // Shutdown all of the modules we depend on
    MI::ModuleShutdown<CMICmnLLDBDebugger>(IDS_MI_INIT_ERR_LLDBDEBUGGER, bOk, errMsg);
    MI::ModuleShutdown<CMICmdMgr>(IDS_MI_INIT_ERR_CMDMGR, bOk, errMsg);
    MI::ModuleShutdown<CMICmnStreamStdin>(IDS_MI_INIT_ERR_STREAMSTDIN, bOk, errMsg);
    MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMANAGER, bOk, errMsg);
    MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnStreamStderr>(IDS_MI_INIT_ERR_STREAMSTDERR, bOk, errMsg);
    MI::ModuleShutdown<CMICmnStreamStdout>(IDS_MI_INIT_ERR_STREAMSTDOUT, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
    }

    m_eCurrentDriverState = eDriverState_NotRunning;

    return bOk;
}
Пример #9
0
//++ ------------------------------------------------------------------------------------
// Details:	Set a unique ID for *this driver. It cannot be empty.
// Type:	Overridden.
// Args:	vId	- (R) Text description.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriver::SetId( const CMIUtilString & vId )
{
	if( vId.empty() )
	{
		SetErrorDescriptionn( MIRSRC( IDS_DRIVER_ERR_ID_INVALID ), GetName().c_str(), vId.c_str() );
		return MIstatus::failure;
	}

	m_strDriverId = vId;
	return MIstatus::success;
}
Пример #10
0
//++
//------------------------------------------------------------------------------------
// Details: Release resources for *this debugger object.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool CMICmnLLDBDebugger::Shutdown() {
  if (--m_clientUsageRefCnt > 0)
    return MIstatus::success;

  if (!m_bInitialized)
    return MIstatus::success;

  m_bInitialized = false;

  ClrErrorDescription();

  bool bOk = MIstatus::success;
  CMIUtilString errMsg;

  // Explicitly delete the remote target in case MI needs to exit prematurely
  // otherwise
  // LLDB debugger may hang in its Destroy() fn waiting on events
  lldb::SBTarget sbTarget = CMICmnLLDBDebugSessionInfo::Instance().GetTarget();
  m_lldbDebugger.DeleteTarget(sbTarget);

  // Debug: May need this but does seem to work without it so commented out the
  // fudge 19/06/2014
  // It appears we need to wait as hang does not occur when hitting a debug
  // breakpoint here
  // const std::chrono::milliseconds time( 1000 );
  // std::this_thread::sleep_for( time );

  lldb::SBDebugger::Destroy(m_lldbDebugger);
  lldb::SBDebugger::Terminate();
  m_pClientDriver = nullptr;
  m_mapBroadcastClassNameToEventMask.clear();
  m_mapIdToEventMask.clear();

  // Note shutdown order is important here
  MI::ModuleShutdown<CMICmnLLDBDebugSessionInfo>(
      IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg);
  MI::ModuleShutdown<CMICmnLLDBDebuggerHandleEvents>(
      IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg);
  MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk,
                                         errMsg);
  MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
  MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);

  if (!bOk) {
    SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_LLDBDEBUGGER),
                         errMsg.c_str());
  }

  return MIstatus::success;
}
Пример #11
0
//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Command Manager.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool
CMICmdMgr::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_bInitialized = false;

    ClrErrorDescription();

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    // Tidy up
    m_setCmdDeleteCallback.clear();

    // Note shutdown order is important here
    if (!m_invoker.Shutdown())
    {
        bOk = false;
        errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINVOKER), m_invoker.GetErrorDescription().c_str());
    }
    if (!m_factory.Shutdown())
    {
        bOk = false;
        if (!errMsg.empty())
            errMsg += ", ";
        errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDFACTORY), m_factory.GetErrorDescription().c_str());
    }
    if (!m_interpretor.Shutdown())
    {
        bOk = false;
        if (!errMsg.empty())
            errMsg += ", ";
        errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINTERPRETER), m_interpretor.GetErrorDescription().c_str());
    }
    MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
    }

    return MIstatus::success;
}
Пример #12
0
//++ ------------------------------------------------------------------------------------
// Details:	Register a driver with *this Driver Manager. Call SetUseThisDriverToDoWork()
//			inform the manager which driver is the one to the work. The manager calls
//			the driver's init function which must be successful in order to complete the
//			registration.
// Type:	Method.
// Args:	vrDriver	- (R) The driver to register.
//			vrDriverID	- (R) The driver's ID to lookup by.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriverMgr::RegisterDriver( const IDriver & vrDriver, const CMIUtilString & vrDriverID )
{
	if( HaveDriverAlready( vrDriver ) )
		return MIstatus::success;

	IDriver * pDriver = const_cast< IDriver * >( &vrDriver );
	if( !pDriver->SetId( vrDriverID ) )
		return MIstatus::failure;
	if( !pDriver->DoInitialize() )
	{
		SetErrorDescriptionn( MIRSRC( IDS_DRIVERMGR_DRIVER_ERR_INIT ), pDriver->GetName().c_str(), vrDriverID.c_str(), pDriver->GetError().c_str() );
		return MIstatus::failure;
	}

	MapPairDriverIdToDriver_t pr( vrDriverID, pDriver );
	m_mapDriverIdToDriver.insert( pr );

	return MIstatus::success;
}
Пример #13
0
//++ ------------------------------------------------------------------------------------
// Details:	Open file for writing. On the first call to this function after *this object
//			is created the file is either created or replace, from then on open only opens
//			an existing file.
// Type:	Method.
// Args:	vFileNamePath	- (R) File name path.
//			vwrbNewCreated	- (W) True - file recreated, false - file appended too.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIUtilFileStd::CreateWrite( const CMIUtilString & vFileNamePath, bool & vwrbNewCreated )
{
	// Reset
	m_bFileError = false;
	vwrbNewCreated = false;
		
	if( vFileNamePath.empty() )
	{
		m_bFileError = true;
		SetErrorDescription( MIRSRC( IDS_UTIL_FILE_ERR_INVALID_PATHNAME ) );
		return MIstatus::failure;
	}
	
	// File is already open so exit
	if( m_pFileHandle != nullptr )
		return MIstatus::success;

#if !defined( _MSC_VER )
	// Open with 'write' and 'binary' mode
	m_pFileHandle = ::fopen( vFileNamePath.c_str(), "wb" );
#else
	// Open a file with exclusive write and shared read permissions
	m_pFileHandle = ::_fsopen( vFileNamePath.c_str(), "wb", _SH_DENYWR );
#endif // !defined( _MSC_VER )

	if( m_pFileHandle == nullptr )
	{
		m_bFileError = true;
		SetErrorDescriptionn( MIRSRC( IDS_UTIL_FILE_ERR_OPENING_FILE ), strerror( errno ), vFileNamePath.c_str() );
		return MIstatus::failure;
	}
	
	vwrbNewCreated = true;
	m_fileNamePath = vFileNamePath;

	return MIstatus::success;
}
Пример #14
0
//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_bInitialized = false;

    ClrErrorDescription();

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    m_pVisitor = nullptr;
    m_bKeyCtrlCHit = false;

// Note shutdown order is important here
#ifndef _MSC_VER
    MI::ModuleShutdown<CMICmnStreamStdinLinux>(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER, bOk, errMsg);
#else
    MI::ModuleShutdown<CMICmnStreamStdinWindows>(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER, bOk, errMsg);
#endif // ( _MSC_VER )
    MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_SHTDWN_ERR_THREADMGR, bOk, errMsg);
    MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
    }

    return MIstatus::success;
}
Пример #15
0
//++ ------------------------------------------------------------------------------------
// Details: Call this function puts *this driver to work.
//          This function is used by the application's main thread.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::DoMainLoop(void)
{
    if (!InitClientIDEToMIDriver()) // Init Eclipse IDE
    {
        SetErrorDescriptionn(MIRSRC(IDS_MI_INIT_ERR_CLIENT_USING_DRIVER));
        return MIstatus::failure;
    }

    if (!StartWorkerThreads())
        return MIstatus::failure;

    bool bOk = MIstatus::success;

    if (HaveExecutableFileNamePathOnCmdLine())
    {
        if (!LocalDebugSessionStartupExecuteCommands())
        {
            SetErrorDescription(MIRSRC(IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION));
            bOk = MIstatus::failure;
        }
    }

    // App is not quitting currently
    m_bExitApp = false;

    // While the app is active
    while (bOk && !m_bExitApp)
    {
        CMIUtilString errorText;
        const MIchar *pCmd = m_rStdin.ReadLine (errorText);
        if (pCmd != nullptr)
        {
            CMIUtilString lineText(pCmd);
            if (!lineText.empty ())
            {
                if (lineText == "quit")
                {
                    // We want to be exiting when receiving a quit command
                    m_bExitApp = true;
                    break;
                }

                {
                    // Lock Mutex before processing commands so that we don't disturb an event
                    // being processed
                    CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
                    bOk = InterpretCommand(lineText);
                }
                // Draw prompt if desired
                if (bOk && m_rStdin.GetEnablePrompt())
                    bOk = m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
            }
        }
    }

    // Signal that the application is shutting down
    DoAppQuit();

    // Close and wait for the workers to stop
    StopWorkerThreads();

    // Ensure that a new line is sent as the last act of the dying driver
    m_rStdOut.WriteMIResponse("\n", false);

    return MIstatus::success;
}
Пример #16
0
//++ ------------------------------------------------------------------------------------
// Details: Call this function puts *this driver to work.
//          This function is used by the application's main thread.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIDriver::DoMainLoop(void)
{
    if (!InitClientIDEToMIDriver()) // Init Eclipse IDE
    {
        SetErrorDescriptionn(MIRSRC(IDS_MI_INIT_ERR_CLIENT_USING_DRIVER));
        return MIstatus::failure;
    }

    if (!StartWorkerThreads())
        return MIstatus::failure;

    bool bOk = MIstatus::success;

    if (HaveExecutableFileNamePathOnCmdLine())
    {
        if (!LocalDebugSessionStartupExecuteCommands())
        {
            SetErrorDescription(MIRSRC(IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION));
            bOk = MIstatus::failure;
        }
    }

    // App is not quitting currently
    m_bExitApp = false;

    // Handle source file
    if (m_bHaveCommandFileNamePathOnCmdLine)
    {
        const bool bAsyncMode = false;
        ExecuteCommandFile(bAsyncMode);
    }

    // While the app is active
    while (bOk && !m_bExitApp)
    {
        CMIUtilString errorText;
        const char *pCmd = m_rStdin.ReadLine (errorText);
        if (pCmd != nullptr)
        {
            CMIUtilString lineText(pCmd);
            if (!lineText.empty ())
            {
                // Check that the handler thread is alive (otherwise we stuck here)
                assert(CMICmnLLDBDebugger::Instance().ThreadIsActive());

                {
                    // Lock Mutex before processing commands so that we don't disturb an event
                    // being processed
                    CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
                    bOk = InterpretCommand(lineText);
                }

                // Draw prompt if desired
                bOk = bOk && CMICmnStreamStdout::WritePrompt();

                // Wait while the handler thread handles incoming events
                CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
            }
        }
    }

    // Signal that the application is shutting down
    DoAppQuit();

    // Close and wait for the workers to stop
    StopWorkerThreads();

    // Ensure that a new line is sent as the last act of the dying driver
    m_rStdOut.WriteMIResponse("\n", false);

    return MIstatus::success;
}
Пример #17
0
//++ ------------------------------------------------------------------------------------
// Details:	Unbind detach or release resources used by this server in general common 
//			functionality shared between versions of any server interfaces implemented.
// Type:	Method.
// Args:	vbAppExitOk	- (R) True = No problems, false = App exiting with problems (investigate!).	
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMIDriverMgr::Shutdown( void )
{
	// Do not want a ref counter because this function needs to be called how ever this 
	// application stops running
	//if( --m_clientUsageRefCnt > 0 )
	//	return MIstatus::success;
	
	bool vbAppExitOk = true;

	ClrErrorDescription();

	if( !m_bInitialized )
		return MIstatus::success;

	if( vbAppExitOk )	
	{
		// The MI Driver's log updating may have been switched off switch back on to say all is ok. 
		CMICmnLog::Instance().SetEnabled( true );
#if _DEBUG
		CMICmnStreamStdout::Instance().Write( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Both stdout and Log
#else
		CMICmnLog::WriteLog( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Just to the Log
#endif // _DEBUG
	}
	else
	{
		CMICmnLog & rAppLog = CMICmnLog::Instance();
		if( rAppLog.GetEnabled()  )
		{
			const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) );
			CMICmnStreamStdout::Instance().Write( msg );
		}
		else
		{
			// The MI Driver's log updating may have been switched off switch back on to say there has been problem. 
			rAppLog.SetEnabled( true );
			const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) );
			CMICmnStreamStdout::Instance().Write( msg );
		}
	}
	
	m_bInitialized = false;

	bool bOk = MIstatus::success;
	CMIUtilString errMsg;

	// Tidy up
	UnregisterDriverAll();
	MIUtilTermios::StdinTermiosReset();
 
	// Note shutdown order is important here 
	MI::ModuleShutdown< CMICmnResources >( IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg );
	MI::ModuleShutdown< CMICmnLog >      ( IDS_MI_SHTDWN_ERR_LOG      , bOk, errMsg );

	if( !bOk )
	{
		SetErrorDescriptionn( MIRSRC( IDS_MI_SHTDWN_ERR_DRIVERMGR ), errMsg.c_str() );
	}

	return bOk;
}