示例#1
0
bool Process::Start( int timeout )
{
    tstring str = m_Executable;
    str += TXT( " " );
    str += Helium::CmdLineDelimiters[0];
    str += Worker::Args::Worker;

    // make our worker wait forever is we were asked to
    if ( m_Wait )
    {
        str += TXT( " " );
        str += Helium::CmdLineDelimiters[0];
        str += Worker::Args::Wait;
        timeout = -1;
    }

    STARTUPINFO startupInfo;
    memset( &startupInfo, 0, sizeof( startupInfo ) );
    startupInfo.cb = sizeof( startupInfo );

    PROCESS_INFORMATION procInfo;
    memset( &procInfo, 0, sizeof( procInfo ) );

    DWORD flags = 0;

#ifdef _DEBUG
    flags |= CREATE_NEW_CONSOLE;
#else
    flags |= CREATE_NO_WINDOW;
#endif

    // Start the child process.
    if( !m_Debug && !::CreateProcess( NULL, (LPTSTR) str.c_str(), NULL, NULL, FALSE, flags, NULL, NULL, &startupInfo, &procInfo ) )
    {
        throw Helium::Exception( TXT( "Failed to run '%s' (%s)\n" ), str.c_str(), Helium::GetErrorString().c_str() );
    }
    else
    {
        // save this for query later
        m_Handle = procInfo.hProcess;

        // create the server side of the connection
        IPC::PipeConnection* connection = new IPC::PipeConnection ();

        // init pipe connection with background process' process id (hex)
        tostringstream stream;

        if ( m_Debug )
        {
            stream << TXT( "worker_debug" );
        }
        else
        {
            stream << TXT( "worker_" ) << std::hex << GetProcessId( m_Handle );
        }

        connection->Initialize(true, TXT( "Worker Process Connection" ), stream.str().c_str());

        // setup global connection
        m_Connection = connection;

        // release handles to our new process
        ::CloseHandle( procInfo.hThread );

        // mutex from kill
        Helium::MutexScopeLock mutex ( m_KillMutex );

        while ( timeout-- != 0 )
        {
            if ( m_Killed )
            {
                break;
            }

            if ( m_Connection && m_Connection->GetState() == IPC::ConnectionStates::Active )
            {
                break;
            }

            if ( m_Handle )
            {
                DWORD code = 0x0;
                ::GetExitCodeProcess( m_Handle, &code );
                if ( code != STILL_ACTIVE )
                {
                    break;
                }
            }

            Sleep( 1 );
        }

        if ( m_Connection && m_Connection->GetState() != IPC::ConnectionStates::Active )
        {
            Kill();

            return false;
        }

        return true;
    }
}
示例#2
0
bool Process::Start( int timeout )
{
    std::string str = m_Executable;
    str += TXT( " " );
    str += Helium::CmdLineDelimiters[0];
    str += Worker::Args::Worker;

    // make our worker wait forever is we were asked to
    if ( m_Wait )
    {
        str += TXT( " " );
        str += Helium::CmdLineDelimiters[0];
        str += Worker::Args::Wait;
        timeout = -1;
    }

    // Start the child process.
    if( !m_Debug )
    {
        m_Handle = Spawn( str.c_str() );
        if ( m_Handle == 0 )
        {
            throw Helium::Exception( TXT( "Failed to run '%s' (%s)\n" ), str.c_str(), Helium::GetErrorString().c_str() );
        }

        // create the server side of the connection
        IPC::PipeConnection* connection = new IPC::PipeConnection ();

        // init pipe connection with background process' process id (hex)
        std::ostringstream stream;

        if ( m_Debug )
        {
            stream << TXT( "worker_debug" );
        }
        else
        {
            stream << TXT( "worker_" ) << std::hex << GetProcessId( m_Handle );
        }

        connection->Initialize(true, TXT( "Worker Process Connection" ), stream.str().c_str());

        // setup global connection
        m_Connection = connection;

        // mutex from kill
        Helium::MutexScopeLock mutex ( m_KillMutex );

        while ( timeout-- != 0 )
        {
            if ( m_Killed )
            {
                break;
            }

            if ( m_Connection && m_Connection->GetState() == IPC::ConnectionStates::Active )
            {
                break;
            }

            if ( m_Handle )
            {
                if ( !SpawnRunning( m_Handle ) )
                {
                    break;
                }
            }

            Thread::Yield();
        }

        if ( m_Connection && m_Connection->GetState() != IPC::ConnectionStates::Active )
        {
            Kill();

            return false;
        }

        return true;
    }

    return false;
}