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