| 660 | } |
| 661 | |
| 662 | void* Thread::SuperviseThread(void* arg) { |
| 663 | Thread* t = static_cast<Thread*>(arg); |
| 664 | int64_t system_tid = Thread::CurrentThreadId(); |
| 665 | PCHECK(system_tid != -1); |
| 666 | |
| 667 | // Take an additional reference to the thread manager, which we'll need below. |
| 668 | ANNOTATE_IGNORE_SYNC_BEGIN(); |
| 669 | shared_ptr<ThreadMgr> thread_mgr_ref = thread_manager; |
| 670 | ANNOTATE_IGNORE_SYNC_END(); |
| 671 | |
| 672 | // Set up the TLS. |
| 673 | // |
| 674 | // We could store a scoped_refptr in the TLS itself, but as its |
| 675 | // lifecycle is poorly defined, we'll use a bare pointer. We |
| 676 | // already incremented the reference count in StartThread. |
| 677 | Thread::tls_ = t; |
| 678 | |
| 679 | // Publish our tid to 'tid_', which unblocks any callers waiting in |
| 680 | // WaitForTid(). |
| 681 | Release_Store(&t->tid_, system_tid); |
| 682 | |
| 683 | string name = strings::Substitute("$0-$1", t->name(), system_tid); |
| 684 | thread_manager->SetThreadName(name, t->tid_); |
| 685 | thread_manager->AddThread(pthread_self(), name, t->category(), t->tid_); |
| 686 | |
| 687 | // FinishThread() is guaranteed to run (even if functor_ throws an |
| 688 | // exception) because pthread_cleanup_push() creates a scoped object |
| 689 | // whose destructor invokes the provided callback. |
| 690 | pthread_cleanup_push(&Thread::FinishThread, t); |
| 691 | t->functor_(); |
| 692 | pthread_cleanup_pop(true); |
| 693 | |
| 694 | return nullptr; |
| 695 | } |
| 696 | |
| 697 | void Thread::FinishThread(void* arg) { |
| 698 | Thread* t = static_cast<Thread*>(arg); |
nothing calls this directly
no test coverage detected