Thread.cc revision cc4062ff
1cd139dc7SShuo Chen// excerpts from http://code.google.com/p/muduo/
2cd139dc7SShuo Chen//
3cd139dc7SShuo Chen// Use of this source code is governed by a BSD-style license
4cd139dc7SShuo Chen// that can be found in the License file.
5cd139dc7SShuo Chen//
6cd139dc7SShuo Chen// Author: Shuo Chen (giantchen at gmail dot com)
7cd139dc7SShuo Chen
8cd139dc7SShuo Chen#include "Thread.h"
9cd139dc7SShuo Chen
102b2bf878SShuo Chen#include <boost/weak_ptr.hpp>
112b2bf878SShuo Chen
12cd139dc7SShuo Chen#include <unistd.h>
13926c960eSShuo Chen#include <sys/prctl.h>
14cd139dc7SShuo Chen#include <sys/syscall.h>
15cd139dc7SShuo Chen#include <sys/types.h>
16cd139dc7SShuo Chen#include <linux/unistd.h>
17cd139dc7SShuo Chen
18cd139dc7SShuo Chennamespace muduo
19cd139dc7SShuo Chen{
20cd139dc7SShuo Chennamespace CurrentThread
21cd139dc7SShuo Chen{
22cd139dc7SShuo Chen  __thread const char* t_threadName = "unknown";
23cd139dc7SShuo Chen}
24cd139dc7SShuo Chen}
25cd139dc7SShuo Chen
26cd139dc7SShuo Chennamespace
27cd139dc7SShuo Chen{
28cd139dc7SShuo Chen__thread pid_t t_cachedTid = 0;
29cd139dc7SShuo Chen
30cc4062ffSShuo Chen#if !__GLIBC_PREREQ(2,30)
31cd139dc7SShuo Chenpid_t gettid()
32cd139dc7SShuo Chen{
33cd139dc7SShuo Chen  return static_cast<pid_t>(::syscall(SYS_gettid));
34cd139dc7SShuo Chen}
35cc4062ffSShuo Chen#endif
36cd139dc7SShuo Chen
3750da4f87SShuo Chenvoid afterFork()
3850da4f87SShuo Chen{
3950da4f87SShuo Chen  t_cachedTid = gettid();
4050da4f87SShuo Chen  muduo::CurrentThread::t_threadName = "main";
4150da4f87SShuo Chen  // no need to call pthread_atfork(NULL, NULL, &afterFork);
4250da4f87SShuo Chen}
4350da4f87SShuo Chen
44cd139dc7SShuo Chenclass ThreadNameInitializer
45cd139dc7SShuo Chen{
46cd139dc7SShuo Chen public:
47cd139dc7SShuo Chen  ThreadNameInitializer()
48cd139dc7SShuo Chen  {
49cd139dc7SShuo Chen    muduo::CurrentThread::t_threadName = "main";
5050da4f87SShuo Chen    pthread_atfork(NULL, NULL, &afterFork);
51cd139dc7SShuo Chen  }
52cd139dc7SShuo Chen};
53cd139dc7SShuo Chen
54cd139dc7SShuo ChenThreadNameInitializer init;
552b2bf878SShuo Chen
562b2bf878SShuo Chenstruct ThreadData
572b2bf878SShuo Chen{
582b2bf878SShuo Chen  typedef muduo::Thread::ThreadFunc ThreadFunc;
592b2bf878SShuo Chen  ThreadFunc func_;
602b2bf878SShuo Chen  std::string name_;
612b2bf878SShuo Chen  boost::weak_ptr<pid_t> wkTid_;
622b2bf878SShuo Chen
632b2bf878SShuo Chen  ThreadData(const ThreadFunc& func,
642b2bf878SShuo Chen             const std::string& name,
652b2bf878SShuo Chen             const boost::shared_ptr<pid_t>& tid)
662b2bf878SShuo Chen    : func_(func),
672b2bf878SShuo Chen      name_(name),
682b2bf878SShuo Chen      wkTid_(tid)
692b2bf878SShuo Chen  { }
702b2bf878SShuo Chen
712b2bf878SShuo Chen  void runInThread()
722b2bf878SShuo Chen  {
73ac2f0106SShuo Chen    pid_t tid = muduo::CurrentThread::tid();
74ac2f0106SShuo Chen    boost::shared_ptr<pid_t> ptid = wkTid_.lock();
75ac2f0106SShuo Chen
76ac2f0106SShuo Chen    if (ptid)
772b2bf878SShuo Chen    {
78ac2f0106SShuo Chen      *ptid = tid;
79ac2f0106SShuo Chen      ptid.reset();
802b2bf878SShuo Chen    }
812b2bf878SShuo Chen
82926c960eSShuo Chen    muduo::CurrentThread::t_threadName = name_.empty() ? "muduoThread" : name_.c_str();
83926c960eSShuo Chen    ::prctl(PR_SET_NAME, muduo::CurrentThread::t_threadName);
842b2bf878SShuo Chen    func_(); // FIXME: surround with try-catch, see muduo
852b2bf878SShuo Chen    muduo::CurrentThread::t_threadName = "finished";
862b2bf878SShuo Chen  }
872b2bf878SShuo Chen};
882b2bf878SShuo Chen
892b2bf878SShuo Chenvoid* startThread(void* obj)
902b2bf878SShuo Chen{
912b2bf878SShuo Chen  ThreadData* data = static_cast<ThreadData*>(obj);
922b2bf878SShuo Chen  data->runInThread();
932b2bf878SShuo Chen  delete data;
942b2bf878SShuo Chen  return NULL;
952b2bf878SShuo Chen}
962b2bf878SShuo Chen
97cd139dc7SShuo Chen}
98cd139dc7SShuo Chen
99cd139dc7SShuo Chenusing namespace muduo;
100cd139dc7SShuo Chen
101cd139dc7SShuo Chenpid_t CurrentThread::tid()
102cd139dc7SShuo Chen{
103cd139dc7SShuo Chen  if (t_cachedTid == 0)
104cd139dc7SShuo Chen  {
105cd139dc7SShuo Chen    t_cachedTid = gettid();
106cd139dc7SShuo Chen  }
107cd139dc7SShuo Chen  return t_cachedTid;
108cd139dc7SShuo Chen}
109cd139dc7SShuo Chen
110cd139dc7SShuo Chenconst char* CurrentThread::name()
111cd139dc7SShuo Chen{
112cd139dc7SShuo Chen  return t_threadName;
113cd139dc7SShuo Chen}
114cd139dc7SShuo Chen
115cd139dc7SShuo Chenbool CurrentThread::isMainThread()
116cd139dc7SShuo Chen{
117cd139dc7SShuo Chen  return tid() == ::getpid();
118cd139dc7SShuo Chen}
119cd139dc7SShuo Chen
120cd139dc7SShuo ChenAtomicInt32 Thread::numCreated_;
121cd139dc7SShuo Chen
122cd139dc7SShuo ChenThread::Thread(const ThreadFunc& func, const std::string& n)
123cd139dc7SShuo Chen  : started_(false),
1242b2bf878SShuo Chen    joined_(false),
125cd139dc7SShuo Chen    pthreadId_(0),
1262b2bf878SShuo Chen    tid_(new pid_t(0)),
127cd139dc7SShuo Chen    func_(func),
128cd139dc7SShuo Chen    name_(n)
129cd139dc7SShuo Chen{
130cd139dc7SShuo Chen  numCreated_.increment();
131cd139dc7SShuo Chen}
132cd139dc7SShuo Chen
133cd139dc7SShuo ChenThread::~Thread()
134cd139dc7SShuo Chen{
1352b2bf878SShuo Chen  if (started_ && !joined_)
1362b2bf878SShuo Chen  {
1372b2bf878SShuo Chen    pthread_detach(pthreadId_);
1382b2bf878SShuo Chen  }
139cd139dc7SShuo Chen}
140cd139dc7SShuo Chen
141cd139dc7SShuo Chenvoid Thread::start()
142cd139dc7SShuo Chen{
143cd139dc7SShuo Chen  assert(!started_);
144cd139dc7SShuo Chen  started_ = true;
1452b2bf878SShuo Chen
1462b2bf878SShuo Chen  ThreadData* data = new ThreadData(func_, name_, tid_);
1472b2bf878SShuo Chen  if (pthread_create(&pthreadId_, NULL, &startThread, data))
1482b2bf878SShuo Chen  {
1492b2bf878SShuo Chen    started_ = false;
1502b2bf878SShuo Chen    delete data;
1512b2bf878SShuo Chen    abort();
1522b2bf878SShuo Chen  }
153cd139dc7SShuo Chen}
154cd139dc7SShuo Chen
155cd139dc7SShuo Chenvoid Thread::join()
156cd139dc7SShuo Chen{
157cd139dc7SShuo Chen  assert(started_);
1582b2bf878SShuo Chen  assert(!joined_);
1592b2bf878SShuo Chen  joined_ = true;
160cd139dc7SShuo Chen  pthread_join(pthreadId_, NULL);
161cd139dc7SShuo Chen}
162