blob: 337ea48b97e82e92af8bb20d93e059aec3995ac8 [file] [log] [blame]
#ifndef AOS_UTIL_THREAD_H_
#define AOS_UTIL_THREAD_H_
#include <functional>
#include <atomic>
#include <pthread.h>
#include "aos/macros.h"
namespace aos {
namespace util {
// A nice wrapper around a pthreads thread.
//
// TODO(aschuh): replace this with std::thread
class Thread {
public:
Thread();
virtual ~Thread();
// Actually creates the thread.
void Start();
// Asks the code to stop and then waits until it has done so.
// This or TryJoin() (returning true) must be called exactly once for every
// instance.
void Join();
// If the code has already finished, returns true. Does not block waiting if
// it isn't.
// Join() must not be called on this instance if this returns true.
// This must return true or Join() must be called exactly once for every
// instance.
bool TryJoin();
// Asks the code to stop (in preparation for a Join()).
void RequestStop();
// Waits until the code has stopped. Does not ask it to do so.
void WaitUntilDone();
protected:
// Subclasses need to call this periodically if they are going to loop to
// check whether they have been asked to stop.
bool should_continue() {
return !should_terminate_.load();
}
private:
// Where subclasses actually do something.
//
// They should not block for long periods of time without checking
// should_continue().
virtual void Run() = 0;
static void *StaticRun(void *self);
pthread_t thread_;
bool started_;
bool joined_;
::std::atomic_bool should_terminate_;
DISALLOW_COPY_AND_ASSIGN(Thread);
};
class FunctionThread : public Thread {
public:
FunctionThread(::std::function<void(FunctionThread *)> function)
: function_(function) {}
// Runs function in a new thread and waits for it to return.
static void RunInOtherThread(::std::function<void()> function) {
FunctionThread t([&function](FunctionThread *) { function(); });
t.Start();
t.Join();
}
private:
virtual void Run() override {
function_(this);
}
const ::std::function<void(FunctionThread *)> function_;
};
} // namespace util
} // namespace aos
#endif // AOS_UTIL_THREAD_H_