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