示例#1
0
// CheckWaitingJobs
//------------------------------------------------------------------------------
void Server::CheckWaitingJobs( const ToolManifest * manifest )
{
    // queue for start any jobs that may now be ready
#ifdef ASSERTS_ENABLED
    bool atLeastOneJobStarted = false;
#endif

    MutexHolder mhC( m_ClientListMutex );
    const ClientState * const * end = m_ClientList.End();
    for ( ClientState ** it = m_ClientList.Begin(); it!=end; ++it )
    {
        // For each connected client...
        ClientState * cs = *it;
        MutexHolder mh2( cs->m_Mutex );

        // .. check all jobs waiting for ToolManifests
        int32_t numJobs = (int32_t)cs->m_WaitingJobs.GetSize();
        for ( int32_t i=( numJobs -1 ); i >= 0; --i )
        {
            Job * job = cs->m_WaitingJobs[ i ];
            ToolManifest * manifestForThisJob = job->GetToolManifest();
            ASSERT( manifestForThisJob );
            if ( manifestForThisJob == manifest )
            {
                cs->m_WaitingJobs.EraseIndex( i );
                JobQueueRemote::Get().QueueJob( job );
                PROTOCOL_DEBUG( "Server: Job %x can now be started\n", job );
#ifdef ASSERTS_ENABLED
                atLeastOneJobStarted = true;
#endif
            }
        }
    }

    // We should only have called this function when a ToolChain sync was complete
    // so at least 1 job should have been waiting for it
    ASSERT( atLeastOneJobStarted );
}
示例#2
0
//------------------------------------------------------------------------------
/*virtual*/ void Server::OnDisconnected( const ConnectionInfo * connection )
{
    ASSERT( connection );
    ClientState * cs = (ClientState *)connection->GetUserData();
    ASSERT( cs );

    // Unhook any jobs which are queued or in progress for this client
    // - deletes the queued jobs
    // - unhooks the UserData for in-progress jobs so the result is discarded on completion
    JobQueueRemote & jqr = JobQueueRemote::Get();
    jqr.CancelJobsWithUserData( cs );

    // check if any tool chain was being sync'd from this Client
    Array< ToolManifest * > cancelledManifests( 0, true );
    {
        MutexHolder manifestMH( m_ToolManifestsMutex );
        const ToolManifest * const * end = m_Tools.End();
        ToolManifest ** it = m_Tools.Begin();
        while ( it != end )
        {
            // if synchronizing from connection that was just disconnected...
            ToolManifest * tm = *it;
            if ( ( tm->IsSynchronized() == false ) &&
                    ( tm->GetUserData() == connection ) )
            {
                // ...flag any expected files as not synching
                tm->CancelSynchronizingFiles();
                tm->SetUserData( nullptr );
                cancelledManifests.Append( tm );
            }
            ++it;
        }
    }

    // free the serverstate structure
    MutexHolder mh( m_ClientListMutex );
    ClientState ** iter = m_ClientList.Find( cs );
    ASSERT( iter );
    m_ClientList.Erase( iter );

    // because we cancelled manifest syncrhonization, we need to check if other
    // connections are waiting for the same manifest
    {
        ClientState ** it = m_ClientList.Begin();
        const ClientState * const * end = m_ClientList.End();
        for ( ; it != end; ++it )
        {
            ClientState * otherCS = *it;

            MutexHolder mh2( otherCS->m_Mutex );
            const Job * const * jEnd = otherCS->m_WaitingJobs.End();
            for ( Job ** jIt = otherCS->m_WaitingJobs.Begin(); jIt != jEnd; ++jIt )
            {
                Job * j = *jIt;
                ToolManifest * jMan = j->GetToolManifest();
                if ( cancelledManifests.Find( jMan ) )
                {
                    RequestMissingFiles( otherCS->m_Connection, jMan );
                }
            }
        }
    }

    // This is usually null here, but might need to be freed if
    // we had the connection drop between message and payload
    FREE( (void *)( cs->m_CurrentMessage ) );

    // delete any jobs where we were waiting on Tool synchronization
    const Job * const * end = cs->m_WaitingJobs.End();
    for ( Job ** it=cs->m_WaitingJobs.Begin(); it!=end; ++it )
    {
        delete *it;
    }

    FDELETE cs;
}