proxygen
folly::ManualExecutor Class Reference

#include <ManualExecutor.h>

Inheritance diagram for folly::ManualExecutor:
folly::DrivableExecutor folly::ScheduledExecutor folly::SequencedExecutor folly::Executor folly::Executor folly::Executor

Classes

struct  ScheduledFunc
 

Public Member Functions

 ~ManualExecutor ()
 
void add (Func) override
 
size_t run ()
 
size_t drain ()
 
void wait ()
 Wait for work to do. More...
 
void makeProgress ()
 Wait for work to do, and do it. More...
 
void drive () override
 Implements DrivableExecutor. More...
 
template<class F >
void waitFor (F const &f)
 makeProgress until this Future is ready. More...
 
void scheduleAt (Func &&f, TimePoint const &t) override
 
void advance (Duration const &dur)
 
void advanceTo (TimePoint const &t)
 
TimePoint now () override
 Get this executor's notion of time. Must be threadsafe. More...
 
std::size_t clear ()
 
- Public Member Functions inherited from folly::DrivableExecutor
 ~DrivableExecutor () override=default
 
- Public Member Functions inherited from folly::Executor
virtual ~Executor ()
 
virtual void addWithPriority (Func, int8_t priority)
 
virtual uint8_t getNumPriorities () const
 
- Public Member Functions inherited from folly::ScheduledExecutor
 ~ScheduledExecutor () override=default
 
void schedule (Func &&a)
 Alias for add() (for Rx consistency) More...
 
void schedule (Func &&a, Duration const &dur)
 

Private Attributes

std::mutex lock_
 
std::queue< Funcfuncs_
 
LifoSem sem_
 
std::priority_queue< ScheduledFuncscheduledFuncs_
 
TimePoint now_ = TimePoint::min()
 

Additional Inherited Members

- Public Types inherited from folly::ScheduledExecutor
typedef std::chrono::microseconds Duration
 
typedef std::chrono::steady_clock::time_point TimePoint
 
- Static Public Member Functions inherited from folly::Executor
template<typename ExecutorT >
static KeepAlive< ExecutorT > getKeepAliveToken (ExecutorT *executor)
 
template<typename ExecutorT >
static KeepAlive< ExecutorT > getKeepAliveToken (ExecutorT &executor)
 
- Static Public Attributes inherited from folly::Executor
static const int8_t LO_PRI = SCHAR_MIN
 
static const int8_t MID_PRI = 0
 
static const int8_t HI_PRI = SCHAR_MAX
 
- Protected Member Functions inherited from folly::Executor
virtual bool keepAliveAcquire ()
 
virtual void keepAliveRelease ()
 
- Static Protected Member Functions inherited from folly::Executor
template<typename ExecutorT >
static bool isKeepAliveDummy (const KeepAlive< ExecutorT > &keepAlive)
 
template<typename ExecutorT >
static KeepAlive< ExecutorT > makeKeepAlive (ExecutorT *executor)
 

Detailed Description

A ManualExecutor only does work when you turn the crank, by calling run() or indirectly with makeProgress() or waitFor().

The clock for a manual executor starts at 0 and advances only when you ask it to. i.e. time is also under manual control.

NB No attempt has been made to make anything other than add and schedule threadsafe.

Definition at line 38 of file ManualExecutor.h.

Constructor & Destructor Documentation

folly::ManualExecutor::~ManualExecutor ( )

Definition at line 25 of file ManualExecutor.cpp.

References drain().

25  {
26  drain();
27 }

Member Function Documentation

void folly::ManualExecutor::add ( Func  )
overridevirtual

Enqueue a function to executed by this executor. This and all variants must be threadsafe.

Implements folly::ScheduledExecutor.

Definition at line 29 of file ManualExecutor.cpp.

References funcs_, folly::lock(), lock_, folly::gen::move, folly::detail::LifoSemBase< Handoff, Atom >::post(), and sem_.

Referenced by TEST().

