Пример #1
0
// Open
//------------------------------------------------------------------------------
bool FileStream::Open( const char * fileName, uint32_t fileMode )
{
    ASSERT( !IsOpen() );

#if defined( __WINDOWS__ )
    DWORD desiredAccess( 0 );
    DWORD shareMode( 0 );
    DWORD creationDisposition( 0 );
    DWORD flags( FILE_ATTRIBUTE_NORMAL );

    // access mode
    if ( ( fileMode & READ_ONLY ) != 0 )
    {
        ASSERT( fileMode == READ_ONLY ); // no extra flags allowed
        desiredAccess       |= GENERIC_READ;
        shareMode           |= FILE_SHARE_READ; // allow other readers
        creationDisposition |= OPEN_EXISTING;
    }
    else if ( ( fileMode & WRITE_ONLY ) != 0 )
    {
        desiredAccess       |= GENERIC_WRITE;
        shareMode           |= FILE_SHARE_READ; // allow other readers
        creationDisposition |= CREATE_ALWAYS; // overwrite existing
    }
    else
    {
        ASSERT( false ); // must specify an access mode
    }

    // extra flags
    if ( ( fileMode & TEMP ) != 0 )
    {
        flags |= FILE_ATTRIBUTE_TEMPORARY; // don't flush to disk if possible
    }

    // for sharing violations, we'll retry a few times as per http://support.microsoft.com/kb/316609
    size_t retryCount = 0;
    while ( retryCount < 5 )
    {
        HANDLE h = CreateFile( fileName,            // _In_     LPCTSTR lpFileName,
                               desiredAccess,       // _In_     DWORD dwDesiredAccess,
                               shareMode,           // _In_     DWORD dwShareMode,
                               nullptr,             // _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                               creationDisposition, // _In_     DWORD dwCreationDisposition,
                               flags,               // _In_     DWORD dwFlagsAndAttributes,
                               nullptr );           // _In_opt_ HANDLE hTemplateFile

        if ( h != INVALID_HANDLE_VALUE )
        {
            // file opened ok
            m_Handle = (void *)h;
            FSDEBUG( DEBUGSPAM( "Open file OK: %x - '%s' on %x\n", m_Handle, fileName, Thread::GetCurrentThreadId() ); )
            return true;
        }
Пример #2
0
// DoBuild
//------------------------------------------------------------------------------
/*static*/ Node::BuildResult JobQueueRemote::DoBuild( Job * job, bool racingRemoteJob )
{
	Timer timer; // track how long the item takes

	ObjectNode * node = job->GetNode()->CastTo< ObjectNode >();

	// remote tasks must output to a tmp file
	if ( job->IsLocal() == false )
	{
		// file name should be the same as on host
		const char * fileName = ( job->GetRemoteName().FindLast( NATIVE_SLASH ) + 1 );

		AStackString<> tmpFileName;
		WorkerThread::CreateTempFilePath( fileName, tmpFileName );
		node->ReplaceDummyName( tmpFileName );

		#ifdef DEBUG
			DEBUGSPAM( "REMOTE: %s (%s)\n", fileName, job->GetRemoteName().Get() );
		#endif
	}

	ASSERT( node->IsAFile() );

	// make sure the output path exists
	if ( Node::EnsurePathExistsForFile( node->GetName() ) == false )
	{
		// error already output by EnsurePathExistsForFile
		return Node::NODE_RESULT_FAILED;
	}

	// Delete any left over PDB from a previous run (to be sure we have a clean pdb)
	if ( node->IsUsingPDB() && ( job->IsLocal() == false ) )
	{
		AStackString<> pdbName;
		node->GetPDBName( pdbName );
		FileIO::FileDelete( pdbName.Get() );
	}

    Node::BuildResult result;
    {
        PROFILE_SECTION( racingRemoteJob ? "RACE" : "LOCAL" );
    	result = ((Node *)node )->DoBuild2( job, racingRemoteJob );
    }

	uint32_t timeTakenMS = uint32_t( timer.GetElapsedMS() );

	if ( result == Node::NODE_RESULT_OK )
	{
		// record new build time only if built (i.e. if failed, the time
		// does not represent how long it takes to create this resource)
		node->SetLastBuildTime( timeTakenMS );
		node->SetStatFlag( Node::STATS_BUILT );
		//FLOG_INFO( "-Build: %u ms\t%s", timeTakenMS, node->GetName().Get() );

		#ifdef DEBUG
			if ( job->IsLocal() )
			{
				// record new file time for remote job we built locally
				ASSERT( node->m_Stamp == FileIO::GetFileLastWriteTime(node->GetName()) );
			}
		#endif
	}

	if ( result == Node::NODE_RESULT_FAILED )
	{
		// build of file failed - if there is a file....
		if ( FileIO::FileExists( node->GetName().Get() ) )
		{
			// ... it is invalid, so try to delete it
			if ( FileIO::FileDelete( node->GetName().Get() ) == false )
			{
				// failed to delete it - this might cause future build problems!
				FLOG_ERROR( "Post failure deletion failed for '%s'", node->GetName().Get() );
			}
		}
	}
	else
	{
		// build completed ok, or retrieved from cache...
		ASSERT( result == Node::NODE_RESULT_OK );

		// TODO:A Also read into job if cache is being used
		if ( job->IsLocal() == false )
		{
			// read results into memory to send back to client	
			if ( ReadResults( job ) == false )
			{	
				result = Node::NODE_RESULT_FAILED;
			}
		}
	}

	// if compiling to a tmp file, do cleanup	
	if ( job->IsLocal() == false )
	{
		// Cleanup obj file
		FileIO::FileDelete( node->GetName().Get() );

		// Cleanup PDB file
		if ( node->IsUsingPDB() )
		{
			AStackString<> pdbName;
			node->GetPDBName( pdbName );
			FileIO::FileDelete( pdbName.Get() );
		}
	}

	// log processing time
	node->AddProcessingTime( timeTakenMS );
	
	return result;
}