//===-- ThreadList.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <stdlib.h>

// C++ Includes
#include <algorithm>

// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/ConvertEnum.h"
#include "lldb/Utility/LLDBAssert.h"

using namespace lldb;
using namespace lldb_private;

ThreadList::ThreadList (Process *process) :
    ThreadCollection(),
    m_process (process),
    m_stop_id (0),
    m_selected_tid (LLDB_INVALID_THREAD_ID)
{
}

ThreadList::ThreadList (const ThreadList &rhs) :
    ThreadCollection(),
    m_process (rhs.m_process),
    m_stop_id (rhs.m_stop_id),
    m_selected_tid ()
{
    // Use the assignment operator since it uses the mutex
    *this = rhs;
}

const ThreadList&
ThreadList::operator = (const ThreadList& rhs)
{
    if (this != &rhs)
    {
        // Lock both mutexes to make sure neither side changes anyone on us
        // while the assignment occurs
        Mutex::Locker locker(GetMutex());
        m_process = rhs.m_process;
        m_stop_id = rhs.m_stop_id;
        m_threads = rhs.m_threads;
        m_selected_tid = rhs.m_selected_tid;
    }
    return *this;
}


ThreadList::~ThreadList()
{
    // Clear the thread list. Clear will take the mutex lock
    // which will ensure that if anyone is using the list
    // they won't get it removed while using it.
    Clear();
}


uint32_t
ThreadList::GetStopID () const
{
    return m_stop_id;
}

void
ThreadList::SetStopID (uint32_t stop_id)
{
    m_stop_id = stop_id;
}

uint32_t
ThreadList::GetSize (bool can_update)
{
    Mutex::Locker locker(GetMutex());
    if (can_update)
        m_process->UpdateThreadListIfNeeded();
    return m_threads.size();
}

ThreadSP
ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
{
    Mutex::Locker locker(GetMutex());
    if (can_update)
        m_process->UpdateThreadListIfNeeded();

    ThreadSP thread_sp;
    if (idx < m_threads.size())
        thread_sp = m_threads[idx];
    return thread_sp;
}

ThreadSP
ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
{
    Mutex::Locker locker(GetMutex());

    if (can_update)
        m_process->UpdateThreadListIfNeeded();

    ThreadSP thread_sp;
    uint32_t idx = 0;
    const uint32_t num_threads = m_threads.size();
    for (idx = 0; idx < num_threads; ++idx)
    {
        if (m_threads[idx]->GetID() == tid)
        {
            thread_sp = m_threads[idx];
            break;
        }
    }
    return thread_sp;
}

ThreadSP
ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
{
    Mutex::Locker locker(GetMutex());
    
    if (can_update)
        m_process->UpdateThreadListIfNeeded();
    
    ThreadSP thread_sp;
    uint32_t idx = 0;
    const uint32_t num_threads = m_threads.size();
    for (idx = 0; idx < num_threads; ++idx)
    {
        if (m_threads[idx]->GetProtocolID() == tid)
        {
            thread_sp = m_threads[idx];
            break;
        }
    }
    return thread_sp;
}


ThreadSP
ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
{
    Mutex::Locker locker(GetMutex());
    
    if (can_update)
        m_process->UpdateThreadListIfNeeded();
    
    ThreadSP thread_sp;
    uint32_t idx = 0;
    const uint32_t num_threads = m_threads.size();
    for (idx = 0; idx < num_threads; ++idx)
    {
        if (m_threads[idx]->GetID() == tid)
        {
            thread_sp = m_threads[idx];
            m_threads.erase(m_threads.begin()+idx);
            break;
        }
    }
    return thread_sp;
}

ThreadSP
ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
{
    Mutex::Locker locker(GetMutex());
    
    if (can_update)
        m_process->UpdateThreadListIfNeeded();
    
    ThreadSP thread_sp;
    uint32_t idx = 0;
    const uint32_t num_threads = m_threads.size();
    for (idx = 0; idx < num_threads; ++idx)
    {
        if (m_threads[idx]->GetProtocolID() == tid)
        {
            thread_sp = m_threads[idx];
            m_threads.erase(m_threads.begin()+idx);
            break;
        }
    }
    return thread_sp;
}