29  {
30  std::lock_guard<std::mutex> lock(lock_);
31  funcs_.emplace(std::move(callback));
32  sem_.post();
33 }
std::queue< Func > funcs_
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
void folly::ManualExecutor::advance ( Duration const &  dur)
inline

Advance the clock. The clock never advances on its own. Advancing the clock causes some work to be done, if work is available to do (perhaps newly available because of the advanced clock). If dur is <= 0 this is a noop.

Definition at line 100 of file ManualExecutor.h.

References advanceTo(), now_, and folly::pushmi::detail::t.

Referenced by TEST().

100  {
101  advanceTo(now_ + dur);
102  }
void advanceTo(TimePoint const &t)
void folly::ManualExecutor::advanceTo ( TimePoint const &  t)

Advance the clock to this absolute time. If t is <= now(), this is a noop.

Definition at line 98 of file ManualExecutor.cpp.

References now_, run(), and folly::pushmi::detail::t.

Referenced by advance(), and TEST().

98  {
99  if (t > now_) {
100  now_ = t;
101  }
102  run();
103 }
std::size_t folly::ManualExecutor::clear ( )
inline

Flush the function queue. Destroys all stored functions without executing them. Returns number of removed functions.

Definition at line 114 of file ManualExecutor.h.

References funcs_, folly::lock(), lock_, and scheduledFuncs_.

Referenced by TEST().

114  {
115  std::queue<Func> funcs;
116  std::priority_queue<ScheduledFunc> scheduled_funcs;
117 
118  {
119  std::lock_guard<std::mutex> lock(lock_);
120  funcs_.swap(funcs);
121  scheduledFuncs_.swap(scheduled_funcs);
122  }
123 
124  return funcs.size() + scheduled_funcs.size();
125  }
std::queue< Func > funcs_
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
std::priority_queue< ScheduledFunc > scheduledFuncs_
size_t folly::ManualExecutor::drain ( )

Definition at line 76 of file ManualExecutor.cpp.

References run().

Referenced by TEST(), and ~ManualExecutor().

76  {
77  size_t tasksRun = 0;
78  size_t tasksForSingleRun = 0;
79  while ((tasksForSingleRun = run()) != 0) {
80  tasksRun += tasksForSingleRun;
81  }
82  return tasksRun;
83 }
void folly::ManualExecutor::drive ( )
inlineoverridevirtual

Implements DrivableExecutor.

Implements folly::DrivableExecutor.

Definition at line 72 of file ManualExecutor.h.

References makeProgress().

72  {
73  makeProgress();
74  }
void makeProgress()
Wait for work to do, and do it.
void folly::ManualExecutor::makeProgress ( )
inline

Wait for work to do, and do it.

Definition at line 66 of file ManualExecutor.h.

References run(), and wait().

Referenced by drive(), and waitFor().

66  {
67  wait();
68  run();
69  }
void wait()
Wait for work to do.
TimePoint folly::ManualExecutor::now ( )
inlineoverridevirtual

Get this executor's notion of time. Must be threadsafe.

Reimplemented from folly::ScheduledExecutor.

Definition at line 108 of file ManualExecutor.h.

References now_.

Referenced by TEST().

108  {
109  return now_;
110  }
size_t folly::ManualExecutor::run ( )

Do work. Returns the number of functions that were executed (maybe 0). Non-blocking, in the sense that we don't wait for work (we can't control whether one of the functions blocks). This is stable, it will not chase an ever-increasing tail of work. This also means, there may be more work available to perform at the moment that this returns.

Definition at line 35 of file ManualExecutor.cpp.

References count, funcs_, folly::lock(), lock_, folly::gen::move, now_, scheduledFuncs_, sem_, and folly::detail::LifoSemBase< Handoff, Atom >::tryWait().

Referenced by advanceTo(), drain(), makeProgress(), TEST(), and waitFor().

