DelegateSimpleThread

来源:互联网 发布:杂志 知乎 编辑:程序博客网 时间:2024/06/06 11:44

 

class SimpleThread : public PlatformThread::Delegate {

 public:

  class Options {

   public:

    Options() : stack_size_(0) { }

    ~Options() { }

 

    // We use the standard compiler-supplied copy constructor.

 

    // A custom stack size, or 0 for the system default.

    void set_stack_size(size_t size) { stack_size_ = size; }

    size_t stack_size() const { return stack_size_; }

   private:

    size_t stack_size_;

  };

 

  // Create a SimpleThread.  |options| should be used to manage any specific

  // configuration involving the thread creation and management.

  // Every thread has a name, in the form of |name_prefix|/TID, for example

  // "my_thread/321".  The thread will not be created until Start() is called.

  explicit SimpleThread(const std::string& name_prefix)

      : name_prefix_(name_prefix), name_(name_prefix),

        thread_(), event_(true, false), tid_(0), joined_(false) { }

  SimpleThread(const std::string& name_prefix, const Options& options)

      : name_prefix_(name_prefix), name_(name_prefix), options_(options),

        thread_(), event_(true, false), tid_(0), joined_(false) { }

 

  virtual ~SimpleThread();

 

  virtual void Start();

  virtual void Join();

 

  // We follow the PlatformThread Delegate interface.

  virtual void ThreadMain();

 

  // Subclasses should override the Run method.

  virtual void Run() = 0;

 

  // Return the thread name prefix, or "unnamed" if none was supplied.

  std::string name_prefix() { return name_prefix_; }

 

  // Return the completed name including TID, only valid after Start().

  std::string name() { return name_; }

 

  // Return the thread id, only valid after Start().

  PlatformThreadId tid() { return tid_; }

 

  // Return True if Start() has ever been called.

  bool HasBeenStarted() { return event_.IsSignaled(); }

 

  // Return True if Join() has evern been called.

  bool HasBeenJoined() { return joined_; }

 

 private:

  const std::string name_prefix_;

  std::string name_;

  const Options options_;

  PlatformThreadHandle thread_;  // PlatformThread handle, invalid after Join!

  WaitableEvent event_;          // Signaled if Start() was ever called.

  PlatformThreadId tid_;         // The backing thread's id.

  bool joined_;                  // True if Join has been called.

};

void SimpleThread::Start() {
  DCHECK(!HasBeenStarted()) << "Tried to Start a thread multiple times.";
  bool success = PlatformThread::Create(options_.stack_size(), this, &thread_);
  CHECK(success);
  event_.Wait();  // Wait for the thread to complete initialization.
}
void SimpleThread::Join() {
  DCHECK(HasBeenStarted()) << "Tried to Join a never-started thread.";
  DCHECK(!HasBeenJoined()) << "Tried to Join a thread multiple times.";
  PlatformThread::Join(thread_);
  joined_ = true;
}
void SimpleThread::ThreadMain() {
  tid_ = PlatformThread::CurrentId();
  // Construct our full name of the form "name_prefix_/TID".
  name_.push_back('/');
  name_.append(IntToString(tid_));
  PlatformThread::SetName(name_.c_str());
  // We've initialized our new thread, signal that we're done to Start().
  event_.Signal();
  Run();
}
SimpleThread::~SimpleThread() {
  DCHECK(HasBeenStarted()) << "SimpleThread was never started.";
  DCHECK(HasBeenJoined()) << "SimpleThread destroyed without being Join()ed.";
}
class DelegateSimpleThread : public SimpleThread {
 public:
  class Delegate {
   public:
    Delegate() { }
    virtual ~Delegate() { }
    virtual void Run() = 0;
  };
  DelegateSimpleThread(Delegate* delegate,
                       const std::string& name_prefix)
      : SimpleThread(name_prefix), delegate_(delegate) { }
  DelegateSimpleThread(Delegate* delegate,
                       const std::string& name_prefix,
                       const Options& options)
      : SimpleThread(name_prefix, options), delegate_(delegate) { }
  virtual ~DelegateSimpleThread() { }
  virtual void Run();
 private:
  Delegate* delegate_;
};
void DelegateSimpleThread::Run() {
  DCHECK(delegate_) << "Tried to call Run without a delegate (called twice?)";
  delegate_->Run();
  delegate_ = NULL;
}

 

原创粉丝点击