ThreadSP
ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
{
    ThreadSP thread_sp;
    if (thread_ptr)
    {
        Mutex::Locker locker(GetMutex());

        uint32_t idx = 0;
        const uint32_t num_threads = m_threads.size();
        for (idx = 0; idx < num_threads; ++idx)
        {
            if (m_threads[idx].get() == thread_ptr)
            {
                thread_sp = m_threads[idx];
                break;
            }
        }
    }
    return thread_sp;
}



ThreadSP
ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
{
    Mutex::Locker locker(GetMutex());

    if (can_update)
        m_process->UpdateThreadListIfNeeded();

    ThreadSP thread_sp;
    const uint32_t num_threads = m_threads.size();
    for (uint32_t idx = 0; idx < num_threads; ++idx)
    {
        if (m_threads[idx]->GetIndexID() == index_id)
        {
            thread_sp = m_threads[idx];
            break;
        }
    }
    return thread_sp;
}

bool
ThreadList::ShouldStop (Event *event_ptr)
{
    // Running events should never stop, obviously...

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    // The ShouldStop method of the threads can do a whole lot of work,
    // figuring out whether the thread plan conditions are met.  So we don't want
    // to keep the ThreadList locked the whole time we are doing this.
    // FIXME: It is possible that running code could cause new threads
    // to be created.  If that happens, we will miss asking them whether
    // they should stop.  This is not a big deal since we haven't had
    // a chance to hang any interesting operations on those threads yet.
    
    collection threads_copy;
    {
        // Scope for locker
        Mutex::Locker locker(GetMutex());

        m_process->UpdateThreadListIfNeeded();
        for (lldb::ThreadSP thread_sp : m_threads)
        {
            // This is an optimization...  If we didn't let a thread run in between the previous stop and this
            // one, we shouldn't have to consult it for ShouldStop.  So just leave it off the list we are going to
            // inspect.
            // On Linux, if a thread-specific conditional breakpoint was hit, it won't necessarily be the thread
            // that hit the breakpoint itself that evaluates the conditional expression, so the thread that hit
            // the breakpoint could still be asked to stop, even though it hasn't been allowed to run since the
            // previous stop.
            if (thread_sp->GetTemporaryResumeState () != eStateSuspended || thread_sp->IsStillAtLastBreakpointHit())
                threads_copy.push_back(thread_sp);
        }

        // It is possible the threads we were allowing to run all exited and then maybe the user interrupted
        // or something, then fall back on looking at all threads:

        if (threads_copy.size() == 0)
            threads_copy = m_threads;
    }

    collection::iterator pos, end = threads_copy.end();

    if (log)
    {
        log->PutCString("");
        log->Printf ("ThreadList::%s: %" PRIu64 " threads, %" PRIu64 " unsuspended threads",
                     __FUNCTION__,
                     (uint64_t)m_threads.size(),
                     (uint64_t)threads_copy.size());
    }

    bool did_anybody_stop_for_a_reason = false;
    
    // If the event is an Interrupt event, then we're going to stop no matter what.  Otherwise, presume we won't stop.
    bool should_stop = false;
    if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr))
    {
        if (log)
            log->Printf("ThreadList::%s handling interrupt event, should stop set to true", __FUNCTION__);
        
        should_stop = true;
    }
    
    // Now we run through all the threads and get their stop info's.  We want to make sure to do this first before
    // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a
    // thread specific breakpoint another thread had stopped at) which could lead us to compute the StopInfo incorrectly.
    // We don't need to use it here, we just want to make sure it gets computed.
    
    for (pos = threads_copy.begin(); pos != end; ++pos)
    {
        ThreadSP thread_sp(*pos);
        thread_sp->GetStopInfo();
    }
    
    for (pos = threads_copy.begin(); pos != end; ++pos)
    {
        ThreadSP thread_sp(*pos);
        
        // We should never get a stop for which no thread had a stop reason, but sometimes we do see this -
        // for instance when we first connect to a remote stub.  In that case we should stop, since we can't figure out
        // the right thing to do and stopping gives the user control over what to do in this instance.
        //
        // Note, this causes a problem when you have a thread specific breakpoint, and a bunch of threads hit the breakpoint,
        // but not the thread which we are waiting for.  All the threads that are not "supposed" to hit the breakpoint
        // are marked as having no stop reason, which is right, they should not show a stop reason.  But that triggers this
        // code and causes us to stop seemingly for no reason.
        //
        // Since the only way we ever saw this error was on first attach, I'm only going to trigger set did_anybody_stop_for_a_reason
        // to true unless this is the first stop.
        //
        // If this becomes a problem, we'll have to have another StopReason like "StopInfoHidden" which will look invalid
        // everywhere but at this check.
    
        if (thread_sp->GetProcess()->GetStopID() > 1)
            did_anybody_stop_for_a_reason = true;
        else
            did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
        
        const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
        if (thread_should_stop)
            should_stop |= true;
    }

    if (!should_stop && !did_anybody_stop_for_a_reason)
    {
        should_stop = true;
        if (log)
            log->Printf ("ThreadList::%s we stopped but no threads had a stop reason, overriding should_stop and stopping.", __FUNCTION__);
    }
    
    if (log)
        log->Printf ("ThreadList::%s overall should_stop = %i", __FUNCTION__, should_stop);

    if (should_stop)
    {
        for (pos = threads_copy.begin(); pos != end; ++pos)
        {
            ThreadSP thread_sp(*pos);
            thread_sp->WillStop ();
        }
    }

    return should_stop;
}