35  {
36  size_t count;
37  size_t n;
38  Func func;
39 
40  {
41  std::lock_guard<std::mutex> lock(lock_);
42 
43  while (!scheduledFuncs_.empty()) {
44  auto& sf = scheduledFuncs_.top();
45  if (sf.time > now_) {
46  break;
47  }
48  funcs_.emplace(sf.moveOutFunc());
49  scheduledFuncs_.pop();
50  }
51 
52  n = funcs_.size();
53  }
54 
55  for (count = 0; count < n; count++) {
56  {
57  std::lock_guard<std::mutex> lock(lock_);
58  if (funcs_.empty()) {
59  break;
60  }
61 
62  // Balance the semaphore so it doesn't grow without bound
63  // if nobody is calling wait().
64  // This may fail (with EAGAIN), that's fine.
65  sem_.tryWait();
66 
67  func = std::move(funcs_.front());
68  funcs_.pop();
69  }
70  func();
71  }
72 
73  return count;
74 }
std::queue< Func > funcs_
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Function< void()> Func
Definition: Executor.h:27
bool tryWait()
Returns true iff value was decremented.
Definition: LifoSem.h:430
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
int * count
std::priority_queue< ScheduledFunc > scheduledFuncs_
void folly::ManualExecutor::scheduleAt ( Func &&  ,
TimePoint const &   
)
inlineoverridevirtual

Schedule a Func to be executed at time t, or as soon afterward as possible. Expect millisecond resolution at best. Must be threadsafe.

Reimplemented from folly::ScheduledExecutor.

Definition at line 90 of file ManualExecutor.h.

References f, folly::lock(), lock_, folly::gen::move, folly::detail::LifoSemBase< Handoff, Atom >::post(), scheduledFuncs_, and sem_.

Referenced by TEST().

90  {
91  std::lock_guard<std::mutex> lock(lock_);
92  scheduledFuncs_.emplace(t, std::move(f));
93  sem_.post();
94  }
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
std::priority_queue< ScheduledFunc > scheduledFuncs_
void folly::ManualExecutor::wait ( )

Wait for work to do.

Definition at line 85 of file ManualExecutor.cpp.

References funcs_, folly::lock(), lock_, sem_, and folly::detail::LifoSemBase< Handoff, Atom >::wait().

Referenced by makeProgress().

85  {
86  while (true) {
87  {
88  std::lock_guard<std::mutex> lock(lock_);
89  if (!funcs_.empty()) {
90  break;
91  }
92  }
93 
94  sem_.wait();
95  }
96 }
std::queue< Func > funcs_
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
template<class F >
void folly::ManualExecutor::waitFor ( F const &  f)
inline

makeProgress until this Future is ready.

Definition at line 78 of file ManualExecutor.h.

References makeProgress(), and run().

Referenced by TEST().

78  {
79  // TODO(5427828)
80 #if 0
81  while (!f.isReady())
82  makeProgress();
83 #else
84  while (!f.isReady()) {
85  run();
86  }
87 #endif
88  }
auto f
void makeProgress()
Wait for work to do, and do it.

Member Data Documentation

std::queue<Func> folly::ManualExecutor::funcs_
private

Definition at line 129 of file ManualExecutor.h.

Referenced by add(), clear(), run(), and wait().

std::mutex folly::ManualExecutor::lock_
private

Definition at line 128 of file ManualExecutor.h.

Referenced by add(), clear(), run(), scheduleAt(), and wait().

TimePoint folly::ManualExecutor::now_ = TimePoint::min()
private

Definition at line 158 of file ManualExecutor.h.

Referenced by advance(), advanceTo(), now(), and run().

std::priority_queue<ScheduledFunc> folly::ManualExecutor::scheduledFuncs_
private

Definition at line 157 of file ManualExecutor.h.

Referenced by clear(), run(), and scheduleAt().

LifoSem folly::ManualExecutor::sem_
private

Definition at line 130 of file ManualExecutor.h.

Referenced by add(), run(), scheduleAt(), and wait().


The documentation for this class was generated from the following files: