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