Vote
ThreadList::ShouldReportStop (Event *event_ptr)
{
    Mutex::Locker locker(GetMutex());

    Vote result = eVoteNoOpinion;
    m_process->UpdateThreadListIfNeeded();
    collection::iterator pos, end = m_threads.end();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    if (log)
        log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());

    // Run through the threads and ask whether we should report this event.
    // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        ThreadSP thread_sp(*pos);
        const Vote vote = thread_sp->ShouldReportStop (event_ptr);
        switch (vote)
        {
        case eVoteNoOpinion:
            continue;

        case eVoteYes:
            result = eVoteYes;
            break;

        case eVoteNo:
            if (result == eVoteNoOpinion)
            {
                result = eVoteNo;
            }
            else
            {
                if (log)
                    log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s",
                                 __FUNCTION__,
                                 thread_sp->GetID (), 
                                 GetVoteAsCString (vote),
                                 GetVoteAsCString (result));
            }
            break;
        }
    }
    if (log)
        log->Printf ("ThreadList::%s returning %s", __FUNCTION__, GetVoteAsCString (result));
    return result;
}

void
ThreadList::SetShouldReportStop (Vote vote)
{
    Mutex::Locker locker(GetMutex());
    m_process->UpdateThreadListIfNeeded();
    collection::iterator pos, end = m_threads.end();
    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        ThreadSP thread_sp(*pos);
        thread_sp->SetShouldReportStop (vote);
    }
}

Vote
ThreadList::ShouldReportRun (Event *event_ptr)
{

    Mutex::Locker locker(GetMutex());

    Vote result = eVoteNoOpinion;
    m_process->UpdateThreadListIfNeeded();
    collection::iterator pos, end = m_threads.end();

    // Run through the threads and ask whether we should report this event.
    // The rule is NO vote wins over everything, a YES vote wins over no opinion.

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    
    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        if ((*pos)->GetResumeState () != eStateSuspended)
        {
            switch ((*pos)->ShouldReportRun (event_ptr))
            {
                case eVoteNoOpinion:
                    continue;
                case eVoteYes:
                    if (result == eVoteNoOpinion)
                        result = eVoteYes;
                    break;
                case eVoteNo:
                    if (log)
                        log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.",
                                     (*pos)->GetIndexID(), 
                                     (*pos)->GetID());
                    result = eVoteNo;
                    break;
            }
        }
    }
    return result;
}

void
ThreadList::Clear()
{
    Mutex::Locker locker(GetMutex());
    m_stop_id = 0;
    m_threads.clear();
    m_selected_tid = LLDB_INVALID_THREAD_ID;
}

void
ThreadList::Destroy()
{
    Mutex::Locker locker(GetMutex());
    const uint32_t num_threads = m_threads.size();
    for (uint32_t idx = 0; idx < num_threads; ++idx)
    {
        m_threads[idx]->DestroyThread();
    }
}

void
ThreadList::RefreshStateAfterStop ()
{
    Mutex::Locker locker(GetMutex());

    m_process->UpdateThreadListIfNeeded();
    
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    if (log && log->GetVerbose())
        log->Printf ("Turning off notification of new threads while single stepping a thread.");

    collection::iterator pos, end = m_threads.end();
    for (pos = m_threads.begin(); pos != end; ++pos)
        (*pos)->RefreshStateAfterStop ();
}

void
ThreadList::DiscardThreadPlans ()
{
    // You don't need to update the thread list here, because only threads
    // that you currently know about have any thread plans.
    Mutex::Locker locker(GetMutex());

    collection::iterator pos, end = m_threads.end();
    for (pos = m_threads.begin(); pos != end; ++pos)
        (*pos)->DiscardThreadPlans (true);

}

bool
ThreadList::WillResume ()
{
    // Run through the threads and perform their momentary actions.
    // But we only do this for threads that are running, user suspended
    // threads stay where they are.

    Mutex::Locker locker(GetMutex());
    m_process->UpdateThreadListIfNeeded();

    collection::iterator pos, end = m_threads.end();

    // See if any thread wants to run stopping others.  If it does, then we won't
    // setup the other threads for resume, since they aren't going to get a chance
    // to run.  This is necessary because the SetupForResume might add "StopOthers"
    // plans which would then get to be part of the who-gets-to-run negotiation, but
    // they're coming in after the fact, and the threads that are already set up should
    // take priority.
    
    bool wants_solo_run = false;
    
    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        lldbassert((*pos)->GetCurrentPlan() && "thread should not have null thread plan");
        if ((*pos)->GetResumeState() != eStateSuspended &&
                 (*pos)->GetCurrentPlan()->StopOthers())
        {
            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
                continue;
            wants_solo_run = true;
            break;
        }
    }   

    if (wants_solo_run)
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (log && log->GetVerbose())
            log->Printf ("Turning on notification of new threads while single stepping a thread.");
        m_process->StartNoticingNewThreads();
    }
    else
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (log && log->GetVerbose())
            log->Printf ("Turning off notification of new threads while single stepping a thread.");
        m_process->StopNoticingNewThreads();
    }
    
    // Give all the threads that are likely to run a last chance to set up their state before we
    // negotiate who is actually going to get a chance to run...
    // Don't set to resume suspended threads, and if any thread wanted to stop others, only
    // call setup on the threads that request StopOthers...
    
    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        if ((*pos)->GetResumeState() != eStateSuspended
            && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers()))
        {
            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
                continue;
            (*pos)->SetupForResume ();
        }
    }

    // Now go through the threads and see if any thread wants to run just itself.
    // if so then pick one and run it.
    
    ThreadList run_me_only_list (m_process);
    
    run_me_only_list.SetStopID(m_process->GetStopID());

    bool run_only_current_thread = false;

    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        ThreadSP thread_sp(*pos);
        if (thread_sp->GetResumeState() != eStateSuspended &&
                 thread_sp->GetCurrentPlan()->StopOthers())
        {
            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
                continue;

            // You can't say "stop others" and also want yourself to be suspended.
            assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);

            if (thread_sp == GetSelectedThread())
            {
                // If the currently selected thread wants to run on its own, always let it.
                run_only_current_thread = true;
                run_me_only_list.Clear();
                run_me_only_list.AddThread (thread_sp);
                break;
            }

            run_me_only_list.AddThread (thread_sp);
        }

    }

    bool need_to_resume = true;
    
    if (run_me_only_list.GetSize (false) == 0)
    {
        // Everybody runs as they wish:
        for (pos = m_threads.begin(); pos != end; ++pos)
        {
            ThreadSP thread_sp(*pos);
            StateType run_state;
            if (thread_sp->GetResumeState() != eStateSuspended)
                run_state = thread_sp->GetCurrentPlan()->RunState();
            else
                run_state = eStateSuspended;
            if (!thread_sp->ShouldResume(run_state))
                need_to_resume = false;
        }
    }
    else
    {
        ThreadSP thread_to_run;

        if (run_only_current_thread)
        {
            thread_to_run = GetSelectedThread();
        }
        else if (run_me_only_list.GetSize (false) == 1)
        {
            thread_to_run = run_me_only_list.GetThreadAtIndex (0);
        }
        else
        {
            int random_thread = (int)
                    ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0));
            thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
        }

        for (pos = m_threads.begin(); pos != end; ++pos)
        {
            ThreadSP thread_sp(*pos);
            if (thread_sp == thread_to_run)
            {
                if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
                    need_to_resume = false;
            }
            else
                thread_sp->ShouldResume (eStateSuspended);
        }
    }

    return need_to_resume;
}

