blob: 993e34394ea58115e66f90f09f05d12d8be5198a [file] [log] [blame]
Brian Silverman798c7782013-03-28 16:48:02 -07001#ifndef AOS_COMMON_UTIL_THREAD_H_
2#define AOS_COMMON_UTIL_THREAD_H_
3
Brian Silverman653491d2014-05-13 16:53:29 -07004#include <functional>
Brian Silvermand4c48322014-09-06 21:17:29 -04005#include <atomic>
Brian Silverman653491d2014-05-13 16:53:29 -07006
Brian Silvermand4c48322014-09-06 21:17:29 -04007#include <pthread.h>
8
Brian Silverman653491d2014-05-13 16:53:29 -07009#include "aos/common/macros.h"
Brian Silverman798c7782013-03-28 16:48:02 -070010
11namespace aos {
12namespace util {
13
14// A nice wrapper around a pthreads thread.
15//
16// TODO(aschuh): Test this.
17class Thread {
18 public:
19 Thread();
Brian Silverman3d5e6972013-09-06 17:30:36 -070020 virtual ~Thread();
Brian Silverman798c7782013-03-28 16:48:02 -070021
22 // Actually creates the thread.
23 void Start();
24
25 // Asks the code to stop and then waits until it has done so.
Brian Silverman325c5972014-09-04 16:12:09 -040026 // This or TryJoin() (returning true) must be called exactly once for every
27 // instance.
Brian Silverman798c7782013-03-28 16:48:02 -070028 void Join();
29
Brian Silverman325c5972014-09-04 16:12:09 -040030 // If the code has already finished, returns true. Does not block waiting if
31 // it isn't.
32 // Join() must not be called on this instance if this returns true.
33 // This must return true or Join() must be called exactly once for every
34 // instance.
35 bool TryJoin();
36
37 // Asks the code to stop (in preparation for a Join()).
38 void RequestStop();
39
Brian Silverman653491d2014-05-13 16:53:29 -070040 // Waits until the code has stopped. Does not ask it to do so.
41 void WaitUntilDone();
42
Brian Silverman798c7782013-03-28 16:48:02 -070043 protected:
44 // Subclasses need to call this periodically if they are going to loop to
45 // check whether they have been asked to stop.
46 bool should_continue() {
Brian Silvermand4c48322014-09-06 21:17:29 -040047 return !should_terminate_.load();
Brian Silverman798c7782013-03-28 16:48:02 -070048 }
49
50 private:
51 // Where subclasses actually do something.
52 //
53 // They should not block for long periods of time without checking
54 // should_continue().
55 virtual void Run() = 0;
56
57 static void *StaticRun(void *self);
58
59 pthread_t thread_;
60 bool started_;
61 bool joined_;
Brian Silvermand4c48322014-09-06 21:17:29 -040062 ::std::atomic_bool should_terminate_;
Brian Silverman653491d2014-05-13 16:53:29 -070063
64 DISALLOW_COPY_AND_ASSIGN(Thread);
65};
66
67class FunctionThread : public Thread {
68 public:
69 FunctionThread(::std::function<void(FunctionThread *)> function)
70 : function_(function) {}
71
Brian Silverman8cfd92c2014-09-04 16:12:43 -040072 // Runs function in a new thread and waits for it to return.
73 static void RunInOtherThread(::std::function<void()> function) {
74 FunctionThread t([&function](FunctionThread *) { function(); });
75 t.Start();
76 t.Join();
77 }
78
Brian Silverman653491d2014-05-13 16:53:29 -070079 private:
80 virtual void Run() override {
81 function_(this);
82 }
83
84 const ::std::function<void(FunctionThread *)> function_;
Brian Silverman798c7782013-03-28 16:48:02 -070085};
86
87} // namespace util
88} // namespace aos
89
90#endif // AOS_COMMON_UTIL_THREAD_H_