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