void
ThreadList::DidResume ()
{
    Mutex::Locker locker(GetMutex());
    collection::iterator pos, end = m_threads.end();
    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        // Don't clear out threads that aren't going to get a chance to run, rather
        // leave their state for the next time around.
        ThreadSP thread_sp(*pos);
        if (thread_sp->GetResumeState() != eStateSuspended)
            thread_sp->DidResume ();
    }
}

void
ThreadList::DidStop ()
{
    Mutex::Locker locker(GetMutex());
    collection::iterator pos, end = m_threads.end();
    for (pos = m_threads.begin(); pos != end; ++pos)
    {
        // Notify threads that the process just stopped.
        // Note, this currently assumes that all threads in the list
        // stop when the process stops.  In the future we will want to support
        // a debugging model where some threads continue to run while others
        // are stopped.  We either need to handle that somehow here or
        // create a special thread list containing only threads which will
        // stop in the code that calls this method (currently
        // Process::SetPrivateState).
        ThreadSP thread_sp(*pos);
        if (StateIsRunningState(thread_sp->GetState()))
            thread_sp->DidStop ();
    }
}

ThreadSP
ThreadList::GetSelectedThread ()
{
    Mutex::Locker locker(GetMutex());
    ThreadSP thread_sp = FindThreadByID(m_selected_tid);
    if (!thread_sp.get())
    {
        if (m_threads.size() == 0)
            return thread_sp;
        m_selected_tid = m_threads[0]->GetID();
        thread_sp = m_threads[0];
    }
    return thread_sp;
}

bool
ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
{
    Mutex::Locker locker(GetMutex());
    ThreadSP selected_thread_sp(FindThreadByID(tid));
    if  (selected_thread_sp)
    {
        m_selected_tid = tid;
        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
    }
    else
        m_selected_tid = LLDB_INVALID_THREAD_ID;

    if (notify)
        NotifySelectedThreadChanged(m_selected_tid);
    
    return m_selected_tid != LLDB_INVALID_THREAD_ID;
}

bool
ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
{
    Mutex::Locker locker(GetMutex());
    ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
    if  (selected_thread_sp.get())
    {
        m_selected_tid = selected_thread_sp->GetID();
        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
    }
    else
        m_selected_tid = LLDB_INVALID_THREAD_ID;

    if (notify)
        NotifySelectedThreadChanged(m_selected_tid);
    
    return m_selected_tid != LLDB_INVALID_THREAD_ID;
}

void
ThreadList::NotifySelectedThreadChanged (lldb::tid_t tid)
{
    ThreadSP selected_thread_sp (FindThreadByID(tid));
    if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected))
        selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
                                           new Thread::ThreadEventData(selected_thread_sp));
}

void
ThreadList::Update (ThreadList &rhs)
{
    if (this != &rhs)
    {
        // Lock both mutexes to make sure neither side changes anyone on us
        // while the assignment occurs
        Mutex::Locker locker(GetMutex());
        m_process = rhs.m_process;
        m_stop_id = rhs.m_stop_id;
        m_threads.swap(rhs.m_threads);
        m_selected_tid = rhs.m_selected_tid;
        
        
        // Now we look for threads that we are done with and
        // make sure to clear them up as much as possible so 
        // anyone with a shared pointer will still have a reference,
        // but the thread won't be of much use. Using std::weak_ptr
        // for all backward references (such as a thread to a process)
        // will eventually solve this issue for us, but for now, we
        // need to work around the issue
        collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
        for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos)
        {
            const lldb::tid_t tid = (*rhs_pos)->GetID();
            bool thread_is_alive = false;
            const uint32_t num_threads = m_threads.size();
            for (uint32_t idx = 0; idx < num_threads; ++idx)
            {
                ThreadSP backing_thread = m_threads[idx]->GetBackingThread();
                if (m_threads[idx]->GetID() == tid || (backing_thread && backing_thread->GetID() == tid))
                {
                    thread_is_alive = true;
                    break;
                }
            }
            if (!thread_is_alive)
                (*rhs_pos)->DestroyThread();
        }        
    }
}

void
ThreadList::Flush ()
{
    Mutex::Locker locker(GetMutex());
    collection::iterator pos, end = m_threads.end();
    for (pos = m_threads.begin(); pos != end; ++pos)
        (*pos)->Flush ();
}

Mutex &
ThreadList::GetMutex ()
{
    return m_process->m_thread_mutex;
}

