1//===-- ThreadList.cpp ------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include <stdlib.h>
10
11#include <algorithm>
12
13#include "lldb/Core/Log.h"
14#include "lldb/Core/State.h"
15#include "lldb/Target/RegisterContext.h"
16#include "lldb/Target/ThreadList.h"
17#include "lldb/Target/Thread.h"
18#include "lldb/Target/ThreadPlan.h"
19#include "lldb/Target/Process.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24ThreadList::ThreadList (Process *process) :
25    m_process (process),
26    m_stop_id (0),
27    m_threads(),
28    m_selected_tid (LLDB_INVALID_THREAD_ID)
29{
30}
31
32ThreadList::ThreadList (const ThreadList &rhs) :
33    m_process (rhs.m_process),
34    m_stop_id (rhs.m_stop_id),
35    m_threads (),
36    m_selected_tid ()
37{
38    // Use the assignment operator since it uses the mutex
39    *this = rhs;
40}
41
42const ThreadList&
43ThreadList::operator = (const ThreadList& rhs)
44{
45    if (this != &rhs)
46    {
47        // Lock both mutexes to make sure neither side changes anyone on us
48        // while the assignement occurs
49        Mutex::Locker locker(GetMutex());
50        m_process = rhs.m_process;
51        m_stop_id = rhs.m_stop_id;
52        m_threads = rhs.m_threads;
53        m_selected_tid = rhs.m_selected_tid;
54    }
55    return *this;
56}
57
58
59ThreadList::~ThreadList()
60{
61    // Clear the thread list. Clear will take the mutex lock
62    // which will ensure that if anyone is using the list
63    // they won't get it removed while using it.
64    Clear();
65}
66
67
68uint32_t
69ThreadList::GetStopID () const
70{
71    return m_stop_id;
72}
73
74void
75ThreadList::SetStopID (uint32_t stop_id)
76{
77    m_stop_id = stop_id;
78}
79
80
81void
82ThreadList::AddThread (const ThreadSP &thread_sp)
83{
84    Mutex::Locker locker(GetMutex());
85    m_threads.push_back(thread_sp);
86}
87
88void
89ThreadList::InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx)
90{
91    Mutex::Locker locker(GetMutex());
92    if (idx < m_threads.size())
93        m_threads.insert(m_threads.begin() + idx, thread_sp);
94    else
95        m_threads.push_back (thread_sp);
96}
97
98
99uint32_t
100ThreadList::GetSize (bool can_update)
101{
102    Mutex::Locker locker(GetMutex());
103    if (can_update)
104        m_process->UpdateThreadListIfNeeded();
105    return m_threads.size();
106}
107
108ThreadSP
109ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
110{
111    Mutex::Locker locker(GetMutex());
112    if (can_update)
113        m_process->UpdateThreadListIfNeeded();
114
115    ThreadSP thread_sp;
116    if (idx < m_threads.size())
117        thread_sp = m_threads[idx];
118    return thread_sp;
119}
120
121ThreadSP
122ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
123{
124    Mutex::Locker locker(GetMutex());
125
126    if (can_update)
127        m_process->UpdateThreadListIfNeeded();
128
129    ThreadSP thread_sp;
130    uint32_t idx = 0;
131    const uint32_t num_threads = m_threads.size();
132    for (idx = 0; idx < num_threads; ++idx)
133    {
134        if (m_threads[idx]->GetID() == tid)
135        {
136            thread_sp = m_threads[idx];
137            break;
138        }
139    }
140    return thread_sp;
141}
142
143ThreadSP
144ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
145{
146    Mutex::Locker locker(GetMutex());
147
148    if (can_update)
149        m_process->UpdateThreadListIfNeeded();
150
151    ThreadSP thread_sp;
152    uint32_t idx = 0;
153    const uint32_t num_threads = m_threads.size();
154    for (idx = 0; idx < num_threads; ++idx)
155    {
156        if (m_threads[idx]->GetProtocolID() == tid)
157        {
158            thread_sp = m_threads[idx];
159            break;
160        }
161    }
162    return thread_sp;
163}
164
165
166ThreadSP
167ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
168{
169    Mutex::Locker locker(GetMutex());
170
171    if (can_update)
172        m_process->UpdateThreadListIfNeeded();
173
174    ThreadSP thread_sp;
175    uint32_t idx = 0;
176    const uint32_t num_threads = m_threads.size();
177    for (idx = 0; idx < num_threads; ++idx)
178    {
179        if (m_threads[idx]->GetID() == tid)
180        {
181            thread_sp = m_threads[idx];
182            m_threads.erase(m_threads.begin()+idx);
183            break;
184        }
185    }
186    return thread_sp;
187}
188
189ThreadSP
190ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
191{
192    Mutex::Locker locker(GetMutex());
193
194    if (can_update)
195        m_process->UpdateThreadListIfNeeded();
196
197    ThreadSP thread_sp;
198    uint32_t idx = 0;
199    const uint32_t num_threads = m_threads.size();
200    for (idx = 0; idx < num_threads; ++idx)
201    {
202        if (m_threads[idx]->GetProtocolID() == tid)
203        {
204            thread_sp = m_threads[idx];
205            m_threads.erase(m_threads.begin()+idx);
206            break;
207        }
208    }
209    return thread_sp;
210}
211
212ThreadSP
213ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
214{
215    ThreadSP thread_sp;
216    if (thread_ptr)
217    {
218        Mutex::Locker locker(GetMutex());
219
220        uint32_t idx = 0;
221        const uint32_t num_threads = m_threads.size();
222        for (idx = 0; idx < num_threads; ++idx)
223        {
224            if (m_threads[idx].get() == thread_ptr)
225            {
226                thread_sp = m_threads[idx];
227                break;
228            }
229        }
230    }
231    return thread_sp;
232}
233
234
235
236ThreadSP
237ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
238{
239    Mutex::Locker locker(GetMutex());
240
241    if (can_update)
242        m_process->UpdateThreadListIfNeeded();
243
244    ThreadSP thread_sp;
245    const uint32_t num_threads = m_threads.size();
246    for (uint32_t idx = 0; idx < num_threads; ++idx)
247    {
248        if (m_threads[idx]->GetIndexID() == index_id)
249        {
250            thread_sp = m_threads[idx];
251            break;
252        }
253    }
254    return thread_sp;
255}
256
257bool
258ThreadList::ShouldStop (Event *event_ptr)
259{
260    // Running events should never stop, obviously...
261
262    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
263
264    // The ShouldStop method of the threads can do a whole lot of work,
265    // running breakpoint commands & conditions, etc.  So we don't want
266    // to keep the ThreadList locked the whole time we are doing this.
267    // FIXME: It is possible that running code could cause new threads
268    // to be created.  If that happens we will miss asking them whether
269    // then should stop.  This is not a big deal, since we haven't had
270    // a chance to hang any interesting operations on those threads yet.
271
272    collection threads_copy;
273    {
274        // Scope for locker
275        Mutex::Locker locker(GetMutex());
276
277        m_process->UpdateThreadListIfNeeded();
278        threads_copy = m_threads;
279    }
280
281    collection::iterator pos, end = threads_copy.end();
282
283    if (log)
284    {
285        log->PutCString("");
286        log->Printf ("ThreadList::%s: %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
287    }
288
289    bool did_anybody_stop_for_a_reason = false;
290    bool should_stop = false;
291
292    // Now we run through all the threads and get their stop info's.  We want to make sure to do this first before
293    // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a
294    // thread specific breakpoint another thread had stopped at) which could lead us to compute the StopInfo incorrectly.
295    // We don't need to use it here, we just want to make sure it gets computed.
296
297    for (pos = threads_copy.begin(); pos != end; ++pos)
298    {
299        ThreadSP thread_sp(*pos);
300        thread_sp->GetStopInfo();
301    }
302
303    for (pos = threads_copy.begin(); pos != end; ++pos)
304    {
305        ThreadSP thread_sp(*pos);
306
307        // We should never get a stop for which no thread had a stop reason, but sometimes we do see this -
308        // for instance when we first connect to a remote stub.  In that case we should stop, since we can't figure out
309        // the right thing to do and stopping gives the user control over what to do in this instance.
310        //
311        // Note, this causes a problem when you have a thread specific breakpoint, and a bunch of threads hit the breakpoint,
312        // but not the thread which we are waiting for.  All the threads that are not "supposed" to hit the breakpoint
313        // are marked as having no stop reason, which is right, they should not show a stop reason.  But that triggers this
314        // code and causes us to stop seemingly for no reason.
315        //
316        // 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
317        // to true unless this is the first stop.
318        //
319        // If this becomes a problem, we'll have to have another StopReason like "StopInfoHidden" which will look invalid
320        // everywhere but at this check.
321
322        if (thread_sp->GetProcess()->GetStopID() > 1)
323            did_anybody_stop_for_a_reason = true;
324        else
325            did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
326
327        const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
328        if (thread_should_stop)
329            should_stop |= true;
330    }
331
332    if (!should_stop && !did_anybody_stop_for_a_reason)
333    {
334        should_stop = true;
335        if (log)
336            log->Printf ("ThreadList::%s we stopped but no threads had a stop reason, overriding should_stop and stopping.", __FUNCTION__);
337    }
338
339    if (log)
340        log->Printf ("ThreadList::%s overall should_stop = %i", __FUNCTION__, should_stop);
341
342    if (should_stop)
343    {
344        for (pos = threads_copy.begin(); pos != end; ++pos)
345        {
346            ThreadSP thread_sp(*pos);
347            thread_sp->WillStop ();
348        }
349    }
350
351    return should_stop;
352}
353
354Vote
355ThreadList::ShouldReportStop (Event *event_ptr)
356{
357    Mutex::Locker locker(GetMutex());
358
359    Vote result = eVoteNoOpinion;
360    m_process->UpdateThreadListIfNeeded();
361    collection::iterator pos, end = m_threads.end();
362
363    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
364
365    if (log)
366        log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
367
368    // Run through the threads and ask whether we should report this event.
369    // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
370    for (pos = m_threads.begin(); pos != end; ++pos)
371    {
372        ThreadSP thread_sp(*pos);
373        const Vote vote = thread_sp->ShouldReportStop (event_ptr);
374        switch (vote)
375        {
376        case eVoteNoOpinion:
377            continue;
378
379        case eVoteYes:
380            result = eVoteYes;
381            break;
382
383        case eVoteNo:
384            if (result == eVoteNoOpinion)
385            {
386                result = eVoteNo;
387            }
388            else
389            {
390                if (log)
391                    log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s",
392                                 __FUNCTION__,
393                                 thread_sp->GetID (),
394                                 GetVoteAsCString (vote),
395                                 GetVoteAsCString (result));
396            }
397            break;
398        }
399    }
400    if (log)
401        log->Printf ("ThreadList::%s returning %s", __FUNCTION__, GetVoteAsCString (result));
402    return result;
403}
404
405void
406ThreadList::SetShouldReportStop (Vote vote)
407{
408    Mutex::Locker locker(GetMutex());
409    m_process->UpdateThreadListIfNeeded();
410    collection::iterator pos, end = m_threads.end();
411    for (pos = m_threads.begin(); pos != end; ++pos)
412    {
413        ThreadSP thread_sp(*pos);
414        thread_sp->SetShouldReportStop (vote);
415    }
416}
417
418Vote
419ThreadList::ShouldReportRun (Event *event_ptr)
420{
421
422    Mutex::Locker locker(GetMutex());
423
424    Vote result = eVoteNoOpinion;
425    m_process->UpdateThreadListIfNeeded();
426    collection::iterator pos, end = m_threads.end();
427
428    // Run through the threads and ask whether we should report this event.
429    // The rule is NO vote wins over everything, a YES vote wins over no opinion.
430
431    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
432
433    for (pos = m_threads.begin(); pos != end; ++pos)
434    {
435        if ((*pos)->GetResumeState () != eStateSuspended)
436        {
437            switch ((*pos)->ShouldReportRun (event_ptr))
438            {
439                case eVoteNoOpinion:
440                    continue;
441                case eVoteYes:
442                    if (result == eVoteNoOpinion)
443                        result = eVoteYes;
444                    break;
445                case eVoteNo:
446                    if (log)
447                        log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.",
448                                     (*pos)->GetIndexID(),
449                                     (*pos)->GetID());
450                    result = eVoteNo;
451                    break;
452            }
453        }
454    }
455    return result;
456}
457
458void
459ThreadList::Clear()
460{
461    Mutex::Locker locker(GetMutex());
462    m_stop_id = 0;
463    m_threads.clear();
464    m_selected_tid = LLDB_INVALID_THREAD_ID;
465}
466
467void
468ThreadList::Destroy()
469{
470    Mutex::Locker locker(GetMutex());
471    const uint32_t num_threads = m_threads.size();
472    for (uint32_t idx = 0; idx < num_threads; ++idx)
473    {
474        m_threads[idx]->DestroyThread();
475    }
476}
477
478void
479ThreadList::RefreshStateAfterStop ()
480{
481    Mutex::Locker locker(GetMutex());
482
483    m_process->UpdateThreadListIfNeeded();
484
485    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
486    if (log && log->GetVerbose())
487        log->Printf ("Turning off notification of new threads while single stepping a thread.");
488
489    collection::iterator pos, end = m_threads.end();
490    for (pos = m_threads.begin(); pos != end; ++pos)
491        (*pos)->RefreshStateAfterStop ();
492}
493
494void
495ThreadList::DiscardThreadPlans ()
496{
497    // You don't need to update the thread list here, because only threads
498    // that you currently know about have any thread plans.
499    Mutex::Locker locker(GetMutex());
500
501    collection::iterator pos, end = m_threads.end();
502    for (pos = m_threads.begin(); pos != end; ++pos)
503        (*pos)->DiscardThreadPlans (true);
504
505}
506
507bool
508ThreadList::WillResume ()
509{
510    // Run through the threads and perform their momentary actions.
511    // But we only do this for threads that are running, user suspended
512    // threads stay where they are.
513
514    Mutex::Locker locker(GetMutex());
515    m_process->UpdateThreadListIfNeeded();
516
517    collection::iterator pos, end = m_threads.end();
518
519    // See if any thread wants to run stopping others.  If it does, then we won't
520    // setup the other threads for resume, since they aren't going to get a chance
521    // to run.  This is necessary because the SetupForResume might add "StopOthers"
522    // plans which would then get to be part of the who-gets-to-run negotiation, but
523    // they're coming in after the fact, and the threads that are already set up should
524    // take priority.
525
526    bool wants_solo_run = false;
527
528    for (pos = m_threads.begin(); pos != end; ++pos)
529    {
530        if ((*pos)->GetResumeState() != eStateSuspended &&
531                 (*pos)->GetCurrentPlan()->StopOthers())
532        {
533            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
534                continue;
535            wants_solo_run = true;
536            break;
537        }
538    }
539
540    if (wants_solo_run)
541    {
542        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
543        if (log && log->GetVerbose())
544            log->Printf ("Turning on notification of new threads while single stepping a thread.");
545        m_process->StartNoticingNewThreads();
546    }
547    else
548    {
549        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
550        if (log && log->GetVerbose())
551            log->Printf ("Turning off notification of new threads while single stepping a thread.");
552        m_process->StopNoticingNewThreads();
553    }
554
555    // Give all the threads that are likely to run a last chance to set up their state before we
556    // negotiate who is actually going to get a chance to run...
557    // Don't set to resume suspended threads, and if any thread wanted to stop others, only
558    // call setup on the threads that request StopOthers...
559
560    for (pos = m_threads.begin(); pos != end; ++pos)
561    {
562        if ((*pos)->GetResumeState() != eStateSuspended
563            && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers()))
564        {
565            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
566                continue;
567            (*pos)->SetupForResume ();
568        }
569    }
570
571    // Now go through the threads and see if any thread wants to run just itself.
572    // if so then pick one and run it.
573
574    ThreadList run_me_only_list (m_process);
575
576    run_me_only_list.SetStopID(m_process->GetStopID());
577
578    bool run_only_current_thread = false;
579
580    for (pos = m_threads.begin(); pos != end; ++pos)
581    {
582        ThreadSP thread_sp(*pos);
583        if (thread_sp->GetResumeState() != eStateSuspended &&
584                 thread_sp->GetCurrentPlan()->StopOthers())
585        {
586            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
587                continue;
588
589            // You can't say "stop others" and also want yourself to be suspended.
590            assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
591
592            if (thread_sp == GetSelectedThread())
593            {
594                run_only_current_thread = true;
595                run_me_only_list.Clear();
596                run_me_only_list.AddThread (thread_sp);
597                break;
598            }
599
600            run_me_only_list.AddThread (thread_sp);
601        }
602
603    }
604
605    bool need_to_resume = true;
606
607    if (run_me_only_list.GetSize (false) == 0)
608    {
609        // Everybody runs as they wish:
610        for (pos = m_threads.begin(); pos != end; ++pos)
611        {
612            ThreadSP thread_sp(*pos);
613            StateType run_state;
614            if (thread_sp->GetResumeState() != eStateSuspended)
615                run_state = thread_sp->GetCurrentPlan()->RunState();
616            else
617                run_state = eStateSuspended;
618            if (!thread_sp->ShouldResume(run_state))
619                need_to_resume = false;
620        }
621    }
622    else
623    {
624        ThreadSP thread_to_run;
625
626        if (run_only_current_thread)
627        {
628            thread_to_run = GetSelectedThread();
629        }
630        else if (run_me_only_list.GetSize (false) == 1)
631        {
632            thread_to_run = run_me_only_list.GetThreadAtIndex (0);
633        }
634        else
635        {
636            int random_thread = (int)
637                    ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0));
638            thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
639        }
640
641        for (pos = m_threads.begin(); pos != end; ++pos)
642        {
643            ThreadSP thread_sp(*pos);
644            if (thread_sp == thread_to_run)
645            {
646                if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
647                    need_to_resume = false;
648            }
649            else
650                thread_sp->ShouldResume (eStateSuspended);
651        }
652    }
653
654    return need_to_resume;
655}
656
657void
658ThreadList::DidResume ()
659{
660    Mutex::Locker locker(GetMutex());
661    collection::iterator pos, end = m_threads.end();
662    for (pos = m_threads.begin(); pos != end; ++pos)
663    {
664        // Don't clear out threads that aren't going to get a chance to run, rather
665        // leave their state for the next time around.
666        ThreadSP thread_sp(*pos);
667        if (thread_sp->GetResumeState() != eStateSuspended)
668            thread_sp->DidResume ();
669    }
670}
671
672void
673ThreadList::DidStop ()
674{
675    Mutex::Locker locker(GetMutex());
676    collection::iterator pos, end = m_threads.end();
677    for (pos = m_threads.begin(); pos != end; ++pos)
678    {
679        // Notify threads that the process just stopped.
680        // Note, this currently assumes that all threads in the list
681        // stop when the process stops.  In the future we will want to support
682        // a debugging model where some threads continue to run while others
683        // are stopped.  We either need to handle that somehow here or
684        // create a special thread list containing only threads which will
685        // stop in the code that calls this method (currently
686        // Process::SetPrivateState).
687        ThreadSP thread_sp(*pos);
688        if (StateIsRunningState(thread_sp->GetState()))
689            thread_sp->DidStop ();
690    }
691}
692
693ThreadSP
694ThreadList::GetSelectedThread ()
695{
696    Mutex::Locker locker(GetMutex());
697    ThreadSP thread_sp = FindThreadByID(m_selected_tid);
698    if (!thread_sp.get())
699    {
700        if (m_threads.size() == 0)
701            return thread_sp;
702        m_selected_tid = m_threads[0]->GetID();
703        thread_sp = m_threads[0];
704    }
705    return thread_sp;
706}
707
708bool
709ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
710{
711    Mutex::Locker locker(GetMutex());
712    ThreadSP selected_thread_sp(FindThreadByID(tid));
713    if  (selected_thread_sp)
714    {
715        m_selected_tid = tid;
716        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
717    }
718    else
719        m_selected_tid = LLDB_INVALID_THREAD_ID;
720
721    if (notify)
722        NotifySelectedThreadChanged(m_selected_tid);
723
724    return m_selected_tid != LLDB_INVALID_THREAD_ID;
725}
726
727bool
728ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
729{
730    Mutex::Locker locker(GetMutex());
731    ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
732    if  (selected_thread_sp.get())
733    {
734        m_selected_tid = selected_thread_sp->GetID();
735        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
736    }
737    else
738        m_selected_tid = LLDB_INVALID_THREAD_ID;
739
740    if (notify)
741        NotifySelectedThreadChanged(m_selected_tid);
742
743    return m_selected_tid != LLDB_INVALID_THREAD_ID;
744}
745
746void
747ThreadList::NotifySelectedThreadChanged (lldb::tid_t tid)
748{
749    ThreadSP selected_thread_sp (FindThreadByID(tid));
750    if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected))
751        selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
752                                           new Thread::ThreadEventData(selected_thread_sp));
753}
754
755void
756ThreadList::Update (ThreadList &rhs)
757{
758    if (this != &rhs)
759    {
760        // Lock both mutexes to make sure neither side changes anyone on us
761        // while the assignement occurs
762        Mutex::Locker locker(GetMutex());
763        m_process = rhs.m_process;
764        m_stop_id = rhs.m_stop_id;
765        m_threads.swap(rhs.m_threads);
766        m_selected_tid = rhs.m_selected_tid;
767
768
769        // Now we look for threads that we are done with and
770        // make sure to clear them up as much as possible so
771        // anyone with a shared pointer will still have a reference,
772        // but the thread won't be of much use. Using std::weak_ptr
773        // for all backward references (such as a thread to a process)
774        // will eventually solve this issue for us, but for now, we
775        // need to work around the issue
776        collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
777        for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos)
778        {
779            const lldb::tid_t tid = (*rhs_pos)->GetID();
780            bool thread_is_alive = false;
781            const uint32_t num_threads = m_threads.size();
782            for (uint32_t idx = 0; idx < num_threads; ++idx)
783            {
784                if (m_threads[idx]->GetID() == tid)
785                {
786                    thread_is_alive = true;
787                    break;
788                }
789            }
790            if (!thread_is_alive)
791                (*rhs_pos)->DestroyThread();
792        }
793    }
794}
795
796void
797ThreadList::Flush ()
798{
799    Mutex::Locker locker(GetMutex());
800    collection::iterator pos, end = m_threads.end();
801    for (pos = m_threads.begin(); pos != end; ++pos)
802        (*pos)->Flush ();
803}
804
805Mutex &
806ThreadList::GetMutex ()
807{
808    return m_process->m_thread_mutex;
809}
810
811